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

spielwiese
Last change on this file since a4771e1 was a4771e1, checked in by Oleksandr Motsak <motsak@…>, 9 years ago
Separation of hilbert function into kernel/combinatorics/hilb.h + include cleanup
  • Property mode set to 100644
File size: 16.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: Utilities for staircase operations
6*/
7
8#include <kernel/mod2.h>
9// #include <kernel/structs.h>
10#include <omalloc/omalloc.h>
11
12#include <polys/simpleideals.h>
13#include <polys/monomials/p_polys.h>
14
15// #include <kernel/ideals.h>
16// #include <kernel/polys.h>
17#include <kernel/combinatorics/hutil.h>
18
19scfmon hexist, hstc, hrad, hwork;
20scmon hpure, hpur0;
21varset hvar, hsel;
22int  hNexist, hNstc, hNrad, hNvar, hNpure;
23int hisModule;
24monf stcmem, radmem;
25
26// Making a global "security" copy of the allocated exponent vectors
27// is a dirty fix for correct memory disallocation: It would be
28// better, if either the fields of heist are never touched
29// (i.e. changed) except in hInit, or, if hInit would return the
30// "security" copy as well. But then, all the relevant data is held in
31// global variables, so we might do that here, as well.
32static scfmon hsecure= NULL;
33
34scfmon hInit(ideal S, ideal Q, int *Nexist, ring tailRing)
35{
36  if (tailRing != currRing)
37    hisModule = id_RankFreeModule(S, currRing, tailRing);
38  else
39    hisModule = id_RankFreeModule(S, currRing);
40
41  if (hisModule < 0)
42    hisModule = 0;
43   
44  int  sl, ql, i, k = 0;
45  polyset si, qi, ss;
46  scfmon ex, ek;
47   
48  if (S!=NULL)
49  {
50    si = S->m;
51    sl = IDELEMS(S);
52  }
53  else
54  {
55    si = NULL;
56    sl = 0;
57  }
58  if (Q!=NULL)
59  {
60    qi = Q->m;
61    ql = IDELEMS(Q);
62  }
63  else
64  {
65    qi = NULL;
66    ql = 0;
67  }
68  if ((sl + ql) == 0)
69  {
70    *Nexist = 0;
71    return NULL;
72  }
73  ss = si;
74  for (i = sl; i>0; i--)
75  {
76    if (*ss!=0)
77      k++;
78    ss++;
79  }
80  ss = qi;
81  for (i = ql; i>0; i--)
82  {
83    if (*ss!=0)
84      k++;
85    ss++;
86  }
87  *Nexist = k;
88  if (k==0)
89    return NULL;
90  ek = ex = (scfmon)omAlloc0(k * sizeof(scmon));
91  hsecure = (scfmon) omAlloc0(k * sizeof(scmon));
92  for (i = sl; i>0; i--)
93  {
94    if (*si!=NULL)
95    {
96      *ek = (scmon) omAlloc(((currRing->N)+1)*sizeof(int));
97      p_GetExpV(*si, *ek, currRing);
98      ek++;
99    }
100    si++;
101  }
102  for (i = ql; i>0; i--)
103  {
104    if (*qi!=NULL)
105    {
106      *ek = (scmon) omAlloc(((currRing->N)+1)*sizeof(int));
107      p_GetExpV(*qi, *ek, currRing);
108      ek++;
109    }
110    qi++;
111  }
112  memcpy(hsecure, ex, k * sizeof(scmon));
113  return ex;
114}
115
116#if 0
117void hWeight()
118{
119  int i, k;
120  int x;
121
122  i = (currRing->N);
123  loop
124  {
125    if (pWeight(i) != 1) break;
126    i--;
127    if (i == 0) return;
128  }
129  for (i=(currRing->N); i>0; i--)
130  {
131    x = pWeight(i);
132    if (x != 1)
133    {
134      for (k=hNexist-1; k>=0; k--)
135      {
136        hexist[k][i] *= x;
137      }
138    }
139  }
140}
141#endif
142
143void hDelete(scfmon ev, int ev_length)
144{
145  int i;
146
147  if (ev_length>0)
148  {
149    for (i=ev_length-1;i>=0;i--)
150      omFreeSize(hsecure[i],((currRing->N)+1)*sizeof(int));
151    omFreeSize(hsecure, ev_length*sizeof(scmon));
152    omFreeSize(ev,  ev_length*sizeof(scmon));
153  }
154}
155
156
157void hComp(scfmon exist, int Nexist, int ak, scfmon stc, int *Nstc)
158{
159  int k = 0;
160  scfmon ex = exist, co = stc;
161  int i;
162
163  for (i = Nexist; i>0; i--)
164  {
165    if (((**ex) == 0) || ((**ex) == ak))
166    {
167      *co = *ex;
168      co++;
169      k++;
170    }
171    ex++;
172  }
173  *Nstc = k;
174}
175
176
177void hSupp(scfmon stc, int Nstc, varset var, int *Nvar)
178{
179  int  nv, i0, i1, i, j;
180  nv = i0 = *Nvar;
181  i1 = 0;
182  for (i = 1; i <= nv; i++)
183  {
184    j = 0;
185    loop
186    {
187      if (stc[j][i]>0)
188      {
189        i1++;
190        var[i1] = i;
191        break;
192      }
193      j++;
194      if (j == Nstc)
195      {
196        var[i0] = i;
197        i0--;
198        break;
199      }
200    }
201  }
202  *Nvar = i1;
203}
204
205void hOrdSupp(scfmon stc, int Nstc, varset var, int Nvar)
206{
207  int  i, i1, j, jj, k, l;
208  int  x;
209  scmon temp, count;
210  float o, h, g, *v1;
211
212  v1 = (float *)omAlloc(Nvar * sizeof(float));
213  temp = (int *)omAlloc(Nstc * sizeof(int));
214  count = (int *)omAlloc(Nstc * sizeof(int));
215  for (i = 1; i <= Nvar; i++)
216  {
217    i1 = var[i];
218    *temp = stc[0][i1];
219    *count = 1;
220    jj = 1;
221    for (j = 1; j < Nstc; j++)
222    {
223      x = stc[j][i1];
224      k = 0;
225      loop
226      {
227        if (x > temp[k])
228        {
229          k++;
230          if (k == jj)
231          {
232            temp[k] = x;
233            count[k] = 1;
234            jj++;
235            break;
236          }
237        }
238        else if (x < temp[k])
239        {
240          for (l = jj; l > k; l--)
241          {
242            temp[l] = temp[l-1];
243            count[l] = count[l-1];
244          }
245          temp[k] = x;
246          count[k] = 1;
247          jj++;
248          break;
249        }
250        else
251        {
252          count[k]++;
253          break;
254        }
255      }
256    }
257    h = 0.0;
258    o = (float)Nstc/(float)jj;
259    for(j = 0; j < jj; j++)
260    {
261       g = (float)count[j];
262       if (g > o)
263         g -= o;
264       else
265         g = o - g;
266       if (g > h)
267         h = g;
268    }
269    v1[i-1] = h * (float)jj;
270  }
271  omFreeSize((ADDRESS)count, Nstc * sizeof(int));
272  omFreeSize((ADDRESS)temp, Nstc * sizeof(int));
273  for (i = 1; i < Nvar; i++)
274  {
275    i1 = var[i+1];
276    h = v1[i];
277    j = 0;
278    loop
279    {
280      if (h > v1[j])
281      {
282        for (l = i; l > j; l--)
283        {
284          v1[l] = v1[l-1];
285          var[l+1] = var[l];
286        }
287        v1[j] = h;
288        var[j+1] = i1;
289        break;
290      }
291      j++;
292      if (j == i)
293        break;
294    }
295  }
296  omFreeSize((ADDRESS)v1, Nvar * sizeof(float));
297}
298
299
300static void hShrink(scfmon co, int a, int Nco)
301{
302  while ((co[a]!=NULL) && (a<Nco)) a++;
303  int i = a;
304  int j;
305  for (j = a; j < Nco; j++)
306  {
307    if (co[j]!=NULL)
308    {
309      co[i] = co[j];
310      i++;
311    }
312  }
313}
314
315
316void hStaircase(scfmon stc, int *Nstc, varset var, int Nvar)
317{
318  int  nc = *Nstc;
319  if (nc < 2)
320    return;
321  int z = 0;
322  int i = 0;
323  int j = 1;
324  scmon n = stc[1 /*j*/];
325  scmon o = stc[0];
326  int k = Nvar;
327  loop
328  {
329    int k1 = var[k];
330    if (o[k1] > n[k1])
331    {
332      loop
333      {
334        k--;
335        if (k==0)
336        {
337          stc[i] = NULL;
338          z++;
339          break;
340        }
341        else
342        {
343          k1 = var[k];
344          if (o[k1] < n[k1])
345            break;
346        }
347      }
348      k = Nvar;
349    }
350    else if (o[k1] < n[k1])
351    {
352      loop
353      {
354        k--;
355        if (k==0)
356        {
357          stc[j] = NULL;
358          z++;
359          break;
360        }
361        else
362        {
363          k1 = var[k];
364          if (o[k1] > n[k1])
365            break;
366        }
367      }
368      k = Nvar;
369    }
370    else
371    {
372      k--;
373      if (k==0)
374      {
375        stc[j] = NULL;
376        z++;
377        k = Nvar;
378      }
379    }
380    if (k == Nvar)
381    {
382      if (stc[j]==NULL)
383        i = j - 1;
384      loop
385      {
386        i++;
387        if (i == j)
388        {
389          i = -1;
390          j++;
391          if (j < nc)
392            n = stc[j];
393          else
394          {
395            if (z!=0)
396            {
397              *Nstc -= z;
398              hShrink(stc, 0, nc);
399            }
400            return;
401          }
402        }
403        else if (stc[i]!=NULL)
404        {
405          o = stc[i];
406          break;
407        }
408      }
409    }
410  }
411}
412
413
414void hRadical(scfmon rad, int *Nrad, int Nvar)
415{
416  int  nc = *Nrad, z = 0, i, j, k;
417  scmon n, o;
418  if (nc < 2)
419    return;
420  i = 0;
421  j = 1;
422  n = rad[j];
423  o = rad[0];
424  k = Nvar;
425  loop
426  {
427    if ((o[k]!=0) && (n[k]==0))
428    {
429      loop
430      {
431        k--;
432        if (k==0)
433        {
434          rad[i] = NULL;
435          z++;
436          break;
437        }
438        else
439        {
440          if ((o[k]==0) && (n[k]!=0))
441            break;
442        }
443      }
444      k = Nvar;
445    }
446    else if (!o[k] && n[k])
447    {
448      loop
449      {
450        k--;
451        if (!k)
452        {
453          rad[j] = NULL;
454          z++;
455          break;
456        }
457        else
458        {
459          if (o[k] && !n[k])
460            break;
461        }
462      }
463      k = Nvar;
464    }
465    else
466    {
467      k--;
468      if (!k)
469      {
470        rad[j] = NULL;
471        z++;
472        k = Nvar;
473      }
474    }
475    if (k == Nvar)
476    {
477      if (!rad[j])
478        i = j - 1;
479      loop
480      {
481        i++;
482        if (i == j)
483        {
484          i = -1;
485          j++;
486          if (j < nc)
487            n = rad[j];
488          else
489          {
490            if (z)
491            {
492              *Nrad -= z;
493              hShrink(rad, 0, nc);
494            }
495            return;
496          }
497        }
498        else if (rad[i])
499        {
500          o = rad[i];
501          break;
502        }
503      }
504    }
505  }
506}
507
508
509void hLexS(scfmon stc, int Nstc, varset var, int Nvar)
510{
511  if (Nstc < 2)
512    return;
513  int  j = 1, i = 0;
514  scmon n = stc[j];
515  scmon o = stc[0];
516  int k = Nvar;
517  loop
518  {
519    int k1 = var[k];
520    if (o[k1] < n[k1])
521    {
522      i++;
523      if (i < j)
524      {
525        o = stc[i];
526        k = Nvar;
527      }
528      else
529      {
530        j++;
531        if (j < Nstc)
532        {
533          i = 0;
534          o = stc[0];
535          n = stc[j];
536          k = Nvar;
537        }
538        else
539          return;
540      }
541    }
542    else if (o[k1] > n[k1])
543    {
544      int tmp_k;
545      for (tmp_k = j; tmp_k > i; tmp_k--)
546        stc[tmp_k] = stc[tmp_k - 1];
547      stc[i] = n;
548      j++;
549      if (j < Nstc)
550      {
551        i = 0;
552        o = stc[0];
553        n = stc[j];
554        k = Nvar;
555      }
556      else
557        return;
558    }
559    else
560    {
561      k--;
562      if (k<=0) return;
563    }
564  }
565}
566
567
568void hLexR(scfmon rad, int Nrad, varset var, int Nvar)
569{
570  int  j = 1, i = 0, k, k1;
571  scmon n, o;
572  if (Nrad < 2)
573    return;
574  n = rad[j];
575  o = rad[0];
576  k = Nvar;
577  loop
578  {
579    k1 = var[k];
580    if (!o[k1] && n[k1])
581    {
582      i++;
583      if (i < j)
584      {
585        o = rad[i];
586        k = Nvar;
587      }
588      else
589      {
590        j++;
591        if (j < Nrad)
592        {
593          i = 0;
594          o = rad[0];
595          n = rad[j];
596          k = Nvar;
597        }
598        else
599          return;
600      }
601    }
602    else if (o[k1] && !n[k1])
603    {
604      for (k = j; k > i; k--)
605        rad[k] = rad[k - 1];
606      rad[i] = n;
607      j++;
608      if (j < Nrad)
609      {
610        i = 0;
611        o = rad[0];
612        n = rad[j];
613        k = Nvar;
614      }
615      else
616        return;
617    }
618    else
619      k--;
620  }
621}
622
623
624void hPure(scfmon stc, int a, int *Nstc, varset var, int Nvar,
625 scmon pure, int *Npure)
626{
627  int  nc = *Nstc, np = 0, nq = 0, j, i, i1, c, l;
628  scmon x;
629  for (j = a; j < nc; j++)
630  {
631    x = stc[j];
632    i = Nvar;
633    c = 2;
634    l = 0;
635    loop
636    {
637      i1 = var[i];
638      if (x[i1])
639      {
640        c--;
641        if (!c)
642        {
643          l = 0;
644          break;
645        }
646        else if (c == 1)
647          l = i1;
648      }
649      i--;
650      if (!i)
651        break;
652    }
653    if (l)
654    {
655      if (!pure[l])
656      {
657        np++;
658        pure[l] = x[l];
659      }
660      else if (x[l] < pure[l])
661        pure[l] = x[l];
662      stc[j] = NULL;
663      nq++;
664    }
665  }
666  *Npure = np;
667  if (nq!=0)
668  {
669    *Nstc -= nq;
670    hShrink(stc, a, nc);
671  }
672}
673
674
675void hElimS(scfmon stc, int *e1, int a2, int e2, varset var, int Nvar)
676{
677  int  nc = *e1, z = 0, i, j, k, k1;
678  scmon n, o;
679  if (!nc || (a2 == e2))
680    return;
681  j = 0;
682  i = a2;
683  o = stc[i];
684  n = stc[0];
685  k = Nvar;
686  loop
687  {
688    k1 = var[k];
689    if (o[k1] > n[k1])
690    {
691      k = Nvar;
692      i++;
693      if (i < e2)
694        o = stc[i];
695      else
696      {
697        j++;
698        if (j < nc)
699        {
700          i = a2;
701          o = stc[i];
702          n = stc[j];
703        }
704        else
705        {
706          if (z!=0)
707          {
708            *e1 -= z;
709            hShrink(stc, 0, nc);
710          }
711          return;
712        }
713      }
714    }
715    else
716    {
717      k--;
718      if (k==0)
719      {
720        stc[j] = NULL;
721        z++;
722        j++;
723        if (j < nc)
724        {
725          i = a2;
726          o = stc[i];
727          n = stc[j];
728          k = Nvar;
729        }
730        else
731        {
732          if (z!=0)
733          {
734            *e1 -= z;
735            hShrink(stc, 0, nc);
736          }
737          return;
738        }
739      }
740    }
741  }
742}
743
744
745void hElimR(scfmon rad, int *e1, int a2, int e2, varset var, int Nvar)
746{
747  int  nc = *e1, z = 0, i, j, k, k1;
748  scmon n, o;
749  if (!nc || (a2 == e2))
750    return;
751  j = 0;
752  i = a2;
753  o = rad[i];
754  n = rad[0];
755  k = Nvar;
756  loop
757  {
758    k1 = var[k];
759    if (o[k1] && !n[k1])
760    {
761      k = Nvar;
762      i++;
763      if (i < e2)
764        o = rad[i];
765      else
766      {
767        j++;
768        if (j < nc)
769        {
770          i = a2;
771          o = rad[i];
772          n = rad[j];
773        }
774        else
775        {
776          if (z!=0)
777          {
778            *e1 -= z;
779            hShrink(rad, 0, nc);
780          }
781          return;
782        }
783      }
784    }
785    else
786    {
787      k--;
788      if (!k)
789      {
790        rad[j] = NULL;
791        z++;
792        j++;
793        if (j < nc)
794        {
795          i = a2;
796          o = rad[i];
797          n = rad[j];
798          k = Nvar;
799        }
800        else
801        {
802          if (z!=0)
803          {
804            *e1 -= z;
805            hShrink(rad, 0, nc);
806          }
807          return;
808        }
809      }
810    }
811  }
812}
813
814
815void hLex2S(scfmon rad, int e1, int a2, int e2, varset var,
816 int Nvar, scfmon w)
817{
818  int  j0 = 0, j = 0, i = a2, k, k1;
819  scmon n, o;
820  if (!e1)
821  {
822    for (; i < e2; i++)
823      rad[i - a2] = rad[i];
824    return;
825  }  else if (i == e2)
826    return;
827  n = rad[j];
828  o = rad[i];
829  loop
830  {
831    k = Nvar;
832    loop
833    {
834      k1 = var[k];
835      if (o[k1] < n[k1])
836      {
837        w[j0] = o;
838        j0++;
839        i++;
840        if (i < e2)
841        {
842          o = rad[i];
843          break;
844        }
845        else
846        {
847          for (; j < e1; j++)
848          {
849            w[j0] = rad[j];
850            j0++;
851          }
852          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
853          return;
854        }
855      }
856      else if (o[k1] > n[k1])
857      {
858        w[j0] = n;
859        j0++;
860        j++;
861        if (j < e1)
862        {
863          n = rad[j];
864          break;
865        }
866        else
867        {
868          for (; i < e2; i++)
869          {
870            w[j0] = rad[i];
871            j0++;
872          }
873          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
874          return;
875        }
876      }
877      k--;
878    }
879  }
880}
881
882
883void hLex2R(scfmon rad, int e1, int a2, int e2, varset var,
884 int Nvar, scfmon w)
885{
886  int  j0 = 0, j = 0, i = a2, k, k1;
887  scmon n, o;
888  if (!e1)
889  {
890    for (; i < e2; i++)
891      rad[i - a2] = rad[i];
892    return;
893  }
894  else if (i == e2)
895    return;
896  n = rad[j];
897  o = rad[i];
898  loop
899  {
900    k = Nvar;
901    loop
902    {
903      k1 = var[k];
904      if (!o[k1] && n[k1])
905      {
906        w[j0] = o;
907        j0++;
908        i++;
909        if (i < e2)
910        {
911          o = rad[i];
912          break;
913        }
914        else
915        {
916          for (; j < e1; j++)
917          {
918            w[j0] = rad[j];
919            j0++;
920          }
921          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
922          return;
923        }
924      }
925      else if (o[k1] && !n[k1])
926      {
927        w[j0] = n;
928        j0++;
929        j++;
930        if (j < e1)
931        {
932          n = rad[j];
933          break;
934        }
935        else
936        {
937          for (; i < e2; i++)
938          {
939            w[j0] = rad[i];
940            j0++;
941          }
942          memcpy(rad, w, (e1 + e2 - a2) * sizeof(scmon));
943          return;
944        }
945      }
946      k--;
947    }
948  }
949}
950
951
952void hStepS(scfmon stc, int Nstc, varset var, int Nvar, int *a, int *x)
953{
954  int  k1, i;
955  int  y;
956  k1 = var[Nvar];
957  y = *x;
958  i = *a;
959  loop
960  {
961    if (y < stc[i][k1])
962    {
963      *a = i;
964      *x = stc[i][k1];
965      return;
966    }
967    i++;
968    if (i == Nstc)
969    {
970      *a = i;
971      return;
972    }
973  }
974}
975
976
977void hStepR(scfmon rad, int Nrad, varset var, int Nvar, int *a)
978{
979  int  k1, i;
980  k1 = var[Nvar];
981  i = 0;
982  loop
983  {
984    if (rad[i][k1])
985    {
986      *a = i;
987      return;
988    }
989    i++;
990    if (i == Nrad)
991    {
992      *a = i;
993      return;
994    }
995  }
996}
997
998
999monf hCreate(int Nvar)
1000{
1001  monf xmem;
1002  int  i;
1003  xmem = (monf)omAlloc((Nvar + 1) * sizeof(monp));
1004  for (i = Nvar; i>0; i--)
1005  {
1006    xmem[i] = (monp)omAlloc(LEN_MON);
1007    xmem[i]->mo = NULL;
1008  }
1009  return xmem;
1010}
1011
1012
1013void hKill(monf xmem, int Nvar)
1014{
1015  int  i;
1016  for (i = Nvar; i!=0; i--)
1017  {
1018    if (xmem[i]->mo!=NULL)
1019      omFreeSize((ADDRESS)xmem[i]->mo, xmem[i]->a * sizeof(scmon));
1020    omFreeSize((ADDRESS)xmem[i], LEN_MON);
1021  }
1022  omFreeSize((ADDRESS)xmem, (Nvar + 1) * sizeof(monp));
1023}
1024
1025
1026scfmon hGetmem(int lm, scfmon old, monp monmem)
1027{
1028  scfmon x = monmem->mo;
1029  int  lx = monmem->a;
1030  if ((x==NULL) || (lm > lx))
1031  {
1032    /* according to http://www.singular.uni-kl.de:8002/trac/ticket/463#comment:4
1033     * we need to work around a compiler bug:
1034    * if ((x!=NULL)&&(lx>0)) omFreeSize((ADDRESS)x, lx * sizeof(scmon));
1035    */
1036    if (x!=NULL) if (lx>0) omFreeSize((ADDRESS)x, lx * sizeof(scmon));
1037    monmem->mo = x = (scfmon)omAlloc(lm * sizeof(scmon));
1038    monmem->a = lm;
1039  }
1040  memcpy(x, old, lm * sizeof(scmon));
1041  return x;
1042}
1043
1044/*
1045* a bug in Metrowerks with "lifetime analysis"
1046*scmon hGetpure(scmon p)
1047*{
1048*  scmon p1, pn;
1049*  p1 = p + 1;
1050*  pn = p1 + (currRing->N);
1051*  memcpy(pn, p1, (currRing->N) * sizeof(int));
1052*  return pn - 1;
1053*}
1054*/
1055scmon hGetpure(scmon p)
1056{
1057  scmon p1 = p;
1058  scmon pn;
1059  p1++;
1060  pn = p1;
1061  pn += (currRing->N);
1062  memcpy(pn, p1, (currRing->N) * sizeof(int));
1063  return pn - 1;
1064}
1065
Note: See TracBrowser for help on using the repository browser.