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

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