source: git/Singular/dyn_modules/customstd/customstd.cc @ ad42521

fieker-DuValspielwiese
Last change on this file since ad42521 was ad42521, checked in by Yue <ren@…>, 8 years ago
new: shared module "customstd" with satstd
  • Property mode set to 100755
File size: 16.0 KB
Line 
1#include <Singular/libsingular.h>
2#include <vector>
3#include <iostream>
4
5// global variable potentially storing output
6ideal idealCache=NULL;
7
8std::vector<int> satstdSaturatingVariables;
9
10// //------------------------------------------------------------------------
11// // example of a routine which changes nothing
12// static BOOLEAN display_sp(kStrategy strat)
13// {
14//   // will be call each time a new s-poly is computed (strat->P)
15//   // the algorithm assures that strat->P.p!=NULL, in currRing
16//   // if strat->P.t_p==NULL: strat->P.p->next is in currRing
17//   // otherwise: strat->P.t_p->next==strat->P.p->next, in strat->tailRing
18//   // must return TRUE, if strat->P is changed, FALSE otherwise
19//   PrintS("a new s-poly found: ");
20//   p_Write(strat->P.p,currRing,strat->tailRing);
21//   return FALSE;
22// }
23// static BOOLEAN std_with_display(leftv res, leftv args)
24// {
25//   if (args!=NULL)
26//   {
27//     if (args->Typ()==IDEAL_CMD)
28//     {
29//       ideal I=(ideal)args->Data();
30//       I=kStd(I,currRing->qideal,testHomog,NULL,NULL,0,0,NULL,display_sp);
31//       idSkipZeroes(I);
32//       res->data=(char*)I;
33//       res->rtyp=IDEAL_CMD;
34//       return FALSE;
35//     }
36//   }
37//   WerrorS("expected: std_with_display(`idea;`)");
38//   return TRUE;
39// }
40
41//------------------------------------------------------------------------
42// routine that simplifies the new element by dividing it with the maximal possible
43// partially saturating the ideal with respect to all variables doing so
44static BOOLEAN sat_vars_sp(kStrategy strat)
45{
46  BOOLEAN b = FALSE; // set b to TRUE, if spoly was changed,
47                     // let it remain FALSE otherwise
48  if (strat->P.t_p==NULL)
49  {
50    poly p=strat->P.p;
51    if (pNext(p)==NULL)
52    {
53      // if a term is contained in the ideal, abort std computation
54      // and store the whole ring in idealCache to be returned
55      while ((strat->Ll >= 0))
56        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
57      idealCache = idInit(1);
58      idealCache->m[0] = p_One(currRing);
59      return FALSE;
60    }
61
62    // iterate over all terms of p and
63    // compute the minimum mm of all exponent vectors
64    int *mm=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
65    int *m0=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
66    p_GetExpV(p,mm,currRing);
67    bool nonTrivialSaturationToBeDone=false;
68    for (p=pNext(p); p!=NULL; pIter(p))
69    {
70      nonTrivialSaturationToBeDone=false;
71      p_GetExpV(p,m0,currRing);
72      for(int i=0; i<satstdSaturatingVariables.size(); i++)
73      {
74        int li = satstdSaturatingVariables[i];
75        mm[li]=si_min(mm[li],m0[li]);
76        if (mm[li]>0) nonTrivialSaturationToBeDone=true;
77      }
78      // abort if the minimum is zero in each component
79      if (nonTrivialSaturationToBeDone==false) break;
80    }
81    if (nonTrivialSaturationToBeDone==true)
82    {
83      std::cout << "simplifying!" << std::endl;
84      p=p_Copy(strat->P.p,currRing);
85      strat->P.p=p;
86      while(p!=NULL)
87      {
88        for (int i=1; i<=rVar(currRing); i++)
89          p_SubExp(p,i,mm[i],currRing);
90        p_Setm(p,currRing);
91        pIter(p);
92      }
93      b = TRUE;
94    }
95    omFree(mm);
96    omFree(m0);
97  }
98  else
99  {
100    poly p=strat->P.t_p;
101    if (pNext(p)==NULL)
102    {
103      // if a term is contained in the ideal, abort std computation
104      // and store the output in idealCache to be returned
105      while ((strat->Ll >= 0))
106        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
107      idealCache = idInit(1);
108      idealCache->m[0] = p_One(currRing);
109      return FALSE;
110    }
111
112    // iterate over all terms of p and
113    // compute the minimum mm of all exponent vectors
114    int *mm=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
115    int *m0=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
116    p_GetExpV(p,mm,strat->tailRing);
117    bool nonTrivialSaturationToBeDone=false;
118    for (p = pNext(p); p!=NULL; pIter(p))
119    {
120      nonTrivialSaturationToBeDone=false;
121      p_GetExpV(p,m0,strat->tailRing);
122      for(int i=0; i<satstdSaturatingVariables.size(); i++)
123      {
124        int li = satstdSaturatingVariables[i];
125        mm[li]=si_min(mm[li],m0[li]);
126        if (mm[li]>0) nonTrivialSaturationToBeDone = true;
127      }
128      // abort if the minimum is zero in each component
129      if (nonTrivialSaturationToBeDone==false) break;
130    }
131    if (nonTrivialSaturationToBeDone==true)
132    {
133      std::cout << "simplifying!" << std::endl;
134      p=p_Copy(strat->P.t_p,strat->tailRing);
135      strat->P.t_p=p;
136      strat->P.p=NULL;
137      while(p!=NULL)
138      {
139        for(int i=1;i<=rVar(currRing);i++)
140          p_SubExp(p,i,mm[i],strat->tailRing);
141        p_Setm(p,strat->tailRing);
142        pIter(p);
143      }
144      strat->P.GetP();
145      b = TRUE;
146    }
147    omFree(mm);
148    omFree(m0);
149  }
150  return b; // return TRUE if sp was changed, FALSE if not
151}
152
153int extractVariableIndex(poly x, ring r)
154{
155  if ((x->next == NULL) && (n_IsOne(p_GetCoeff(x,r),r->cf)))
156  {
157    int l0=0;
158    for (int i=1; i<=rVar(r); i++)
159    {
160      int l1 = p_GetExp(x,i,r);
161      if (l1>0)
162      {
163        if (l0>0)
164          return 0;
165        l0 = l1;
166      }
167    }
168  }
169  return (0);
170}
171
172static BOOLEAN satstd(leftv res, leftv args)
173{
174  leftv u = args;
175  if ((u!=NULL) && (u->Typ()==IDEAL_CMD))
176  {
177    leftv v = u->next;
178
179    if (v==NULL)
180    {
181      ideal I = (ideal) u->Data();
182      int n = rVar(currRing);
183      satstdSaturatingVariables = std::vector<int>(n);
184      for (int i=0; i<n; i++)
185        satstdSaturatingVariables[i] = i+1;
186
187      idealCache = NULL;
188      I=kStd(I,currRing->qideal,testHomog,NULL,NULL,0,0,NULL,sat_vars_sp);
189      satstdSaturatingVariables = std::vector<int>();
190
191      res->rtyp=IDEAL_CMD;
192      if (idealCache)
193      {
194        id_Delete(&I,currRing);
195        res->data = (char*) idealCache;
196        idealCache = NULL;
197      }
198      else
199      {
200        idSkipZeroes(I);
201        res->data=(char*)I;
202      }
203      return FALSE;
204    }
205
206    if ((v!=NULL) && (v->Typ()==IDEAL_CMD))
207    {
208      ideal I = (ideal) u->Data();
209      ideal J = (ideal) v->Data();
210
211      int k = idSize(J);
212      satstdSaturatingVariables = std::vector<int>(k);
213      for (int i=0; i<k; i++)
214      {
215        poly x = I->m[i];
216        int li = extractVariableIndex(x,currRing);
217        if (li>0)
218          satstdSaturatingVariables[i]=li;
219        else
220        {
221          WerrorS("satstd: only ideals generated by variables supported for now");
222          return FALSE;
223        }
224      }
225
226      idealCache = NULL;
227      I=kStd(I,currRing->qideal,testHomog,NULL,NULL,0,0,NULL,sat_vars_sp);
228      res->rtyp=IDEAL_CMD;
229      if (idealCache)
230      {
231        id_Delete(&I,currRing);
232        res->data=(char*)idealCache;
233      }
234      else
235      {
236        idSkipZeroes(I);
237        res->data=(char*)I;
238      }
239      return FALSE;
240    }
241  }
242  WerrorS("satstd: unexpected parameters");
243  return TRUE;
244}
245
246static BOOLEAN abortIfMonomial_sp(kStrategy strat)
247{
248  BOOLEAN b = FALSE; // set b to TRUE, if spoly was changed,
249                     // let it remain FALSE otherwise
250  if (strat->P.t_p==NULL)
251  {
252    poly p=strat->P.p;
253    if (pNext(p)==NULL)
254    {
255      // if a term is contained in the ideal, abort std computation
256      // and store the output in idealCache to be returned
257      while ((strat->Ll >= 0))
258        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
259      std::cout << "aborting!" << std::endl;
260      return FALSE;
261    }
262  }
263  else
264  {
265    poly p=strat->P.t_p;
266    if (pNext(p)==NULL)
267    {
268      // if a term is contained in the ideal, abort std computation
269      // and store the output in idealCache to be returned
270      while ((strat->Ll >= 0))
271        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
272      std::cout << "aborting!" << std::endl;
273      return FALSE;
274    }
275  }
276  return b; // return TRUE if sp was changed, FALSE if not
277}
278static BOOLEAN abortifmonomialstd(leftv res, leftv args)
279{
280  if (args!=NULL)
281  {
282    if ((args->Typ()==IDEAL_CMD) && (args->next==NULL))
283    {
284      ideal I=(ideal)args->Data();
285      idealCache = NULL;
286      I=kStd(I,currRing->qideal,testHomog,NULL,NULL,0,0,NULL,abortIfMonomial_sp);
287      res->rtyp=IDEAL_CMD;
288      if (idealCache)
289        res->data=(char*)idealCache;
290      else
291      {
292        idSkipZeroes(I);
293        res->data=(char*)I;
294      }
295      return FALSE;
296    }
297  }
298  WerrorS("abortifmonomialstd: unexpected parameters");
299  return TRUE;
300}
301
302
303//------------------------------------------------------------------------
304// routine that simplifies the ideal dividing each generator by the maximal monomial dividing it
305// in particular returns 1 if a generator is a term
306// to be used before starting saturation with respect to all variables
307static BOOLEAN simplifySat(leftv res, leftv args)
308{
309  if (args!=NULL)
310  {
311    if ((args->Typ()==IDEAL_CMD) && (args->next==NULL))
312    {
313      ideal I=(ideal)args->CopyD();
314      idSkipZeroes(I);
315      int k = IDELEMS(I);
316      int *mm=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
317      int *m0=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
318      for (int i=0; i<k; i++)
319      {
320        poly p = I->m[i];
321        // check whether p is a term, return 1 if true
322        if (p != NULL)
323        {
324          if (p->next == NULL)
325          {
326            id_Delete(&I,currRing);
327            ideal oneIdeal = idInit(1);
328            oneIdeal->m[0] = p_One(currRing);
329            res->rtyp=IDEAL_CMD;
330            res->data=(char*) oneIdeal;
331            omFree(mm);
332            omFree(m0);
333            return FALSE;
334          }
335
336          // check whether p is divisible by a monomial
337          // divide if true
338          p_GetExpV(p,mm,currRing);
339          bool satNecessary=false;
340          for (; p!=NULL; pIter(p))
341          {
342            satNecessary=false;
343            p_GetExpV(p,m0,currRing);
344            for(int i=1;i<=rVar(currRing);i++)
345            {
346              mm[i]=si_min(mm[i],m0[i]);
347              if (mm[i]>0)
348                satNecessary=true;
349            }
350            if (satNecessary==false)
351              break;
352          }
353          if (satNecessary==true)
354          {
355            for (p=I->m[i]; p!=NULL; pIter(p))
356            {
357              for (int i=1; i<=rVar(currRing); i++)
358                p_SubExp(p,i,mm[i],currRing);
359              p_Setm(p,currRing);
360            }
361          }
362        }
363      }
364      omFree(mm);
365      omFree(m0);
366      res->rtyp=IDEAL_CMD;
367      res->data=(char*)I;
368      return FALSE;
369    }
370  }
371  WerrorS("simplifySat: unexpected parameters");
372  return TRUE;
373}
374
375
376static long wDeg(const poly p, const ring r)
377{
378  if (r->order[0] == ringorder_lp)
379    return p_GetExp(p,1,currRing);
380  if (r->order[0] == ringorder_ls)
381    return -p_GetExp(p,1,currRing);
382
383  if (r->order[0] == ringorder_dp)
384  {
385    long d = 0;
386    for (int i=1; i<=rVar(r); i++)
387      d = d + p_GetExp(p,i,r);
388    return d;
389  }
390  if (r->order[0] == ringorder_wp || r->order[0] == ringorder_a)
391  {
392    long d = 0;
393    for (int i=r->block0[0]; i<=r->block1[0]; i++)
394      d = d + p_GetExp(p,i,r)*r->wvhdl[0][i-1];
395    return d;
396  }
397  if (r->order[0] == ringorder_ws)
398  {
399    long d = 0;
400    for (int i=r->block0[0]; i<=r->block1[0]; i++)
401      d = d - p_GetExp(p,i,r)*r->wvhdl[0][i-1];
402    return d;
403  }
404}
405
406static bool isInitialFormMonomial(const poly g, const ring r)
407{
408  if (g->next==NULL)
409    return true;
410  return wDeg(g,r)!=wDeg(g->next,r);
411}
412
413//------------------------------------------------------------------------
414// routine that checks whether the initial form is a monomial,
415// breaks computation if it finds one, writing the element into idealCache
416static BOOLEAN sat_sp_initial(kStrategy strat)
417{
418  BOOLEAN b = FALSE; // set b to TRUE, if spoly was changed,
419                     // let it remain FALSE otherwise
420  if (strat->P.t_p==NULL)
421  {
422    poly p=strat->P.p;
423    if (pNext(p)==NULL)
424    {
425      // if a term is contained in the ideal, abort std computation
426      // and store the output in idealCache to be returned
427      while ((strat->Ll >= 0))
428        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
429      idealCache = idInit(1);
430      idealCache->m[0] = p_One(currRing);
431      return FALSE;
432    }
433    if (isInitialFormMonomial(p,currRing))
434    {
435      while ((strat->Ll >= 0))
436        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
437      idealCache = idInit(1);
438      idealCache->m[0] = p_Copy(p,currRing);
439    }
440    int *mm=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
441    int *m0=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
442    p_GetExpV(p,mm,currRing);
443    int m_null=0;
444    while(p!=NULL)
445    {
446      m_null=0;
447      p_GetExpV(p,m0,currRing);
448      for(int i=1;i<=rVar(currRing);i++)
449      {
450        mm[i]=si_min(mm[i],m0[i]);
451        if (mm[i]>0) m_null++;
452      }
453      if (m_null==0) break;
454      pIter(p);
455    }
456    if (m_null>0)
457    {
458      std::cout << "simplifying!" << std::endl;
459      p=p_Copy(strat->P.p,currRing);
460      strat->P.p=p;
461      while(p!=NULL)
462      {
463        for(int i=1;i<=rVar(currRing);i++)
464          p_SubExp(p,i,mm[i],currRing);
465        p_Setm(p,currRing);
466        pIter(p);
467      }
468      b = TRUE;
469    }
470    omFree(mm);
471    omFree(m0);
472  }
473  else
474  {
475    poly p=strat->P.t_p;
476    if (pNext(p)==NULL)
477    {
478      // if a term is contained in the ideal, abort std computation
479      // and store the output in idealCache to be returned
480      while ((strat->Ll >= 0))
481        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
482      idealCache = idInit(1);
483      idealCache->m[0] = p_One(currRing);
484      return FALSE;
485    }
486    if (isInitialFormMonomial(p,strat->tailRing))
487    {
488      while ((strat->Ll >= 0))
489        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
490      nMapFunc identity = n_SetMap(strat->tailRing,currRing);
491      idealCache = idInit(1);
492      idealCache->m[0] = p_PermPoly(p,NULL,strat->tailRing,currRing,identity,NULL,0);
493    }
494    int *mm=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
495    int *m0=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
496    p_GetExpV(p,mm,strat->tailRing);
497    int m_null=0;
498    while(p!=NULL)
499    {
500      m_null=0;
501      p_GetExpV(p,m0,strat->tailRing);
502      for(int i=1;i<=rVar(currRing);i++)
503      {
504        mm[i]=si_min(mm[i],m0[i]);
505        if (mm[i]>0) m_null++;
506      }
507      if (m_null==0) break;
508      pIter(p);
509    }
510    if (m_null>0)
511    {
512      std::cout << "simplifying!" << std::endl;
513      p=p_Copy(strat->P.t_p,strat->tailRing);
514      strat->P.t_p=p;
515      strat->P.p=NULL;
516      while(p!=NULL)
517      {
518        for(int i=1;i<=rVar(currRing);i++)
519          p_SubExp(p,i,mm[i],strat->tailRing);
520        p_Setm(p,strat->tailRing);
521        pIter(p);
522      }
523      strat->P.GetP();
524      b = TRUE;
525    }
526    omFree(mm);
527    omFree(m0);
528  }
529  return b; // return TRUE if sp was changed, FALSE if not
530}
531static BOOLEAN satstdWithInitialCheck(leftv res, leftv args)
532{
533  if (args!=NULL)
534  {
535    if ((args->Typ()==IDEAL_CMD) && (args->next==NULL))
536    {
537      ideal I=(ideal)args->Data();
538      idealCache = NULL;
539      I=kStd(I,currRing->qideal,testHomog,NULL,NULL,0,0,NULL,sat_sp_initial);
540      res->rtyp=IDEAL_CMD;
541      if (idealCache)
542        res->data=(char*)idealCache;
543      else
544        res->data=(char*)I;
545      return FALSE;
546    }
547  }
548  WerrorS("satstdWithInitialCheck: unexpected parameters");
549  return TRUE;
550}
551
552
553
554//------------------------------------------------------------------------
555// initialisation of the module
556extern "C" int SI_MOD_INIT(std_demo)(SModulFunctions* p)
557{
558  // p->iiAddCproc("std_demo","std_with_display",FALSE,std_with_display);
559  p->iiAddCproc("std_demo","satstd",FALSE,satstd);
560  p->iiAddCproc("std_demo","simplifySat",FALSE,simplifySat);
561  // p->iiAddCproc("std_demo","satstdWithInitialCheck",FALSE,satstdWithInitialCheck);
562  // p->iiAddCproc("std_demo","abortifmonomialstd",FALSE,abortifmonomialstd);
563  PrintS("init of std_demo - type `listvar(Std_demo);` to its contents\n");
564  return (MAX_TOK);
565}
Note: See TracBrowser for help on using the repository browser.