source: git/Singular/dyn_modules/gfanlib/bbpolytope.cc @ a6574c3

fieker-DuValspielwiese
Last change on this file since a6574c3 was a6574c3, checked in by Yue <ren@…>, 8 years ago
fix: memoryleak due to missing deallocation of cddlib global variables
  • Property mode set to 100644
File size: 15.0 KB
Line 
1#include <kernel/mod2.h>
2
3#if HAVE_GFANLIB
4
5#include <Singular/ipid.h>
6#include <Singular/ipshell.h>
7#include <Singular/blackbox.h>
8#include <misc/intvec.h>
9#include <coeffs/bigintmat.h>
10
11#include <callgfanlib_conversion.h>
12#include <sstream>
13
14#include <gfanlib/gfanlib.h>
15#include <gfanlib/gfanlib_q.h>
16
17int polytopeID;
18
19std::string bbpolytopeToString(gfan::ZCone const &c)
20{
21  std::stringstream s;
22  gfan::ZMatrix i=c.getInequalities();
23  gfan::ZMatrix e=c.getEquations();
24  s<<"AMBIENT_DIM"<<std::endl;
25  s<<c.ambientDimension()-1<<std::endl;
26  s<<"INEQUALITIES"<<std::endl;
27  s<<toString(i)<<std::endl;
28  s<<"EQUATIONS"<<std::endl;
29  s<<toString(e)<<std::endl;
30  return s.str();
31}
32
33void *bbpolytope_Init(blackbox* /*b*/)
34{
35  return (void*)(new gfan::ZCone());
36}
37
38BOOLEAN bbpolytope_Assign(leftv l, leftv r)
39{
40  gfan::ZCone* newZc;
41  if (r==NULL)
42  {
43    if (l->Data()!=NULL)
44    {
45      gfan::ZCone* zd = (gfan::ZCone*)l->Data();
46      delete zd;
47    }
48    newZc = new gfan::ZCone();
49  }
50  else if (r->Typ()==l->Typ())
51  {
52    if (l->Data()!=NULL)
53    {
54      gfan::ZCone* zd = (gfan::ZCone*)l->Data();
55      delete zd;
56    }
57    gfan::ZCone* zc = (gfan::ZCone*)r->Data();
58    newZc = new gfan::ZCone(*zc);
59  }
60  // else if (r->Typ()==INT_CMD)  TODO:r->Typ()==BIGINTMAT_CMD
61  // {
62  //   int ambientDim = (int)(long)r->Data();
63  //   if (ambientDim < 0)
64  //   {
65  //     Werror("expected an int >= 0, but got %d", ambientDim);
66  //     return TRUE;
67  //   }
68  //   if (l->Data()!=NULL)
69  //   {
70  //     gfan::ZCone* zd = (gfan::ZCone*)l->Data();
71  //     delete zd;
72  //   }
73  //   newZc = new gfan::ZCone(ambientDim);
74  // }
75  else
76  {
77    Werror("assign Type(%d) = Type(%d) not implemented",l->Typ(),r->Typ());
78    return TRUE;
79  }
80
81  if (l->rtyp==IDHDL)
82  {
83    IDDATA((idhdl)l->data) = (char*) newZc;
84  }
85  else
86  {
87    l->data=(void *)newZc;
88  }
89  return FALSE;
90}
91
92char* bbpolytope_String(blackbox* /*b*/, void *d)
93{ if (d==NULL) return omStrDup("invalid object");
94   else
95   {
96     gfan::ZCone* zc = (gfan::ZCone*)d;
97     std::string s=bbpolytopeToString(*zc);
98     return omStrDup(s.c_str());
99   }
100}
101
102void bbpolytope_destroy(blackbox* /*b*/, void *d)
103{
104  if (d!=NULL)
105  {
106    gfan::ZCone* zc = (gfan::ZCone*) d;
107    delete zc;
108  }
109}
110
111void* bbpolytope_Copy(blackbox* /*b*/, void *d)
112{
113  gfan::ZCone* zc = (gfan::ZCone*)d;
114  gfan::ZCone* newZc = new gfan::ZCone(*zc);
115  return newZc;
116}
117
118static BOOLEAN ppCONERAYS1(leftv res, leftv v)
119{
120  /* method for generating a cone object from half-lines
121     (cone = convex hull of the half-lines; note: there may be
122     entire lines in the cone);
123     valid parametrizations: (bigintmat) */
124  bigintmat* rays = NULL;
125  if (v->Typ() == INTMAT_CMD)
126  {
127    intvec* rays0 = (intvec*) v->Data();
128    rays = iv2bim(rays0,coeffs_BIGINT);
129  }
130  else
131    rays = (bigintmat*) v->Data();
132
133  gfan::ZMatrix* zm = bigintmatToZMatrix(rays);
134  gfan::ZCone* zc = new gfan::ZCone();
135  *zc = gfan::ZCone::givenByRays(*zm, gfan::ZMatrix(0, zm->getWidth()));
136  res->rtyp = polytopeID;
137  res->data = (void*) zc;
138
139  delete zm;
140  if (v->Typ() == INTMAT_CMD)
141    delete rays;
142  return FALSE;
143}
144
145static BOOLEAN ppCONERAYS3(leftv res, leftv u, leftv v)
146{
147  /* method for generating a cone object from half-lines
148     (any point in the cone being the sum of a point
149     in the convex hull of the half-lines and a point in the span
150     of the lines), and an integer k;
151     valid parametrizations: (bigintmat, int);
152     Errors will be invoked in the following cases:
153     - k not 0 or 1;
154     if the k=1, then the extreme rays are known:
155     each half-line spans a (different) extreme ray */
156  bigintmat* rays = NULL;
157  if (u->Typ() == INTMAT_CMD)
158  {
159    intvec* rays0 = (intvec*) u->Data();
160    rays = iv2bim(rays0,coeffs_BIGINT);
161  }
162  else
163    rays = (bigintmat*) u->Data();
164  int k = (int)(long)v->Data();
165
166  if ((k < 0) || (k > 1))
167  {
168    WerrorS("expected int argument in [0..1]");
169    return TRUE;
170  }
171  k=k*2;
172  gfan::ZMatrix* zm = bigintmatToZMatrix(rays);
173  gfan::ZCone* zc = new gfan::ZCone();
174  *zc = gfan::ZCone::givenByRays(*zm,gfan::ZMatrix(0, zm->getWidth()));
175  //k should be passed on to zc; not available yet
176  res->rtyp = polytopeID;
177  res->data = (void*) zc;
178
179  delete zm;
180  if (v->Typ() == INTMAT_CMD)
181    delete rays;
182  return FALSE;
183}
184
185BOOLEAN polytopeViaVertices(leftv res, leftv args)
186{
187  gfan::deinitializeCddlibIfRequired();
188  gfan::initializeCddlibIfRequired();
189  leftv u = args;
190  if ((u != NULL) && ((u->Typ() == BIGINTMAT_CMD) || (u->Typ() == INTMAT_CMD)))
191  {
192    if (u->next == NULL) return ppCONERAYS1(res, u);
193    leftv v = u->next;
194    if ((v != NULL) && (v->Typ() == INT_CMD))
195    {
196      if (v->next == NULL) return ppCONERAYS3(res, u, v);
197    }
198  }
199  WerrorS("polytopeViaPoints: unexpected parameters");
200  return TRUE;
201}
202
203static BOOLEAN ppCONENORMALS1(leftv res, leftv v)
204{
205  /* method for generating a cone object from inequalities;
206     valid parametrizations: (bigintmat) */
207  bigintmat* ineq = NULL;
208  if (v->Typ() == INTMAT_CMD)
209  {
210    intvec* ineq0 = (intvec*) v->Data();
211    ineq = iv2bim(ineq0,coeffs_BIGINT);
212  }
213  else
214    ineq = (bigintmat*) v->Data();
215  gfan::ZMatrix* zm = bigintmatToZMatrix(ineq);
216  gfan::ZCone* zc = new gfan::ZCone(*zm, gfan::ZMatrix(0, zm->getWidth()));
217  delete zm;
218  if (v->Typ() == INTMAT_CMD)
219    delete ineq;
220  res->rtyp = polytopeID;
221  res->data = (void*) zc;
222  return FALSE;
223}
224
225static BOOLEAN ppCONENORMALS2(leftv res, leftv u, leftv v)
226{
227  /* method for generating a cone object from iequalities,
228     and equations (...)
229     valid parametrizations: (bigintmat, bigintmat)
230     Errors will be invoked in the following cases:
231     - u and v have different numbers of columns */
232  bigintmat* ineq = NULL; bigintmat* eq = NULL;
233  if (u->Typ() == INTMAT_CMD)
234  {
235    intvec* ineq0 = (intvec*) u->Data();
236    ineq = iv2bim(ineq0,coeffs_BIGINT);
237  }
238  else
239    ineq = (bigintmat*) u->Data();
240  if (v->Typ() == INTMAT_CMD)
241  {
242    intvec* eq0 = (intvec*) v->Data();
243    eq = iv2bim(eq0,coeffs_BIGINT);
244  }
245  else
246    eq = (bigintmat*) v->Data();
247
248  if (ineq->cols() != eq->cols())
249  {
250    Werror("expected same number of columns but got %d vs. %d",
251           ineq->cols(), eq->cols());
252    return TRUE;
253  }
254  gfan::ZMatrix* zm1 = bigintmatToZMatrix(ineq);
255  gfan::ZMatrix* zm2 = bigintmatToZMatrix(eq);
256  gfan::ZCone* zc = new gfan::ZCone(*zm1, *zm2);
257  delete zm1;
258  delete zm2;
259  if (u->Typ() == INTMAT_CMD)
260    delete ineq;
261  if (v->Typ() == INTMAT_CMD)
262    delete eq;
263
264  res->rtyp = polytopeID;
265  res->data = (void*) zc;
266  return FALSE;
267}
268
269static BOOLEAN ppCONENORMALS3(leftv res, leftv u, leftv v, leftv w)
270{
271  /* method for generating a cone object from inequalities, equations,
272     and an integer k;
273     valid parametrizations: (bigintmat, bigintmat, int);
274     Errors will be invoked in the following cases:
275     - u and v have different numbers of columns,
276     - k not in [0..3];
277     if the 2^0-bit of k is set, then ... */
278  bigintmat* ineq = NULL; bigintmat* eq = NULL;
279  if (u->Typ() == INTMAT_CMD)
280  {
281    intvec* ineq0 = (intvec*) u->Data();
282    ineq = iv2bim(ineq0,coeffs_BIGINT);
283  }
284  else
285    ineq = (bigintmat*) u->Data();
286  if (v->Typ() == INTMAT_CMD)
287  {
288    intvec* eq0 = (intvec*) v->Data();
289    eq = iv2bim(eq0,coeffs_BIGINT);
290  }
291  else
292    eq = (bigintmat*) v->Data();
293
294  if (ineq->cols() != eq->cols())
295  {
296    Werror("expected same number of columns but got %d vs. %d",
297           ineq->cols(), eq->cols());
298    return TRUE;
299  }
300  int k = (int)(long)w->Data();
301  if ((k < 0) || (k > 3))
302  {
303    WerrorS("expected int argument in [0..3]");
304    return TRUE;
305  }
306  gfan::ZMatrix* zm1 = bigintmatToZMatrix(ineq);
307  gfan::ZMatrix* zm2 = bigintmatToZMatrix(eq);
308  gfan::ZCone* zc = new gfan::ZCone(*zm1, *zm2, k);
309  delete zm1;
310  delete zm2;
311  if (u->Typ() == INTMAT_CMD)
312    delete ineq;
313  if (v->Typ() == INTMAT_CMD)
314    delete eq;
315
316  res->rtyp = polytopeID;
317  res->data = (void*) zc;
318  return FALSE;
319}
320
321BOOLEAN polytopeViaNormals(leftv res, leftv args)
322{
323  gfan::deinitializeCddlibIfRequired();
324  gfan::initializeCddlibIfRequired();
325  leftv u = args;
326  if ((u != NULL) && ((u->Typ() == BIGINTMAT_CMD) || (u->Typ() == INTMAT_CMD)))
327  {
328    if (u->next == NULL) return ppCONENORMALS1(res, u);
329  }
330  leftv v = u->next;
331  if ((v != NULL) && ((v->Typ() == BIGINTMAT_CMD) || (v->Typ() == INTMAT_CMD)))
332  {
333    if (v->next == NULL) return ppCONENORMALS2(res, u, v);
334  }
335  leftv w = v->next;
336  if ((w != NULL) && (w->Typ() == INT_CMD))
337  {
338    if (w->next == NULL) return ppCONENORMALS3(res, u, v, w);
339  }
340  WerrorS("polytopeViaInequalities: unexpected parameters");
341  return TRUE;
342}
343
344BOOLEAN vertices(leftv res, leftv args)
345{
346  gfan::deinitializeCddlibIfRequired();
347  gfan::initializeCddlibIfRequired();
348  leftv u = args;
349  if ((u != NULL) && (u->Typ() == polytopeID))
350    {
351      gfan::ZCone* zc = (gfan::ZCone*)u->Data();
352      gfan::ZMatrix zmat = zc->extremeRays();
353      res->rtyp = BIGINTMAT_CMD;
354      res->data = (void*)zMatrixToBigintmat(zmat);
355      return FALSE;
356    }
357  WerrorS("vertices: unexpected parameters");
358  return TRUE;
359}
360
361int getAmbientDimension(gfan::ZCone* zc) // zc is meant to represent a polytope here
362{                                        // hence ambientDimension-1
363  return zc->ambientDimension()-1;
364}
365
366int getCodimension(gfan::ZCone *zc)
367{
368  return zc->codimension();
369}
370
371int getDimension(gfan::ZCone* zc)
372{
373  return zc->dimension()-1;
374}
375
376gfan::ZVector intStar2ZVectorWithLeadingOne(const int d, const int* i)
377{
378  gfan::ZVector zv(d+1);
379  zv[0]=1;
380  for(int j=1; j<=d; j++)
381  {
382    zv[j]=i[j];
383  }
384  return zv;
385}
386
387gfan::ZCone newtonPolytope(poly p, ring r)
388{
389  int N = rVar(r);
390  gfan::ZMatrix zm(0,N+1);
391  int *leadexpv = (int*)omAlloc((N+1)*sizeof(int));
392  while (p!=NULL)
393  {
394    p_GetExpV(p,leadexpv,r);
395    gfan::ZVector zv = intStar2ZVectorWithLeadingOne(N, leadexpv);
396    zm.appendRow(zv);
397    pIter(p);
398  }
399  omFreeSize(leadexpv,(N+1)*sizeof(int));
400  gfan::ZCone Delta = gfan::ZCone::givenByRays(zm,gfan::ZMatrix(0, zm.getWidth()));
401  return Delta;
402}
403
404BOOLEAN newtonPolytope(leftv res, leftv args)
405{
406  gfan::deinitializeCddlibIfRequired();
407  gfan::initializeCddlibIfRequired();
408  leftv u = args;
409  if ((u != NULL) && (u->Typ() == POLY_CMD))
410  {
411    poly p = (poly)u->Data();
412    res->rtyp = polytopeID;
413    res->data = (void*) new gfan::ZCone(newtonPolytope(p,currRing));
414    return FALSE;
415  }
416  WerrorS("newtonPolytope: unexpected parameters");
417  return TRUE;
418}
419
420BOOLEAN scalePolytope(leftv res, leftv args)
421{
422  gfan::deinitializeCddlibIfRequired();
423  gfan::initializeCddlibIfRequired();
424  leftv u = args;
425  if ((u != NULL) && (u->Typ() == INT_CMD))
426  {
427    leftv v = u->next;
428    if ((v != NULL) && (v->Typ() == polytopeID))
429    {
430      int s = (int)(long) u->Data();
431      gfan::ZCone* zp = (gfan::ZCone*) v->Data();
432      gfan::ZMatrix zm = zp->extremeRays();
433      for (int i=0; i<zm.getHeight(); i++)
434        for (int j=1; j<zm.getWidth(); j++)
435          zm[i][j]*=s;
436      gfan::ZCone* zq = new gfan::ZCone();
437      *zq = gfan::ZCone::givenByRays(zm,gfan::ZMatrix(0, zm.getWidth()));
438      res->rtyp = polytopeID;
439      res->data = (void*) zq;
440      return FALSE;
441    }
442  }
443  WerrorS("scalePolytope: unexpected parameters");
444  return TRUE;
445}
446
447BOOLEAN dualPolytope(leftv res, leftv args)
448{
449  gfan::deinitializeCddlibIfRequired();
450  gfan::initializeCddlibIfRequired();
451  leftv u = args;
452  if ((u != NULL) && (u->Typ() == polytopeID))
453  {
454    gfan::ZCone* zp = (gfan::ZCone*) u->Data();
455    gfan::ZCone* zq = new gfan::ZCone(zp->dualCone());
456    res->rtyp = polytopeID;
457    res->data = (void*) zq;
458    return FALSE;
459  }
460  WerrorS("dualPolytope: unexpected parameters");
461  return TRUE;
462}
463
464BOOLEAN mixedVolume(leftv res, leftv args)
465{
466  gfan::deinitializeCddlibIfRequired();
467  gfan::initializeCddlibIfRequired();
468  leftv u = args;
469  if ((u != NULL) && (u->Typ() == LIST_CMD))
470  {
471    lists l = (lists) u->Data();
472    int k = lSize(l)+1;
473    std::vector<gfan::IntMatrix> P(k);
474    for (int i=0; i<k; i++)
475    {
476      if (l->m[i].Typ() == polytopeID)
477      {
478        gfan::ZCone* p = (gfan::ZCone*) l->m[i].Data();
479        gfan::ZMatrix pv = p->extremeRays();
480        int r = pv.getHeight();
481        int c = pv.getWidth();
482        gfan::IntMatrix pw(r,c-1);
483        for (int n=0; n<r; n++)
484          for (int m=1; m<c; m++)
485            pw[n][m-1] = pv[n][m].toInt();
486        P[i]=pw.transposed();
487      } else if (l->m[i].Typ() == POLY_CMD)
488      {
489        poly p = (poly) l->m[i].Data();
490        int N = rVar(currRing);
491        gfan::IntMatrix pw(0,N);
492        int *leadexpv = (int*)omAlloc((N+1)*sizeof(int));
493        while (p!=NULL)
494        {
495          p_GetExpV(p,leadexpv,currRing);
496          gfan::IntVector zv(N);
497          for (int i=0; i<N; i++)
498            zv[i] = leadexpv[i+1];
499          pw.appendRow(zv);
500          pIter(p);
501        }
502        P[i]=pw.transposed();
503        omFreeSize(leadexpv,(N+1)*sizeof(int));
504      }
505      else
506      {
507        WerrorS("mixedVolume: entries of unsupported type in list");
508        return TRUE;
509      }
510    }
511    gfan::Integer mv = gfan::mixedVolume(P);
512
513    res->rtyp = BIGINT_CMD;
514    res->data = (void*) integerToNumber(mv);
515    return FALSE;
516  }
517  WerrorS("mixedVolume: unexpected parameters");
518  return TRUE;
519}
520
521
522
523void bbpolytope_setup(SModulFunctions* p)
524{
525  blackbox *b=(blackbox*)omAlloc0(sizeof(blackbox));
526  // all undefined entries will be set to default in setBlackboxStuff
527  // the default Print is quite usefule,
528  // all other are simply error messages
529  b->blackbox_destroy=bbpolytope_destroy;
530  b->blackbox_String=bbpolytope_String;
531  //b->blackbox_Print=blackbox_default_Print;
532  b->blackbox_Init=bbpolytope_Init;
533  b->blackbox_Copy=bbpolytope_Copy;
534  b->blackbox_Assign=bbpolytope_Assign;
535  p->iiAddCproc("gfan.lib","polytopeViaPoints",FALSE,polytopeViaVertices);
536  p->iiAddCproc("gfan.lib","polytopeViaInequalities",FALSE,polytopeViaNormals);
537  p->iiAddCproc("gfan.lib","vertices",FALSE,vertices);
538  p->iiAddCproc("gfan.lib","newtonPolytope",FALSE,newtonPolytope);
539  p->iiAddCproc("gfan.lib","scalePolytope",FALSE,scalePolytope);
540  p->iiAddCproc("gfan.lib","dualPolytope",FALSE,dualPolytope);
541  p->iiAddCproc("gfan.lib","mixedVolume",FALSE,mixedVolume);
542  /********************************************************/
543  /* the following functions are implemented in bbcone.cc */
544  // iiAddCproc("gfan.lib","getAmbientDimension",FALSE,getAmbientDimension);
545  // iiAddCproc("gfan.lib","getCodimension",FALSE,getAmbientDimension);
546  // iiAddCproc("gfan.lib","getDimension",FALSE,getDimension);
547  /********************************************************/
548  /* the following functions are identical to those in bbcone.cc */
549  // iiAddCproc("gfan.lib","facets",FALSE,facets);
550  // iiAddCproc("gfan.lib","setLinearForms",FALSE,setLinearForms);
551  // iiAddCproc("gfan.lib","getLinearForms",FALSE,getLinearForms);
552  // iiAddCproc("gfan.lib","setMultiplicity",FALSE,setMultiplicity);
553  // iiAddCproc("gfan.lib","getMultiplicity",FALSE,getMultiplicity);
554  // iiAddCproc("gfan.lib","hasFace",FALSE,hasFace);
555  /***************************************************************/
556  // iiAddCproc("gfan.lib","getEquations",FALSE,getEquations);
557  // iiAddCproc("gfan.lib","getInequalities",FALSE,getInequalities);
558  polytopeID=setBlackboxStuff(b,"polytope");
559  //Print("created type %d (polytope)\n",polytopeID);
560}
561
562#endif
Note: See TracBrowser for help on using the repository browser.