source: git/Singular/dyn_modules/gfanlib/groebnerCone.cc @ e744d9

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