source: git/kernel/combinatorics/hilb.cc @ 4cb74e

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