source: git/dyn_modules/callgfanlib/bbpolytope.cc @ 81384b

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