source: git/kernel/combinatorics/hdegree.cc @ a4771e1

spielwiese
Last change on this file since a4771e1 was a4771e1, checked in by Oleksandr Motsak <motsak@…>, 10 years ago
Separation of hilbert function into kernel/combinatorics/hilb.h + include cleanup
  • Property mode set to 100644
File size: 29.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5*  ABSTRACT -  dimension, multiplicity, HC, kbase
6*/
7
8#include <kernel/mod2.h>
9
10#include <omalloc/omalloc.h>
11#include <misc/intvec.h>
12#include <coeffs/numbers.h>
13
14#include <kernel/structs.h>
15#include <kernel/ideals.h>
16#include <kernel/polys.h>
17
18#include <kernel/combinatorics/hutil.h>
19#include <kernel/combinatorics/hilb.h>
20#include <kernel/combinatorics/stairc.h>
21
22int  hCo, hMu, hMu2;
23omBin indlist_bin = omGetSpecBin(sizeof(indlist));
24
25/*0 implementation*/
26
27// dimension
28
29void hDimSolve(scmon pure, int Npure, scfmon rad, int Nrad,
30 varset var, int Nvar)
31{
32  int  dn, iv, rad0, b, c, x;
33  scmon pn;
34  scfmon rn;
35  if (Nrad < 2)
36  {
37    dn = Npure + Nrad;
38    if (dn < hCo)
39      hCo = dn;
40    return;
41  }
42  if (Npure+1 >= hCo)
43    return;
44  iv = Nvar;
45  while(pure[var[iv]]) iv--;
46  hStepR(rad, Nrad, var, iv, &rad0);
47  if (rad0!=0)
48  {
49    iv--;
50    if (rad0 < Nrad)
51    {
52      pn = hGetpure(pure);
53      rn = hGetmem(Nrad, rad, radmem[iv]);
54      hDimSolve(pn, Npure + 1, rn, rad0, var, iv);
55      b = rad0;
56      c = Nrad;
57      hElimR(rn, &rad0, b, c, var, iv);
58      hPure(rn, b, &c, var, iv, pn, &x);
59      hLex2R(rn, rad0, b, c, var, iv, hwork);
60      rad0 += (c - b);
61      hDimSolve(pn, Npure + x, rn, rad0, var, iv);
62    }
63    else
64    {
65      hDimSolve(pure, Npure, rad, Nrad, var, iv);
66    }
67  }
68  else
69    hCo = Npure + 1;
70}
71
72int  scDimInt(ideal S, ideal Q)
73{
74  int  mc;
75  hexist = hInit(S, Q, &hNexist, currRing);
76  if (!hNexist)
77    return (currRing->N);
78  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
79  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
80  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
81  mc = hisModule;
82  if (!mc)
83  {
84    hrad = hexist;
85    hNrad = hNexist;
86  }
87  else
88    hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
89  radmem = hCreate((currRing->N) - 1);
90  hCo = (currRing->N) + 1;
91  loop
92  {
93    if (mc)
94      hComp(hexist, hNexist, mc, hrad, &hNrad);
95    if (hNrad)
96    {
97      hNvar = (currRing->N);
98      hRadical(hrad, &hNrad, hNvar);
99      hSupp(hrad, hNrad, hvar, &hNvar);
100      if (hNvar)
101      {
102        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
103        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
104        hLexR(hrad, hNrad, hvar, hNvar);
105        hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
106      }
107    }
108    else
109    {
110      hCo = 0;
111      break;
112    }
113    mc--;
114    if (mc <= 0)
115      break;
116  }
117  hKill(radmem, (currRing->N) - 1);
118  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
119  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
120  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
121  hDelete(hexist, hNexist);
122  if (hisModule)
123    omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
124  return (currRing->N) - hCo;
125}
126
127// independent set
128static scmon hInd;
129
130static void hIndSolve(scmon pure, int Npure, scfmon rad, int Nrad,
131 varset var, int Nvar)
132{
133  int  dn, iv, rad0, b, c, x;
134  scmon pn;
135  scfmon rn;
136  if (Nrad < 2)
137  {
138    dn = Npure + Nrad;
139    if (dn < hCo)
140    {
141      hCo = dn;
142      for (iv=(currRing->N); iv; iv--)
143      {
144        if (pure[iv])
145          hInd[iv] = 0;
146        else
147          hInd[iv] = 1;
148      }
149      if (Nrad)
150      {
151        pn = *rad;
152        iv = Nvar;
153        loop
154        {
155          x = var[iv];
156          if (pn[x])
157          {
158            hInd[x] = 0;
159            break;
160          }
161          iv--;
162        }
163      }
164    }
165    return;
166  }
167  if (Npure+1 >= hCo)
168    return;
169  iv = Nvar;
170  while(pure[var[iv]]) iv--;
171  hStepR(rad, Nrad, var, iv, &rad0);
172  if (rad0)
173  {
174    iv--;
175    if (rad0 < Nrad)
176    {
177      pn = hGetpure(pure);
178      rn = hGetmem(Nrad, rad, radmem[iv]);
179      pn[var[iv + 1]] = 1;
180      hIndSolve(pn, Npure + 1, rn, rad0, var, iv);
181      pn[var[iv + 1]] = 0;
182      b = rad0;
183      c = Nrad;
184      hElimR(rn, &rad0, b, c, var, iv);
185      hPure(rn, b, &c, var, iv, pn, &x);
186      hLex2R(rn, rad0, b, c, var, iv, hwork);
187      rad0 += (c - b);
188      hIndSolve(pn, Npure + x, rn, rad0, var, iv);
189    }
190    else
191    {
192      hIndSolve(pure, Npure, rad, Nrad, var, iv);
193    }
194  }
195  else
196  {
197    hCo = Npure + 1;
198    for (x=(currRing->N); x; x--)
199    {
200      if (pure[x])
201        hInd[x] = 0;
202      else
203        hInd[x] = 1;
204    }
205    hInd[var[iv]] = 0;
206  }
207}
208
209intvec * scIndIntvec(ideal S, ideal Q)
210{
211  intvec *Set=new intvec((currRing->N));
212  int  mc,i;
213  hexist = hInit(S, Q, &hNexist, currRing);
214  if (hNexist==0)
215  {
216    for(i=0; i<(currRing->N); i++)
217      (*Set)[i]=1;
218    return Set;
219  }
220  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
221  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
222  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
223  hInd = (scmon)omAlloc0((1 + (currRing->N)) * sizeof(int));
224  mc = hisModule;
225  if (mc==0)
226  {
227    hrad = hexist;
228    hNrad = hNexist;
229  }
230  else
231    hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
232  radmem = hCreate((currRing->N) - 1);
233  hCo = (currRing->N) + 1;
234  loop
235  {
236    if (mc!=0)
237      hComp(hexist, hNexist, mc, hrad, &hNrad);
238    if (hNrad!=0)
239    {
240      hNvar = (currRing->N);
241      hRadical(hrad, &hNrad, hNvar);
242      hSupp(hrad, hNrad, hvar, &hNvar);
243      if (hNvar!=0)
244      {
245        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
246        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
247        hLexR(hrad, hNrad, hvar, hNvar);
248        hIndSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
249      }
250    }
251    else
252    {
253      hCo = 0;
254      break;
255    }
256    mc--;
257    if (mc <= 0)
258      break;
259  }
260  for(i=0; i<(currRing->N); i++)
261    (*Set)[i] = hInd[i+1];
262  hKill(radmem, (currRing->N) - 1);
263  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
264  omFreeSize((ADDRESS)hInd, (1 + (currRing->N)) * sizeof(int));
265  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
266  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
267  hDelete(hexist, hNexist);
268  if (hisModule)
269    omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
270  return Set;
271}
272
273indset ISet, JSet;
274
275static BOOLEAN hNotZero(scfmon rad, int Nrad, varset var, int Nvar)
276{
277  int  k1, i;
278  k1 = var[Nvar];
279  i = 0;
280  loop
281  {
282    if (rad[i][k1]==0)
283      return FALSE;
284    i++;
285    if (i == Nrad)
286      return TRUE;
287  }
288}
289
290static void hIndep(scmon pure)
291{
292  int iv;
293  intvec *Set;
294
295  Set = ISet->set = new intvec((currRing->N));
296  for (iv=(currRing->N); iv!=0 ; iv--)
297  {
298    if (pure[iv])
299      (*Set)[iv-1] = 0;
300    else
301      (*Set)[iv-1] = 1;
302  }
303  ISet = ISet->nx = (indset)omAlloc0Bin(indlist_bin);
304  hMu++;
305}
306
307void hIndMult(scmon pure, int Npure, scfmon rad, int Nrad,
308 varset var, int Nvar)
309{
310  int  dn, iv, rad0, b, c, x;
311  scmon pn;
312  scfmon rn;
313  if (Nrad < 2)
314  {
315    dn = Npure + Nrad;
316    if (dn == hCo)
317    {
318      if (Nrad==0)
319        hIndep(pure);
320      else
321      {
322        pn = *rad;
323        for (iv = Nvar; iv!=0; iv--)
324        {
325          x = var[iv];
326          if (pn[x])
327          {
328            pure[x] = 1;
329            hIndep(pure);
330            pure[x] = 0;
331          }
332        }
333      }
334    }
335    return;
336  }
337  iv = Nvar;
338  dn = Npure+1;
339  if (dn >= hCo)
340  {
341    if (dn > hCo)
342      return;
343    loop
344    {
345      if(!pure[var[iv]])
346      {
347        if(hNotZero(rad, Nrad, var, iv))
348        {
349          pure[var[iv]] = 1;
350          hIndep(pure);
351          pure[var[iv]] = 0;
352        }
353      }
354      iv--;
355      if (!iv)
356        return;
357    }
358  }
359  while(pure[var[iv]]) iv--;
360  hStepR(rad, Nrad, var, iv, &rad0);
361  iv--;
362  if (rad0 < Nrad)
363  {
364    pn = hGetpure(pure);
365    rn = hGetmem(Nrad, rad, radmem[iv]);
366    pn[var[iv + 1]] = 1;
367    hIndMult(pn, Npure + 1, rn, rad0, var, iv);
368    pn[var[iv + 1]] = 0;
369    b = rad0;
370    c = Nrad;
371    hElimR(rn, &rad0, b, c, var, iv);
372    hPure(rn, b, &c, var, iv, pn, &x);
373    hLex2R(rn, rad0, b, c, var, iv, hwork);
374    rad0 += (c - b);
375    hIndMult(pn, Npure + x, rn, rad0, var, iv);
376  }
377  else
378  {
379    hIndMult(pure, Npure, rad, Nrad, var, iv);
380  }
381}
382
383/*3
384* consider indset x := !pure
385* (for all i) (if(sm(i) > x) return FALSE)
386* else return TRUE
387*/
388static BOOLEAN hCheck1(indset sm, scmon pure)
389{
390  int iv;
391  intvec *Set;
392  while (sm->nx != NULL)
393  {
394    Set = sm->set;
395    iv=(currRing->N);
396    loop
397    {
398      if (((*Set)[iv-1] == 0) && (pure[iv] == 0))
399        break;
400      iv--;
401      if (iv == 0)
402        return FALSE;
403    }
404    sm = sm->nx;
405  }
406  return TRUE;
407}
408
409/*3
410* consider indset x := !pure
411* (for all i) if(x > sm(i)) delete sm(i))
412* return (place for x)
413*/
414static indset hCheck2(indset sm, scmon pure)
415{
416  int iv;
417  intvec *Set;
418  indset be, a1 = NULL;
419  while (sm->nx != NULL)
420  {
421    Set = sm->set;
422    iv=(currRing->N);
423    loop
424    {
425      if ((pure[iv] == 1) && ((*Set)[iv-1] == 1))
426        break;
427      iv--;
428      if (iv == 0)
429      {
430        if (a1 == NULL)
431        {
432          a1 = sm;
433        }
434        else
435        {
436          hMu2--;
437          be->nx = sm->nx;
438          delete Set;
439          omFreeBin((ADDRESS)sm, indlist_bin);
440          sm = be;
441        }
442        break;
443      }
444    }
445    be = sm;
446    sm = sm->nx;
447  }
448  if (a1 != NULL)
449  {
450    return a1;
451  }
452  else
453  {
454    hMu2++;
455    sm->set = new intvec((currRing->N));
456    sm->nx = (indset)omAlloc0Bin(indlist_bin);
457    return sm;
458  }
459}
460
461/*2
462*  definition x >= y
463*      x(i) == 0 => y(i) == 0
464*      > ex. j with x(j) == 1 and y(j) == 0
465*/
466static void hCheckIndep(scmon pure)
467{
468  intvec *Set;
469  indset res;
470  int iv;
471  if (hCheck1(ISet, pure))
472  {
473    if (hCheck1(JSet, pure))
474    {
475      res = hCheck2(JSet,pure);
476      if (res == NULL)
477        return;
478      Set = res->set;
479      for (iv=(currRing->N); iv; iv--)
480      {
481        if (pure[iv])
482          (*Set)[iv-1] = 0;
483        else
484          (*Set)[iv-1] = 1;
485      }
486    }
487  }
488}
489
490void hIndAllMult(scmon pure, int Npure, scfmon rad, int Nrad,
491 varset var, int Nvar)
492{
493  int  dn, iv, rad0, b, c, x;
494  scmon pn;
495  scfmon rn;
496  if (Nrad < 2)
497  {
498    dn = Npure + Nrad;
499    if (dn > hCo)
500    {
501      if (!Nrad)
502        hCheckIndep(pure);
503      else
504      {
505        pn = *rad;
506        for (iv = Nvar; iv; iv--)
507        {
508          x = var[iv];
509          if (pn[x])
510          {
511            pure[x] = 1;
512            hCheckIndep(pure);
513            pure[x] = 0;
514          }
515        }
516      }
517    }
518    return;
519  }
520  iv = Nvar;
521  while(pure[var[iv]]) iv--;
522  hStepR(rad, Nrad, var, iv, &rad0);
523  iv--;
524  if (rad0 < Nrad)
525  {
526    pn = hGetpure(pure);
527    rn = hGetmem(Nrad, rad, radmem[iv]);
528    pn[var[iv + 1]] = 1;
529    hIndAllMult(pn, Npure + 1, rn, rad0, var, iv);
530    pn[var[iv + 1]] = 0;
531    b = rad0;
532    c = Nrad;
533    hElimR(rn, &rad0, b, c, var, iv);
534    hPure(rn, b, &c, var, iv, pn, &x);
535    hLex2R(rn, rad0, b, c, var, iv, hwork);
536    rad0 += (c - b);
537    hIndAllMult(pn, Npure + x, rn, rad0, var, iv);
538  }
539  else
540  {
541    hIndAllMult(pure, Npure, rad, Nrad, var, iv);
542  }
543}
544
545// multiplicity
546
547static int hZeroMult(scmon pure, scfmon stc, int Nstc, varset var, int Nvar)
548{
549  int  iv = Nvar -1, sum, a, a0, a1, b, i;
550  int  x, x0;
551  scmon pn;
552  scfmon sn;
553  if (!iv)
554    return pure[var[1]];
555  else if (!Nstc)
556  {
557    sum = 1;
558    for (i = Nvar; i; i--)
559      sum *= pure[var[i]];
560    return sum;
561  }
562  x = a = 0;
563  pn = hGetpure(pure);
564  sn = hGetmem(Nstc, stc, stcmem[iv]);
565  hStepS(sn, Nstc, var, Nvar, &a, &x);
566  if (a == Nstc)
567    return pure[var[Nvar]] * hZeroMult(pn, sn, a, var, iv);
568  else
569    sum = x * hZeroMult(pn, sn, a, var, iv);
570  b = a;
571  loop
572  {
573    a0 = a;
574    x0 = x;
575    hStepS(sn, Nstc, var, Nvar, &a, &x);
576    hElimS(sn, &b, a0, a, var, iv);
577    a1 = a;
578    hPure(sn, a0, &a1, var, iv, pn, &i);
579    hLex2S(sn, b, a0, a1, var, iv, hwork);
580    b += (a1 - a0);
581    if (a < Nstc)
582    {
583      sum += (x - x0) * hZeroMult(pn, sn, b, var, iv);
584    }
585    else
586    {
587      sum += (pure[var[Nvar]] - x0) * hZeroMult(pn, sn, b, var, iv);
588      return sum;
589    }
590  }
591}
592
593static void hProject(scmon pure, varset sel)
594{
595  int  i, i0, k;
596  i0 = 0;
597  for (i = 1; i <= (currRing->N); i++)
598  {
599    if (pure[i])
600    {
601      i0++;
602      sel[i0] = i;
603    }
604  }
605  i = hNstc;
606  memcpy(hwork, hstc, i * sizeof(scmon));
607  hStaircase(hwork, &i, sel, i0);
608  if ((i0 > 2) && (i > 10))
609    hOrdSupp(hwork, i, sel, i0);
610  memset(hpur0, 0, ((currRing->N) + 1) * sizeof(int));
611  hPure(hwork, 0, &i, sel, i0, hpur0, &k);
612  hLexS(hwork, i, sel, i0);
613  hMu += hZeroMult(hpur0, hwork, i, sel, i0);
614}
615
616static void hDimMult(scmon pure, int Npure, scfmon rad, int Nrad,
617 varset var, int Nvar)
618{
619  int  dn, iv, rad0, b, c, x;
620  scmon pn;
621  scfmon rn;
622  if (Nrad < 2)
623  {
624    dn = Npure + Nrad;
625    if (dn == hCo)
626    {
627      if (!Nrad)
628        hProject(pure, hsel);
629      else
630      {
631        pn = *rad;
632        for (iv = Nvar; iv; iv--)
633        {
634          x = var[iv];
635          if (pn[x])
636          {
637            pure[x] = 1;
638            hProject(pure, hsel);
639            pure[x] = 0;
640          }
641        }
642      }
643    }
644    return;
645  }
646  iv = Nvar;
647  dn = Npure+1;
648  if (dn >= hCo)
649  {
650    if (dn > hCo)
651      return;
652    loop
653    {
654      if(!pure[var[iv]])
655      {
656        if(hNotZero(rad, Nrad, var, iv))
657        {
658          pure[var[iv]] = 1;
659          hProject(pure, hsel);
660          pure[var[iv]] = 0;
661        }
662      }
663      iv--;
664      if (!iv)
665        return;
666    }
667  }
668  while(pure[var[iv]]) iv--;
669  hStepR(rad, Nrad, var, iv, &rad0);
670  iv--;
671  if (rad0 < Nrad)
672  {
673    pn = hGetpure(pure);
674    rn = hGetmem(Nrad, rad, radmem[iv]);
675    pn[var[iv + 1]] = 1;
676    hDimMult(pn, Npure + 1, rn, rad0, var, iv);
677    pn[var[iv + 1]] = 0;
678    b = rad0;
679    c = Nrad;
680    hElimR(rn, &rad0, b, c, var, iv);
681    hPure(rn, b, &c, var, iv, pn, &x);
682    hLex2R(rn, rad0, b, c, var, iv, hwork);
683    rad0 += (c - b);
684    hDimMult(pn, Npure + x, rn, rad0, var, iv);
685  }
686  else
687  {
688    hDimMult(pure, Npure, rad, Nrad, var, iv);
689  }
690}
691
692static void hDegree(ideal S, ideal Q)
693{
694  int  di;
695  int  mc;
696  hexist = hInit(S, Q, &hNexist, currRing);
697  if (!hNexist)
698  {
699    hCo = 0;
700    hMu = 1;
701    return;
702  }
703  //hWeight();
704  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
705  hvar = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
706  hsel = (varset)omAlloc(((currRing->N) + 1) * sizeof(int));
707  hpure = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
708  hpur0 = (scmon)omAlloc((1 + ((currRing->N) * (currRing->N))) * sizeof(int));
709  mc = hisModule;
710  hrad = (scfmon)omAlloc(hNexist * sizeof(scmon));
711  if (!mc)
712  {
713    memcpy(hrad, hexist, hNexist * sizeof(scmon));
714    hstc = hexist;
715    hNrad = hNstc = hNexist;
716  }
717  else
718    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
719  radmem = hCreate((currRing->N) - 1);
720  stcmem = hCreate((currRing->N) - 1);
721  hCo = (currRing->N) + 1;
722  di = hCo + 1;
723  loop
724  {
725    if (mc)
726    {
727      hComp(hexist, hNexist, mc, hrad, &hNrad);
728      hNstc = hNrad;
729      memcpy(hstc, hrad, hNrad * sizeof(scmon));
730    }
731    if (hNrad)
732    {
733      hNvar = (currRing->N);
734      hRadical(hrad, &hNrad, hNvar);
735      hSupp(hrad, hNrad, hvar, &hNvar);
736      if (hNvar)
737      {
738        hCo = hNvar;
739        memset(hpure, 0, ((currRing->N) + 1) * sizeof(int));
740        hPure(hrad, 0, &hNrad, hvar, hNvar, hpure, &hNpure);
741        hLexR(hrad, hNrad, hvar, hNvar);
742        hDimSolve(hpure, hNpure, hrad, hNrad, hvar, hNvar);
743      }
744    }
745    else
746    {
747      hNvar = 1;
748      hCo = 0;
749    }
750    if (hCo < di)
751    {
752      di = hCo;
753      hMu = 0;
754    }
755    if (hNvar && (hCo == di))
756    {
757      if (di && (di < (currRing->N)))
758        hDimMult(hpure, hNpure, hrad, hNrad, hvar, hNvar);
759      else if (!di)
760        hMu++;
761      else
762      {
763        hStaircase(hstc, &hNstc, hvar, hNvar);
764        if ((hNvar > 2) && (hNstc > 10))
765          hOrdSupp(hstc, hNstc, hvar, hNvar);
766        memset(hpur0, 0, ((currRing->N) + 1) * sizeof(int));
767        hPure(hstc, 0, &hNstc, hvar, hNvar, hpur0, &hNpure);
768        hLexS(hstc, hNstc, hvar, hNvar);
769        hMu += hZeroMult(hpur0, hstc, hNstc, hvar, hNvar);
770      }
771    }
772    mc--;
773    if (mc <= 0)
774      break;
775  }
776  hCo = di;
777  hKill(stcmem, (currRing->N) - 1);
778  hKill(radmem, (currRing->N) - 1);
779  omFreeSize((ADDRESS)hpur0, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
780  omFreeSize((ADDRESS)hpure, (1 + ((currRing->N) * (currRing->N))) * sizeof(int));
781  omFreeSize((ADDRESS)hsel, ((currRing->N) + 1) * sizeof(int));
782  omFreeSize((ADDRESS)hvar, ((currRing->N) + 1) * sizeof(int));
783  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
784  omFreeSize((ADDRESS)hrad, hNexist * sizeof(scmon));
785  hDelete(hexist, hNexist);
786  if (hisModule)
787    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
788}
789
790int  scMultInt(ideal S, ideal Q)
791{
792  hDegree(S, Q);
793  return hMu;
794}
795
796void scPrintDegree(int co, int mu)
797{
798  int di = (currRing->N)-co;
799  if (currRing->OrdSgn == 1)
800  {
801    if (di>0)
802      Print("// dimension (proj.)  = %d\n// degree (proj.)   = %d\n", di-1, mu);
803    else
804      Print("// dimension (affine) = 0\n// degree (affine)  = %d\n",       mu);
805  }
806  else
807    Print("// dimension (local)   = %d\n// multiplicity = %d\n", di, mu);
808}
809
810void scDegree(ideal S, intvec *modulweight, ideal Q)
811{
812  int co, mu, l;
813  intvec *hseries2;
814  intvec *hseries1 = hFirstSeries(S, modulweight, Q);
815  l = hseries1->length()-1;
816  if (l > 1)
817    hseries2 = hSecondSeries(hseries1);
818  else
819    hseries2 = hseries1;
820  hDegreeSeries(hseries1, hseries2, &co, &mu);
821  if ((l == 1) &&(mu == 0))
822    scPrintDegree((currRing->N)+1, 0);
823  else
824    scPrintDegree(co, mu);
825  if (l>1)
826    delete hseries1;
827  delete hseries2;
828}
829
830static void hDegree0(ideal S, ideal Q, const ring r=currRing)
831{
832  int  mc;
833  hexist = hInit(S, Q, &hNexist, currRing);
834  if (!hNexist)
835  {
836    hMu = -1;
837    return;
838  }
839  else
840    hMu = 0;
841  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
842  hvar = (varset)omAlloc(((r->N) + 1) * sizeof(int));
843  hpur0 = (scmon)omAlloc((1 + ((r->N) * (r->N))) * sizeof(int));
844  mc = hisModule;
845  if (!mc)
846  {
847    hstc = hexist;
848    hNstc = hNexist;
849  }
850  else
851    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
852  stcmem = hCreate((r->N) - 1);
853  loop
854  {
855    if (mc)
856    {
857      hComp(hexist, hNexist, mc, hstc, &hNstc);
858      if (!hNstc)
859      {
860        hMu = -1;
861        break;
862      }
863    }
864    hNvar = (r->N);
865    for (int i = hNvar; i; i--)
866      hvar[i] = i;
867    hStaircase(hstc, &hNstc, hvar, hNvar);
868    hSupp(hstc, hNstc, hvar, &hNvar);
869    if ((hNvar == (r->N)) && (hNstc >= (r->N)))
870    {
871      if ((hNvar > 2) && (hNstc > 10))
872        hOrdSupp(hstc, hNstc, hvar, hNvar);
873      memset(hpur0, 0, ((r->N) + 1) * sizeof(int));
874      hPure(hstc, 0, &hNstc, hvar, hNvar, hpur0, &hNpure);
875      if (hNpure == hNvar)
876      {
877        hLexS(hstc, hNstc, hvar, hNvar);
878        hMu += hZeroMult(hpur0, hstc, hNstc, hvar, hNvar);
879      }
880      else
881        hMu = -1;
882    }
883    else if (hNvar)
884      hMu = -1;
885    mc--;
886    if (mc <= 0 || hMu < 0)
887      break;
888  }
889  hKill(stcmem, (r->N) - 1);
890  omFreeSize((ADDRESS)hpur0, (1 + ((r->N) * (r->N))) * sizeof(int));
891  omFreeSize((ADDRESS)hvar, ((r->N) + 1) * sizeof(int));
892  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
893  hDelete(hexist, hNexist);
894  if (hisModule)
895    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
896}
897
898int  scMult0Int(ideal S, ideal Q, const ring r)
899{
900  hDegree0(S, Q);
901  return hMu;
902}
903
904
905// HC
906
907static poly pWork;
908
909static void hHedge(poly hEdge)
910{
911  pSetm(pWork);
912  if (pLmCmp(pWork, hEdge) == currRing->OrdSgn)
913  {
914    for (int i = hNvar; i>0; i--)
915      pSetExp(hEdge,i, pGetExp(pWork,i));
916    pSetm(hEdge);
917  }
918}
919
920
921static void hHedgeStep(scmon pure, scfmon stc,
922                       int Nstc, varset var, int Nvar,poly hEdge)
923{
924  int  iv = Nvar -1, k = var[Nvar], a, a0, a1, b, i;
925  int  x/*, x0*/;
926  scmon pn;
927  scfmon sn;
928  if (iv==0)
929  {
930    pSetExp(pWork, k, pure[k]);
931    hHedge(hEdge);
932    return;
933  }
934  else if (Nstc==0)
935  {
936    for (i = Nvar; i>0; i--)
937      pSetExp(pWork, var[i], pure[var[i]]);
938    hHedge(hEdge);
939    return;
940  }
941  x = a = 0;
942  pn = hGetpure(pure);
943  sn = hGetmem(Nstc, stc, stcmem[iv]);
944  hStepS(sn, Nstc, var, Nvar, &a, &x);
945  if (a == Nstc)
946  {
947    pSetExp(pWork, k, pure[k]);
948    hHedgeStep(pn, sn, a, var, iv,hEdge);
949    return;
950  }
951  else
952  {
953    pSetExp(pWork, k, x);
954    hHedgeStep(pn, sn, a, var, iv,hEdge);
955  }
956  b = a;
957  loop
958  {
959    a0 = a;
960    // x0 = x;
961    hStepS(sn, Nstc, var, Nvar, &a, &x);
962    hElimS(sn, &b, a0, a, var, iv);
963    a1 = a;
964    hPure(sn, a0, &a1, var, iv, pn, &i);
965    hLex2S(sn, b, a0, a1, var, iv, hwork);
966    b += (a1 - a0);
967    if (a < Nstc)
968    {
969      pSetExp(pWork, k, x);
970      hHedgeStep(pn, sn, b, var, iv,hEdge);
971    }
972    else
973    {
974      pSetExp(pWork, k, pure[k]);
975      hHedgeStep(pn, sn, b, var, iv,hEdge);
976      return;
977    }
978  }
979}
980
981void scComputeHC(ideal S, ideal Q, int ak, poly &hEdge, ring tailRing)
982{
983  int  i;
984  int  k = ak;
985
986  #if HAVE_RINGS
987  if (rField_is_Ring(currRing) && (currRing->OrdSgn == -1))
988  {
989  //consider just monic generators (over rings with zero-divisors)
990  ideal SS=id_Copy(S,tailRing);
991  for(i=0;i<=idElem(SS);i++)
992        {
993        if(pIsPurePower(SS->m[i])==0)
994                p_Delete(&SS->m[i],tailRing);
995        }
996        S=id_Copy(SS,tailRing);
997  }
998  #endif
999
1000  hNvar = (currRing->N);
1001  hexist = hInit(S, Q, &hNexist, tailRing);
1002  if (k!=0)
1003    hComp(hexist, hNexist, k, hexist, &hNstc);
1004  else
1005    hNstc = hNexist;
1006  hwork = (scfmon)omAlloc(hNexist * sizeof(scmon));
1007  hvar = (varset)omAlloc((hNvar + 1) * sizeof(int));
1008  hpure = (scmon)omAlloc((1 + (hNvar * hNvar)) * sizeof(int));
1009  stcmem = hCreate(hNvar - 1);
1010  for (i = hNvar; i>0; i--)
1011    hvar[i] = i;
1012  hStaircase(hexist, &hNstc, hvar, hNvar);
1013  if ((hNvar > 2) && (hNstc > 10))
1014    hOrdSupp(hexist, hNstc, hvar, hNvar);
1015  memset(hpure, 0, (hNvar + 1) * sizeof(int));
1016  hPure(hexist, 0, &hNstc, hvar, hNvar, hpure, &hNpure);
1017  hLexS(hexist, hNstc, hvar, hNvar);
1018  if (hEdge!=NULL)
1019    pLmFree(hEdge);
1020  hEdge = pInit();
1021  pWork = pInit();
1022  hHedgeStep(hpure, hexist, hNstc, hvar, hNvar,hEdge);
1023  pSetComp(hEdge,ak);
1024  hKill(stcmem, hNvar - 1);
1025  omFreeSize((ADDRESS)hwork, hNexist * sizeof(scmon));
1026  omFreeSize((ADDRESS)hvar, (hNvar + 1) * sizeof(int));
1027  omFreeSize((ADDRESS)hpure, (1 + (hNvar * hNvar)) * sizeof(int));
1028  hDelete(hexist, hNexist);
1029  pLmFree(pWork);
1030}
1031
1032
1033
1034//  kbase
1035
1036static poly last;
1037static scmon act;
1038
1039static void scElKbase()
1040{
1041  poly q = pInit();
1042  pSetCoeff0(q,nInit(1));
1043  pSetExpV(q,act);
1044  pNext(q) = NULL;
1045  last = pNext(last) = q;
1046}
1047
1048static int scMax( int i, scfmon stc, int Nvar)
1049{
1050  int x, y=stc[0][Nvar];
1051  for (; i;)
1052  {
1053    i--;
1054    x = stc[i][Nvar];
1055    if (x > y) y = x;
1056  }
1057  return y;
1058}
1059
1060static int scMin( int i, scfmon stc, int Nvar)
1061{
1062  int x, y=stc[0][Nvar];
1063  for (; i;)
1064  {
1065    i--;
1066    x = stc[i][Nvar];
1067    if (x < y) y = x;
1068  }
1069  return y;
1070}
1071
1072static int scRestrict( int &Nstc, scfmon stc, int Nvar)
1073{
1074  int x, y;
1075  int i, j, Istc = Nstc;
1076
1077  y = MAX_INT_VAL;
1078  for (i=Nstc-1; i>=0; i--)
1079  {
1080    j = Nvar-1;
1081    loop
1082    {
1083      if(stc[i][j] != 0) break;
1084      j--;
1085      if (j == 0)
1086      {
1087        Istc--;
1088        x = stc[i][Nvar];
1089        if (x < y) y = x;
1090        stc[i] = NULL;
1091        break;
1092      }
1093    }
1094  }
1095  if (Istc < Nstc)
1096  {
1097    for (i=Nstc-1; i>=0; i--)
1098    {
1099      if (stc[i] && (stc[i][Nvar] >= y))
1100      {
1101        Istc--;
1102        stc[i] = NULL;
1103      }
1104    }
1105    j = 0;
1106    while (stc[j]) j++;
1107    i = j+1;
1108    for(; i<Nstc; i++)
1109    {
1110      if (stc[i])
1111      {
1112        stc[j] = stc[i];
1113        j++;
1114      }
1115    }
1116    Nstc = Istc;
1117    return y;
1118  }
1119  else
1120    return -1;
1121}
1122
1123static void scAll( int Nvar, int deg)
1124{
1125  int i;
1126  int d = deg;
1127  if (d == 0)
1128  {
1129    for (i=Nvar; i; i--) act[i] = 0;
1130    scElKbase();
1131    return;
1132  }
1133  if (Nvar == 1)
1134  {
1135    act[1] = d;
1136    scElKbase();
1137    return;
1138  }
1139  do
1140  {
1141    act[Nvar] = d;
1142    scAll(Nvar-1, deg-d);
1143    d--;
1144  } while (d >= 0);
1145}
1146
1147static void scAllKbase( int Nvar, int ideg, int deg)
1148{
1149  do
1150  {
1151    act[Nvar] = ideg;
1152    scAll(Nvar-1, deg-ideg);
1153    ideg--;
1154  } while (ideg >= 0);
1155}
1156
1157static void scDegKbase( scfmon stc, int Nstc, int Nvar, int deg)
1158{
1159  int  Ivar, Istc, i, j;
1160  scfmon sn;
1161  int x, ideg;
1162
1163  if (deg == 0)
1164  {
1165    for (i=Nstc-1; i>=0; i--)
1166    {
1167      for (j=Nvar;j;j--){ if(stc[i][j]) break; }
1168      if (j==0){return;}
1169    }
1170    for (i=Nvar; i; i--) act[i] = 0;
1171    scElKbase();
1172    return;
1173  }
1174  if (Nvar == 1)
1175  {
1176    for (i=Nstc-1; i>=0; i--) if(deg >= stc[i][1]) return;
1177    act[1] = deg;
1178    scElKbase();
1179    return;
1180  }
1181  Ivar = Nvar-1;
1182  sn = hGetmem(Nstc, stc, stcmem[Ivar]);
1183  x = scRestrict(Nstc, sn, Nvar);
1184  if (x <= 0)
1185  {
1186    if (x == 0) return;
1187    ideg = deg;
1188  }
1189  else
1190  {
1191    if (deg < x) ideg = deg;
1192    else ideg = x-1;
1193    if (Nstc == 0)
1194    {
1195      scAllKbase(Nvar, ideg, deg);
1196      return;
1197    }
1198  }
1199  loop
1200  {
1201    x = scMax(Nstc, sn, Nvar);
1202    while (ideg >= x)
1203    {
1204      act[Nvar] = ideg;
1205      scDegKbase(sn, Nstc, Ivar, deg-ideg);
1206      ideg--;
1207    }
1208    if (ideg < 0) return;
1209    Istc = Nstc;
1210    for (i=Nstc-1; i>=0; i--)
1211    {
1212      if (ideg < sn[i][Nvar])
1213      {
1214        Istc--;
1215        sn[i] = NULL;
1216      }
1217    }
1218    if (Istc == 0)
1219    {
1220      scAllKbase(Nvar, ideg, deg);
1221      return;
1222    }
1223    j = 0;
1224    while (sn[j]) j++;
1225    i = j+1;
1226    for (; i<Nstc; i++)
1227    {
1228      if (sn[i])
1229      {
1230        sn[j] = sn[i];
1231        j++;
1232      }
1233    }
1234    Nstc = Istc;
1235  }
1236}
1237
1238static void scInKbase( scfmon stc, int Nstc, int Nvar)
1239{
1240  int  Ivar, Istc, i, j;
1241  scfmon sn;
1242  int x, ideg;
1243
1244  if (Nvar == 1)
1245  {
1246    ideg = scMin(Nstc, stc, 1);
1247    while (ideg > 0)
1248    {
1249      ideg--;
1250      act[1] = ideg;
1251      scElKbase();
1252    }
1253    return;
1254  }
1255  Ivar = Nvar-1;
1256  sn = hGetmem(Nstc, stc, stcmem[Ivar]);
1257  x = scRestrict(Nstc, sn, Nvar);
1258  if (x == 0) return;
1259  ideg = x-1;
1260  loop
1261  {
1262    x = scMax(Nstc, sn, Nvar);
1263    while (ideg >= x)
1264    {
1265      act[Nvar] = ideg;
1266      scInKbase(sn, Nstc, Ivar);
1267      ideg--;
1268    }
1269    if (ideg < 0) return;
1270    Istc = Nstc;
1271    for (i=Nstc-1; i>=0; i--)
1272    {
1273      if (ideg < sn[i][Nvar])
1274      {
1275        Istc--;
1276        sn[i] = NULL;
1277      }
1278    }
1279    j = 0;
1280    while (sn[j]) j++;
1281    i = j+1;
1282    for (; i<Nstc; i++)
1283    {
1284      if (sn[i])
1285      {
1286        sn[j] = sn[i];
1287        j++;
1288      }
1289    }
1290    Nstc = Istc;
1291  }
1292}
1293
1294static ideal scIdKbase()
1295{
1296  polyset mm;
1297  ideal res;
1298  poly p, q = last;
1299  int i = pLength(q);
1300  res = idInit(i,1);
1301  mm = res->m;
1302  i = 0;
1303  do
1304  {
1305    mm[i] = q;
1306    i++;
1307    p = pNext(q);
1308    pNext(q) = NULL;
1309    q = p;
1310  } while (q!=NULL);
1311  return res;
1312}
1313
1314ideal scKBase(int deg, ideal s, ideal Q, intvec * mv)
1315{
1316  int  i, di;
1317  poly p;
1318
1319  if (deg < 0)
1320  {
1321    di = scDimInt(s, Q);
1322    if (di != 0)
1323    {
1324      //Werror("KBase not finite");
1325      return idInit(1,s->rank);
1326    }
1327  }
1328  stcmem = hCreate((currRing->N) - 1);
1329  hexist = hInit(s, Q, &hNexist, currRing);
1330  p = last = pInit();
1331  /*pNext(p) = NULL;*/
1332  act = (scmon)omAlloc(((currRing->N) + 1) * sizeof(int));
1333  *act = 0;
1334  if (!hNexist)
1335  {
1336    scAll((currRing->N), deg);
1337    goto ende;
1338  }
1339  if (!hisModule)
1340  {
1341    if (deg < 0) scInKbase(hexist, hNexist, (currRing->N));
1342    else scDegKbase(hexist, hNexist, (currRing->N), deg);
1343  }
1344  else
1345  {
1346    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
1347    for (i = 1; i <= hisModule; i++)
1348    {
1349      *act = i;
1350      hComp(hexist, hNexist, i, hstc, &hNstc);
1351      int deg_ei=deg;
1352      if (mv!=NULL) deg_ei -= (*mv)[i-1];
1353      if ((deg < 0) || (deg_ei>=0))
1354      {
1355        if (hNstc)
1356        {
1357          if (deg < 0) scInKbase(hstc, hNstc, (currRing->N));
1358          else scDegKbase(hstc, hNstc, (currRing->N), deg_ei);
1359        }
1360        else
1361          scAll((currRing->N), deg_ei);
1362      }
1363    }
1364    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
1365  }
1366ende:
1367  hDelete(hexist, hNexist);
1368  omFreeSize((ADDRESS)act, ((currRing->N) + 1) * sizeof(int));
1369  hKill(stcmem, (currRing->N) - 1);
1370  pLmDelete(&p);
1371  if (p == NULL)
1372    return idInit(1,s->rank);
1373  else
1374  {
1375    last = p;
1376    ideal res=scIdKbase();
1377    res->rank=s->rank;
1378    return res;
1379  }
1380}
1381
1382#if 0 //-- alternative implementation of scComputeHC
1383void scComputeHCw(ideal ss, ideal Q, int ak, poly &hEdge, ring tailRing)
1384{
1385  int  i, di;
1386  poly p;
1387
1388  if (hEdge!=NULL)
1389    pLmFree(hEdge);
1390
1391  ideal s=idInit(IDELEMS(ss),ak);
1392  for(i=IDELEMS(ss)-1;i>=0;i--)
1393  {
1394    if (ss->m[i]!=NULL) s->m[i]=pHead(ss->m[i]);
1395  }
1396  di = scDimInt(s, Q);
1397  stcmem = hCreate((currRing->N) - 1);
1398  hexist = hInit(s, Q, &hNexist, currRing);
1399  p = last = pInit();
1400  /*pNext(p) = NULL;*/
1401  act = (scmon)omAlloc(((currRing->N) + 1) * sizeof(int));
1402  *act = 0;
1403  if (!hNexist)
1404  {
1405    scAll((currRing->N), -1);
1406    goto ende;
1407  }
1408  if (!hisModule)
1409  {
1410    scInKbase(hexist, hNexist, (currRing->N));
1411  }
1412  else
1413  {
1414    hstc = (scfmon)omAlloc(hNexist * sizeof(scmon));
1415    for (i = 1; i <= hisModule; i++)
1416    {
1417      *act = i;
1418      hComp(hexist, hNexist, i, hstc, &hNstc);
1419      if (hNstc)
1420      {
1421        scInKbase(hstc, hNstc, (currRing->N));
1422      }
1423      else
1424        scAll((currRing->N), -1);
1425    }
1426    omFreeSize((ADDRESS)hstc, hNexist * sizeof(scmon));
1427  }
1428ende:
1429  hDelete(hexist, hNexist);
1430  omFreeSize((ADDRESS)act, ((currRing->N) + 1) * sizeof(int));
1431  hKill(stcmem, (currRing->N) - 1);
1432  pDeleteLm(&p);
1433  idDelete(&s);
1434  if (p == NULL)
1435  {
1436    return; // no HEdge
1437  }
1438  else
1439  {
1440    last = p;
1441    ideal res=scIdKbase();
1442    res->rank=ss->rank;
1443    poly p_ind=res->m[0]; int ind=0;
1444    for(i=IDELEMS(res)-1;i>0;i--)
1445    {
1446      if (pCmp(res->m[i],p_ind)==-1) { p_ind=res->m[i]; ind=i; }
1447    }
1448    assume(p_ind!=NULL);
1449    assume(res->m[ind]==p_ind);
1450    hEdge=p_ind;
1451    res->m[ind]=NULL;
1452    nDelete(&pGetCoeff(hEdge));
1453    pGetCoeff(hEdge)=NULL;
1454    for(i=(currRing->N);i>0;i--)
1455      pIncrExp(hEdge,i);
1456    pSetm(hEdge);
1457
1458    idDelete(&res);
1459    return;
1460  }
1461}
1462#endif
Note: See TracBrowser for help on using the repository browser.