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

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