source: git/kernel/hutil.cc @ a82c308

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