source: git/Singular/dyn_modules/gfanlib/startingCone.cc @ 551009

spielwiese
Last change on this file since 551009 was 551009, checked in by Yue Ren <ren@…>, 9 years ago
new: tropicalTraversalMinimizingFlips
  • Property mode set to 100644
File size: 19.5 KB
Line 
1#include <callgfanlib_conversion.h>
2#include <containsMonomial.h>
3#include <tropical.h>
4#include <initial.h>
5#include <lift.h>
6#include <groebnerCone.h>
7#include <neighbours.h>
8#include <tropicalStrategy.h>
9#include <tropicalCurves.h>
10#include <bbcone.h>
11#include <tropicalVarietyOfPolynomials.h>
12#include <tropicalVariety.h>
13#include <tropicalStrategy.h>
14
15
16/***
17 * checks whether sigma is contained in the tropical variety
18 * by testing whether the initial Ideal with respect to the interior point
19 * is monomial free.
20 **/
21static bool checkContainmentInTropicalVariety(const groebnerCone sigma)
22{
23  ideal I = sigma.getPolynomialIdeal();
24  ring r = sigma.getPolynomialRing();
25  const tropicalStrategy* currentStrategy = sigma.getTropicalStrategy();
26
27  gfan::ZCone zc = sigma.getPolyhedralCone();
28  gfan::ZMatrix zm = zc.extremeRays();
29  for (int i=0; i<zm.getHeight(); i++)
30  {
31    gfan::ZVector w = zm[i];
32    if (currentStrategy->isValuationNonTrivial() && w[0].sign()==0)
33      continue;
34    poly s = currentStrategy->checkInitialIdealForMonomial(I,r,w);
35    if (s)
36    {
37      p_Delete(&s,r);
38      return false;
39    }
40  }
41
42  zm = zc.generatorsOfLinealitySpace();
43  for (int i=0; i<zm.getHeight(); i++)
44  {
45    gfan::ZVector w = zm[i];
46    if (currentStrategy->isValuationNonTrivial() && w[0].sign()==0)
47      continue;
48    poly s = currentStrategy->checkInitialIdealForMonomial(I,r,w);
49    if (s)
50    {
51      p_Delete(&s,r);
52      return false;
53    }
54  }
55
56  return true;
57}
58
59
60static bool checkOneCodimensionalLinealitySpace(const groebnerCone sigma)
61{
62  gfan::ZCone zc = sigma.getPolyhedralCone();
63  int linDim = zc.dimensionOfLinealitySpace();
64  int dim = zc.dimension();
65  return (linDim+1)==dim;
66}
67
68
69/**
70 * Computes a starting point outside the lineatliy space by traversing the Groebner fan,
71 * checking each cone whether it contains a ray in the tropical variety.
72 * Returns a point in the tropical variety and a maximal Groebner cone containing the point.
73 **/
74std::pair<gfan::ZVector,groebnerCone> tropicalStartingPoint(const ideal I, const ring r, const tropicalStrategy& currentStrategy)
75{
76  // start by computing a maximal Groebner cone and
77  // check whether one of its rays lies in the tropical variety
78  const groebnerCone sigma(I,r,currentStrategy);
79  gfan::ZVector startingPoint = sigma.tropicalPoint();
80  if (startingPoint.size() > 0)
81    return std::make_pair(startingPoint,sigma);
82
83  // if not, traverse the groebnerFan and until such a cone is found
84  // and return the maximal cone together with a point in its ray
85  groebnerCones groebnerFan;
86  groebnerCones workingList;
87  workingList.insert(sigma);
88  while (!workingList.empty())
89  {
90    const groebnerCone sigma = *(workingList.begin());
91    groebnerCones neighbours = sigma.groebnerNeighbours();
92    for (groebnerCones::iterator tau = neighbours.begin(); tau!=neighbours.end(); tau++)
93    {
94      if (groebnerFan.count(*tau) == 0)
95      {
96        if (workingList.count(*tau) == 0)
97        {
98          startingPoint = tau->tropicalPoint();
99          if (startingPoint.size() > 0)
100            return std::make_pair(startingPoint,*tau);
101        }
102        workingList.insert(*tau);
103      }
104    }
105    groebnerFan.insert(sigma);
106    workingList.erase(sigma);
107  }
108
109  // return some trivial output, if such a cone cannot be found
110  gfan::ZVector emptyVector = gfan::ZVector(0);
111  groebnerCone emptyCone = groebnerCone();
112  return std::pair<gfan::ZVector,groebnerCone>(emptyVector,emptyCone);
113}
114
115
116/**
117 * Computes a starting point outside the lineatliy space by traversing the Groebner fan,
118 * checking each cone whether it contains a ray in the tropical variety.
119 * Returns a point in the tropical variety and a maximal Groebner cone containing the point.
120 **/
121std::pair<gfan::ZVector,groebnerCone> tropicalStartingDataViaGroebnerFan(const ideal I, const ring r, const tropicalStrategy& currentStrategy)
122{
123  // start by computing a maximal Groebner cone and
124  // check whether one of its rays lies in the tropical variety
125  const groebnerCone sigma(I,r,currentStrategy);
126  gfan::ZVector startingPoint = sigma.tropicalPoint();
127  if (startingPoint.size() > 0)
128    return std::make_pair(startingPoint,sigma);
129
130  // if not, traverse the groebnerFan and until such a cone is found
131  // and return the maximal cone together with a point in its ray
132  groebnerCones groebnerFan;
133  groebnerCones workingList;
134  workingList.insert(sigma);
135  while (!workingList.empty())
136  {
137    const groebnerCone sigma = *(workingList.begin());
138    groebnerCones neighbours = sigma.groebnerNeighbours();
139    for (groebnerCones::iterator tau = neighbours.begin(); tau!=neighbours.end(); tau++)
140    {
141      if (groebnerFan.count(*tau) == 0)
142      {
143        if (workingList.count(*tau) == 0)
144        {
145          startingPoint = tau->tropicalPoint();
146          if (startingPoint.size() > 0)
147            return std::make_pair(startingPoint,*tau);
148        }
149        workingList.insert(*tau);
150      }
151    }
152    groebnerFan.insert(sigma);
153    workingList.erase(sigma);
154  }
155
156  // return some trivial output, if such a cone cannot be found
157  gfan::ZVector emptyVector = gfan::ZVector(0);
158  groebnerCone emptyCone = groebnerCone();
159  return std::pair<gfan::ZVector,groebnerCone>(emptyVector,emptyCone);
160}
161
162BOOLEAN positiveTropicalStartingPoint(leftv res, leftv args)
163{
164  leftv u = args;
165  if ((u!=NULL) && (u->Typ()==IDEAL_CMD))
166  {
167    ideal I = (ideal) u->Data();
168    if (idSize(I)==1)
169    {
170      tropicalStrategy currentStrategy(I,currRing);
171      poly g = I->m[0];
172      std::set<gfan::ZCone> Tg = tropicalVariety(g,currRing,&currentStrategy);
173      for (std::set<gfan::ZCone>::iterator zc=Tg.begin(); zc!=Tg.end(); zc++)
174      {
175        gfan::ZMatrix ray = zc->extremeRays();
176        for (int i=0; i<ray.getHeight(); i++)
177        {
178          if (ray[i].isPositive())
179          {
180            res->rtyp = BIGINTMAT_CMD;
181            res->data = (void*) zVectorToBigintmat(ray[i]);
182            return FALSE;
183          }
184        }
185      }
186      res->rtyp = BIGINTMAT_CMD;
187      res->data = (void*) zVectorToBigintmat(gfan::ZVector(0));
188      return FALSE;
189    }
190    WerrorS("positiveTropicalStartingPoint: ideal not principal");
191    return TRUE;
192  }
193  WerrorS("positiveTropicalStartingPoint: unexpected parameters");
194  return TRUE;
195}
196
197BOOLEAN nonNegativeTropicalStartingPoint(leftv res, leftv args)
198{
199  leftv u = args;
200  if ((u!=NULL) && (u->Typ()==IDEAL_CMD))
201  {
202    ideal I = (ideal) u->Data();
203    if (idSize(I)==1)
204    {
205      tropicalStrategy currentStrategy(I,currRing);
206      poly g = I->m[0];
207      std::set<gfan::ZCone> Tg = tropicalVariety(g,currRing,&currentStrategy);
208      for (std::set<gfan::ZCone>::iterator zc=Tg.begin(); zc!=Tg.end(); zc++)
209      {
210        gfan::ZMatrix ray = zc->extremeRays();
211        for (int i=0; i<ray.getHeight(); i++)
212        {
213          if (ray[i].isNonNegative())
214          {
215            res->rtyp = BIGINTMAT_CMD;
216            res->data = (void*) zVectorToBigintmat(ray[i]);
217            return FALSE;
218          }
219        }
220      }
221      res->rtyp = BIGINTMAT_CMD;
222      res->data = (void*) zVectorToBigintmat(gfan::ZVector(0));
223      return FALSE;
224    }
225    WerrorS("nonNegativeTropicalStartingPoint: ideal not principal");
226    return TRUE;
227  }
228  WerrorS("nonNegativeTropicalStartingPoint: unexpected parameters");
229  return TRUE;
230}
231
232BOOLEAN negativeTropicalStartingPoint(leftv res, leftv args)
233{
234  leftv u = args;
235  if ((u!=NULL) && (u->Typ()==IDEAL_CMD))
236  {
237    ideal I = (ideal) u->Data();
238    if (idSize(I)==1)
239    {
240      tropicalStrategy currentStrategy(I,currRing);
241      poly g = I->m[0];
242      std::set<gfan::ZCone> Tg = tropicalVariety(g,currRing,&currentStrategy);
243      for (std::set<gfan::ZCone>::iterator zc=Tg.begin(); zc!=Tg.end(); zc++)
244      {
245        gfan::ZMatrix ray = zc->extremeRays();
246        for (int i=0; i<ray.getHeight(); i++)
247        {
248          gfan::ZVector negatedRay = gfan::Integer(-1)*ray[i];
249          if (negatedRay.isPositive())
250          {
251            res->rtyp = BIGINTMAT_CMD;
252            res->data = (void*) zVectorToBigintmat(ray[i]);
253            return FALSE;
254          }
255        }
256      }
257      res->rtyp = BIGINTMAT_CMD;
258      res->data = (void*) zVectorToBigintmat(gfan::ZVector(0));
259      return FALSE;
260    }
261    WerrorS("negativeTropicalStartingPoint: ideal not principal");
262    return TRUE;
263  }
264  WerrorS("negativeTropicalStartingPoint: unexpected parameters");
265  return TRUE;
266}
267
268BOOLEAN nonPositiveTropicalStartingPoint(leftv res, leftv args)
269{
270  leftv u = args;
271  if ((u!=NULL) && (u->Typ()==IDEAL_CMD))
272  {
273    ideal I = (ideal) u->Data();
274    if (idSize(I)==1)
275    {
276      tropicalStrategy currentStrategy(I,currRing);
277      poly g = I->m[0];
278      std::set<gfan::ZCone> Tg = tropicalVariety(g,currRing,&currentStrategy);
279      for (std::set<gfan::ZCone>::iterator zc=Tg.begin(); zc!=Tg.end(); zc++)
280      {
281        gfan::ZMatrix ray = zc->extremeRays();
282        for (int i=0; i<ray.getHeight(); i++)
283        {
284          gfan::ZVector negatedRay = gfan::Integer(-1)*ray[i];
285          if (negatedRay.isNonNegative())
286          {
287            res->rtyp = BIGINTMAT_CMD;
288            res->data = (void*) zVectorToBigintmat(ray[i]);
289            return FALSE;
290          }
291        }
292      }
293      res->rtyp = BIGINTMAT_CMD;
294      res->data = (void*) zVectorToBigintmat(gfan::ZVector(0));
295      return FALSE;
296    }
297    WerrorS("nonPositiveTropicalStartingPoint: ideal not principal");
298    return TRUE;
299  }
300  WerrorS("nonPositiveTropicalStartingPoint: unexpected parameters");
301  return TRUE;
302}
303
304BOOLEAN tropicalStartingPoint(leftv res, leftv args)
305{
306  leftv u = args;
307  if ((u!=NULL) && (u->Typ()==IDEAL_CMD))
308  {
309    ideal I = (ideal) u->Data();
310    tropicalStrategy currentStrategy(I,currRing);
311    if (idSize(I)==1)
312    {
313      poly g = I->m[0];
314      std::set<gfan::ZCone> Tg = tropicalVariety(g,currRing,&currentStrategy);
315      if (Tg.empty())
316      {
317        res->rtyp = BIGINTMAT_CMD;
318        res->data = (void*) zVectorToBigintmat(gfan::ZVector(0));
319        return FALSE;
320      }
321      gfan::ZCone C = *(Tg.begin());
322      gfan::ZMatrix rays = C.extremeRays();
323      if (rays.getHeight()==0)
324      {
325        gfan::ZMatrix lin = C.generatorsOfLinealitySpace();
326        res->rtyp = BIGINTMAT_CMD;
327        res->data = (void*) zVectorToBigintmat(lin[0]);
328        return FALSE;
329      }
330      res->rtyp = BIGINTMAT_CMD;
331      res->data = (void*) zVectorToBigintmat(rays[0]);
332      return FALSE;
333    }
334    gfan::ZCone C0 = currentStrategy.getHomogeneitySpace();
335    if (C0.dimension()==currentStrategy.getExpectedDimension())
336    {
337      gfan::ZMatrix lin = C0.generatorsOfLinealitySpace();
338      res->rtyp = BIGINTMAT_CMD;
339      res->data = (void*) zVectorToBigintmat(lin[0]);
340      return FALSE;
341    }
342    std::pair<gfan::ZVector,groebnerCone> startingData = tropicalStartingDataViaGroebnerFan(I,currRing,currentStrategy);
343    gfan::ZVector startingPoint = startingData.first;
344    res->rtyp = BIGINTMAT_CMD;
345    res->data = (void*) zVectorToBigintmat(startingPoint);
346    return FALSE;
347  }
348  WerrorS("tropicalStartingPoint: unexpected parameters");
349  return TRUE;
350}
351
352/***
353 * returs the lineality space of the Groebner fan
354 **/
355static gfan::ZCone linealitySpaceOfGroebnerFan(const ideal I, const ring r)
356{
357  int n = rVar(r);
358  gfan::ZMatrix equations = gfan::ZMatrix(0,n);
359  int* expv = (int*) omAlloc((n+1)*sizeof(int));
360  int k = idSize(I);
361  for (int i=0; i<k; i++)
362  {
363    poly g = I->m[i];
364    if (g)
365    {
366      p_GetExpV(g,expv,r);
367      gfan::ZVector leadexp = intStar2ZVector(n,expv);
368      for (pIter(g); g; pIter(g))
369      {
370        p_GetExpV(g,expv,r);
371        equations.appendRow(leadexp-intStar2ZVector(n,expv));
372      }
373    }
374  }
375  omFreeSize(expv,(n+1)*sizeof(int));
376  return gfan::ZCone(gfan::ZMatrix(0,n),equations);
377}
378
379/***
380 * Computes a starting cone in the tropical variety.
381 **/
382groebnerCone tropicalStartingCone(const tropicalStrategy& currentStrategy)
383{
384  ring r = currentStrategy.getStartingRing();
385  ideal I = currentStrategy.getStartingIdeal();
386  currentStrategy.reduce(I,r);
387  if (currentStrategy.isConstantCoefficientCase())
388  {
389    // copy the data, so that it be deleted when passed to the loop
390    // s <- r
391    // inI <- I
392    ring s = rCopy(r);
393    int k = idSize(I); ideal inI = idInit(k);
394    nMapFunc identityMap = n_SetMap(r->cf,s->cf);
395    for (int i=0; i<k; i++)
396      inI->m[i] = p_PermPoly(I->m[i],NULL,r,s,identityMap,NULL,0);
397
398    // repeatedly computes a point in the tropical variety outside the lineality space,
399    // take the initial ideal with respect to it
400    // and check whether the dimension of its homogeneity space
401    // equals the dimension of the tropical variety
402    gfan::ZCone zc = linealitySpaceOfGroebnerFan(inI,s);
403    gfan::ZVector startingPoint; groebnerCone ambientMaximalCone;
404    while (zc.dimension()<currentStrategy.getExpectedDimension())
405    {
406      // compute a point in the tropical variety outside the lineality space
407      std::pair<gfan::ZVector,groebnerCone> startingData = tropicalStartingDataViaGroebnerFan(inI,s,currentStrategy);
408      startingPoint = startingData.first;
409      ambientMaximalCone = groebnerCone(startingData.second);
410
411      id_Delete(&inI,s); rDelete(s);
412      inI = ambientMaximalCone.getPolynomialIdeal();
413      s = ambientMaximalCone.getPolynomialRing();
414
415      // compute the initial ideal with respect to the weight
416      inI = initial(inI,s,startingPoint);
417      zc = linealitySpaceOfGroebnerFan(inI,s);
418    }
419
420    // once the dimension of the homogeneity space equals that of the tropical variety
421    // we know that we have an initial ideal with respect to a weight
422    // in the relative interior of a maximal cone in the tropical variety
423    // from this we can read of the inequalities and equations
424
425    // but before doing so, we must lift the generating set of inI
426    // to a generating set of I
427    ideal J = lift(I,r,inI,s);
428    groebnerCone startingCone(J,inI,s,currentStrategy);
429    id_Delete(&inI,s);
430    id_Delete(&J,s);
431
432    // assume(checkContainmentInTropicalVariety(startingCone));
433    return startingCone;
434  }
435  else
436  {
437    // copy the data, so that it be deleted when passed to the loop
438    // s <- r
439    // inJ <- I
440    ring s = rCopy(r);
441    int k = idSize(I); ideal inJ = idInit(k);
442    nMapFunc identityMap = n_SetMap(r->cf,s->cf);
443    for (int i=0; i<k; i++)
444      inJ->m[i] = p_PermPoly(I->m[i],NULL,r,s,identityMap,NULL,0);
445
446    // and check whether the dimension of its homogeneity space
447    // equals the dimension of the tropical variety
448    gfan::ZCone zc = linealitySpaceOfGroebnerFan(inJ,s);
449    if (zc.dimension()==currentStrategy.getExpectedDimension())
450    { // this shouldn't happen as trivial cases should be caught beforehand
451      // this is the case that the tropical variety consists soely out of the lineality space
452      groebnerCone startingCone(I,inJ,s,currentStrategy);
453      id_Delete(&inJ,s);
454      rDelete(s);
455      return startingCone;
456    }
457
458    // compute a point in the tropical variety outside the lineality space
459    // compute the initial ideal with respect to the weight
460    std::pair<gfan::ZVector,groebnerCone> startingData = tropicalStartingDataViaGroebnerFan(inJ,s,currentStrategy);
461    gfan::ZVector startingPoint = startingData.first;
462    groebnerCone ambientMaximalCone = groebnerCone(startingData.second);
463    id_Delete(&inJ,s); rDelete(s);
464    inJ = ambientMaximalCone.getPolynomialIdeal();
465    s = ambientMaximalCone.getPolynomialRing();
466    inJ = initial(inJ,s,startingPoint);
467    ideal inI = initial(I,r,startingPoint);
468    zc = linealitySpaceOfGroebnerFan(inJ,s);
469
470    // and check whether the dimension of its homogeneity space
471    // equals the dimension of the tropical variety
472    if (zc.dimension()==currentStrategy.getExpectedDimension())
473    { // this case shouldn't happen as trivial cases should be caught beforehand
474      // this is the case that the tropical variety has a one-codimensional lineality space
475      ideal J = lift(I,r,inJ,s);
476      groebnerCone startingCone(J,inJ,s,currentStrategy);
477      id_Delete(&inJ,s);
478      id_Delete(&J,s);
479      return startingCone;
480    }
481
482    // from this point on, inJ contains the uniformizing parameter,
483    // hence it contains a monomial if and only if its residue over the residue field does.
484    // so we will switch to the residue field
485    ring rShortcut = rCopy0(r);
486    nKillChar(rShortcut->cf);
487    rShortcut->cf = nCopyCoeff((currentStrategy.getShortcutRing())->cf);
488    rComplete(rShortcut);
489    rTest(rShortcut);
490    k = idSize(inJ);
491    ideal inJShortcut = idInit(k);
492    nMapFunc takingResidues = n_SetMap(s->cf,rShortcut->cf);
493    for (int i=0; i<k; i++)
494      inJShortcut->m[i] = p_PermPoly(inJ->m[i],NULL,s,rShortcut,takingResidues,NULL,0);
495    idSkipZeroes(inJShortcut);
496    id_Delete(&inJ,s);
497
498    // we are interested in a maximal cone of the tropical variety of inJShortcut
499    // this basically equivalent to the case without valuation (or constant coefficient case)
500    // except that our ideal is still only homogeneous in the later variables,
501    // hence we set the optional parameter completelyHomogeneous as 'false'
502    tropicalStrategy shortcutStrategy(inJShortcut,rShortcut,false);
503    groebnerCone startingConeShortcut = tropicalStartingCone(shortcutStrategy);
504    id_Delete(&inJShortcut,rShortcut); rDelete(rShortcut);
505
506    // now we need to obtain the initial of the residue of inJ
507    // with respect to a weight in the tropical cone,
508    // and obtain the initial of inJ with respect to the same weight
509    ring sShortcut = startingConeShortcut.getPolynomialRing();
510    inJShortcut = startingConeShortcut.getPolynomialIdeal();
511    gfan::ZCone zd = startingConeShortcut.getPolyhedralCone();
512    gfan::ZVector interiorPoint = startingConeShortcut.getInteriorPoint();
513    inJShortcut = initial(inJShortcut,sShortcut,interiorPoint);
514    inI = initial(inI,r,interiorPoint);
515
516    s = rCopy0(sShortcut); // s will be a ring over the valuation ring
517    nKillChar(s->cf);      // with the same ordering as sShortcut
518    s->cf = nCopyCoeff(r->cf);
519    rComplete(s);
520    rTest(s);
521
522    k = idSize(inJShortcut); // inJ will be overwritten with initial of inJ
523    inJ = idInit(k+1);
524    inJ->m[0] = p_One(s);    // with respect to that weight
525    identityMap = n_SetMap(r->cf,s->cf); // first element will obviously be p
526    p_SetCoeff(inJ->m[0],identityMap(currentStrategy.getUniformizingParameter(),r->cf,s->cf),s);
527    nMapFunc findingRepresentatives = n_SetMap(sShortcut->cf,s->cf);
528    for (int i=0; i<k; i++)              // and then come the rest
529      inJ->m[i+1] = p_PermPoly(inJShortcut->m[i],NULL,sShortcut,s,findingRepresentatives,NULL,0);
530
531    ideal J = currentStrategy.computeLift(inJ,s,inI,I,r);
532    // currentStrategy.reduce(J,s);
533    groebnerCone startingCone(J,inJ,s,currentStrategy);
534    id_Delete(&inJ,s);
535    id_Delete(&J,s);
536    rDelete(s);
537    id_Delete(&inI,r);
538
539    assume(checkContainmentInTropicalVariety(startingCone));
540    return startingCone;
541  }
542}
543
544BOOLEAN tropicalStartingCone(leftv res, leftv args)
545{
546  leftv u = args;
547  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
548  {
549    ideal I = (ideal) u->CopyD();
550    leftv v = u->next;
551    if ((v != NULL) && (v->Typ() == NUMBER_CMD))
552    {
553      number p = (number) v->Data();
554      leftv w = v->next;
555      if (w==NULL)
556      {
557        tropicalStrategy currentStrategy(I,p,currRing);
558        groebnerCone sigma = tropicalStartingCone(currentStrategy);
559        gfan::ZCone* startingCone = new gfan::ZCone(sigma.getPolyhedralCone());
560        res->rtyp = coneID;
561        res->data = (char*) startingCone;
562        return FALSE;
563      }
564    }
565    else
566    {
567      if (v==NULL)
568      {
569        tropicalStrategy currentStrategy(I,currRing);
570        groebnerCone sigma = tropicalStartingCone(currentStrategy);
571        res->rtyp = coneID;
572        res->data = (char*) new gfan::ZCone(sigma.getPolyhedralCone());
573        return FALSE;
574      }
575    }
576  }
577  WerrorS("tropicalStartingCone: unexpected parameters");
578  return TRUE;
579}
Note: See TracBrowser for help on using the repository browser.