source: git/kernel/combinatorics/hdegree.cc @ 2bf04b

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