source: git/kernel/combinatorics/hilb.cc @ aad4ca4

spielwiese
Last change on this file since aad4ca4 was aad4ca4, checked in by Hans Schoenemann <hannes@…>, 6 years ago
format: Warn -> WarnS, trailing spaces
  • Property mode set to 100644
File size: 49.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5*  ABSTRACT -  Hilbert series
6*/
7
8#include "kernel/mod2.h"
9
10#include "omalloc/omalloc.h"
11#include "misc/mylimits.h"
12#include "misc/intvec.h"
13
14#include "kernel/combinatorics/hilb.h"
15#include "kernel/combinatorics/stairc.h"
16#include "kernel/combinatorics/hutil.h"
17
18#include "polys/monomials/ring.h"
19#include "polys/monomials/p_polys.h"
20#include "polys/simpleideals.h"
21
22
23// #include "kernel/structs.h"
24// #include "kernel/polys.h"
25//ADICHANGES:
26#include "kernel/ideals.h"
27// #include "kernel/GBEngine/kstd1.h"
28
29# define omsai 1
30#if omsai
31
32#include "polys/ext_fields/transext.h"
33#include "coeffs/coeffs.h"
34#include "kernel/linear_algebra/linearAlgebra.h"
35#include "coeffs/numbers.h"
36#include <vector>
37#include "Singular/ipshell.h"
38
39
40#include <Singular/ipshell.h>
41#include <ctime>
42#include <iostream>
43#endif
44
45static int  **Qpol;
46static int  *Q0, *Ql;
47static int  hLength;
48
49
50static int hMinModulweight(intvec *modulweight)
51{
52  int i,j,k;
53
54  if(modulweight==NULL) return 0;
55  j=(*modulweight)[0];
56  for(i=modulweight->rows()-1;i!=0;i--)
57  {
58    k=(*modulweight)[i];
59    if(k<j) j=k;
60  }
61  return j;
62}
63
64static void hHilbEst(scfmon stc, int Nstc, varset var, int Nvar)
65{
66  int  i, j;
67  int  x, y, z = 1;
68  int  *p;
69  for (i = Nvar; i>0; i--)
70  {
71    x = 0;
72    for (j = 0; j < Nstc; j++)
73    {
74      y = stc[j][var[i]];
75      if (y > x)
76        x = y;
77    }
78    z += x;
79    j = i - 1;
80    if (z > Ql[j])
81    {
82      if (z>(MAX_INT_VAL)/2)
83      {
84       WerrorS("internal arrays too big");
85       return;
86      }
87      p = (int *)omAlloc((unsigned long)z * sizeof(int));
88      if (Ql[j]!=0)
89      {
90        if (j==0)
91          memcpy(p, Qpol[j], Ql[j] * sizeof(int));
92        omFreeSize((ADDRESS)Qpol[j], Ql[j] * sizeof(int));
93      }
94      if (j==0)
95      {
96        for (x = Ql[j]; x < z; x++)
97          p[x] = 0;
98      }
99      Ql[j] = z;
100      Qpol[j] = p;
101    }
102  }
103}
104
105static int  *hAddHilb(int Nv, int x, int *pol, int *lp)
106{
107  int  l = *lp, ln, i;
108  int  *pon;
109  *lp = ln = l + x;
110  pon = Qpol[Nv];
111  memcpy(pon, pol, l * sizeof(int));
112  if (l > x)
113  {
114    for (i = x; i < l; i++)
115      pon[i] -= pol[i - x];
116    for (i = l; i < ln; i++)
117      pon[i] = -pol[i - x];
118  }
119  else
120  {
121    for (i = l; i < x; i++)
122      pon[i] = 0;
123    for (i = x; i < ln; i++)
124      pon[i] = -pol[i - x];
125  }
126  return pon;
127}
128
129static void hLastHilb(scmon pure, int Nv, varset var, int *pol, int lp)
130{
131  int  l = lp, x, i, j;
132  int  *p, *pl;
133  p = pol;
134  for (i = Nv; i>0; i--)
135  {
136    x = pure[var[i + 1]];
137    if (x!=0)
138      p = hAddHilb(i, x, p, &l);
139  }
140  pl = *Qpol;
141  j = Q0[Nv + 1];
142  for (i = 0; i < l; i++)
143    pl[i + j] += p[i];
144  x = pure[var[1]];
145  if (x!=0)
146  {
147    j += x;
148    for (i = 0; i < l; i++)
149      pl[i + j] -= p[i];
150  }
151  j += l;
152  if (j > hLength)
153    hLength = j;
154}
155
156static void hHilbStep(scmon pure, scfmon stc, int Nstc, varset var,
157 int Nvar, int *pol, int Lpol)
158{
159  int  iv = Nvar -1, ln, a, a0, a1, b, i;
160  int  x, x0;
161  scmon pn;
162  scfmon sn;
163  int  *pon;
164  if (Nstc==0)
165  {
166    hLastHilb(pure, iv, var, pol, Lpol);
167    return;
168  }
169  x = a = 0;
170  pn = hGetpure(pure);
171  sn = hGetmem(Nstc, stc, stcmem[iv]);
172  hStepS(sn, Nstc, var, Nvar, &a, &x);
173  Q0[iv] = Q0[Nvar];
174  ln = Lpol;
175  pon = pol;
176  if (a == Nstc)
177  {
178    x = pure[var[Nvar]];
179    if (x!=0)
180      pon = hAddHilb(iv, x, pon, &ln);
181    hHilbStep(pn, sn, a, var, iv, pon, ln);
182    return;
183  }
184  else
185  {
186    pon = hAddHilb(iv, x, pon, &ln);
187    hHilbStep(pn, sn, a, var, iv, pon, ln);
188  }
189  b = a;
190  x0 = 0;
191  loop
192  {
193    Q0[iv] += (x - x0);
194    a0 = a;
195    x0 = x;
196    hStepS(sn, Nstc, var, Nvar, &a, &x);
197    hElimS(sn, &b, a0, a, var, iv);
198    a1 = a;
199    hPure(sn, a0, &a1, var, iv, pn, &i);
200    hLex2S(sn, b, a0, a1, var, iv, hwork);
201    b += (a1 - a0);
202    ln = Lpol;
203    if (a < Nstc)
204    {
205      pon = hAddHilb(iv, x - x0, pol, &ln);
206      hHilbStep(pn, sn, b, var, iv, pon, ln);
207    }
208    else
209    {
210      x = pure[var[Nvar]];
211      if (x!=0)
212        pon = hAddHilb(iv, x - x0, pol, &ln);
213      else
214        pon = pol;
215      hHilbStep(pn, sn, b, var, iv, pon, ln);
216      return;
217    }
218  }
219}
220
221/*
222*basic routines
223*/
224static void hWDegree(intvec *wdegree)
225{
226  int i, k;
227  int x;
228
229  for (i=(currRing->N); i; i--)
230  {
231    x = (*wdegree)[i-1];
232    if (x != 1)
233    {
234      for (k=hNexist-1; k>=0; k--)
235      {
236        hexist[k][i] *= x;
237      }
238    }
239  }
240}
241// ---------------------------------- ADICHANGES ---------------------------------------------
242//!!!!!!!!!!!!!!!!!!!!! Just for Monomial Ideals !!!!!!!!!!!!!!!!!!!!!!!!!!!!
243
244#if 0 // unused
245//Tests if the ideal is sorted by degree
246static bool idDegSortTest(ideal I)
247{
248    if((I == NULL)||(idIs0(I)))
249    {
250        return(TRUE);
251    }
252    for(int i = 0; i<IDELEMS(I)-1; i++)
253    {
254        if(p_Totaldegree(I->m[i],currRing)>p_Totaldegree(I->m[i+1],currRing))
255        {
256            idPrint(I);
257            WerrorS("Ideal is not deg sorted!!");
258            return(FALSE);
259        }
260    }
261    return(TRUE);
262}
263#endif
264
265//adds the new polynomial at the coresponding position
266//and simplifies the ideal
267static ideal SortByDeg_p(ideal I, poly p)
268{
269    int i,j;
270    if((I == NULL) || (idIs0(I)))
271    {
272        ideal res = idInit(1,1);
273        res->m[0] = p;
274        return(res);
275    }
276    idSkipZeroes(I);
277    #if 1
278    for(i = 0; (i<IDELEMS(I)) && (p_Totaldegree(I->m[i],currRing)<=p_Totaldegree(p,currRing)); i++)
279    {
280        if(p_DivisibleBy( I->m[i],p, currRing))
281        {
282            return(I);
283        }
284    }
285    for(i = IDELEMS(I)-1; (i>=0) && (p_Totaldegree(I->m[i],currRing)>=p_Totaldegree(p,currRing)); i--)
286    {
287        if(p_DivisibleBy(p,I->m[i], currRing))
288        {
289            I->m[i] = NULL;
290        }
291    }
292    if(idIs0(I))
293    {
294        idSkipZeroes(I);
295        I->m[0] = p;
296        return(I);
297    }
298    #endif
299    idSkipZeroes(I);
300    //First I take the case when all generators have the same degree
301    if(p_Totaldegree(I->m[0],currRing) == p_Totaldegree(I->m[IDELEMS(I)-1],currRing))
302    {
303        if(p_Totaldegree(p,currRing)<p_Totaldegree(I->m[0],currRing))
304        {
305            idInsertPoly(I,p);
306            idSkipZeroes(I);
307            for(i=IDELEMS(I)-1;i>=1; i--)
308            {
309                I->m[i] = I->m[i-1];
310            }
311            I->m[0] = p;
312            return(I);
313        }
314        if(p_Totaldegree(p,currRing)>=p_Totaldegree(I->m[IDELEMS(I)-1],currRing))
315        {
316            idInsertPoly(I,p);
317            idSkipZeroes(I);
318            return(I);
319        }
320    }
321    if(p_Totaldegree(p,currRing)<=p_Totaldegree(I->m[0],currRing))
322    {
323        idInsertPoly(I,p);
324        idSkipZeroes(I);
325        for(i=IDELEMS(I)-1;i>=1; i--)
326        {
327            I->m[i] = I->m[i-1];
328        }
329        I->m[0] = p;
330        return(I);
331    }
332    if(p_Totaldegree(p,currRing)>=p_Totaldegree(I->m[IDELEMS(I)-1],currRing))
333    {
334        idInsertPoly(I,p);
335        idSkipZeroes(I);
336        return(I);
337    }
338    for(i = IDELEMS(I)-2; ;)
339    {
340        if(p_Totaldegree(p,currRing)==p_Totaldegree(I->m[i],currRing))
341        {
342            idInsertPoly(I,p);
343            idSkipZeroes(I);
344            for(j = IDELEMS(I)-1; j>=i+1;j--)
345            {
346                I->m[j] = I->m[j-1];
347            }
348            I->m[i] = p;
349            return(I);
350        }
351        if(p_Totaldegree(p,currRing)>p_Totaldegree(I->m[i],currRing))
352        {
353            idInsertPoly(I,p);
354            idSkipZeroes(I);
355            for(j = IDELEMS(I)-1; j>=i+2;j--)
356            {
357                I->m[j] = I->m[j-1];
358            }
359            I->m[i+1] = p;
360            return(I);
361        }
362        i--;
363    }
364}
365
366//it sorts the ideal by the degrees
367static ideal SortByDeg(ideal I)
368{
369    if(idIs0(I))
370    {
371        return(I);
372    }
373    int i;
374    ideal res;
375    idSkipZeroes(I);
376    res = idInit(1,1);
377    res->m[0] = poly(0);
378    for(i = 0; i<=IDELEMS(I)-1;i++)
379    {
380        res = SortByDeg_p(res, I->m[i]);
381    }
382    idSkipZeroes(res);
383    //idDegSortTest(res);
384    return(res);
385}
386
387//idQuot(I,p) for I monomial ideal, p a ideal with a single monomial.
388ideal idQuotMon(ideal Iorig, ideal p)
389{
390    if(idIs0(Iorig))
391    {
392        ideal res = idInit(1,1);
393        res->m[0] = poly(0);
394        return(res);
395    }
396    if(idIs0(p))
397    {
398        ideal res = idInit(1,1);
399        res->m[0] = pOne();
400        return(res);
401    }
402    ideal I = idCopy(Iorig);
403    ideal res = idInit(IDELEMS(I),1);
404    int i,j;
405    int dummy;
406    for(i = 0; i<IDELEMS(I); i++)
407    {
408        res->m[i] = p_Copy(I->m[i], currRing);
409        for(j = 1; (j<=currRing->N) ; j++)
410        {
411            dummy = p_GetExp(p->m[0], j, currRing);
412            if(dummy > 0)
413            {
414                if(p_GetExp(I->m[i], j, currRing) < dummy)
415                {
416                    p_SetExp(res->m[i], j, 0, currRing);
417                }
418                else
419                {
420                    p_SetExp(res->m[i], j, p_GetExp(I->m[i], j, currRing) - dummy, currRing);
421                }
422            }
423        }
424        p_Setm(res->m[i], currRing);
425        if(p_Totaldegree(res->m[i],currRing) == p_Totaldegree(I->m[i],currRing))
426        {
427            res->m[i] = NULL; // pDelete
428        }
429        else
430        {
431            I->m[i] = NULL; // pDelete
432        }
433    }
434    idSkipZeroes(res);
435    idSkipZeroes(I);
436    if(!idIs0(res))
437    {
438      for(i = 0; i<=IDELEMS(res)-1; i++)
439      {
440        I = SortByDeg_p(I,res->m[i]);
441      }
442    }
443    //idDegSortTest(I);
444    return(I);
445}
446
447//id_Add for monomials
448static ideal idAddMon(ideal I, ideal p)
449{
450    #if 1
451    I = SortByDeg_p(I,p->m[0]);
452    #else
453    I = id_Add(I,p,currRing);
454    #endif
455    //idSkipZeroes(I);
456    return(I);
457}
458
459//searches for a variable that is not yet used (assumes that the ideal is sqrfree)
460static poly ChoosePVar (ideal I)
461{
462    bool flag=TRUE;
463    int i,j;
464    poly res;
465    for(i=1;i<=currRing->N;i++)
466    {
467        flag=TRUE;
468        for(j=IDELEMS(I)-1;(j>=0)&&(flag);j--)
469        {
470            if(p_GetExp(I->m[j], i, currRing)>0)
471            {
472                flag=FALSE;
473            }
474        }
475
476        if(flag == TRUE)
477        {
478            res = p_ISet(1, currRing);
479            p_SetExp(res, i, 1, currRing);
480            p_Setm(res,currRing);
481            return(res);
482        }
483        else
484        {
485            p_Delete(&res, currRing);
486        }
487    }
488    return(NULL); //i.e. it is the maximal ideal
489}
490
491#if 0 // unused
492//choice XL: last entry divided by x (xy10z15 -> y9z14)
493static poly ChoosePXL(ideal I)
494{
495    int i,j,dummy=0;
496    poly m;
497    for(i = IDELEMS(I)-1; (i>=0) && (dummy == 0); i--)
498    {
499        for(j = 1; (j<=currRing->N) && (dummy == 0); j++)
500        {
501            if(p_GetExp(I->m[i],j, currRing)>1)
502            {
503                dummy = 1;
504            }
505        }
506    }
507    m = p_Copy(I->m[i+1],currRing);
508    for(j = 1; j<=currRing->N; j++)
509    {
510        dummy = p_GetExp(m,j,currRing);
511        if(dummy >= 1)
512        {
513            p_SetExp(m, j, dummy-1, currRing);
514        }
515    }
516    if(!p_IsOne(m, currRing))
517    {
518        p_Setm(m, currRing);
519        return(m);
520    }
521    m = ChoosePVar(I);
522    return(m);
523}
524#endif
525
526#if 0 // unused
527//choice XF: first entry divided by x (xy10z15 -> y9z14)
528static poly ChoosePXF(ideal I)
529{
530    int i,j,dummy=0;
531    poly m;
532    for(i =0 ; (i<=IDELEMS(I)-1) && (dummy == 0); i++)
533    {
534        for(j = 1; (j<=currRing->N) && (dummy == 0); j++)
535        {
536            if(p_GetExp(I->m[i],j, currRing)>1)
537            {
538                dummy = 1;
539            }
540        }
541    }
542    m = p_Copy(I->m[i-1],currRing);
543    for(j = 1; j<=currRing->N; j++)
544    {
545        dummy = p_GetExp(m,j,currRing);
546        if(dummy >= 1)
547        {
548            p_SetExp(m, j, dummy-1, currRing);
549        }
550    }
551    if(!p_IsOne(m, currRing))
552    {
553        p_Setm(m, currRing);
554        return(m);
555    }
556    m = ChoosePVar(I);
557    return(m);
558}
559#endif
560
561#if 0 // unused
562//choice OL: last entry the first power (xy10z15 -> xy9z15)
563static poly ChoosePOL(ideal I)
564{
565    int i,j,dummy;
566    poly m;
567    for(i = IDELEMS(I)-1;i>=0;i--)
568    {
569        m = p_Copy(I->m[i],currRing);
570        for(j=1;j<=currRing->N;j++)
571        {
572            dummy = p_GetExp(m,j,currRing);
573            if(dummy > 0)
574            {
575                p_SetExp(m,j,dummy-1,currRing);
576                p_Setm(m,currRing);
577            }
578        }
579        if(!p_IsOne(m, currRing))
580        {
581            return(m);
582        }
583        else
584        {
585            p_Delete(&m,currRing);
586        }
587    }
588    m = ChoosePVar(I);
589    return(m);
590}
591#endif
592
593#if 0 // unused
594//choice OF: first entry the first power (xy10z15 -> xy9z15)
595static poly ChoosePOF(ideal I)
596{
597    int i,j,dummy;
598    poly m;
599    for(i = 0 ;i<=IDELEMS(I)-1;i++)
600    {
601        m = p_Copy(I->m[i],currRing);
602        for(j=1;j<=currRing->N;j++)
603        {
604            dummy = p_GetExp(m,j,currRing);
605            if(dummy > 0)
606            {
607                p_SetExp(m,j,dummy-1,currRing);
608                p_Setm(m,currRing);
609            }
610        }
611        if(!p_IsOne(m, currRing))
612        {
613            return(m);
614        }
615        else
616        {
617            p_Delete(&m,currRing);
618        }
619    }
620    m = ChoosePVar(I);
621    return(m);
622}
623#endif
624
625#if 0 // unused
626//choice VL: last entry the first variable with power (xy10z15 -> y)
627static poly ChoosePVL(ideal I)
628{
629    int i,j,dummy;
630    bool flag = TRUE;
631    poly m = p_ISet(1,currRing);
632    for(i = IDELEMS(I)-1;(i>=0) && (flag);i--)
633    {
634        flag = TRUE;
635        for(j=1;(j<=currRing->N) && (flag);j++)
636        {
637            dummy = p_GetExp(I->m[i],j,currRing);
638            if(dummy >= 2)
639            {
640                p_SetExp(m,j,1,currRing);
641                p_Setm(m,currRing);
642                flag = FALSE;
643            }
644        }
645        if(!p_IsOne(m, currRing))
646        {
647            return(m);
648        }
649    }
650    m = ChoosePVar(I);
651    return(m);
652}
653#endif
654
655#if 0 // unused
656//choice VF: first entry the first variable with power (xy10z15 -> y)
657static poly ChoosePVF(ideal I)
658{
659    int i,j,dummy;
660    bool flag = TRUE;
661    poly m = p_ISet(1,currRing);
662    for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++)
663    {
664        flag = TRUE;
665        for(j=1;(j<=currRing->N) && (flag);j++)
666        {
667            dummy = p_GetExp(I->m[i],j,currRing);
668            if(dummy >= 2)
669            {
670                p_SetExp(m,j,1,currRing);
671                p_Setm(m,currRing);
672                flag = FALSE;
673            }
674        }
675        if(!p_IsOne(m, currRing))
676        {
677            return(m);
678        }
679    }
680    m = ChoosePVar(I);
681    return(m);
682}
683#endif
684
685//choice JL: last entry just variable with power (xy10z15 -> y10)
686static poly ChoosePJL(ideal I)
687{
688    int i,j,dummy;
689    bool flag = TRUE;
690    poly m = p_ISet(1,currRing);
691    for(i = IDELEMS(I)-1;(i>=0) && (flag);i--)
692    {
693        flag = TRUE;
694        for(j=1;(j<=currRing->N) && (flag);j++)
695        {
696            dummy = p_GetExp(I->m[i],j,currRing);
697            if(dummy >= 2)
698            {
699                p_SetExp(m,j,dummy-1,currRing);
700                p_Setm(m,currRing);
701                flag = FALSE;
702            }
703        }
704        if(!p_IsOne(m, currRing))
705        {
706            return(m);
707        }
708    }
709    m = ChoosePVar(I);
710    return(m);
711}
712
713#if 0
714//choice JF: last entry just variable with power -1 (xy10z15 -> y9)
715static poly ChoosePJF(ideal I)
716{
717    int i,j,dummy;
718    bool flag = TRUE;
719    poly m = p_ISet(1,currRing);
720    for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++)
721    {
722        flag = TRUE;
723        for(j=1;(j<=currRing->N) && (flag);j++)
724        {
725            dummy = p_GetExp(I->m[i],j,currRing);
726            if(dummy >= 2)
727            {
728                p_SetExp(m,j,dummy-1,currRing);
729                p_Setm(m,currRing);
730                flag = FALSE;
731            }
732        }
733        if(!p_IsOne(m, currRing))
734        {
735            return(m);
736        }
737    }
738    m = ChoosePVar(I);
739    return(m);
740}
741#endif
742
743//chooses 1 \neq p \not\in S. This choice should be made optimal
744static poly ChooseP(ideal I)
745{
746    poly m;
747    //  TEST TO SEE WHICH ONE IS BETTER
748    //m = ChoosePXL(I);
749    //m = ChoosePXF(I);
750    //m = ChoosePOL(I);
751    //m = ChoosePOF(I);
752    //m = ChoosePVL(I);
753    //m = ChoosePVF(I);
754    m = ChoosePJL(I);
755    //m = ChoosePJF(I);
756    return(m);
757}
758
759///searches for a monomial of degree d>=2 and divides it by a variable (result monomial of deg d-1)
760static poly SearchP(ideal I)
761{
762    int i,j,exp;
763    poly res;
764    if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)<=1)
765    {
766        res = ChoosePVar(I);
767        return(res);
768    }
769    i = IDELEMS(I)-1;
770    res = p_Copy(I->m[i], currRing);
771    for(j=1;j<=currRing->N;j++)
772    {
773        exp = p_GetExp(I->m[i], j, currRing);
774        if(exp > 0)
775        {
776            p_SetExp(res, j, exp - 1, currRing);
777            p_Setm(res,currRing);
778            break;
779        }
780    }
781    assume( j <= currRing->N );
782    return(res);
783}
784
785//test if the ideal is of the form (x1, ..., xr)
786static bool JustVar(ideal I)
787{
788    #if 0
789    int i,j;
790    bool foundone;
791    for(i=0;i<=IDELEMS(I)-1;i++)
792    {
793        foundone = FALSE;
794        for(j = 1;j<=currRing->N;j++)
795        {
796            if(p_GetExp(I->m[i], j, currRing)>0)
797            {
798                if(foundone == TRUE)
799                {
800                    return(FALSE);
801                }
802                foundone = TRUE;
803            }
804        }
805    }
806    return(TRUE);
807    #else
808    if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)>1)
809    {
810        return(FALSE);
811    }
812    return(TRUE);
813    #endif
814}
815
816//computes the Euler Characteristic of the ideal
817static void eulerchar (ideal I, int variables, mpz_ptr ec)
818{
819  loop
820  {
821    mpz_t dummy;
822    if(JustVar(I) == TRUE)
823    {
824        if(IDELEMS(I) == variables)
825        {
826            mpz_init(dummy);
827            if((variables % 2) == 0)
828                {mpz_set_ui(dummy, 1);}
829            else
830                {mpz_set_si(dummy, -1);}
831            mpz_add(ec, ec, dummy);
832        }
833        //mpz_clear(dummy);
834        return;
835    }
836    ideal p = idInit(1,1);
837    p->m[0] = SearchP(I);
838    //idPrint(I);
839    //idPrint(p);
840    //printf("\nNow get in idQuotMon\n");
841    ideal Ip = idQuotMon(I,p);
842    //idPrint(Ip);
843    //Ip = SortByDeg(Ip);
844    int i,howmanyvarinp = 0;
845    for(i = 1;i<=currRing->N;i++)
846    {
847        if(p_GetExp(p->m[0],i,currRing)>0)
848        {
849            howmanyvarinp++;
850        }
851    }
852    eulerchar(Ip, variables-howmanyvarinp, ec);
853    id_Delete(&Ip, currRing);
854    I = idAddMon(I,p);
855  }
856}
857
858//tests if an ideal is Square Free, if no, returns the variable which appears at powers >1
859static poly SqFree (ideal I)
860{
861    int i,j;
862    bool flag=TRUE;
863    poly notsqrfree = NULL;
864    if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)<=1)
865    {
866        return(notsqrfree);
867    }
868    for(i=IDELEMS(I)-1;(i>=0)&&(flag);i--)
869    {
870        for(j=1;(j<=currRing->N)&&(flag);j++)
871        {
872            if(p_GetExp(I->m[i],j,currRing)>1)
873            {
874                flag=FALSE;
875                notsqrfree = p_ISet(1,currRing);
876                p_SetExp(notsqrfree,j,1,currRing);
877            }
878        }
879    }
880    if(notsqrfree != NULL)
881    {
882        p_Setm(notsqrfree,currRing);
883    }
884    return(notsqrfree);
885}
886
887//checks if a polynomial is in I
888static bool IsIn(poly p, ideal I)
889{
890    //assumes that I is ordered by degree
891    if(idIs0(I))
892    {
893        if(p==poly(0))
894        {
895            return(TRUE);
896        }
897        else
898        {
899            return(FALSE);
900        }
901    }
902    if(p==poly(0))
903    {
904        return(FALSE);
905    }
906    int i,j;
907    bool flag;
908    for(i = 0;i<IDELEMS(I);i++)
909    {
910        flag = TRUE;
911        for(j = 1;(j<=currRing->N) &&(flag);j++)
912        {
913            if(p_GetExp(p, j, currRing)<p_GetExp(I->m[i], j, currRing))
914            {
915                flag = FALSE;
916            }
917        }
918        if(flag)
919        {
920            return(TRUE);
921        }
922    }
923    return(FALSE);
924}
925
926//computes the lcm of min I, I monomial ideal
927static poly LCMmon(ideal I)
928{
929    if(idIs0(I))
930    {
931        return(NULL);
932    }
933    poly m;
934    int dummy,i,j;
935    m = p_ISet(1,currRing);
936    for(i=1;i<=currRing->N;i++)
937    {
938        dummy=0;
939        for(j=IDELEMS(I)-1;j>=0;j--)
940        {
941            if(p_GetExp(I->m[j],i,currRing) > dummy)
942            {
943                dummy = p_GetExp(I->m[j],i,currRing);
944            }
945        }
946        p_SetExp(m,i,dummy,currRing);
947    }
948    p_Setm(m,currRing);
949    return(m);
950}
951
952//the Roune Slice Algorithm
953void rouneslice(ideal I, ideal S, poly q, poly x, int &prune, int &moreprune, int &steps, int &NNN, mpz_ptr &hilbertcoef, int* &hilbpower)
954{
955  loop
956  {
957    (steps)++;
958    int i,j;
959    int dummy;
960    poly m;
961    ideal p;
962    //----------- PRUNING OF S ---------------
963    //S SHOULD IN THIS POINT BE ORDERED BY DEGREE
964    for(i=IDELEMS(S)-1;i>=0;i--)
965    {
966        if(IsIn(S->m[i],I))
967        {
968            S->m[i]=NULL;
969            prune++;
970        }
971    }
972    idSkipZeroes(S);
973    //----------------------------------------
974    for(i=IDELEMS(I)-1;i>=0;i--)
975    {
976        m = p_Copy(I->m[i],currRing);
977        for(j=1;j<=currRing->N;j++)
978        {
979            dummy = p_GetExp(m,j,currRing);
980            if(dummy > 0)
981            {
982                p_SetExp(m,j,dummy-1,currRing);
983            }
984        }
985        p_Setm(m, currRing);
986        if(IsIn(m,S))
987        {
988            I->m[i]=NULL;
989            //printf("\n Deleted, since pi(m) is in S\n");pWrite(m);
990        }
991    }
992    idSkipZeroes(I);
993    //----------- MORE PRUNING OF S ------------
994    m = LCMmon(I);
995    if(m != NULL)
996    {
997        for(i=0;i<IDELEMS(S);i++)
998        {
999            if(!(p_DivisibleBy(S->m[i], m, currRing)))
1000            {
1001                S->m[i] = NULL;
1002                j++;
1003                moreprune++;
1004            }
1005            else
1006            {
1007                if(pLmEqual(S->m[i],m))
1008                {
1009                    S->m[i] = NULL;
1010                    moreprune++;
1011                }
1012            }
1013        }
1014    idSkipZeroes(S);
1015    }
1016    /*printf("\n---------------------------\n");
1017    printf("\n      I\n");idPrint(I);
1018    printf("\n      S\n");idPrint(S);
1019    printf("\n      q\n");pWrite(q);
1020    getchar();*/
1021
1022    if(idIs0(I))
1023    {
1024        id_Delete(&I, currRing);
1025        id_Delete(&S, currRing);
1026        p_Delete(&m, currRing);
1027        break;
1028    }
1029    m = LCMmon(I);
1030    if(!p_DivisibleBy(x,m, currRing))
1031    {
1032        //printf("\nx does not divide lcm(I)");
1033        //printf("\nEmpty set");pWrite(q);
1034        id_Delete(&I, currRing);
1035        id_Delete(&S, currRing);
1036        p_Delete(&m, currRing);
1037        break;
1038    }
1039    m = SqFree(I);
1040    if(m==NULL)
1041    {
1042        //printf("\n      Corner: ");
1043        //pWrite(q);
1044        //printf("\n      With the facets of the dual simplex:\n");
1045        //idPrint(I);
1046        mpz_t ec;
1047        mpz_init(ec);
1048        mpz_ptr ec_ptr = ec;
1049        eulerchar(I, currRing->N, ec_ptr);
1050        bool flag = FALSE;
1051        if(NNN==0)
1052            {
1053                hilbertcoef = (mpz_ptr)omAlloc((NNN+1)*sizeof(mpz_t));
1054                hilbpower = (int*)omAlloc((NNN+1)*sizeof(int));
1055                mpz_init( &hilbertcoef[NNN]);
1056                mpz_set(  &hilbertcoef[NNN], ec);
1057                mpz_clear(ec);
1058                hilbpower[NNN] = p_Totaldegree(q,currRing);
1059                NNN++;
1060            }
1061        else
1062        {
1063            //I look if the power appears already
1064            for(i = 0;(i<NNN)&&(flag == FALSE)&&(p_Totaldegree(q,currRing)>=hilbpower[i]);i++)
1065            {
1066                if((hilbpower[i]) == (p_Totaldegree(q,currRing)))
1067                {
1068                    flag = TRUE;
1069                    mpz_add(&hilbertcoef[i],&hilbertcoef[i],ec_ptr);
1070                }
1071            }
1072            if(flag == FALSE)
1073            {
1074                hilbertcoef = (mpz_ptr)omRealloc(hilbertcoef, (NNN+1)*sizeof(mpz_t));
1075                hilbpower = (int*)omRealloc(hilbpower, (NNN+1)*sizeof(int));
1076                mpz_init(&hilbertcoef[NNN]);
1077                for(j = NNN; j>i; j--)
1078                {
1079                    mpz_set(&hilbertcoef[j],&hilbertcoef[j-1]);
1080                    hilbpower[j] = hilbpower[j-1];
1081                }
1082                mpz_set(  &hilbertcoef[i], ec);
1083                mpz_clear(ec);
1084                hilbpower[i] = p_Totaldegree(q,currRing);
1085                NNN++;
1086            }
1087        }
1088        break;
1089    }
1090    m = ChooseP(I);
1091    p = idInit(1,1);
1092    p->m[0] = m;
1093    ideal Ip = idQuotMon(I,p);
1094    ideal Sp = idQuotMon(S,p);
1095    poly pq = pp_Mult_mm(q,m,currRing);
1096    rouneslice(Ip, Sp, pq, x, prune, moreprune, steps, NNN, hilbertcoef,hilbpower);
1097    //id_Delete(&Ip, currRing);
1098    //id_Delete(&Sp, currRing);
1099    S = idAddMon(S,p);
1100    p->m[0]=NULL;
1101    id_Delete(&p, currRing); // p->m[0] was also in S
1102    p_Delete(&pq,currRing);
1103  }
1104}
1105
1106//it computes the first hilbert series by means of Roune Slice Algorithm
1107void slicehilb(ideal I)
1108{
1109    //printf("Adi changes are here: \n");
1110    int i, NNN = 0;
1111    int steps = 0, prune = 0, moreprune = 0;
1112    mpz_ptr hilbertcoef;
1113    int *hilbpower;
1114    ideal S = idInit(1,1);
1115    poly q = p_ISet(1,currRing);
1116    ideal X = idInit(1,1);
1117    X->m[0]=p_One(currRing);
1118    for(i=1;i<=currRing->N;i++)
1119    {
1120            p_SetExp(X->m[0],i,1,currRing);
1121    }
1122    p_Setm(X->m[0],currRing);
1123    I = id_Mult(I,X,currRing);
1124    I = SortByDeg(I);
1125    //printf("\n-------------RouneSlice--------------\n");
1126    rouneslice(I,S,q,X->m[0],prune, moreprune, steps, NNN, hilbertcoef, hilbpower);
1127    //printf("\nIn total Prune got rid of %i elements\n",prune);
1128    //printf("\nIn total More Prune got rid of %i elements\n",moreprune);
1129    //printf("\nSteps of rouneslice: %i\n\n", steps);
1130    mpz_t coefhilb;
1131    mpz_t dummy;
1132    mpz_init(coefhilb);
1133    mpz_init(dummy);
1134    printf("\n//  %8d t^0",1);
1135    for(i = 0; i<NNN; i++)
1136    {
1137        if(mpz_sgn(&hilbertcoef[i])!=0)
1138        {
1139            gmp_printf("\n//  %8Zd t^%d",&hilbertcoef[i],hilbpower[i]);
1140        }
1141    }
1142    omFreeSize(hilbertcoef, (NNN)*sizeof(mpz_t));
1143    omFreeSize(hilbpower, (NNN)*sizeof(int));
1144    //printf("\n-------------------------------------\n");
1145}
1146
1147// -------------------------------- END OF CHANGES -------------------------------------------
1148static intvec * hSeries(ideal S, intvec *modulweight,
1149                int /*notstc*/, intvec *wdegree, ideal Q, ring tailRing)
1150{
1151//  id_TestTail(S, currRing, tailRing);
1152
1153  intvec *work, *hseries1=NULL;
1154  int  mc;
1155  int  p0;
1156  int  i, j, k, l, ii, mw;
1157  hexist = hInit(S, Q, &hNexist, tailRing);
1158  if (hNexist==0)
1159  {
1160    hseries1=new intvec(2);
1161    (*hseries1)[0]=1;
1162    (*hseries1)[1]=0;
1163    return hseries1;
1164  }
1165
1166  #if 0
1167  if (wdegree == NULL)
1168    hWeight();
1169  else
1170    hWDegree(wdegree);
1171  #else
1172  if (wdegree != NULL) hWDegree(wdegree);
1173  #endif
1174
1175  p0 = 1;
1176  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
1177  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
1178  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
1179  stcmem = hCreate((currRing->N) - 1);
1180  Qpol = (int **)omAlloc(((currRing->N) + 1) * sizeof(int *));
1181  Ql = (int *)omAlloc0(((currRing->N) + 1) * sizeof(int));
1182  Q0 = (int *)omAlloc(((currRing->N) + 1) * sizeof(int));
1183  *Qpol = NULL;
1184  hLength = k = j = 0;
1185  mc = hisModule;
1186  if (mc!=0)
1187  {
1188    mw = hMinModulweight(modulweight);
1189    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
1190  }
1191  else
1192  {
1193    mw = 0;
1194    hstc = hexist;
1195    hNstc = hNexist;
1196  }
1197  loop
1198  {
1199    if (mc!=0)
1200    {
1201      hComp(hexist, hNexist, mc, hstc, &hNstc);
1202      if (modulweight != NULL)
1203        j = (*modulweight)[mc-1]-mw;
1204    }
1205    if (hNstc!=0)
1206    {
1207      hNvar = (currRing->N);
1208      for (i = hNvar; i>=0; i--)
1209        hvar[i] = i;
1210      //if (notstc) // TODO: no mon divides another
1211        hStaircase(hstc, &hNstc, hvar, hNvar);
1212      hSupp(hstc, hNstc, hvar, &hNvar);
1213      if (hNvar!=0)
1214      {
1215        if ((hNvar > 2) && (hNstc > 10))
1216          hOrdSupp(hstc, hNstc, hvar, hNvar);
1217        hHilbEst(hstc, hNstc, hvar, hNvar);
1218        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
1219        hPure(hstc, 0, &hNstc, hvar, hNvar, hpure, &hNpure);
1220        hLexS(hstc, hNstc, hvar, hNvar);
1221        Q0[hNvar] = 0;
1222        hHilbStep(hpure, hstc, hNstc, hvar, hNvar, &p0, 1);
1223      }
1224    }
1225    else
1226    {
1227      if(*Qpol!=NULL)
1228        (**Qpol)++;
1229      else
1230      {
1231        *Qpol = (int *)omAlloc(sizeof(int));
1232        hLength = *Ql = **Qpol = 1;
1233      }
1234    }
1235    if (*Qpol!=NULL)
1236    {
1237      i = hLength;
1238      while ((i > 0) && ((*Qpol)[i - 1] == 0))
1239        i--;
1240      if (i > 0)
1241      {
1242        l = i + j;
1243        if (l > k)
1244        {
1245          work = new intvec(l);
1246          for (ii=0; ii<k; ii++)
1247            (*work)[ii] = (*hseries1)[ii];
1248          if (hseries1 != NULL)
1249            delete hseries1;
1250          hseries1 = work;
1251          k = l;
1252        }
1253        while (i > 0)
1254        {
1255          (*hseries1)[i + j - 1] += (*Qpol)[i - 1];
1256          (*Qpol)[i - 1] = 0;
1257          i--;
1258        }
1259      }
1260    }
1261    mc--;
1262    if (mc <= 0)
1263      break;
1264  }
1265  if (k==0)
1266  {
1267    hseries1=new intvec(2);
1268    (*hseries1)[0]=0;
1269    (*hseries1)[1]=0;
1270  }
1271  else
1272  {
1273    l = k+1;
1274    while ((*hseries1)[l-2]==0) l--;
1275    if (l!=k)
1276    {
1277      work = new intvec(l);
1278      for (ii=l-2; ii>=0; ii--)
1279        (*work)[ii] = (*hseries1)[ii];
1280      delete hseries1;
1281      hseries1 = work;
1282    }
1283    (*hseries1)[l-1] = mw;
1284  }
1285  for (i = 0; i <= (currRing->N); i++)
1286  {
1287    if (Ql[i]!=0)
1288      omFreeSize((ADDRESS)Qpol[i], Ql[i] * sizeof(int));
1289  }
1290  omFreeSize((ADDRESS)Q0, ((currRing->N) + 1) * sizeof(int));
1291  omFreeSize((ADDRESS)Ql, ((currRing->N) + 1) * sizeof(int));
1292  omFreeSize((ADDRESS)Qpol, ((currRing->N) + 1) * sizeof(int *));
1293  hKill(stcmem, (currRing->N) - 1);
1294  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
1295  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
1296  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
1297  hDelete(hexist, hNexist);
1298  if (hisModule!=0)
1299    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
1300  return hseries1;
1301}
1302
1303
1304intvec * hHstdSeries(ideal S, intvec *modulweight, intvec *wdegree, ideal Q, ring tailRing)
1305{
1306  id_TestTail(S, currRing, tailRing);
1307  if (Q!=NULL) id_TestTail(Q, currRing, tailRing);
1308  return hSeries(S, modulweight, 0, wdegree, Q, tailRing);
1309}
1310
1311intvec * hFirstSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing)
1312{
1313  id_TestTail(S, currRing, tailRing);
1314  if (Q!= NULL) id_TestTail(Q, currRing, tailRing);
1315
1316  return hSeries(S, modulweight, 1, wdegree, Q, tailRing);
1317}
1318
1319intvec * hSecondSeries(intvec *hseries1)
1320{
1321  intvec *work, *hseries2;
1322  int i, j, k, s, t, l;
1323  if (hseries1 == NULL)
1324    return NULL;
1325  work = new intvec(hseries1);
1326  k = l = work->length()-1;
1327  s = 0;
1328  for (i = k-1; i >= 0; i--)
1329    s += (*work)[i];
1330  loop
1331  {
1332    if ((s != 0) || (k == 1))
1333      break;
1334    s = 0;
1335    t = (*work)[k-1];
1336    k--;
1337    for (i = k-1; i >= 0; i--)
1338    {
1339      j = (*work)[i];
1340      (*work)[i] = -t;
1341      s += t;
1342      t += j;
1343    }
1344  }
1345  hseries2 = new intvec(k+1);
1346  for (i = k-1; i >= 0; i--)
1347    (*hseries2)[i] = (*work)[i];
1348  (*hseries2)[k] = (*work)[l];
1349  delete work;
1350  return hseries2;
1351}
1352
1353void hDegreeSeries(intvec *s1, intvec *s2, int *co, int *mu)
1354{
1355  int m, i, j, k;
1356  *co = *mu = 0;
1357  if ((s1 == NULL) || (s2 == NULL))
1358    return;
1359  i = s1->length();
1360  j = s2->length();
1361  if (j > i)
1362    return;
1363  m = 0;
1364  for(k=j-2; k>=0; k--)
1365    m += (*s2)[k];
1366  *mu = m;
1367  *co = i - j;
1368}
1369
1370static void hPrintHilb(intvec *hseries)
1371{
1372  int  i, j, l, k;
1373  if (hseries == NULL)
1374    return;
1375  l = hseries->length()-1;
1376  k = (*hseries)[l];
1377  for (i = 0; i < l; i++)
1378  {
1379    j = (*hseries)[i];
1380    if (j != 0)
1381    {
1382      Print("//  %8d t^%d\n", j, i+k);
1383    }
1384  }
1385}
1386
1387/*
1388*caller
1389*/
1390void hLookSeries(ideal S, intvec *modulweight, ideal Q, intvec *wdegree, ring tailRing)
1391{
1392  id_TestTail(S, currRing, tailRing);
1393
1394  intvec *hseries1 = hFirstSeries(S, modulweight, Q, wdegree, tailRing);
1395
1396  hPrintHilb(hseries1);
1397
1398  const int l = hseries1->length()-1;
1399
1400  intvec *hseries2 = (l > 1) ? hSecondSeries(hseries1) : hseries1;
1401
1402  int co, mu;
1403  hDegreeSeries(hseries1, hseries2, &co, &mu);
1404
1405  PrintLn();
1406  hPrintHilb(hseries2);
1407  if ((l == 1) &&(mu == 0))
1408    scPrintDegree(rVar(currRing)+1, 0);
1409  else
1410    scPrintDegree(co, mu);
1411  if (l>1)
1412    delete hseries1;
1413  delete hseries2;
1414}
1415
1416/***********************************************************************
1417 Computation of Hilbert series of non-commutative monomial algebras
1418************************************************************************/
1419
1420
1421static void idInsertMonomial(ideal I, poly p)
1422{
1423  /*
1424   * It adds monomial in I and if required,
1425   * enlarge the size of poly-set by 16.
1426   * It does not make copy of  p.
1427   */
1428
1429  if(I == NULL)
1430  {
1431    return;
1432  }
1433
1434  int j = IDELEMS(I) - 1;
1435  while ((j >= 0) && (I->m[j] == NULL))
1436  {
1437    j--;
1438  }
1439  j++;
1440  if (j == IDELEMS(I))
1441  {
1442    pEnlargeSet(&(I->m), IDELEMS(I), 16);
1443    IDELEMS(I) +=16;
1444  }
1445  I->m[j] = p;
1446}
1447
1448static int comapreMonoIdBases(ideal J, ideal Ob)
1449{
1450  /*
1451   * Monomials of J and Ob are assumed to
1452   * be already sorted. J and Ob are
1453   * represented by the minimal generating set.
1454   */
1455  int i, s;
1456  s = 1;
1457  int JCount = IDELEMS(J);
1458  int ObCount = IDELEMS(Ob);
1459
1460  if(idIs0(J))
1461  {
1462    return(1);
1463  }
1464  if(JCount != ObCount)
1465  {
1466    return(0);
1467  }
1468
1469  for(i = 0; i < JCount; i++)
1470  {
1471    if(!(p_LmEqual(J->m[i], Ob->m[i], currRing)))
1472    {
1473      return(0);
1474    }
1475  }
1476  return(s);
1477}
1478
1479static int CountOnIdUptoTruncationIndex(ideal I, int tr)
1480{
1481  /*
1482   * The ideal I must be sorted in increasing total degree.
1483   * It counts the number of monomials in I up to
1484   * degree less than or equal to tr.
1485   */
1486
1487  //case when I=1;
1488  if(p_Totaldegree(I->m[0], currRing) == 0)
1489  {
1490    return(1);
1491  }
1492
1493  int count = 0;
1494  for(int i = 0; i < IDELEMS(I); i++)
1495  {
1496    if(p_Totaldegree(I->m[i], currRing) > tr)
1497    {
1498      return (count);
1499    }
1500    count = count + 1;
1501  }
1502
1503  return(count);
1504}
1505
1506static int comapreMonoIdBases_IG_Case(ideal J, int JCount, ideal Ob, int ObCount)
1507{
1508  /*
1509   * Monomials of J and Ob are assumed to
1510   * be already sorted in increasing degrees.
1511   * J and Ob are represented by the minimal
1512   * generating set.  It checks if J and Ob have
1513   * same monomials  up to deg <=tr.
1514   */
1515
1516  int i, s;
1517  s = 1;
1518  //when J is null
1519  //
1520  if(JCount != ObCount)
1521  {
1522    return(0);
1523  }
1524
1525  if(JCount == 0)
1526  {
1527    return(1);
1528  }
1529
1530  for(i = 0; i< JCount; i++)
1531  {
1532    if(!(p_LmEqual(J->m[i], Ob->m[i], currRing)))
1533    {
1534      return(0);
1535    }
1536  }
1537
1538  return(s);
1539}
1540
1541static int positionInOrbit_IG_Case(ideal I, poly w, std::vector<ideal> idorb, std::vector<poly> polist, int trInd, int trunDegHs)
1542{
1543  /*
1544   * It compares the ideal I with ideals in the set 'idorb'
1545   * up to total degree =
1546   * trInd - max(deg of w, deg of word in polist) polynomials.
1547   *
1548   * It returns 0 if I is not equal to any ideal in the
1549   * 'idorb' else returns position of the matched ideal.
1550   */
1551
1552  int ps = 0;
1553  int i, s = 0;
1554  int orbCount = idorb.size();
1555
1556  if(idIs0(I))
1557  {
1558    return(1);
1559  }
1560
1561  int degw = p_Totaldegree(w, currRing);
1562  int degp;
1563  int dtr;
1564  int dtrp;
1565
1566  dtr = trInd - degw;
1567  int IwCount;
1568
1569   IwCount = CountOnIdUptoTruncationIndex(I, dtr);
1570
1571  if(IwCount == 0)
1572  {
1573    return(1);
1574  }
1575
1576  int ObCount;
1577
1578  bool flag2 = FALSE;
1579
1580  for(i = 1;i < orbCount; i++)
1581  {
1582    degp = p_Totaldegree(polist[i], currRing);
1583    if(degw > degp)
1584    {
1585      dtr = trInd - degw;
1586
1587      ObCount = 0;
1588      ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtr);
1589      if(ObCount == 0)
1590      {continue;}
1591      if(flag2)
1592      {
1593        IwCount = 0;
1594        IwCount = CountOnIdUptoTruncationIndex(I, dtr);
1595        flag2 = FALSE;
1596      }
1597    }
1598    else
1599    {
1600      flag2 = TRUE;
1601      dtrp = trInd - degp;
1602      ObCount = 0;
1603      ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtrp);
1604      IwCount = 0;
1605      IwCount = CountOnIdUptoTruncationIndex(I, dtrp);
1606    }
1607
1608    s = comapreMonoIdBases_IG_Case(I, IwCount, idorb[i], ObCount);
1609
1610    if(s)
1611    {
1612      ps = i + 1;
1613      break;
1614    }
1615  }
1616  return(ps);
1617}
1618
1619static int positionInOrbit_FG_Case(ideal I, poly, std::vector<ideal> idorb, std::vector<poly>, int, int)
1620{
1621  /*
1622   * It compares the ideal I with ideals in the set 'idorb'.
1623   * I and ideals of 'idorb' are sorted.
1624   *
1625   * It returns 0 if I is not equal to any ideal of 'idorb'
1626   * else returns position of the matched ideal.
1627   */
1628  int ps = 0;
1629  int i, s = 0;
1630  int OrbCount = idorb.size();
1631
1632  if(idIs0(I))
1633  {
1634    return(1);
1635  }
1636
1637  for(i = 1; i < OrbCount; i++)
1638  {
1639    s = comapreMonoIdBases(I, idorb[i]);
1640    if(s)
1641    {
1642      ps = i + 1;
1643      break;
1644    }
1645  }
1646
1647  return(ps);
1648}
1649
1650static int positionInOrbitTruncationCase(ideal I, poly w, std::vector<ideal> idorb, std::vector<poly> polist, int , int trunDegHs)
1651{
1652  /*
1653   * It compares the ideal I with ideals in the set 'idorb'.
1654   * I and ideals in 'idorb' are sorted.
1655
1656   * returns 0 if I is not equal to any ideal of 'idorb'
1657   * else returns position of the matched ideal.
1658   */
1659
1660  int ps = 0;
1661  int i, s = 0;
1662  int OrbCount = idorb.size();
1663  int dtr=0; int IwCount, ObCount;
1664  dtr = trunDegHs - 1 - p_Totaldegree(w, currRing);
1665
1666  if(idIs0(I))
1667  {
1668    for(i = 1; i < OrbCount; i++)
1669    {
1670      if(p_Totaldegree(w, currRing) == p_Totaldegree(polist[i], currRing))
1671      {
1672        if(idIs0(idorb[i]))
1673          return(i+1);
1674        ObCount=0;
1675        ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtr);
1676        if(ObCount==0)
1677        {
1678          ps = i + 1;
1679          break;
1680        }
1681      }
1682    }
1683
1684    return(ps);
1685  }
1686
1687  IwCount = CountOnIdUptoTruncationIndex(I, dtr);
1688
1689  if(p_Totaldegree(I->m[0], currRing)==0)
1690  {
1691    for(i = 1; i < OrbCount; i++)
1692    {
1693       if(idIs0(idorb[i]))
1694         continue;
1695       if(p_Totaldegree(idorb[i]->m[0], currRing)==0)
1696       {
1697         ps = i + 1;
1698         break;
1699       }
1700     }
1701     return(ps);
1702  }
1703
1704  for(i = 1; i < OrbCount; i++)
1705  {
1706    if(p_Totaldegree(w, currRing) == p_Totaldegree(polist[i], currRing))
1707    {
1708      if(idIs0(idorb[i]))
1709        continue;
1710      ObCount=0;
1711      ObCount = CountOnIdUptoTruncationIndex(idorb[i], dtr);
1712      s = comapreMonoIdBases_IG_Case(I, IwCount, idorb[i], ObCount);
1713      if(s)
1714      {
1715        ps = i + 1;
1716        break;
1717      }
1718    }
1719  }
1720
1721  return(ps);
1722}
1723
1724static int monCompare( const void *m, const void *n)
1725{
1726  /* compares monomials */
1727
1728 return(p_Compare(*(poly*) m, *(poly*)n, currRing));
1729}
1730
1731void sortMonoIdeal_pCompare(ideal I)
1732{
1733  /*
1734   * sorts monomial ideal in ascending order
1735   * order must be a total degree
1736   */
1737
1738  qsort(I->m, IDELEMS(I), sizeof(poly), monCompare);
1739
1740}
1741
1742
1743
1744static ideal  minimalMonomialGenSet(ideal I)
1745{
1746  /*
1747   * eliminates monomials which
1748   * can be generated by others in I
1749   */
1750  //first sort monomials of the ideal
1751
1752  idSkipZeroes(I);
1753
1754  sortMonoIdeal_pCompare(I);
1755
1756  int i, k;
1757  int ICount = IDELEMS(I);
1758
1759  for(k = ICount - 1; k >=1; k--)
1760  {
1761    for(i = 0; i < k; i++)
1762    {
1763
1764      if(p_LmDivisibleBy(I->m[i], I->m[k], currRing))
1765      {
1766        pDelete(&(I->m[k]));
1767        break;
1768      }
1769    }
1770  }
1771
1772  idSkipZeroes(I);
1773  return(I);
1774}
1775
1776static poly shiftInMon(poly p, int i, int lV, const ring r)
1777{
1778  /*
1779   * shifts the varibles of monomial p in the  i^th layer,
1780   * p remains unchanged,
1781   * creates new poly and returns it for the colon ideal
1782   */
1783  poly smon = p_One(r);
1784  int j, sh, cnt;
1785  cnt = r->N;
1786  sh = i*lV;
1787  int *e=(int *)omAlloc((r->N+1)*sizeof(int));
1788  int *s=(int *)omAlloc0((r->N+1)*sizeof(int));
1789  p_GetExpV(p, e, r);
1790
1791  for(j = 1; j <= cnt; j++)
1792  {
1793    if(e[j] == 1)
1794    {
1795      s[j+sh] = e[j];
1796    }
1797  }
1798
1799  p_SetExpV(smon, s, currRing);
1800  omFree(e);
1801  omFree(s);
1802
1803  p_SetComp(smon, p_GetComp(p, currRing), currRing);
1804  p_Setm(smon, currRing);
1805
1806  return(smon);
1807}
1808
1809static poly deleteInMon(poly w, int i, int lV, const ring r)
1810{
1811  /*
1812   * deletes the variables upto i^th layer of monomial w
1813   * w remains unchanged
1814   * creates new poly and returns it for the colon ideal
1815   */
1816
1817  poly dw = p_One(currRing);
1818  int *e = (int *)omAlloc((r->N+1)*sizeof(int));
1819  int *s=(int *)omAlloc0((r->N+1)*sizeof(int));
1820  p_GetExpV(w, e, r);
1821  int j, cnt;
1822  cnt = i*lV;
1823  /*
1824  for(j=1;j<=cnt;j++)
1825  {
1826    e[j]=0;
1827  }*/
1828  for(j = (cnt+1); j < (r->N+1); j++)
1829  {
1830    s[j] = e[j];
1831  }
1832
1833  p_SetExpV(dw, s, currRing);//new exponents
1834  omFree(e);
1835  omFree(s);
1836
1837  p_SetComp(dw, p_GetComp(w, currRing), currRing);
1838  p_Setm(dw, currRing);
1839
1840  return(dw);
1841}
1842
1843static void TwordMap(poly p, poly w, int lV, int d, ideal Jwi, bool &flag)
1844{
1845  /*
1846   * computes T_w(p) in a new poly object and places it
1847   * in Jwi which stores elements of colon ideal of I,
1848   * p and w remain unchanged,
1849   * the new polys for Jwi are constructed by sub-routines
1850   * deleteInMon, shiftInMon, p_MDivide,
1851   * places the result in Jwi and deletes the new polys
1852   * coming in dw, smon, qmon
1853   */
1854  int i;
1855  poly smon, dw;
1856  poly qmonp = NULL;
1857  bool del;
1858
1859  for(i = 0;i <= d - 1; i++)
1860  {
1861    dw = deleteInMon(w, i, lV, currRing);
1862    smon = shiftInMon(p, i, lV, currRing);
1863    del = TRUE;
1864
1865    if(pLmDivisibleBy(smon, w))
1866    {
1867      flag = TRUE;
1868      del  = FALSE;
1869
1870      pDelete(&dw);
1871      pDelete(&smon);
1872
1873      //delete all monomials of Jwi
1874      //and make Jwi =1
1875
1876      for(int j = 0;j < IDELEMS(Jwi); j++)
1877      {
1878        pDelete(&Jwi->m[j]);
1879      }
1880
1881      idInsertMonomial(Jwi, p_One(currRing));
1882      break;
1883    }
1884
1885    if(pLmDivisibleBy(dw, smon))
1886    {
1887      del = FALSE;
1888      qmonp = p_MDivide(smon, dw, currRing);
1889      idInsertMonomial(Jwi, shiftInMon(qmonp, -d, lV, currRing));
1890      pLmFree(&qmonp);
1891      pDelete(&dw);
1892      pDelete(&smon);
1893    }
1894    //in case both if are false, delete dw and smon
1895    if(del)
1896    {
1897      pDelete(&dw);
1898      pDelete(&smon);
1899    }
1900  }
1901
1902}
1903
1904static ideal colonIdeal(ideal S, poly w, int lV, ideal Jwi, int trunDegHs)
1905{
1906  /*
1907   * It computes the right colon ideal of a two-sided ideal S
1908   * w.r.t. word w and save it in a new object Jwi.
1909   * It keeps S and w unchanged.
1910   */
1911
1912  if(idIs0(S))
1913  {
1914    return(S);
1915  }
1916
1917  int i, d;
1918  d = p_Totaldegree(w, currRing);
1919  if(trunDegHs !=0 && d >= trunDegHs)
1920  {
1921   idInsertMonomial(Jwi, p_One(currRing));
1922   return(Jwi);
1923  }
1924  bool flag = FALSE;
1925  int SCount = IDELEMS(S);
1926  for(i = 0; i < SCount; i++)
1927  {
1928    TwordMap(S->m[i], w, lV, d, Jwi, flag);
1929    if(flag)
1930    {
1931      break;
1932    }
1933  }
1934
1935  Jwi = minimalMonomialGenSet(Jwi);
1936  return(Jwi);
1937}
1938
1939void HilbertSeries_OrbitData(ideal S, int lV, bool IG_CASE, bool mgrad, bool odp, int trunDegHs)
1940{
1941  /*
1942   * This is based on iterative right colon operations on a
1943   * two-sided monomial ideal of the free associative algebra.
1944   * The algorithm terminates for those monomial ideals
1945   * whose monomials define  "regular formal languages",
1946   * that is, all monomials of the input ideal can be obtained
1947   * from finite languages by applying finite number of
1948   * rational operations.
1949   */
1950
1951  int trInd;
1952  S = minimalMonomialGenSet(S);
1953  if( !idIs0(S) && p_Totaldegree(S->m[0], currRing)==0)
1954  {
1955    PrintS("Hilbert Series:\n 0\n");
1956    return;
1957  }
1958  int (*POS)(ideal, poly, std::vector<ideal>, std::vector<poly>, int, int);
1959  if(trunDegHs != 0)
1960  {
1961    Print("\nTruncation degree = %d\n",trunDegHs);
1962    POS=&positionInOrbitTruncationCase;
1963  }
1964  else
1965  {
1966    if(IG_CASE)
1967    {
1968      if(idIs0(S))
1969      {
1970        WerrorS("wrong input: it is not an infinitely gen. case");
1971        return;
1972      }
1973      trInd = p_Totaldegree(S->m[IDELEMS(S)-1], currRing);
1974      POS = &positionInOrbit_IG_Case;
1975    }
1976    else
1977    POS = &positionInOrbit_FG_Case;
1978  }
1979  std::vector<ideal > idorb;
1980  std::vector< poly > polist;
1981
1982  ideal orb_init = idInit(1, 1);
1983  idorb.push_back(orb_init);
1984
1985  polist.push_back( p_One(currRing));
1986
1987  std::vector< std::vector<int> > posMat;
1988  std::vector<int> posRow(lV,0);
1989  std::vector<int> C;
1990
1991  int ds, is, ps;
1992  int lpcnt = 0;
1993
1994  poly w, wi;
1995  ideal Jwi;
1996
1997  while(lpcnt < idorb.size())
1998  {
1999    w = NULL;
2000    w = polist[lpcnt];
2001    if(lpcnt >= 1 && idIs0(idorb[lpcnt]) == FALSE)
2002    {
2003      if(p_Totaldegree(idorb[lpcnt]->m[0], currRing) != 0)
2004      {
2005        C.push_back(1);
2006      }
2007      else
2008        C.push_back(0);
2009    }
2010    else
2011    {
2012      C.push_back(1);
2013    }
2014
2015    ds = p_Totaldegree(w, currRing);
2016    lpcnt++;
2017
2018    for(is = 1; is <= lV; is++)
2019    {
2020      wi = NULL;
2021      //make new copy 'wi' of word w=polist[lpcnt]
2022      //and update it (for the colon operation).
2023      //if corresponding to wi, right colon operation gives
2024      //a new (right colon) ideal of S,
2025      //keep 'wi' in the polist else delete it
2026
2027      wi = pCopy(w);
2028      p_SetExp(wi, (ds*lV)+is, 1, currRing);
2029      p_Setm(wi, currRing);
2030      Jwi = NULL;
2031      //Jwi stores (right) colon ideal of S w.r.t. word
2032      //wi if colon operation gives a new ideal place it
2033      //in the vector of ideals  'idorb'
2034      //otherwise delete it
2035
2036      Jwi = idInit(1,1);
2037
2038      Jwi = colonIdeal(S, wi, lV, Jwi, trunDegHs);
2039      ps = (*POS)(Jwi, wi, idorb, polist, trInd, trunDegHs);
2040
2041      if(ps == 0)  // finds a new ideal
2042      {
2043        posRow[is-1] = idorb.size();
2044
2045        idorb.push_back(Jwi);
2046        polist.push_back(wi);
2047      }
2048      else // ideal is already there  in the set
2049      {
2050        posRow[is-1]=ps-1;
2051        idDelete(&Jwi);
2052        pDelete(&wi);
2053      }
2054    }
2055    posMat.push_back(posRow);
2056    posRow.resize(lV,0);
2057  }
2058  int lO = C.size();//size of the orbit
2059  PrintLn();
2060  Print("maximal length of words = %ld\n", p_Totaldegree(polist[lO-1], currRing));
2061  Print("\nlength of the Orbit = %d", lO);
2062  PrintLn();
2063
2064  if(odp)
2065  {
2066    Print("words description of the Orbit: \n");
2067    for(is = 0; is < lO; is++)
2068    {
2069      pWrite0(polist[is]);
2070      PrintS("    ");
2071    }
2072    PrintLn();
2073    PrintS("\nmaximal degree,  #(sum_j R(w,w_j))");
2074    PrintLn();
2075    for(is = 0; is < lO; is++)
2076    {
2077      if(idIs0(idorb[is]))
2078      {
2079        PrintS("NULL\n");
2080      }
2081      else
2082      {
2083        Print("%ld,  %d \n",p_Totaldegree(idorb[is]->m[IDELEMS(idorb[is])-1], currRing),IDELEMS(idorb[is]));
2084      }
2085    }
2086  }
2087
2088  for(is = idorb.size()-1; is >= 0; is--)
2089  {
2090    idDelete(&idorb[is]);
2091  }
2092  for(is = polist.size()-1; is >= 0; is--)
2093  {
2094    pDelete(&polist[is]);
2095  }
2096
2097  idorb.resize(0);
2098  polist.resize(0);
2099
2100  int adjMatrix[lO][lO];
2101  memset(adjMatrix, 0, lO*lO*sizeof(int));
2102  int rowCount, colCount;
2103  int tm = 0;
2104  if(!mgrad)
2105  {
2106    for(rowCount = 0; rowCount < lO; rowCount++)
2107    {
2108      for(colCount = 0; colCount < lV; colCount++)
2109      {
2110        tm = posMat[rowCount][colCount];
2111        adjMatrix[rowCount][tm] = adjMatrix[rowCount][tm] + 1;
2112      }
2113    }
2114  }
2115
2116  ring r = currRing;
2117  int npar;
2118  char** tt;
2119  TransExtInfo p;
2120  if(!mgrad)
2121  {
2122    tt=(char**)omalloc(sizeof(char*));
2123    tt[0] = omStrDup("t");
2124    npar = 1;
2125  }
2126  else
2127  {
2128    tt=(char**)omalloc(lV*sizeof(char*));
2129    for(is = 0; is < lV; is++)
2130    {
2131      tt[is] = (char*)omalloc(7*sizeof(char)); //if required enlarge it later
2132      sprintf (tt[is], "t%d", is+1);
2133    }
2134    npar = lV;
2135  }
2136
2137  p.r = rDefault(0, npar, tt);
2138  coeffs cf = nInitChar(n_transExt, &p);
2139  char** xx = (char**)omalloc(sizeof(char*));
2140  xx[0] = omStrDup("x");
2141  ring R = rDefault(cf, 1, xx);
2142  rChangeCurrRing(R);//rWrite(R);
2143  /*
2144   * matrix corresponding to the orbit of the ideal
2145   */
2146  matrix mR = mpNew(lO, lO);
2147  matrix cMat = mpNew(lO,1);
2148  poly rc;
2149
2150  if(!mgrad)
2151  {
2152    for(rowCount = 0; rowCount < lO; rowCount++)
2153    {
2154      for(colCount = 0; colCount < lO; colCount++)
2155      {
2156        if(adjMatrix[rowCount][colCount] != 0)
2157        {
2158          MATELEM(mR, rowCount + 1, colCount + 1) = p_ISet(adjMatrix[rowCount][colCount], R);
2159          p_SetCoeff(MATELEM(mR, rowCount + 1, colCount + 1), n_Mult(pGetCoeff(mR->m[lO*rowCount+colCount]),n_Param(1, R->cf), R->cf), R);
2160        }
2161      }
2162    }
2163  }
2164  else
2165  {
2166     for(rowCount = 0; rowCount < lO; rowCount++)
2167     {
2168       for(colCount = 0; colCount < lV; colCount++)
2169       {
2170          rc=NULL;
2171          rc=p_One(R);
2172          p_SetCoeff(rc, n_Mult(pGetCoeff(rc), n_Param(colCount+1, R->cf),R->cf), R);
2173          MATELEM(mR, rowCount +1, posMat[rowCount][colCount]+1)=p_Add_q(rc,MATELEM(mR, rowCount +1, posMat[rowCount][colCount]+1), R);
2174       }
2175     }
2176  }
2177
2178  for(rowCount = 0; rowCount < lO; rowCount++)
2179  {
2180    if(C[rowCount] != 0)
2181    {
2182      MATELEM(cMat, rowCount + 1, 1) = p_ISet(C[rowCount], R);
2183    }
2184  }
2185
2186  matrix u;
2187  unitMatrix(lO, u); //unit matrix
2188  matrix gMat = mp_Sub(u, mR, R);
2189
2190  char* s;
2191
2192  if(odp)
2193  {
2194    PrintS("\nlinear system:\n");
2195    if(!mgrad)
2196    {
2197      for(rowCount = 0; rowCount < lO; rowCount++)
2198      {
2199        Print("H(%d) = ", rowCount+1);
2200        for(colCount = 0; colCount < lV; colCount++)
2201        {
2202          StringSetS(""); nWrite(n_Param(1, R->cf));
2203          s = StringEndS(); PrintS(s);
2204          Print("*"); omFree(s);
2205          Print("H(%d) + ", posMat[rowCount][colCount] + 1);
2206        }
2207        Print(" %d\n", C[rowCount] );
2208      }
2209      PrintS("where H(1) represents the series corresp. to input ideal\n");
2210      PrintS("and i^th summand in the rhs of an eqn. is according\n");
2211      PrintS("to the right colon map corresp. to the i^th variable\n");
2212    }
2213    else
2214    {
2215      for(rowCount = 0; rowCount < lO; rowCount++)
2216      {
2217        Print("H(%d) = ", rowCount+1);
2218        for(colCount = 0; colCount < lV; colCount++)
2219        {
2220           StringSetS(""); nWrite(n_Param(colCount+1, R->cf));
2221           s = StringEndS(); PrintS(s);
2222           Print("*");omFree(s);
2223           Print("H(%d) + ", posMat[rowCount][colCount] + 1);
2224        }
2225        Print(" %d\n", C[rowCount] );
2226      }
2227      PrintS("where H(1) represents the series corresp. to input ideal\n");
2228    }
2229  }
2230  PrintLn();
2231  posMat.resize(0);
2232  C.resize(0);
2233  matrix pMat;
2234  matrix lMat;
2235  matrix uMat;
2236  matrix H_serVec = mpNew(lO, 1);
2237  matrix Hnot;
2238
2239  //std::clock_t start;
2240  //start = std::clock();
2241
2242  luDecomp(gMat, pMat, lMat, uMat, R);
2243  luSolveViaLUDecomp(pMat, lMat, uMat, cMat, H_serVec, Hnot);
2244
2245  //to print system solving time
2246  //if(odp){
2247  //std::cout<<"solving time of the system = "<<(std::clock()-start)/(double)(CLOCKS_PER_SEC / 1000)<<" ms"<<std::endl;}
2248
2249  mp_Delete(&mR, R);
2250  mp_Delete(&u, R);
2251  mp_Delete(&pMat, R);
2252  mp_Delete(&lMat, R);
2253  mp_Delete(&uMat, R);
2254  mp_Delete(&cMat, R);
2255  mp_Delete(&gMat, R);
2256  mp_Delete(&Hnot, R);
2257  //print the Hilbert series and length of the Orbit
2258  PrintLn();
2259  Print("Hilbert series:");
2260  PrintLn();
2261  pWrite(H_serVec->m[0]);
2262  if(!mgrad)
2263  {
2264    omFree(tt[0]);
2265  }
2266  else
2267  {
2268    for(is = lV-1; is >= 0; is--)
2269
2270      omFree( tt[is]);
2271  }
2272  omFree(tt);
2273  omFree(xx[0]);
2274  omFree(xx);
2275  rChangeCurrRing(r);
2276  rKill(R);
2277}
2278
2279ideal RightColonOperation(ideal S, poly w, int lV)
2280{
2281  /*
2282   * This returns right colon ideal of a monomial two-sided ideal of
2283   * the free associative algebra with respect to a monomial 'w'
2284   * (S:_R w).
2285   */
2286  S = minimalMonomialGenSet(S);
2287  ideal Iw = idInit(1,1);
2288  Iw = colonIdeal(S, w, lV, Iw, 0);
2289  return (Iw);
2290}
2291
Note: See TracBrowser for help on using the repository browser.