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

spielwiese
Last change on this file since b71400a was b71400a, checked in by Yue Ren <ren@…>, 10 years ago
chg: status update 15.09.
  • Property mode set to 100644
File size: 17.6 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> 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  const ideal I = currentStrategy.getStartingIdeal();
339  if (currentStrategy.isConstantCoefficientCase())
340  {
341    // copy the data, so that it be deleted when passed to the loop
342    // s <- r
343    // inI <- I
344    ring s = rCopy(r);
345    int k = idSize(I); ideal inI = idInit(k);
346    nMapFunc identityMap = n_SetMap(r->cf,s->cf);
347    for (int i=0; i<k; i++)
348      inI->m[i] = p_PermPoly(I->m[i],NULL,r,s,identityMap,NULL,0);
349
350    // repeatedly computes a point in the tropical variety outside the lineality space,
351    // take the initial ideal with respect to it
352    // and check whether the dimension of its homogeneity space
353    // equals the dimension of the tropical variety
354    gfan::ZCone zc = linealitySpaceOfGroebnerFan(inI,s);
355    gfan::ZVector startingPoint; groebnerCone ambientMaximalCone;
356    while (zc.dimension()<currentStrategy.getExpectedDimension())
357    {
358      // compute a point in the tropical variety outside the lineality space
359      std::pair<gfan::ZVector,groebnerCone> startingData = tropicalStartingDataViaGroebnerFan(inI,s,currentStrategy);
360      startingPoint = startingData.first;
361      ambientMaximalCone = groebnerCone(startingData.second);
362
363      id_Delete(&inI,s); rDelete(s);
364      inI = ambientMaximalCone.getPolynomialIdeal();
365      s = ambientMaximalCone.getPolynomialRing();
366
367      // compute the initial ideal with respect to the weight
368      inI = sloppyInitial(inI,s,startingPoint);
369      zc = linealitySpaceOfGroebnerFan(inI,s);
370    }
371
372    // once the dimension of the homogeneity space equals that of the tropical variety
373    // we know that we have an initial ideal with respect to a weight
374    // in the relative interior of a maximal cone in the tropical variety
375    // from this we can read of the inequalities and equations
376
377    // but before doing so, we must lift the generating set of inI
378    // to a generating set of I
379    ideal J = lift(I,r,inI,s);
380    groebnerCone startingCone(J,inI,s,currentStrategy);
381    id_Delete(&inI,s);
382    id_Delete(&J,s);
383
384    // assume(checkContainmentInTropicalVariety(startingCone));
385    return startingCone;
386  }
387  else
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    // and check whether the dimension of its homogeneity space
399    // equals the dimension of the tropical variety
400    gfan::ZCone zc = linealitySpaceOfGroebnerFan(inI,s);
401    if (zc.dimension()==currentStrategy.getExpectedDimension())
402    { // this shouldn't happen as trivial cases should be caught beforehand
403      // this is the case that the tropical variety consists soely out of the lineality space
404      groebnerCone startingCone(I,inI,s,currentStrategy);
405      id_Delete(&inI,s);
406      rDelete(s);
407      return startingCone;
408    }
409
410    // compute a point in the tropical variety outside the lineality space
411    // compute the initial ideal with respect to the weight
412    std::pair<gfan::ZVector,groebnerCone> startingData = tropicalStartingDataViaGroebnerFan(inI,s,currentStrategy);
413    gfan::ZVector startingPoint = startingData.first;
414    groebnerCone ambientMaximalCone = groebnerCone(startingData.second);
415    id_Delete(&inI,s); rDelete(s);
416    inI = ambientMaximalCone.getPolynomialIdeal();
417    s = ambientMaximalCone.getPolynomialRing();
418    inI = sloppyInitial(inI,s,startingPoint);
419    zc = linealitySpaceOfGroebnerFan(inI,s);
420
421    // and check whether the dimension of its homogeneity space
422    // equals the dimension of the tropical variety
423    if (zc.dimension()==currentStrategy.getExpectedDimension())
424    { // this case shouldn't happen as trivial cases should be caught beforehand
425      // this is the case that the tropical variety has a one-codimensional lineality space
426      ideal J = lift(I,r,inI,s);
427      groebnerCone startingCone(J,inI,s,currentStrategy);
428      id_Delete(&inI,s);
429      id_Delete(&J,s);
430      return startingCone;
431    }
432
433    // from this point on, inI contains the uniformizing parameter,
434    // hence it contains a monomial if and only if its residue over the residue field does.
435    // so we will switch to the residue field
436    ring rShortcut = rCopy0(r);
437    nKillChar(rShortcut->cf);
438    rShortcut->cf = nCopyCoeff((currentStrategy.getShortcutRing())->cf);
439    rComplete(rShortcut);
440    rTest(rShortcut);
441    k = idSize(inI);
442    ideal inIShortcut = idInit(k);
443    nMapFunc takingResidues = n_SetMap(s->cf,rShortcut->cf);
444    for (int i=0; i<k; i++)
445      inIShortcut->m[i] = p_PermPoly(inI->m[i],NULL,s,rShortcut,takingResidues,NULL,0);
446    idSkipZeroes(inIShortcut);
447    id_Delete(&inI,s);
448
449    // we are interested in a maximal cone of the tropical variety of inIShortcut
450    // this basically equivalent to the case without valuation (or constant coefficient case)
451    // except that our ideal is still only homogeneous in the later variables,
452    // hence we set the optional parameter completelyHomogeneous as 'false'
453    tropicalStrategy shortcutStrategy(inIShortcut,rShortcut,false);
454    groebnerCone startingConeShortcut = tropicalStartingCone(shortcutStrategy);
455    id_Delete(&inIShortcut,rShortcut); rDelete(rShortcut);
456
457    // now we need to obtain the initial of the residue of inI
458    // with respect to a weight in the tropical cone,
459    // and obtain the initial of inI with respect to the same weight
460    ring sShortcut = startingConeShortcut.getPolynomialRing();
461    inIShortcut = startingConeShortcut.getPolynomialIdeal();
462    gfan::ZCone zd = startingConeShortcut.getPolyhedralCone();
463    gfan::ZVector interiorPoint = startingConeShortcut.getInteriorPoint();
464    inIShortcut = sloppyInitial(inIShortcut,sShortcut,interiorPoint);
465
466    s = rCopy0(sShortcut); // s will be a ring over the valuation ring
467    nKillChar(s->cf);      // with the same ordering as sShortcut
468    s->cf = nCopyCoeff(r->cf);
469    rComplete(s);
470    rTest(s);
471
472    k = idSize(inIShortcut); // inI will be overwritten with initial of inI
473    inI = idInit(k+1);
474    inI->m[0] = p_One(s);    // with respect to that weight
475    identityMap = n_SetMap(r->cf,s->cf); // first element will obviously be p
476    p_SetCoeff(inI->m[0],identityMap(currentStrategy.getUniformizingParameter(),r->cf,s->cf),s);
477    nMapFunc findingRepresentatives = n_SetMap(sShortcut->cf,s->cf);
478    for (int i=0; i<k; i++)              // and then come the rest
479      inI->m[i+1] = p_PermPoly(inIShortcut->m[i],NULL,sShortcut,s,findingRepresentatives,NULL,0);
480
481    ideal J = lift(I,r,inI,s);
482    // currentStrategy.reduce(J,s);
483    groebnerCone startingCone(J,inI,s,currentStrategy);
484    id_Delete(&inI,s);
485    id_Delete(&J,s);
486    rDelete(s);
487
488    assume(checkContainmentInTropicalVariety(startingCone));
489    return startingCone;
490  }
491}
492
493BOOLEAN tropicalStartingCone(leftv res, leftv args)
494{
495  leftv u = args;
496  if ((u != NULL) && (u->Typ() == IDEAL_CMD))
497  {
498    ideal I = (ideal) u->CopyD();
499    leftv v = u->next;
500    if ((v != NULL) && (v->Typ() == NUMBER_CMD))
501    {
502      number p = (number) v->Data();
503      leftv w = v->next;
504      if (w==NULL)
505      {
506        tropicalStrategy currentStrategy(I,p,currRing);
507        groebnerCone sigma = tropicalStartingCone(currentStrategy);
508        gfan::ZCone* startingCone = new gfan::ZCone(sigma.getPolyhedralCone());
509        res->rtyp = coneID;
510        res->data = (char*) startingCone;
511        return FALSE;
512      }
513    }
514    else
515    {
516      if (v==NULL)
517      {
518        tropicalStrategy currentStrategy(I,currRing);
519        groebnerCone sigma = tropicalStartingCone(currentStrategy);
520        res->rtyp = coneID;
521        res->data = (char*) new gfan::ZCone(sigma.getPolyhedralCone());
522        return FALSE;
523      }
524    }
525  }
526  WerrorS("tropicalStartingCone: unexpected parameters");
527  return TRUE;
528}
Note: See TracBrowser for help on using the repository browser.