source: git/dyn_modules/callpolymake/polymake_conversion.cc @ 47e8b04

spielwiese
Last change on this file since 47e8b04 was 47e8b04, checked in by Yue Ren <ren@…>, 11 years ago
new: first try in polymake interface
  • Property mode set to 100644
File size: 12.5 KB
Line 
1#include <gmpxx.h>
2
3#include <polymake/Main.h>
4#include <polymake/Matrix.h>
5#include <polymake/Rational.h>
6#include <polymake/Integer.h>
7#include <polymake/Set.h>
8#include <polymake/common/lattice_tools.h>
9// #include <polymake/perl/macros.h>
10// #include <polymake/IncidenceMatrix.h>
11
12#include <gfanlib/gfanlib.h>
13#include <gfanlib/gfanlib_q.h>
14
15#include <kernel/mod2.h>
16// #include <kernel/structs.h>
17// #include <kernel/febase.h>
18#include <libpolys/misc/intvec.h>
19
20// #include <callgfanlib/bbcone.h>
21// #include <callgfanlib/bbfan.h>
22// #include <callgfanlib/bbpolytope.h>
23
24// #include <Singular/blackbox.h>
25// #include <Singular/ipshell.h>
26// #include <Singular/subexpr.h>
27// #include <Singular/tok.h>
28
29
30/* Functions for converting Integers, Rationals and their Matrices
31   in between C++, gfan, polymake and singular */
32
33/* gfan -> polymake */
34
35polymake::Integer GfInteger2PmInteger (const gfan::Integer& gi)
36{
37  mpz_t cache; mpz_init(cache);
38  gi.setGmp(cache);
39  polymake::Integer pi(cache);
40  return pi;
41}
42
43polymake::Rational GfRational2PmRational (const gfan::Rational& gr)
44{
45  mpq_t cache; mpq_init(cache);
46  gr.setGmp(cache);
47  polymake::Rational pr(cache);
48  return pr;
49}
50
51polymake::Vector<polymake::Integer> Intvec2PmVectorInteger (const intvec* iv)
52{
53  polymake::Vector<polymake::Integer> vi(iv->length());
54  for(int i=1; i<=iv->length(); i++)
55  {
56    vi[i-1]=(*iv)[i-1];
57  }
58  return vi;
59}
60
61polymake::Matrix<polymake::Integer> GfZMatrix2PmMatrixInteger (const gfan::ZMatrix* zm)
62{
63  int rows=zm->getHeight();
64  int cols=zm->getWidth();
65  polymake::Matrix<polymake::Integer> mi(rows,cols);
66  for(int r=1; r<=rows; r++)
67    for(int c=1; c<=cols; c++)
68      mi(r-1,c-1) = GfInteger2PmInteger((*zm)[r-1][c-1]);
69  return mi;
70}
71
72polymake::Matrix<polymake::Rational> GfQMatrix2PmMatrixRational (const gfan::QMatrix* qm)
73{
74  int rows=qm->getHeight();
75  int cols=qm->getWidth();
76  polymake::Matrix<polymake::Rational> mr(rows,cols);
77  for(int r=1; r<=rows; r++)
78    for(int c=1; c<=cols; c++)
79      mr(r-1,c-1) = GfRational2PmRational((*qm)[r-1][c-1]);
80  return mr;
81}
82
83/* gfan <- polymake */
84
85gfan::Integer PmInteger2GfInteger (const polymake::Integer& pi)
86{
87  mpz_class cache(pi.get_rep());
88  gfan::Integer gi(cache.get_mpz_t());
89  return gi;
90}
91
92gfan::Rational PmRational2GfRational (const polymake::Rational& pr)
93{
94  mpq_class cache(pr.get_rep());
95  gfan::Rational gr(cache.get_mpq_t());
96  return gr;
97}
98
99gfan::ZMatrix PmMatrixInteger2GfZMatrix (const polymake::Matrix<polymake::Integer>* mi)
100{
101  int rows=mi->rows();
102  int cols=mi->cols();
103  gfan::ZMatrix zm(rows,cols);
104  for(int r=1; r<=rows; r++)
105    for(int c=1; c<=cols; c++)
106      zm[r-1][c-1] = PmInteger2GfInteger((*mi)(r-1,c-1));
107  return zm;
108}
109
110gfan::QMatrix PmMatrixRational2GfQMatrix (const polymake::Matrix<polymake::Rational>* mr)
111{
112  int rows=mr->rows();
113  int cols=mr->cols();
114  gfan::QMatrix qm(rows,cols);
115  for(int r=1; r<=rows; r++)
116    for(int c=1; c<=cols; c++)
117      qm[r-1][c-1] = PmRational2GfRational((*mr)(r-1,c-1));
118  return qm;
119}
120
121/* polymake -> singular */
122
123int PmInteger2Int(const polymake::Integer& pi, bool &ok)
124{
125  int i=0;
126  try
127  {
128    i = pi.to_int();
129  }
130  catch (const std::exception& ex)
131  {
132    WerrorS("ERROR: "); WerrorS(ex.what()); WerrorS("\n");
133    ok = false;
134  }
135  return i;
136}
137
138intvec* PmVectorInteger2Intvec (const polymake::Vector<polymake::Integer>* vi, bool &ok)
139{
140  intvec* iv = new intvec(vi->size());
141  for(int i=1; i<=vi->size(); i++)
142  {
143    (*iv)[i-1] = PmInteger2Int((*vi)[i-1],ok);
144  }
145  return iv;
146}
147
148intvec* PmMatrixInteger2Intvec (polymake::Matrix<polymake::Integer>* mi, bool &ok)
149{
150  int rows = mi->rows();
151  int cols = mi->cols();
152  intvec* iv = new intvec(rows,cols,0);
153  const polymake::Integer* pi = concat_rows(*mi).begin();
154  for (int r = 1; r <= rows; r++)
155    for (int c = 1; c <= cols; c++)
156    {
157      IMATELEM(*iv,r,c) = PmInteger2Int(*pi, ok);
158      pi++;
159    }
160  return iv;
161}
162
163// intvec* PmIncidenceMatrix2Intvec (polymake::IncidenceMatrix<polymake::NonSymmetric>* icmat)
164// {
165//   int rows = icmat->rows();
166//   int cols = icmat->cols();
167//   intvec* iv = new intvec(rows,cols,0);
168//   for (int r = 1; r <= rows; r++)
169//     for (int c = 1; c <= cols; c++)
170//       IMATELEM(*iv,r,c) = (int) (*icmat).row(r).exists(c);
171//   return iv;
172// }
173
174intvec* PmSetInteger2Intvec (polymake::Set<polymake::Integer>* si, bool &b)
175{
176  polymake::Vector<polymake::Integer> vi(*si);
177  return PmVectorInteger2Intvec(&vi,b);
178}
179
180/* polymake <- singular */
181
182polymake::Matrix<polymake::Integer> Intvec2PmMatrixInteger (const intvec* im)
183{
184  int rows=im->rows();
185  int cols=im->cols();
186  polymake::Matrix<polymake::Integer> mi(rows,cols);
187  for(int r=0; r<rows; r++)
188    for(int c=0; c<cols; c++)
189      mi(r,c) = polymake::Integer(IMATELEM(*im, r+1, c+1));
190  return mi;
191}
192
193/* Functions for converting cones and fans in between gfan and polymake,
194   Singular shares the same cones and fans with gfan */
195
196gfan::ZCone* PmCone2ZCone (polymake::perl::Object* pc)
197{
198  if (pc->isa("Cone"))
199  {
200    polymake::Integer ambientdim1 = pc->give("CONE_AMBIENT_DIM");
201    bool ok=true; int ambientdim2 = PmInteger2Int(ambientdim1, ok);
202    if (!ok)
203    {
204      WerrorS("PmCone2ZCone: overflow while converting polymake::Integer to int");
205    }
206    polymake::Matrix<polymake::Rational> ineqrational = pc->give("FACETS");
207    polymake::Matrix<polymake::Rational> eqrational = pc->give("LINEAR_SPAN");
208    // polymake::Matrix<polymake::Rational> exraysrational = pc->give("RAYS");
209    // polymake::Matrix<polymake::Rational> linrational = pc->give("LINEALITY_SPACE");
210
211    gfan::ZMatrix zv, zw, zx, zy, zz;
212    // the following branching statements are to cover cases in which polymake returns empty matrices
213    // by convention, gfanlib ignores empty matrices, hence zero matrices of right dimensions have to be supplied
214    if (ineqrational.cols()!=0)
215    {
216      polymake::Matrix<polymake::Integer> ineqinteger = polymake::common::primitive(ineqrational);
217      zv = PmMatrixInteger2GfZMatrix(&ineqinteger);
218    }
219    else
220      zv = gfan::ZMatrix(0, ambientdim2);
221    if (eqrational.cols()!=0)
222    {
223      polymake::Matrix<polymake::Integer> eqinteger = polymake::common::primitive(eqrational);
224      zw = PmMatrixInteger2GfZMatrix(&eqinteger);
225    }
226    else
227      zw = gfan::ZMatrix(0, ambientdim2);
228    // if (exraysrational.cols()!=0)
229    // {
230    //   polymake::Matrix<polymake::Integer> exraysinteger = polymake::common::primitive(exraysrational);
231    //   zx = PmMatrixInteger2GfZMatrix(&exraysinteger);
232    // }
233    // else
234    //   zx = gfan::ZMatrix(0, ambientdim2);
235    // if (linrational.cols()!=0)
236    // {
237    //   polymake::Matrix<polymake::Integer> lininteger = polymake::common::primitive(linrational);
238    //   zy = PmMatrixInteger2GfZMatrix(&lininteger);
239    // }
240    // else
241    //   zy = gfan::ZMatrix(0, ambientdim2);
242
243    // gfan::ZCone* zc = new gfan::ZCone(zv,zw,zx,zy,zz,3);
244    gfan::ZCone* zc = new gfan::ZCone(zv,zw,3);
245    return zc;
246  }
247  WerrorS("PmCone2ZCone: unexpected parameters");
248  return NULL;
249}
250
251gfan::ZCone* PmPolytope2ZPolytope (polymake::perl::Object* pp)
252{
253  if (pp->isa("Polytope<Rational>"))
254  {
255    polymake::Integer ambientdim1 = pp->give("CONE_AMBIENT_DIM");
256    bool ok=true; int ambientdim2 = PmInteger2Int(ambientdim1, ok);
257    if (!ok)
258    {
259      WerrorS("overflow while converting polymake::Integer to int");
260    }
261    polymake::Matrix<polymake::Rational> ineqrational = pp->give("FACETS");
262    polymake::Matrix<polymake::Rational> eqrational = pp->give("AFFINE_HULL");
263    // polymake::Matrix<polymake::Rational> vertrational = pp->give("VERTICES");
264    // polymake::Matrix<polymake::Rational> linrational = pp->give("LINEALITY_SPACE");
265
266    gfan::ZMatrix zv, zw;
267    // the following branching statements are to cover the cases when polymake returns empty matrices
268    // by convention, gfanlib ignores empty matrices, hence zero matrices of right dimensions have to be supplied
269    if (ineqrational.cols()!=0)
270    {
271      polymake::Matrix<polymake::Integer> ineqinteger = polymake::common::primitive(ineqrational);
272      zv = PmMatrixInteger2GfZMatrix(&ineqinteger);
273    }
274    else
275      zv = gfan::ZMatrix(0, ambientdim2);
276
277    if (eqrational.cols()!=0)
278    {
279      polymake::Matrix<polymake::Integer> eqinteger = polymake::common::primitive(eqrational);
280      zw = PmMatrixInteger2GfZMatrix(&eqinteger);
281    }
282    else
283      zw = gfan::ZMatrix(0, ambientdim2);
284
285    // if (vertrational.cols()!=0)
286    // {
287    //   polymake::Matrix<polymake::Integer> vertinteger = polymake::common::primitive(vertrational);
288    //   zx = PmMatrixInteger2GfZMatrix(&vertinteger);
289    // }
290    // else
291    //   zx = gfan::ZMatrix(0, ambientdim2);
292    // if (linrational.cols()!=0)
293    //   {
294    //     polymake::Matrix<polymake::Integer> lininteger = polymake::common::primitive(linrational);
295    //     zy = PmMatrixInteger2GfZMatrix(&lininteger);
296    //   }
297    // else
298    //   zy = gfan::ZMatrix(0, ambientdim2);
299
300    // gfan::ZCone* zp = new gfan::ZCone(zv,zw,zx,zy,zz,3);
301    gfan::ZCone* zp = new gfan::ZCone(zv,zw,3);
302
303    return zp;
304  }
305  WerrorS("PmPolytope2ZPolytope: unexpected parameters");
306  return NULL;
307}
308
309gfan::ZFan* PmFan2ZFan (polymake::perl::Object* pf)
310{
311  if (pf->isa("PolyhedralFan"))
312  {
313    int d = (int) pf->give("FAN_AMBIENT_DIM");
314    gfan::ZFan* zf = new gfan::ZFan(d);
315
316    int n = pf->give("N_MAXIMAL_CONES");
317    for (int i=0; i<n; i++)
318      {
319        polymake::perl::Object pmcone=pf->CallPolymakeMethod("cone",i);
320        gfan::ZCone* zc=PmCone2ZCone(&pmcone);
321        zf->insert(*zc);
322      }
323    return zf;
324  }
325  WerrorS("PmFan2ZFan: unexpected parameters");
326  return NULL;
327}
328
329polymake::perl::Object* ZCone2PmCone (gfan::ZCone* zc)
330{
331  polymake::perl::Object* gc = new polymake::perl::Object("Cone<Rational>");
332
333  gfan::ZMatrix inequalities = zc->getInequalities();
334  gc->take("FACETS") << GfZMatrix2PmMatrixInteger(&inequalities);
335
336  gfan::ZMatrix equations = zc->getEquations();
337  gc->take("LINEAR_SPAN") << GfZMatrix2PmMatrixInteger(&equations);
338
339  // if(zc->areExtremeRaysKnown())
340  //   {
341  //     gfan::ZMatrix extremeRays = zc->extremeRays();
342  //     gc->take("RAYS") << GfZMatrix2PmMatrixInteger(&extremeRays);
343  //   }
344
345  // if(zc->areGeneratorsOfLinealitySpaceKnown())
346  //   {
347  //     gfan::ZMatrix lineality = zc->generatorsOfLinealitySpace();
348  //     gc->take("LINEALITY_SPACE") << GfZMatrix2PmMatrixInteger(&lineality);
349  //   }
350
351  return gc;
352}
353
354polymake::perl::Object* ZPolytope2PmPolytope (gfan::ZCone* zc)
355{
356  polymake::perl::Object* pp = new polymake::perl::Object("Polytope<Rational>");
357
358  gfan::ZMatrix inequalities = zc->getInequalities();
359  pp->take("FACETS") << GfZMatrix2PmMatrixInteger(&inequalities);
360
361  gfan::ZMatrix equations = zc->getEquations();
362  pp->take("LINEAR_SPAN") << GfZMatrix2PmMatrixInteger(&equations);
363
364  // if(zc->areExtremeRaysKnown())
365  //   {
366  //     gfan::ZMatrix vertices = zc->extremeRays();
367  //     pp->take("VERTICES") << GfZMatrix2PmMatrixInteger(&vertices);
368  //   }
369
370  return pp;
371}
372
373polymake::Matrix<polymake::Integer> raysOf(gfan::ZFan* zf)
374{
375  int d = zf->getAmbientDimension();
376  int n = zf->numberOfConesOfDimension(1,0,0);
377  gfan::ZMatrix zm(n,d);
378
379  for (int i=0; i<n; i++)
380    {
381      gfan::ZCone zc = zf->getCone(1,i,0,0);
382      gfan::ZMatrix ray = zc.extremeRays();
383      for (int j=0; j<d; j++)
384        {
385          zm[i][j]=ray[0][j];
386        }
387    }
388
389  return GfZMatrix2PmMatrixInteger(&zm);
390}
391
392int numberOfRaysOf(gfan::ZFan* zf)
393{
394  int n = zf->numberOfConesOfDimension(1,0,0);
395  return n;
396}
397
398int numberOfMaximalConesOf(gfan::ZFan* zf)
399{
400  int d = zf->getAmbientDimension();
401  int n = 0;
402
403  for (int i=0; i<=d; i++)
404    {
405      n = n + zf->numberOfConesOfDimension(i,0,1);
406    }
407
408  return n;
409}
410
411polymake::Array<polymake::Set<int> > conesOf(gfan::ZFan* zf)
412{
413  int r = numberOfMaximalConesOf(zf);
414
415  polymake::Matrix<polymake::Integer> pm=raysOf(zf);
416  polymake::Array<polymake::Set<int> > L(r);
417
418  int ii = 0;
419  for (int d=1; d<=zf->getAmbientDimension(); d++)
420    {
421      for (int i=0; i<zf->numberOfConesOfDimension(d,0,1); i++)
422        {
423          gfan::IntVector v = zf->getConeIndices(d,i,0,1);
424          polymake::Set<int> s;
425          for (int j=0; j<(int)v.size(); j++)
426            {
427              s = s+v[j];
428            }
429          L[ii] = s;
430          ii = ii + 1;
431        }
432    }
433  return L;
434}
435
436polymake::perl::Object* ZFan2PmFan (gfan::ZFan* zf)
437{
438  polymake::perl::Object* pf = new polymake::perl::Object("PolyhedralFan");
439
440  polymake::Matrix<polymake::Integer> zm = raysOf(zf);
441  pf->take("RAYS") << zm;  // using rays here instead of INPUT_RAYS prevents redundant computations
442
443  polymake::Array<polymake::Set<int> > ar = conesOf(zf);
444  pf->take("MAXIMAL_CONES") << ar;
445
446  return pf;
447}
Note: See TracBrowser for help on using the repository browser.