source: git/Singular/dyn_modules/gfanlib/groebnerCone.cc @ 78abc7

fieker-DuValspielwiese
Last change on this file since 78abc7 was 78abc7, checked in by Yue Ren <ren@…>, 10 years ago
chg: status update 18.08.
  • Property mode set to 100644
File size: 17.1 KB
Line 
1#include <utility>
2
3#include <kernel/GBEngine/kstd1.h>
4#include <kernel/ideals.h>
5#include <Singular/ipid.h>
6
7#include <libpolys/polys/monomials/p_polys.h>
8#include <libpolys/polys/monomials/ring.h>
9#include <libpolys/polys/prCopy.h>
10
11#include <gfanlib/gfanlib.h>
12#include <gfanlib/gfanlib_matrix.h>
13
14#include <tropicalStrategy.h>
15#include <groebnerCone.h>
16#include <callgfanlib_conversion.h>
17#include <containsMonomial.h>
18#include <initial.h>
19#include <flip.h>
20#include <tropicalCurves.h>
21#include <bbcone.h>
22
23static bool checkPolynomialInput(const ideal I, const ring r)
24{
25  if (r) rTest(r);
26  if (I && r) id_Test(I,r);
27  return ((!I) || (I && r));
28}
29
30static bool checkOrderingAndCone(const ring r, const gfan::ZCone zc)
31{
32  if (r)
33  {
34    int n = rVar(r); int* w = r->wvhdl[0];
35    gfan::ZVector v = wvhdlEntryToZVector(n,w);
36    if (r->order[0]==ringorder_ws)
37      v = gfan::Integer((long)-1)*v;
38    if (!zc.contains(v))
39    {
40      std::cout << "ERROR: weight of ordering not inside Groebner cone!" << std::endl
41                << "cone: " << std::endl
42                << toString(&zc)
43                << "weight: " << std::endl
44                << v << std::endl;
45      return false;
46    }
47    return true;
48  }
49  return (zc.dimension()==0);
50}
51
52static bool checkPolyhedralInput(const gfan::ZCone zc, const gfan::ZVector p)
53{
54  return zc.containsRelatively(p);
55}
56
57groebnerCone::groebnerCone():
58  polynomialIdeal(NULL),
59  polynomialRing(NULL),
60  polyhedralCone(gfan::ZCone(0)),
61  interiorPoint(gfan::ZVector(0)),
62  currentStrategy(NULL)
63{
64}
65
66groebnerCone::groebnerCone(const ideal I, const ring r, const tropicalStrategy& currentCase):
67  polynomialIdeal(NULL),
68  polynomialRing(NULL),
69  currentStrategy(&currentCase)
70{
71  assume(checkPolynomialInput(I,r));
72  if (I) polynomialIdeal = id_Copy(I,r);
73  if (r) polynomialRing = rCopy(r);
74
75  int n = rVar(polynomialRing);
76  poly g = NULL;
77  int* leadexpv = (int*) omAlloc((n+1)*sizeof(int));
78  int* tailexpv = (int*) omAlloc((n+1)*sizeof(int));
79  gfan::ZVector leadexpw = gfan::ZVector(n);
80  gfan::ZVector tailexpw = gfan::ZVector(n);
81  gfan::ZMatrix inequalities = gfan::ZMatrix(0,n);
82  for (int i=0; i<idSize(polynomialIdeal); i++)
83  {
84    g = polynomialIdeal->m[i];
85    pGetExpV(g,leadexpv);
86    leadexpw = intStar2ZVector(n, leadexpv);
87    pIter(g);
88    while (g)
89    {
90      pGetExpV(g,tailexpv);
91      tailexpw = intStar2ZVector(n, tailexpv);
92      inequalities.appendRow(leadexpw-tailexpw);
93      pIter(g);
94    }
95  }
96  omFreeSize(leadexpv,(n+1)*sizeof(int));
97  omFreeSize(tailexpv,(n+1)*sizeof(int));
98  polyhedralCone = gfan::ZCone(inequalities,gfan::ZMatrix(0, inequalities.getWidth()));
99  interiorPoint = polyhedralCone.getRelativeInteriorPoint();
100  assume(checkOrderingAndCone(polynomialRing,polyhedralCone));
101}
102
103static bool checkOrderingAndWeight(const ideal I, const ring r, const gfan::ZVector w, const tropicalStrategy& currentCase)
104{
105  groebnerCone sigma(I,r,currentCase);
106  gfan::ZCone zc = sigma.getPolyhedralCone();
107  return zc.contains(w);
108}
109
110groebnerCone::groebnerCone(const ideal I, const ring r, const gfan::ZVector& w, const tropicalStrategy& currentCase):
111  polynomialIdeal(NULL),
112  polynomialRing(NULL),
113  currentStrategy(&currentCase)
114{
115  assume(checkPolynomialInput(I,r));
116  if (I) polynomialIdeal = id_Copy(I,r);
117  if (r) polynomialRing = rCopy(r);
118
119  int n = rVar(r);
120  gfan::ZMatrix inequalities = gfan::ZMatrix(0,n);
121  gfan::ZMatrix equations = gfan::ZMatrix(0,n);
122  int* expv = (int*) omAlloc((n+1)*sizeof(int));
123  for (int i=0; i<idSize(polynomialIdeal); i++)
124  {
125    poly g = polynomialIdeal->m[i];
126    p_GetExpV(g,expv,polynomialRing);
127    gfan::ZVector leadexpv = intStar2ZVector(n,expv);
128    long d = wDeg(g,polynomialRing,w);
129    for (pIter(g); g; pIter(g))
130    {
131      p_GetExpV(g,expv,polynomialRing);
132      gfan::ZVector tailexpv = intStar2ZVector(n,expv);
133      if (wDeg(g,polynomialRing,w)==d)
134        equations.appendRow(leadexpv-tailexpv);
135      else
136      {
137        assume(wDeg(g,polynomialRing,w)<d);
138        inequalities.appendRow(leadexpv-tailexpv);
139      }
140    }
141  }
142  omFreeSize(expv,(n+1)*sizeof(int));
143
144  polyhedralCone = gfan::ZCone(inequalities,equations);
145  interiorPoint = polyhedralCone.getRelativeInteriorPoint();
146  assume(checkOrderingAndCone(polynomialRing,polyhedralCone));
147}
148
149/***
150 * Computes the groebner cone of I around u+e*w for e>0 sufficiently small.
151 * Assumes that this cone is a face of the maximal Groenbner cone given by the ordering of r.
152 **/
153groebnerCone::groebnerCone(const ideal I, const ring r, const gfan::ZVector& u, const gfan::ZVector& w, const tropicalStrategy& currentCase):
154  polynomialIdeal(NULL),
155  polynomialRing(NULL),
156  currentStrategy(&currentCase)
157{
158  assume(checkPolynomialInput(I,r));
159  if (I) polynomialIdeal = id_Copy(I,r);
160  if (r) polynomialRing = rCopy(r);
161
162  int n = rVar(r);
163  gfan::ZMatrix inequalities = gfan::ZMatrix(0,n);
164  gfan::ZMatrix equations = gfan::ZMatrix(0,n);
165  int* expv = (int*) omAlloc((n+1)*sizeof(int));
166  for (int i=0; i<idSize(polynomialIdeal); i++)
167  {
168    poly g = polynomialIdeal->m[i];
169    p_GetExpV(g,expv,polynomialRing);
170    gfan::ZVector leadexpv = intStar2ZVector(n,expv);
171    long d1 = wDeg(g,polynomialRing,u);
172    long d2 = wDeg(g,polynomialRing,w);
173    for (pIter(g); g; pIter(g))
174    {
175      p_GetExpV(g,expv,polynomialRing);
176      gfan::ZVector tailexpv = intStar2ZVector(n,expv);
177      if (wDeg(g,polynomialRing,u)==d1 && wDeg(g,polynomialRing,w)==d2)
178        equations.appendRow(leadexpv-tailexpv);
179      else
180      {
181        assume(wDeg(g,polynomialRing,u)<d1 || wDeg(g,polynomialRing,w)<d2);
182        inequalities.appendRow(leadexpv-tailexpv);
183      }
184    }
185  }
186  omFreeSize(expv,(n+1)*sizeof(int));
187
188  polyhedralCone = gfan::ZCone(inequalities,equations);
189  interiorPoint = polyhedralCone.getRelativeInteriorPoint();
190  assume(checkOrderingAndCone(polynomialRing,polyhedralCone));
191}
192
193
194groebnerCone::groebnerCone(const ideal I, const ideal inI, const ring r, const tropicalStrategy& currentCase):
195  polynomialIdeal(id_Copy(I,r)),
196  polynomialRing(rCopy(r)),
197  currentStrategy(&currentCase)
198{
199  assume(checkPolynomialInput(I,r));
200  assume(checkPolynomialInput(inI,r));
201  int n = rVar(r);
202  gfan::ZMatrix equations = gfan::ZMatrix(0,n);
203  int* expv = (int*) omAlloc((n+1)*sizeof(int));
204  for (int i=0; i<idSize(inI); i++)
205  {
206    poly g = inI->m[i];
207    p_GetExpV(g,expv,r);
208    gfan::ZVector leadexpv = intStar2ZVector(n,expv);
209    for (pIter(g); g; pIter(g))
210    {
211      p_GetExpV(g,expv,r);
212      gfan::ZVector tailexpv = intStar2ZVector(n,expv);
213      equations.appendRow(leadexpv-tailexpv);
214    }
215  }
216  gfan::ZMatrix inequalities = gfan::ZMatrix(0,n);
217  for (int i=0; i<idSize(I); i++)
218  {
219    poly g = I->m[i];
220    p_GetExpV(g,expv,r);
221    gfan::ZVector leadexpv = intStar2ZVector(n,expv);
222    for (pIter(g); g; pIter(g))
223    {
224      p_GetExpV(g,expv,r);
225      gfan::ZVector tailexpv = intStar2ZVector(n,expv);
226      inequalities.appendRow(leadexpv-tailexpv);
227    }
228  }
229  omFreeSize(expv,(n+1)*sizeof(int));
230
231  polyhedralCone = gfan::ZCone(inequalities,equations);
232  interiorPoint = polyhedralCone.getRelativeInteriorPoint();
233  assume(checkOrderingAndCone(polynomialRing,polyhedralCone));
234}
235
236groebnerCone::groebnerCone(const groebnerCone &sigma):
237  polynomialIdeal(NULL),
238  polynomialRing(NULL),
239  polyhedralCone(gfan::ZCone(sigma.getPolyhedralCone())),
240  interiorPoint(gfan::ZVector(sigma.getInteriorPoint())),
241  currentStrategy(sigma.getTropicalStrategy())
242{
243  assume(checkPolynomialInput(sigma.getPolynomialIdeal(),sigma.getPolynomialRing()));
244  assume(checkOrderingAndCone(sigma.getPolynomialRing(),sigma.getPolyhedralCone()));
245  assume(checkPolyhedralInput(sigma.getPolyhedralCone(),sigma.getInteriorPoint()));
246  if (sigma.getPolynomialIdeal()) polynomialIdeal = id_Copy(sigma.getPolynomialIdeal(),sigma.getPolynomialRing());
247  if (sigma.getPolynomialRing()) polynomialRing = rCopy(sigma.getPolynomialRing());
248}
249
250groebnerCone::~groebnerCone()
251{
252  assume(checkPolynomialInput(polynomialIdeal,polynomialRing));
253  assume(checkOrderingAndCone(polynomialRing,polyhedralCone));
254  assume(checkPolyhedralInput(polyhedralCone,interiorPoint));
255  if (polynomialIdeal) id_Delete(&polynomialIdeal,polynomialRing);
256  if (polynomialRing) rDelete(polynomialRing);
257}
258
259groebnerCone& groebnerCone::operator=(const groebnerCone& sigma)
260{
261  assume(checkPolynomialInput(sigma.getPolynomialIdeal(),sigma.getPolynomialRing()));
262  assume(checkOrderingAndCone(sigma.getPolynomialRing(),sigma.getPolyhedralCone()));
263  assume(checkPolyhedralInput(sigma.getPolyhedralCone(),sigma.getInteriorPoint()));
264  if (sigma.getPolynomialIdeal()) polynomialIdeal = id_Copy(sigma.getPolynomialIdeal(),sigma.getPolynomialRing());
265  if (sigma.getPolynomialRing()) polynomialRing = rCopy(sigma.getPolynomialRing());
266  polyhedralCone = sigma.getPolyhedralCone();
267  interiorPoint = sigma.getInteriorPoint();
268  currentStrategy = sigma.getTropicalStrategy();
269  return *this;
270}
271
272
273/***
274 * Returns a point in the tropical variety, if the groebnerCone contains one.
275 * Returns an empty vector otherwise.
276 **/
277gfan::ZVector groebnerCone::tropicalPoint() const
278{
279  ideal I = polynomialIdeal;
280  ring r = polynomialRing;
281  gfan::ZCone zc = polyhedralCone;
282  gfan::ZMatrix R = zc.extremeRays();
283  assume(checkOrderingAndCone(r,zc));
284  for (int i=0; i<R.getHeight(); i++)
285  {
286    ideal inI = initial(I,r,R[i]);
287    poly s = checkForMonomialViaSuddenSaturation(inI,r);
288    if (s == NULL)
289    {
290      id_Delete(&inI,r);
291      p_Delete(&s,r);
292      return R[i];
293    }
294    id_Delete(&inI,r);
295    p_Delete(&s,r);
296  }
297  return gfan::ZVector();
298}
299
300bool groebnerCone::checkFlipConeInput(const gfan::ZVector interiorPoint, const gfan::ZVector facetNormal) const
301{
302  /* check first whether interiorPoint lies on the boundary of the cone */
303  if (!polyhedralCone.contains(interiorPoint))
304  {
305    std::cout << "ERROR: interiorPoint is not contained in the Groebner cone!" << std::endl
306              << "cone: " << std::endl
307              << toString(&polyhedralCone)
308              << "interiorPoint:" << std::endl
309              << interiorPoint << std::endl;
310    return false;
311  }
312  gfan::ZCone hopefullyAFacet = polyhedralCone.faceContaining(interiorPoint);
313  if (hopefullyAFacet.dimension()!=(polyhedralCone.dimension()-1))
314  {
315    std::cout << "ERROR: interiorPoint is not contained in the interior of a facet!" << std::endl
316              << "cone: " << std::endl
317              << toString(&polyhedralCone)
318              << "interiorPoint:" << std::endl
319              << interiorPoint << std::endl;
320    return false;
321  }
322  /* check whether facet normal points outwards */
323  gfan::ZCone dual = polyhedralCone.dualCone();
324  if(dual.contains(facetNormal))
325  {
326    std::cout << "ERROR: facetNormal is not pointing outwards!" << std::endl
327              << "cone: " << std::endl
328              << toString(&polyhedralCone)
329              << "facetNormal:" << std::endl
330              << facetNormal << std::endl;
331    return false;
332  }
333  return true;
334}
335
336/***
337 * Given an interior point on the facet and the outer normal factor on the facet,
338 * returns the adjacent groebnerCone sharing that facet
339 **/
340groebnerCone groebnerCone::flipCone(const gfan::ZVector interiorPoint, const gfan::ZVector facetNormal) const
341{
342  assume(this->checkFlipConeInput(interiorPoint,facetNormal));
343  /* Note: the polynomial ring created will have a weighted ordering with respect to interiorPoint
344   *   and with a weighted ordering with respect to facetNormal as tiebreaker.
345   *   Hence it is sufficient to compute the initial form with respect to facetNormal,
346   *   to obtain an initial form with respect to interiorPoint+e*facetNormal,
347   *   for e>0 sufficiently small */
348  std::pair<ideal,ring> flipped = flip(polynomialIdeal,polynomialRing,interiorPoint,facetNormal,*currentStrategy);
349  assume(checkPolynomialInput(flipped.first,flipped.second));
350  groebnerCone flippedCone(flipped.first, flipped.second, interiorPoint, facetNormal, *currentStrategy);
351  return flippedCone;
352}
353
354
355/***
356 * Computes a relative interior point and an outer normal vector for each facet of zc
357 **/
358static std::pair<gfan::ZMatrix,gfan::ZMatrix> interiorPointsAndNormalsOfFacets(const gfan::ZCone zc)
359{
360  gfan::ZMatrix inequalities = zc.getFacets();
361  gfan::ZMatrix equations = zc.getImpliedEquations();
362  int r = inequalities.getHeight();
363  int c = inequalities.getWidth();
364
365  /* our cone has r facets, if r==0 return empty matrices */
366  gfan::ZMatrix relativeInteriorPoints = gfan::ZMatrix(0,c);
367  gfan::ZMatrix outerFacetNormals = gfan::ZMatrix(0,c);
368  if (r==0)
369    return std::make_pair(relativeInteriorPoints,outerFacetNormals);
370
371  /* next we iterate over each of the r facets,
372   * build the respective cone and add it to the list
373   * this is the i=0 case */
374  gfan::ZMatrix newInequalities = inequalities.submatrix(1,0,r,c);
375  gfan::ZMatrix newEquations = equations;
376  newEquations.appendRow(inequalities[0]);
377  gfan::ZCone facet = gfan::ZCone(newInequalities,newEquations);
378  relativeInteriorPoints.appendRow(facet.getRelativeInteriorPoint());
379  assume(zc.contains(relativeInteriorPoints[0]) && !zc.containsRelatively(relativeInteriorPoints[0]));
380  outerFacetNormals.appendRow(-inequalities[0]);
381
382  /* these are the cases i=1,...,r-2 */
383  for (int i=1; i<r-1; i++)
384  {
385    newInequalities = inequalities.submatrix(0,0,i,c);
386    newInequalities.append(inequalities.submatrix(i+1,0,r,c));
387    newEquations = equations;
388    newEquations.appendRow(inequalities[i]);
389    facet = gfan::ZCone(newInequalities,newEquations);
390    relativeInteriorPoints.appendRow(facet.getRelativeInteriorPoint());
391    assume(zc.contains(relativeInteriorPoints[i]) && !zc.containsRelatively(relativeInteriorPoints[i]));
392    outerFacetNormals.appendRow(-inequalities[i]);
393  }
394
395  /* this is the i=r-1 case */
396  newInequalities = inequalities.submatrix(0,0,r-1,c);
397  newEquations = equations;
398  newEquations.appendRow(inequalities[r-1]);
399  facet = gfan::ZCone(newInequalities,newEquations);
400  relativeInteriorPoints.appendRow(facet.getRelativeInteriorPoint());
401  assume(zc.contains(relativeInteriorPoints[r-1]) && !zc.containsRelatively(relativeInteriorPoints[r-1]));
402  outerFacetNormals.appendRow(-inequalities[r-1]);
403
404  return std::make_pair(relativeInteriorPoints,outerFacetNormals);
405}
406
407
408/***
409 * Returns a complete list of neighboring Groebner cones.
410 **/
411groebnerCones groebnerCone::groebnerNeighbours() const
412{
413  std::pair<gfan::ZMatrix, gfan::ZMatrix> facetsData = interiorPointsAndNormalsOfFacets(polyhedralCone);
414  gfan::ZMatrix interiorPoints = facetsData.first;
415  gfan::ZMatrix facetNormals = facetsData.second;
416
417  groebnerCones neighbours;
418  for (int i=0; i<interiorPoints.getHeight(); i++)
419    neighbours.insert(this->flipCone(interiorPoints[i],facetNormals[i]));
420
421  return neighbours;
422}
423
424
425/***
426 * Computes a relative interior point for each facet of zc
427 **/
428static gfan::ZMatrix interiorPointsOfFacets(const gfan::ZCone zc)
429{
430  gfan::ZMatrix inequalities = zc.getFacets();
431  gfan::ZMatrix equations = zc.getImpliedEquations();
432  int r = inequalities.getHeight();
433  int c = inequalities.getWidth();
434
435  /* our cone has r facets, if r==0 return empty matrices */
436  gfan::ZMatrix relativeInteriorPoints = gfan::ZMatrix(0,c);
437  if (r==0) return relativeInteriorPoints;
438
439  /* next we iterate over each of the r facets,
440   * build the respective cone and add it to the list
441   * this is the i=0 case */
442  gfan::ZMatrix newInequalities = inequalities.submatrix(1,0,r,c);
443  gfan::ZMatrix newEquations = equations;
444  newEquations.appendRow(inequalities[0]);
445  gfan::ZCone facet = gfan::ZCone(newInequalities,newEquations);
446  relativeInteriorPoints.appendRow(facet.getRelativeInteriorPoint());
447
448  /* these are the cases i=1,...,r-2 */
449  for (int i=1; i<r-1; i++)
450  {
451    newInequalities = inequalities.submatrix(0,0,i-1,c);
452    newInequalities.append(inequalities.submatrix(i+1,0,r,c));
453    newEquations = equations;
454    newEquations.appendRow(inequalities[i]);
455    facet = gfan::ZCone(newInequalities,newEquations);
456    relativeInteriorPoints.appendRow(facet.getRelativeInteriorPoint());
457  }
458
459  /* this is the i=r-1 case */
460  newInequalities = inequalities.submatrix(0,0,r-1,c);
461  newEquations = equations;
462  newEquations.appendRow(inequalities[r-1]);
463  facet = gfan::ZCone(newInequalities,newEquations);
464  relativeInteriorPoints.appendRow(facet.getRelativeInteriorPoint());
465
466  return relativeInteriorPoints;
467}
468
469
470/***
471 * Returns a complete list of neighboring Groebner cones in the tropical variety.
472 **/
473groebnerCones groebnerCone::tropicalNeighbours() const
474{
475  gfan::ZMatrix interiorPoints = interiorPointsOfFacets(polyhedralCone);
476  groebnerCones neighbours;
477  for (int i=0; i<interiorPoints.getHeight(); i++)
478  {
479    ideal initialIdeal = initial(polynomialIdeal,polynomialRing,interiorPoints[i]);
480    std::set<gfan::ZVector> rays = raysOfTropicalStar(initialIdeal,polynomialRing,interiorPoints[i],*currentStrategy);
481    for (std::set<gfan::ZVector>::iterator ray = rays.begin(); ray!=rays.end(); ray++)
482      neighbours.insert(this->flipCone(interiorPoints[i],*ray));
483  }
484  return neighbours;
485}
486
487
488gfan::ZFan* toFanStar(groebnerCones setOfCones)
489{
490  if (setOfCones.size() > 0)
491  {
492    groebnerCones::iterator sigma = setOfCones.begin();
493    gfan::ZFan* zf = new gfan::ZFan(sigma->getPolyhedralCone().ambientDimension());
494    for (; sigma!=setOfCones.end(); sigma++)
495      zf->insert(sigma->getPolyhedralCone());
496    return zf;
497  }
498  else
499    return new gfan::ZFan(gfan::ZFan::fullFan(currRing->N));
500}
Note: See TracBrowser for help on using the repository browser.