source: git/kernel/combinatorics/hilb.cc @ 598f45b

spielwiese
Last change on this file since 598f45b was 598f45b, checked in by Hans Schoenemann <hannes@…>, 6 years ago
fix: system("hilbroune",I): memory leaks, format
  • Property mode set to 100644
File size: 48.3 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 void SortByDeg_p(ideal I, poly p)
268{
269  int i,j;
270  if(idIs0(I))
271  {
272    I->m[0] = p;
273    return;
274  }
275  idSkipZeroes(I);
276  #if 1
277  for(i = 0; (i<IDELEMS(I)) && (p_Totaldegree(I->m[i],currRing)<=p_Totaldegree(p,currRing)); i++)
278  {
279    if(p_DivisibleBy( I->m[i],p, currRing))
280    {
281      return;
282    }
283  }
284  for(i = IDELEMS(I)-1; (i>=0) && (p_Totaldegree(I->m[i],currRing)>=p_Totaldegree(p,currRing)); i--)
285  {
286    if(p_DivisibleBy(p,I->m[i], currRing))
287    {
288      I->m[i] = NULL;
289    }
290  }
291  if(idIs0(I))
292  {
293    idSkipZeroes(I);
294    I->m[0] = p;
295    return;
296  }
297  #endif
298  idSkipZeroes(I);
299  //First I take the case when all generators have the same degree
300  if(p_Totaldegree(I->m[0],currRing) == p_Totaldegree(I->m[IDELEMS(I)-1],currRing))
301  {
302    if(p_Totaldegree(p,currRing)<p_Totaldegree(I->m[0],currRing))
303    {
304      idInsertPoly(I,p);
305      idSkipZeroes(I);
306      for(i=IDELEMS(I)-1;i>=1; i--)
307      {
308        I->m[i] = I->m[i-1];
309      }
310      I->m[0] = p;
311      return;
312    }
313    if(p_Totaldegree(p,currRing)>=p_Totaldegree(I->m[IDELEMS(I)-1],currRing))
314    {
315      idInsertPoly(I,p);
316      idSkipZeroes(I);
317      return;
318    }
319  }
320  if(p_Totaldegree(p,currRing)<=p_Totaldegree(I->m[0],currRing))
321  {
322    idInsertPoly(I,p);
323    idSkipZeroes(I);
324    for(i=IDELEMS(I)-1;i>=1; i--)
325    {
326      I->m[i] = I->m[i-1];
327    }
328    I->m[0] = p;
329    return;
330  }
331  if(p_Totaldegree(p,currRing)>=p_Totaldegree(I->m[IDELEMS(I)-1],currRing))
332  {
333    idInsertPoly(I,p);
334    idSkipZeroes(I);
335    return;
336  }
337  for(i = IDELEMS(I)-2; ;)
338  {
339    if(p_Totaldegree(p,currRing)==p_Totaldegree(I->m[i],currRing))
340    {
341      idInsertPoly(I,p);
342      idSkipZeroes(I);
343      for(j = IDELEMS(I)-1; j>=i+1;j--)
344      {
345        I->m[j] = I->m[j-1];
346      }
347      I->m[i] = p;
348      return;
349    }
350    if(p_Totaldegree(p,currRing)>p_Totaldegree(I->m[i],currRing))
351    {
352      idInsertPoly(I,p);
353      idSkipZeroes(I);
354      for(j = IDELEMS(I)-1; j>=i+2;j--)
355      {
356        I->m[j] = I->m[j-1];
357      }
358      I->m[i+1] = p;
359      return;
360    }
361    i--;
362  }
363}
364
365//it sorts the ideal by the degrees
366static ideal SortByDeg(ideal I)
367{
368  if(idIs0(I))
369  {
370    return id_Copy(I,currRing);
371  }
372  int i;
373  ideal res;
374  idSkipZeroes(I);
375  res = idInit(1,1);
376  res->m[0] = poly(0);
377  for(i = 0; i<=IDELEMS(I)-1;i++)
378  {
379    SortByDeg_p(res, I->m[i]);
380  }
381  idSkipZeroes(res);
382  //idDegSortTest(res);
383  return(res);
384}
385
386//idQuot(I,p) for I monomial ideal, p a ideal with a single monomial.
387ideal idQuotMon(ideal Iorig, ideal p)
388{
389    if(idIs0(Iorig))
390    {
391      ideal res = idInit(1,1);
392      res->m[0] = poly(0);
393      return(res);
394    }
395    if(idIs0(p))
396    {
397      ideal res = idInit(1,1);
398      res->m[0] = pOne();
399      return(res);
400    }
401    ideal I = id_Head(Iorig,currRing);
402    ideal res = idInit(IDELEMS(I),1);
403    int i,j;
404    int dummy;
405    for(i = 0; i<IDELEMS(I); i++)
406    {
407      res->m[i] = p_Head(I->m[i], currRing);
408      for(j = 1; (j<=currRing->N) ; j++)
409      {
410        dummy = p_GetExp(p->m[0], j, currRing);
411        if(dummy > 0)
412        {
413          if(p_GetExp(I->m[i], j, currRing) < dummy)
414          {
415            p_SetExp(res->m[i], j, 0, currRing);
416          }
417          else
418          {
419            p_SetExp(res->m[i], j, p_GetExp(I->m[i], j, currRing) - dummy, currRing);
420          }
421        }
422      }
423      p_Setm(res->m[i], currRing);
424      if(p_Totaldegree(res->m[i],currRing) == p_Totaldegree(I->m[i],currRing))
425      {
426        p_Delete(&res->m[i],currRing);
427      }
428      else
429      {
430        p_Delete(&I->m[i],currRing);
431      }
432    }
433    idSkipZeroes(res);
434    idSkipZeroes(I);
435    if(!idIs0(res))
436    {
437      for(i = 0; i<=IDELEMS(res)-1; i++)
438      {
439        SortByDeg_p(I,res->m[i]);
440      }
441    }
442    id_Delete(&res,currRing);
443    //idDegSortTest(I);
444    return(I);
445}
446
447//id_Add for monomials
448static void idAddMon(ideal I, ideal p)
449{
450  SortByDeg_p(I,p->m[0]);
451  //idSkipZeroes(I);
452}
453
454//searches for a variable that is not yet used (assumes that the ideal is sqrfree)
455static poly ChoosePVar (ideal I)
456{
457    bool flag=TRUE;
458    int i,j;
459    poly res;
460    for(i=1;i<=currRing->N;i++)
461    {
462        flag=TRUE;
463        for(j=IDELEMS(I)-1;(j>=0)&&(flag);j--)
464        {
465            if(p_GetExp(I->m[j], i, currRing)>0)
466            {
467                flag=FALSE;
468            }
469        }
470
471        if(flag == TRUE)
472        {
473            res = p_ISet(1, currRing);
474            p_SetExp(res, i, 1, currRing);
475            p_Setm(res,currRing);
476            return(res);
477        }
478        else
479        {
480            p_Delete(&res, currRing);
481        }
482    }
483    return(NULL); //i.e. it is the maximal ideal
484}
485
486#if 0 // unused
487//choice XL: last entry divided by x (xy10z15 -> y9z14)
488static poly ChoosePXL(ideal I)
489{
490    int i,j,dummy=0;
491    poly m;
492    for(i = IDELEMS(I)-1; (i>=0) && (dummy == 0); i--)
493    {
494        for(j = 1; (j<=currRing->N) && (dummy == 0); j++)
495        {
496            if(p_GetExp(I->m[i],j, currRing)>1)
497            {
498                dummy = 1;
499            }
500        }
501    }
502    m = p_Copy(I->m[i+1],currRing);
503    for(j = 1; j<=currRing->N; j++)
504    {
505        dummy = p_GetExp(m,j,currRing);
506        if(dummy >= 1)
507        {
508            p_SetExp(m, j, dummy-1, currRing);
509        }
510    }
511    if(!p_IsOne(m, currRing))
512    {
513        p_Setm(m, currRing);
514        return(m);
515    }
516    m = ChoosePVar(I);
517    return(m);
518}
519#endif
520
521#if 0 // unused
522//choice XF: first entry divided by x (xy10z15 -> y9z14)
523static poly ChoosePXF(ideal I)
524{
525    int i,j,dummy=0;
526    poly m;
527    for(i =0 ; (i<=IDELEMS(I)-1) && (dummy == 0); i++)
528    {
529        for(j = 1; (j<=currRing->N) && (dummy == 0); j++)
530        {
531            if(p_GetExp(I->m[i],j, currRing)>1)
532            {
533                dummy = 1;
534            }
535        }
536    }
537    m = p_Copy(I->m[i-1],currRing);
538    for(j = 1; j<=currRing->N; j++)
539    {
540        dummy = p_GetExp(m,j,currRing);
541        if(dummy >= 1)
542        {
543            p_SetExp(m, j, dummy-1, currRing);
544        }
545    }
546    if(!p_IsOne(m, currRing))
547    {
548        p_Setm(m, currRing);
549        return(m);
550    }
551    m = ChoosePVar(I);
552    return(m);
553}
554#endif
555
556#if 0 // unused
557//choice OL: last entry the first power (xy10z15 -> xy9z15)
558static poly ChoosePOL(ideal I)
559{
560    int i,j,dummy;
561    poly m;
562    for(i = IDELEMS(I)-1;i>=0;i--)
563    {
564        m = p_Copy(I->m[i],currRing);
565        for(j=1;j<=currRing->N;j++)
566        {
567            dummy = p_GetExp(m,j,currRing);
568            if(dummy > 0)
569            {
570                p_SetExp(m,j,dummy-1,currRing);
571                p_Setm(m,currRing);
572            }
573        }
574        if(!p_IsOne(m, currRing))
575        {
576            return(m);
577        }
578        else
579        {
580            p_Delete(&m,currRing);
581        }
582    }
583    m = ChoosePVar(I);
584    return(m);
585}
586#endif
587
588#if 0 // unused
589//choice OF: first entry the first power (xy10z15 -> xy9z15)
590static poly ChoosePOF(ideal I)
591{
592    int i,j,dummy;
593    poly m;
594    for(i = 0 ;i<=IDELEMS(I)-1;i++)
595    {
596        m = p_Copy(I->m[i],currRing);
597        for(j=1;j<=currRing->N;j++)
598        {
599            dummy = p_GetExp(m,j,currRing);
600            if(dummy > 0)
601            {
602                p_SetExp(m,j,dummy-1,currRing);
603                p_Setm(m,currRing);
604            }
605        }
606        if(!p_IsOne(m, currRing))
607        {
608            return(m);
609        }
610        else
611        {
612            p_Delete(&m,currRing);
613        }
614    }
615    m = ChoosePVar(I);
616    return(m);
617}
618#endif
619
620#if 0 // unused
621//choice VL: last entry the first variable with power (xy10z15 -> y)
622static poly ChoosePVL(ideal I)
623{
624    int i,j,dummy;
625    bool flag = TRUE;
626    poly m = p_ISet(1,currRing);
627    for(i = IDELEMS(I)-1;(i>=0) && (flag);i--)
628    {
629        flag = TRUE;
630        for(j=1;(j<=currRing->N) && (flag);j++)
631        {
632            dummy = p_GetExp(I->m[i],j,currRing);
633            if(dummy >= 2)
634            {
635                p_SetExp(m,j,1,currRing);
636                p_Setm(m,currRing);
637                flag = FALSE;
638            }
639        }
640        if(!p_IsOne(m, currRing))
641        {
642            return(m);
643        }
644    }
645    m = ChoosePVar(I);
646    return(m);
647}
648#endif
649
650#if 0 // unused
651//choice VF: first entry the first variable with power (xy10z15 -> y)
652static poly ChoosePVF(ideal I)
653{
654    int i,j,dummy;
655    bool flag = TRUE;
656    poly m = p_ISet(1,currRing);
657    for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++)
658    {
659        flag = TRUE;
660        for(j=1;(j<=currRing->N) && (flag);j++)
661        {
662            dummy = p_GetExp(I->m[i],j,currRing);
663            if(dummy >= 2)
664            {
665                p_SetExp(m,j,1,currRing);
666                p_Setm(m,currRing);
667                flag = FALSE;
668            }
669        }
670        if(!p_IsOne(m, currRing))
671        {
672            return(m);
673        }
674    }
675    m = ChoosePVar(I);
676    return(m);
677}
678#endif
679
680//choice JL: last entry just variable with power (xy10z15 -> y10)
681static poly ChoosePJL(ideal I)
682{
683  int i,j,dummy;
684  bool flag = TRUE;
685  poly m = p_ISet(1,currRing);
686  for(i = IDELEMS(I)-1;(i>=0) && (flag);i--)
687  {
688    flag = TRUE;
689    for(j=1;(j<=currRing->N) && (flag);j++)
690    {
691      dummy = p_GetExp(I->m[i],j,currRing);
692      if(dummy >= 2)
693      {
694        p_SetExp(m,j,dummy-1,currRing);
695        p_Setm(m,currRing);
696        flag = FALSE;
697      }
698    }
699    if(!p_IsOne(m, currRing))
700    {
701      return(m);
702    }
703  }
704  p_Delete(&m,currRing);
705  m = ChoosePVar(I);
706  return(m);
707}
708
709#if 0
710//choice JF: last entry just variable with power -1 (xy10z15 -> y9)
711static poly ChoosePJF(ideal I)
712{
713    int i,j,dummy;
714    bool flag = TRUE;
715    poly m = p_ISet(1,currRing);
716    for(i = 0;(i<=IDELEMS(I)-1) && (flag);i++)
717    {
718        flag = TRUE;
719        for(j=1;(j<=currRing->N) && (flag);j++)
720        {
721            dummy = p_GetExp(I->m[i],j,currRing);
722            if(dummy >= 2)
723            {
724                p_SetExp(m,j,dummy-1,currRing);
725                p_Setm(m,currRing);
726                flag = FALSE;
727            }
728        }
729        if(!p_IsOne(m, currRing))
730        {
731            return(m);
732        }
733    }
734    m = ChoosePVar(I);
735    return(m);
736}
737#endif
738
739//chooses 1 \neq p \not\in S. This choice should be made optimal
740static poly ChooseP(ideal I)
741{
742  poly m;
743  //  TEST TO SEE WHICH ONE IS BETTER
744  //m = ChoosePXL(I);
745  //m = ChoosePXF(I);
746  //m = ChoosePOL(I);
747  //m = ChoosePOF(I);
748  //m = ChoosePVL(I);
749  //m = ChoosePVF(I);
750  m = ChoosePJL(I);
751  //m = ChoosePJF(I);
752  return(m);
753}
754
755///searches for a monomial of degree d>=2 and divides it by a variable (result monomial of deg d-1)
756static poly SearchP(ideal I)
757{
758    int i,j,exp;
759    poly res;
760    if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)<=1)
761    {
762        res = ChoosePVar(I);
763        return(res);
764    }
765    i = IDELEMS(I)-1;
766    res = p_Copy(I->m[i], currRing);
767    for(j=1;j<=currRing->N;j++)
768    {
769        exp = p_GetExp(I->m[i], j, currRing);
770        if(exp > 0)
771        {
772            p_SetExp(res, j, exp - 1, currRing);
773            p_Setm(res,currRing);
774            break;
775        }
776    }
777    assume( j <= currRing->N );
778    return(res);
779}
780
781//test if the ideal is of the form (x1, ..., xr)
782static bool JustVar(ideal I)
783{
784    #if 0
785    int i,j;
786    bool foundone;
787    for(i=0;i<=IDELEMS(I)-1;i++)
788    {
789        foundone = FALSE;
790        for(j = 1;j<=currRing->N;j++)
791        {
792            if(p_GetExp(I->m[i], j, currRing)>0)
793            {
794                if(foundone == TRUE)
795                {
796                    return(FALSE);
797                }
798                foundone = TRUE;
799            }
800        }
801    }
802    return(TRUE);
803    #else
804    if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)>1)
805    {
806        return(FALSE);
807    }
808    return(TRUE);
809    #endif
810}
811
812//computes the Euler Characteristic of the ideal
813static void eulerchar (ideal I, int variables, mpz_ptr ec)
814{
815  loop
816  {
817    mpz_t dummy;
818    if(JustVar(I) == TRUE)
819    {
820      if(IDELEMS(I) == variables)
821      {
822        mpz_init(dummy);
823        if((variables % 2) == 0)
824          mpz_set_ui(dummy, 1);
825        else
826          mpz_set_si(dummy, -1);
827        mpz_add(ec, ec, dummy);
828        mpz_clear(dummy);
829      }
830      return;
831    }
832    ideal p = idInit(1,1);
833    p->m[0] = SearchP(I);
834    //idPrint(I);
835    //idPrint(p);
836    //printf("\nNow get in idQuotMon\n");
837    ideal Ip = idQuotMon(I,p);
838    //idPrint(Ip);
839    //Ip = SortByDeg(Ip);
840    int i,howmanyvarinp = 0;
841    for(i = 1;i<=currRing->N;i++)
842    {
843      if(p_GetExp(p->m[0],i,currRing)>0)
844      {
845        howmanyvarinp++;
846      }
847    }
848    eulerchar(Ip, variables-howmanyvarinp, ec);
849    id_Delete(&Ip, currRing);
850    idAddMon(I,p);
851    id_Delete(&p, currRing);
852  }
853}
854
855//tests if an ideal is Square Free, if no, returns the variable which appears at powers >1
856static poly SqFree (ideal I)
857{
858    int i,j;
859    bool flag=TRUE;
860    poly notsqrfree = NULL;
861    if(p_Totaldegree(I->m[IDELEMS(I)-1],currRing)<=1)
862    {
863        return(notsqrfree);
864    }
865    for(i=IDELEMS(I)-1;(i>=0)&&(flag);i--)
866    {
867        for(j=1;(j<=currRing->N)&&(flag);j++)
868        {
869            if(p_GetExp(I->m[i],j,currRing)>1)
870            {
871                flag=FALSE;
872                notsqrfree = p_ISet(1,currRing);
873                p_SetExp(notsqrfree,j,1,currRing);
874            }
875        }
876    }
877    if(notsqrfree != NULL)
878    {
879        p_Setm(notsqrfree,currRing);
880    }
881    return(notsqrfree);
882}
883
884//checks if a polynomial is in I
885static bool IsIn(poly p, ideal I)
886{
887  //assumes that I is ordered by degree
888  if(idIs0(I))
889  {
890    if(p==poly(0))
891    {
892      return(TRUE);
893    }
894    else
895    {
896      return(FALSE);
897    }
898  }
899  if(p==poly(0))
900  {
901    return(FALSE);
902  }
903  int i,j;
904  bool flag;
905  for(i = 0;i<IDELEMS(I);i++)
906  {
907    flag = TRUE;
908    for(j = 1;(j<=currRing->N) &&(flag);j++)
909    {
910      if(p_GetExp(p, j, currRing)<p_GetExp(I->m[i], j, currRing))
911      {
912        flag = FALSE;
913      }
914    }
915    if(flag)
916    {
917      return(TRUE);
918    }
919  }
920  return(FALSE);
921}
922
923//computes the lcm of min I, I monomial ideal
924static poly LCMmon(ideal I)
925{
926  if(idIs0(I))
927  {
928    return(NULL);
929  }
930  poly m;
931  int dummy,i,j;
932  m = p_ISet(1,currRing);
933  for(i=1;i<=currRing->N;i++)
934  {
935    dummy=0;
936    for(j=IDELEMS(I)-1;j>=0;j--)
937    {
938      if(p_GetExp(I->m[j],i,currRing) > dummy)
939      {
940        dummy = p_GetExp(I->m[j],i,currRing);
941      }
942    }
943    p_SetExp(m,i,dummy,currRing);
944  }
945  p_Setm(m,currRing);
946  return(m);
947}
948
949//the Roune Slice Algorithm
950void rouneslice(ideal I, ideal S, poly q, poly x, int &prune, int &moreprune, int &steps, int &NNN, mpz_ptr &hilbertcoef, int* &hilbpower)
951{
952  loop
953  {
954    (steps)++;
955    int i,j;
956    int dummy;
957    poly m;
958    ideal p;
959    //----------- PRUNING OF S ---------------
960    //S SHOULD IN THIS POINT BE ORDERED BY DEGREE
961    for(i=IDELEMS(S)-1;i>=0;i--)
962    {
963      if(IsIn(S->m[i],I))
964      {
965        p_Delete(&S->m[i],currRing);
966        prune++;
967      }
968    }
969    idSkipZeroes(S);
970    //----------------------------------------
971    for(i=IDELEMS(I)-1;i>=0;i--)
972    {
973      m = p_Head(I->m[i],currRing);
974      for(j=1;j<=currRing->N;j++)
975      {
976        dummy = p_GetExp(m,j,currRing);
977        if(dummy > 0)
978        {
979          p_SetExp(m,j,dummy-1,currRing);
980        }
981      }
982      p_Setm(m, currRing);
983      if(IsIn(m,S))
984      {
985        p_Delete(&I->m[i],currRing);
986        //printf("\n Deleted, since pi(m) is in S\n");pWrite(m);
987      }
988      p_Delete(&m,currRing);
989    }
990    idSkipZeroes(I);
991    //----------- MORE PRUNING OF S ------------
992    m = LCMmon(I);
993    if(m != NULL)
994    {
995      for(i=0;i<IDELEMS(S);i++)
996      {
997        if(!(p_DivisibleBy(S->m[i], m, currRing)))
998        {
999          S->m[i] = NULL;
1000          j++;
1001          moreprune++;
1002        }
1003        else
1004        {
1005          if(pLmEqual(S->m[i],m))
1006          {
1007            S->m[i] = NULL;
1008            moreprune++;
1009          }
1010        }
1011      }
1012      idSkipZeroes(S);
1013    }
1014    p_Delete(&m,currRing);
1015    /*printf("\n---------------------------\n");
1016    printf("\n      I\n");idPrint(I);
1017    printf("\n      S\n");idPrint(S);
1018    printf("\n      q\n");pWrite(q);
1019    getchar();*/
1020
1021    if(idIs0(I))
1022    {
1023      id_Delete(&I, currRing);
1024      id_Delete(&S, currRing);
1025      break;
1026    }
1027    m = LCMmon(I);
1028    if(!p_DivisibleBy(x,m, currRing))
1029    {
1030      //printf("\nx does not divide lcm(I)");
1031      //printf("\nEmpty set");pWrite(q);
1032      id_Delete(&I, currRing);
1033      id_Delete(&S, currRing);
1034      p_Delete(&m, currRing);
1035      break;
1036    }
1037    p_Delete(&m, currRing);
1038    m = SqFree(I);
1039    if(m==NULL)
1040    {
1041      //printf("\n      Corner: ");
1042      //pWrite(q);
1043      //printf("\n      With the facets of the dual simplex:\n");
1044      //idPrint(I);
1045      mpz_t ec;
1046      mpz_init(ec);
1047      mpz_ptr ec_ptr = ec;
1048      eulerchar(I, currRing->N, ec_ptr);
1049      bool flag = FALSE;
1050      if(NNN==0)
1051      {
1052        hilbertcoef = (mpz_ptr)omAlloc((NNN+1)*sizeof(mpz_t));
1053        hilbpower = (int*)omAlloc((NNN+1)*sizeof(int));
1054        mpz_init_set( &hilbertcoef[NNN], ec);
1055        hilbpower[NNN] = p_Totaldegree(q,currRing);
1056        NNN++;
1057      }
1058      else
1059      {
1060        //I look if the power appears already
1061        for(i = 0;(i<NNN)&&(flag == FALSE)&&(p_Totaldegree(q,currRing)>=hilbpower[i]);i++)
1062        {
1063          if((hilbpower[i]) == (p_Totaldegree(q,currRing)))
1064          {
1065            flag = TRUE;
1066            mpz_add(&hilbertcoef[i],&hilbertcoef[i],ec_ptr);
1067          }
1068        }
1069        if(flag == FALSE)
1070        {
1071          hilbertcoef = (mpz_ptr)omRealloc(hilbertcoef, (NNN+1)*sizeof(mpz_t));
1072          hilbpower = (int*)omRealloc(hilbpower, (NNN+1)*sizeof(int));
1073          mpz_init(&hilbertcoef[NNN]);
1074          for(j = NNN; j>i; j--)
1075          {
1076            mpz_set(&hilbertcoef[j],&hilbertcoef[j-1]);
1077            hilbpower[j] = hilbpower[j-1];
1078          }
1079          mpz_set(  &hilbertcoef[i], ec);
1080          hilbpower[i] = p_Totaldegree(q,currRing);
1081          NNN++;
1082        }
1083      }
1084      mpz_clear(ec);
1085      id_Delete(&I, currRing);
1086      id_Delete(&S, currRing);
1087      break;
1088    }
1089    else
1090      p_Delete(&m, currRing);
1091    m = ChooseP(I);
1092    p = idInit(1,1);
1093    p->m[0] = m;
1094    ideal Ip = idQuotMon(I,p);
1095    ideal Sp = idQuotMon(S,p);
1096    poly pq = pp_Mult_mm(q,m,currRing);
1097    rouneslice(Ip, Sp, pq, x, prune, moreprune, steps, NNN, hilbertcoef,hilbpower);
1098    idAddMon(S,p);
1099    p->m[0]=NULL;
1100    id_Delete(&p, currRing); // p->m[0] was also in S
1101    p_Delete(&pq,currRing);
1102  }
1103}
1104
1105//it computes the first hilbert series by means of Roune Slice Algorithm
1106void slicehilb(ideal I)
1107{
1108    //printf("Adi changes are here: \n");
1109    int i, NNN = 0;
1110    int steps = 0, prune = 0, moreprune = 0;
1111    mpz_ptr hilbertcoef;
1112    int *hilbpower;
1113    ideal S = idInit(1,1);
1114    poly q = p_One(currRing);
1115    ideal X = idInit(1,1);
1116    X->m[0]=p_One(currRing);
1117    for(i=1;i<=currRing->N;i++)
1118    {
1119      p_SetExp(X->m[0],i,1,currRing);
1120    }
1121    p_Setm(X->m[0],currRing);
1122    I = id_Mult(I,X,currRing);
1123    ideal Itmp = SortByDeg(I);
1124    id_Delete(&I,currRing);
1125    I = Itmp;
1126    //printf("\n-------------RouneSlice--------------\n");
1127    rouneslice(I,S,q,X->m[0],prune, moreprune, steps, NNN, hilbertcoef, hilbpower);
1128    id_Delete(&X,currRing);
1129    p_Delete(&q,currRing);
1130    //printf("\nIn total Prune got rid of %i elements\n",prune);
1131    //printf("\nIn total More Prune got rid of %i elements\n",moreprune);
1132    //printf("\nSteps of rouneslice: %i\n\n", steps);
1133    printf("\n//  %8d t^0",1);
1134    for(i = 0; i<NNN; i++)
1135    {
1136      if(mpz_sgn(&hilbertcoef[i])!=0)
1137      {
1138        gmp_printf("\n//  %8Zd t^%d",&hilbertcoef[i],hilbpower[i]);
1139      }
1140    }
1141    PrintLn();
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.