source: git/Singular/dyn_modules/gfanlib/startingCone.cc @ 24d30d

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