source: git/libpolys/polys/simpleideals.cc @ 600f62

spielwiese
Last change on this file since 600f62 was 16f511, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Fixed the usage of "config.h" (if defined HAVE_CONFIG_H)
  • Property mode set to 100644
File size: 36.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT - all basic methods to manipulate ideals
6*/
7
8
9/* includes */
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif /* HAVE_CONFIG_H */
13#include <misc/auxiliary.h>
14
15#include <omalloc/omalloc.h>
16
17#include <misc/options.h>
18#include <misc/intvec.h>
19
20// #include <coeffs/longrat.h>
21#include "matpol.h"
22
23#include "monomials/p_polys.h"
24#include "weight.h"
25#include "sbuckets.h"
26#include "clapsing.h"
27
28#include "simpleideals.h"
29
30omBin sip_sideal_bin = omGetSpecBin(sizeof(sip_sideal));
31
32static poly * idpower;
33/*collects the monomials in makemonoms, must be allocated befor*/
34static int idpowerpoint;
35/*index of the actual monomial in idpower*/
36static poly * givenideal;
37/*the ideal from which a power is computed*/
38
39/*2
40* initialise an ideal
41*/
42ideal idInit(int idsize, int rank)
43{
44  /*- initialise an ideal -*/
45  ideal hh = (ideal )omAllocBin(sip_sideal_bin);
46  hh->nrows = 1;
47  hh->rank = rank;
48  IDELEMS(hh) = idsize;
49  if (idsize>0)
50  {
51    hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
52  }
53  else
54    hh->m=NULL;
55  return hh;
56}
57
58#ifdef PDEBUG
59// this is only for outputting an ideal within the debugger
60void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
61{
62  assume( debugPrint >= 0 );
63
64  if( id == NULL )
65    PrintS("(NULL)");
66  else
67  {
68    Print("Module of rank %ld,real rank %ld and %d generators.\n",
69          id->rank,id_RankFreeModule(id, lmRing, tailRing),IDELEMS(id));
70
71    int j = (id->ncols*id->nrows) - 1;
72    while ((j > 0) && (id->m[j]==NULL)) j--;
73    for (int i = 0; i <= j; i++)
74    {
75      Print("generator %d: ",i); p_DebugPrint(id->m[i], lmRing, tailRing, debugPrint);
76    }
77  }
78}
79#endif
80
81/// index of generator with leading term in ground ring (if any);
82/// otherwise -1
83int id_PosConstant(ideal id, const ring r)
84{
85  id_Test(id, r);
86  const int N = IDELEMS(id) - 1; 
87  const poly * m = id->m + N; 
88 
89  for (int k = N; k >= 0; --k, --m)
90  {
91    const poly p = *m;
92    if (p!=NULL)
93       if (p_LmIsConstantComp(p, r) == TRUE)
94         return k;
95  }
96   
97  return -1;
98}
99
100/*2
101* initialise the maximal ideal (at 0)
102*/
103ideal id_MaxIdeal (const ring r)
104{
105  int l;
106  ideal hh=NULL;
107
108  hh=idInit(rVar(r),1);
109  for (l=0; l<rVar(r); l++)
110  {
111    hh->m[l] = p_One(r);
112    p_SetExp(hh->m[l],l+1,1,r);
113    p_Setm(hh->m[l],r);
114  }
115  return hh;
116}
117
118/*2
119* deletes an ideal/matrix
120*/
121void id_Delete (ideal * h, ring r)
122{
123  int j,elems;
124  if (*h == NULL)
125    return;
126  elems=j=(*h)->nrows*(*h)->ncols;
127  if (j>0)
128  {
129    do
130    {
131      j--;
132      poly pp=((*h)->m[j]);
133      if (pp!=NULL) p_Delete(&pp, r);
134    }
135    while (j>0);
136    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
137  }
138  omFreeBin((ADDRESS)*h, sip_sideal_bin);
139  *h=NULL;
140}
141
142
143/*2
144* Shallowdeletes an ideal/matrix
145*/
146void id_ShallowDelete (ideal *h, ring r)
147{
148  int j,elems;
149  if (*h == NULL)
150    return;
151  elems=j=(*h)->nrows*(*h)->ncols;
152  if (j>0)
153  {
154    do
155    {
156      p_ShallowDelete(&((*h)->m[--j]), r);
157    }
158    while (j>0);
159    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
160  }
161  omFreeBin((ADDRESS)*h, sip_sideal_bin);
162  *h=NULL;
163}
164
165/*2
166*gives an ideal the minimal possible size
167*/
168void idSkipZeroes (ideal ide)
169{
170  int k;
171  int j = -1;
172  BOOLEAN change=FALSE;
173  for (k=0; k<IDELEMS(ide); k++)
174  {
175    if (ide->m[k] != NULL)
176    {
177      j++;
178      if (change)
179      {
180        ide->m[j] = ide->m[k];
181      }
182    }
183    else
184    {
185      change=TRUE;
186    }
187  }
188  if (change)
189  {
190    if (j == -1)
191      j = 0;
192    else
193    {
194      for (k=j+1; k<IDELEMS(ide); k++)
195        ide->m[k] = NULL;
196    }
197    pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
198    IDELEMS(ide) = j+1;
199  }
200}
201
202int idElem(const ideal F)
203{
204  int i=0,j=IDELEMS(F)-1;
205
206  while(j>=0)
207  {
208    if ((F->m)[j]!=NULL) i++;
209    j--;
210  }
211  return i;
212}
213
214/*2
215* copies the first k (>= 1) entries of the given ideal
216* and returns these as a new ideal
217* (Note that the copied polynomials may be zero.)
218*/
219ideal id_CopyFirstK (const ideal ide, const int k,const ring r)
220{
221  ideal newI = idInit(k, 0);
222  for (int i = 0; i < k; i++)
223    newI->m[i] = p_Copy(ide->m[i],r);
224  return newI;
225}
226
227/*2
228* ideal id = (id[i])
229* result is leadcoeff(id[i]) = 1
230*/
231void id_Norm(ideal id, const ring r)
232{
233  for (int i=IDELEMS(id)-1; i>=0; i--)
234  {
235    if (id->m[i] != NULL)
236    {
237      p_Norm(id->m[i],r);
238    }
239  }
240}
241
242/*2
243* ideal id = (id[i]), c any unit
244* if id[i] = c*id[j] then id[j] is deleted for j > i
245*/
246void id_DelMultiples(ideal id, const ring r)
247{
248  int i, j;
249  int k = IDELEMS(id)-1;
250  for (i=k; i>=0; i--)
251  {
252    if (id->m[i]!=NULL)
253    {
254      for (j=k; j>i; j--)
255      {
256        if (id->m[j]!=NULL)
257        {
258#ifdef HAVE_RINGS
259          if (rField_is_Ring(r))
260          {
261            /* if id[j] = c*id[i] then delete id[j].
262               In the below cases of a ground field, we
263               check whether id[i] = c*id[j] and, if so,
264               delete id[j] for historical reasons (so
265               that previous output does not change) */
266            if (p_ComparePolys(id->m[j], id->m[i],r)) p_Delete(&id->m[j],r);
267          }
268          else
269          {
270            if (p_ComparePolys(id->m[i], id->m[j],r)) p_Delete(&id->m[j],r);
271          }
272#else
273          if (p_ComparePolys(id->m[i], id->m[j],r)) p_Delete(&id->m[j],r);
274#endif
275        }
276      }
277    }
278  }
279}
280
281/*2
282* ideal id = (id[i])
283* if id[i] = id[j] then id[j] is deleted for j > i
284*/
285void id_DelEquals(ideal id, const ring r)
286{
287  int i, j;
288  int k = IDELEMS(id)-1;
289  for (i=k; i>=0; i--)
290  {
291    if (id->m[i]!=NULL)
292    {
293      for (j=k; j>i; j--)
294      {
295        if ((id->m[j]!=NULL)
296        && (p_EqualPolys(id->m[i], id->m[j],r)))
297        {
298          p_Delete(&id->m[j],r);
299        }
300      }
301    }
302  }
303}
304
305//
306// Delete id[j], if Lm(j) == Lm(i) and both LC(j), LC(i) are units and j > i
307//
308void id_DelLmEquals(ideal id, const ring r)
309{
310  int i, j;
311  int k = IDELEMS(id)-1;
312  for (i=k; i>=0; i--)
313  {
314    if (id->m[i] != NULL)
315    {
316      for (j=k; j>i; j--)
317      {
318        if ((id->m[j] != NULL)
319        && p_LmEqual(id->m[i], id->m[j],r)
320#ifdef HAVE_RINGS
321        && n_IsUnit(pGetCoeff(id->m[i]),r->cf) && n_IsUnit(pGetCoeff(id->m[j]),r->cf)
322#endif
323        )
324        {
325          p_Delete(&id->m[j],r);
326        }
327      }
328    }
329  }
330}
331
332//
333// delete id[j], if LT(j) == coeff*mon*LT(i) and vice versa, i.e.,
334// delete id[i], if LT(i) == coeff*mon*LT(j)
335//
336void id_DelDiv(ideal id, const ring r)
337{
338  int i, j;
339  int k = IDELEMS(id)-1;
340  for (i=k; i>=0; i--)
341  {
342    if (id->m[i] != NULL)
343    {
344      for (j=k; j>i; j--)
345      {
346        if (id->m[j]!=NULL)
347        {
348#ifdef HAVE_RINGS
349          if (rField_is_Ring(r))
350          {
351            if (p_DivisibleByRingCase(id->m[i], id->m[j],r))
352            {
353              p_Delete(&id->m[j],r);
354            }
355            else if (p_DivisibleByRingCase(id->m[j], id->m[i],r))
356            {
357              p_Delete(&id->m[i],r);
358              break;
359            }
360          }
361          else
362          {
363#endif
364          /* the case of a ground field: */
365          if (p_DivisibleBy(id->m[i], id->m[j],r))
366          {
367            p_Delete(&id->m[j],r);
368          }
369          else if (p_DivisibleBy(id->m[j], id->m[i],r))
370          {
371            p_Delete(&id->m[i],r);
372            break;
373          }
374#ifdef HAVE_RINGS
375          }
376#endif
377        }
378      }
379    }
380  }
381}
382
383/*2
384*test if the ideal has only constant polynomials
385*/
386BOOLEAN id_IsConstant(ideal id, const ring r)
387{
388  int k;
389  for (k = IDELEMS(id)-1; k>=0; k--)
390  {
391    if (!p_IsConstantPoly(id->m[k],r))
392      return FALSE;
393  }
394  return TRUE;
395}
396
397/*2
398* copy an ideal
399*/
400ideal id_Copy(ideal h1, const ring r)
401{
402  int i;
403  ideal h2;
404
405//#ifdef TEST
406  if (h1 == NULL)
407  {
408    h2=idInit(1,1);
409  }
410  else
411//#endif
412  {
413    h2=idInit(IDELEMS(h1),h1->rank);
414    for (i=IDELEMS(h1)-1; i>=0; i--)
415      h2->m[i] = p_Copy(h1->m[i],r);
416  }
417  return h2;
418}
419
420#ifdef PDEBUG
421void id_DBTest(ideal h1, int level, const char *f,const int l, const ring r)
422{
423  int i;
424
425  if (h1 != NULL)
426  {
427    // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
428    omCheckAddrSize(h1,sizeof(*h1));
429    omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
430    /* to be able to test matrices: */
431    for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
432      _p_Test(h1->m[i], r, level);
433    int new_rk=id_RankFreeModule(h1,r);
434    if(new_rk > h1->rank)
435    {
436      dReportError("wrong rank %d (should be %d) in %s:%d\n",
437                   h1->rank, new_rk, f,l);
438      omPrintAddrInfo(stderr, h1, " for ideal");
439      h1->rank=new_rk;
440    }
441  }
442}
443#endif
444
445///3 for idSort: compare a and b revlex inclusive module comp.
446static int p_Comp_RevLex(poly a, poly b,BOOLEAN nolex, const ring R)
447{
448  if (b==NULL) return 1;
449  if (a==NULL) return -1;
450
451  if (nolex)
452  {
453    int r=p_LmCmp(a,b,R);
454    if (r!=0) return r;
455    number h=n_Sub(pGetCoeff(a),pGetCoeff(b),R->cf);
456    r = -1+n_IsZero(h,R->cf)+2*n_GreaterZero(h,R->cf); /* -1: <, 0:==, 1: > */
457    n_Delete(&h, R->cf);
458    return r;
459  }
460  int l=rVar(R);
461  while ((l>0) && (p_GetExp(a,l,R)==p_GetExp(b,l,R))) l--;
462  if (l==0)
463  {
464    if (p_GetComp(a,R)==p_GetComp(b,R))
465    {
466      number h=n_Sub(pGetCoeff(a),pGetCoeff(b),R->cf);
467      int r = -1+n_IsZero(h,R->cf)+2*n_GreaterZero(h,R->cf); /* -1: <, 0:==, 1: > */
468      n_Delete(&h,R->cf);
469      return r;
470    }
471    if (p_GetComp(a,R)>p_GetComp(b,R)) return 1;
472  }
473  else if (p_GetExp(a,l,R)>p_GetExp(b,l,R))
474    return 1;
475  return -1;
476}
477
478// sorts the ideal w.r.t. the actual ringordering
479// uses lex-ordering when nolex = FALSE
480intvec *id_Sort(const ideal id, const BOOLEAN nolex, const ring r)
481{
482  intvec * result = new intvec(IDELEMS(id));
483  int i, j, actpos=0, newpos;
484  int diff, olddiff, lastcomp, newcomp;
485  BOOLEAN notFound;
486
487  for (i=0;i<IDELEMS(id);i++)
488  {
489    if (id->m[i]!=NULL)
490    {
491      notFound = TRUE;
492      newpos = actpos / 2;
493      diff = (actpos+1) / 2;
494      diff = (diff+1) / 2;
495      lastcomp = p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r);
496      if (lastcomp<0)
497      {
498        newpos -= diff;
499      }
500      else if (lastcomp>0)
501      {
502        newpos += diff;
503      }
504      else
505      {
506        notFound = FALSE;
507      }
508      //while ((newpos>=0) && (newpos<actpos) && (notFound))
509      while (notFound && (newpos>=0) && (newpos<actpos))
510      {
511        newcomp = p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r);
512        olddiff = diff;
513        if (diff>1)
514        {
515          diff = (diff+1) / 2;
516          if ((newcomp==1)
517          && (actpos-newpos>1)
518          && (diff>1)
519          && (newpos+diff>=actpos))
520          {
521            diff = actpos-newpos-1;
522          }
523          else if ((newcomp==-1)
524          && (diff>1)
525          && (newpos<diff))
526          {
527            diff = newpos;
528          }
529        }
530        if (newcomp<0)
531        {
532          if ((olddiff==1) && (lastcomp>0))
533            notFound = FALSE;
534          else
535            newpos -= diff;
536        }
537        else if (newcomp>0)
538        {
539          if ((olddiff==1) && (lastcomp<0))
540          {
541            notFound = FALSE;
542            newpos++;
543          }
544          else
545          {
546            newpos += diff;
547          }
548        }
549        else
550        {
551          notFound = FALSE;
552        }
553        lastcomp = newcomp;
554        if (diff==0) notFound=FALSE; /*hs*/
555      }
556      if (newpos<0) newpos = 0;
557      if (newpos>actpos) newpos = actpos;
558      while ((newpos<actpos) && (p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r)==0))
559        newpos++;
560      for (j=actpos;j>newpos;j--)
561      {
562        (*result)[j] = (*result)[j-1];
563      }
564      (*result)[newpos] = i;
565      actpos++;
566    }
567  }
568  for (j=0;j<actpos;j++) (*result)[j]++;
569  return result;
570}
571
572/*2
573* concat the lists h1 and h2 without zeros
574*/
575ideal id_SimpleAdd (ideal h1,ideal h2, const ring R)
576{
577  int i,j,r,l;
578  ideal result;
579
580  if (h1==NULL) return id_Copy(h2,R);
581  if (h2==NULL) return id_Copy(h1,R);
582  j = IDELEMS(h1)-1;
583  while ((j >= 0) && (h1->m[j] == NULL)) j--;
584  i = IDELEMS(h2)-1;
585  while ((i >= 0) && (h2->m[i] == NULL)) i--;
586  r = si_max(h1->rank,h2->rank);
587  if (i+j==(-2))
588    return idInit(1,r);
589  else
590    result=idInit(i+j+2,r);
591  for (l=j; l>=0; l--)
592  {
593    result->m[l] = p_Copy(h1->m[l],R);
594  }
595  r = i+j+1;
596  for (l=i; l>=0; l--, r--)
597  {
598    result->m[r] = p_Copy(h2->m[l],R);
599  }
600  return result;
601}
602
603/*2
604* insert h2 into h1 (if h2 is not the zero polynomial)
605* return TRUE iff h2 was indeed inserted
606*/
607BOOLEAN idInsertPoly (ideal h1, poly h2)
608{
609  if (h2==NULL) return FALSE;
610  int j = IDELEMS(h1)-1;
611  while ((j >= 0) && (h1->m[j] == NULL)) j--;
612  j++;
613  if (j==IDELEMS(h1))
614  {
615    pEnlargeSet(&(h1->m),IDELEMS(h1),16);
616    IDELEMS(h1)+=16;
617  }
618  h1->m[j]=h2;
619  return TRUE;
620}
621
622/*2
623* insert h2 into h1 depending on the two boolean parameters:
624* - if zeroOk is true, then h2 will also be inserted when it is zero
625* - if duplicateOk is true, then h2 will also be inserted when it is
626*   already present in h1
627* return TRUE iff h2 was indeed inserted
628*/
629BOOLEAN id_InsertPolyWithTests (ideal h1, const int validEntries,
630  const poly h2, const bool zeroOk, const bool duplicateOk, const ring r)
631{
632  if ((!zeroOk) && (h2 == NULL)) return FALSE;
633  if (!duplicateOk)
634  {
635    bool h2FoundInH1 = false;
636    int i = 0;
637    while ((i < validEntries) && (!h2FoundInH1))
638    {
639      h2FoundInH1 = p_EqualPolys(h1->m[i], h2,r);
640      i++;
641    }
642    if (h2FoundInH1) return FALSE;
643  }
644  if (validEntries == IDELEMS(h1))
645  {
646    pEnlargeSet(&(h1->m), IDELEMS(h1), 16);
647    IDELEMS(h1) += 16;
648  }
649  h1->m[validEntries] = h2;
650  return TRUE;
651}
652
653/*2
654* h1 + h2
655*/
656ideal id_Add (ideal h1,ideal h2, const ring r)
657{
658  ideal result = id_SimpleAdd(h1,h2,r);
659  id_Compactify(result,r);
660  return result;
661}
662
663/*2
664* h1 * h2
665*/
666ideal  id_Mult (ideal h1,ideal  h2, const ring r)
667{
668  int i,j,k;
669  ideal  hh;
670
671  j = IDELEMS(h1);
672  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
673  i = IDELEMS(h2);
674  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
675  j = j * i;
676  if (j == 0)
677    hh = idInit(1,1);
678  else
679    hh=idInit(j,1);
680  if (h1->rank<h2->rank)
681    hh->rank = h2->rank;
682  else
683    hh->rank = h1->rank;
684  if (j==0) return hh;
685  k = 0;
686  for (i=0; i<IDELEMS(h1); i++)
687  {
688    if (h1->m[i] != NULL)
689    {
690      for (j=0; j<IDELEMS(h2); j++)
691      {
692        if (h2->m[j] != NULL)
693        {
694          hh->m[k] = pp_Mult_qq(h1->m[i],h2->m[j],r);
695          k++;
696        }
697      }
698    }
699  }
700  {
701    id_Compactify(hh,r);
702    return hh;
703  }
704}
705
706/*2
707*returns true if h is the zero ideal
708*/
709BOOLEAN idIs0 (ideal h)
710{
711  int i;
712
713  if (h == NULL) return TRUE;
714  i = IDELEMS(h)-1;
715  while ((i >= 0) && (h->m[i] == NULL))
716  {
717    i--;
718  }
719  if (i < 0)
720    return TRUE;
721  else
722    return FALSE;
723}
724
725/*2
726* return the maximal component number found in any polynomial in s
727*/
728long id_RankFreeModule (ideal s, ring lmRing, ring tailRing)
729{
730  if (s!=NULL)
731  {
732    long  j=0;
733
734    if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
735    {
736      poly *p=s->m;
737      for (unsigned int l=IDELEMS(s); l != 0; --l, ++p)
738      {
739        if (*p!=NULL)
740        {
741          pp_Test(*p, lmRing, tailRing);
742          const long k = p_MaxComp(*p, lmRing, tailRing);
743          if (k>j) j = k;
744        }
745      }
746    }
747    return j;
748  }
749  return -1;
750}
751
752BOOLEAN idIsModule(ideal id, ring r)
753{
754  if (id != NULL && rRing_has_Comp(r))
755  {
756    int j, l = IDELEMS(id);
757    for (j=0; j<l; j++)
758    {
759      if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0) return TRUE;
760    }
761  }
762  return FALSE;
763}
764
765
766/*2
767*returns true if id is homogenous with respect to the aktual weights
768*/
769BOOLEAN id_HomIdeal (ideal id, ideal Q, const ring r)
770{
771  int i;
772  BOOLEAN     b;
773  if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
774  i = 0;
775  b = TRUE;
776  while ((i < IDELEMS(id)) && b)
777  {
778    b = p_IsHomogeneous(id->m[i],r);
779    i++;
780  }
781  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
782  {
783    i=0;
784    while ((i < IDELEMS(Q)) && b)
785    {
786      b = p_IsHomogeneous(Q->m[i],r);
787      i++;
788    }
789  }
790  return b;
791}
792
793/*2
794*initialized a field with r numbers between beg and end for the
795*procedure idNextChoise
796*/
797void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
798{
799  /*returns the first choise of r numbers between beg and end*/
800  int i;
801  for (i=0; i<r; i++)
802  {
803    choise[i] = 0;
804  }
805  if (r <= end-beg+1)
806    for (i=0; i<r; i++)
807    {
808      choise[i] = beg+i;
809    }
810  if (r > end-beg+1)
811    *endch = TRUE;
812  else
813    *endch = FALSE;
814}
815
816/*2
817*returns the next choise of r numbers between beg and end
818*/
819void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
820{
821  int i = r-1,j;
822  while ((i >= 0) && (choise[i] == end))
823  {
824    i--;
825    end--;
826  }
827  if (i == -1)
828    *endch = TRUE;
829  else
830  {
831    choise[i]++;
832    for (j=i+1; j<r; j++)
833    {
834      choise[j] = choise[i]+j-i;
835    }
836    *endch = FALSE;
837  }
838}
839
840/*2
841*takes the field choise of d numbers between beg and end, cancels the t-th
842*entree and searches for the ordinal number of that d-1 dimensional field
843* w.r.t. the algorithm of construction
844*/
845int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
846{
847  int * localchoise,i,result=0;
848  BOOLEAN b=FALSE;
849
850  if (d<=1) return 1;
851  localchoise=(int*)omAlloc((d-1)*sizeof(int));
852  idInitChoise(d-1,begin,end,&b,localchoise);
853  while (!b)
854  {
855    result++;
856    i = 0;
857    while ((i<t) && (localchoise[i]==choise[i])) i++;
858    if (i>=t)
859    {
860      i = t+1;
861      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
862      if (i>=d)
863      {
864        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
865        return result;
866      }
867    }
868    idGetNextChoise(d-1,end,&b,localchoise);
869  }
870  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
871  return 0;
872}
873
874/*2
875*computes the binomial coefficient
876*/
877int binom (int n,int r)
878{
879  int i,result;
880
881  if (r==0) return 1;
882  if (n-r<r) return binom(n,n-r);
883  result = n-r+1;
884  for (i=2;i<=r;i++)
885  {
886    result *= n-r+i;
887    if (result<0)
888    {
889      WarnS("overflow in binomials");
890      return 0;
891    }
892    result /= i;
893  }
894  return result;
895}
896
897/*2
898*the free module of rank i
899*/
900ideal id_FreeModule (int i, const ring r)
901{
902  int j;
903  ideal h;
904
905  h=idInit(i,i);
906  for (j=0; j<i; j++)
907  {
908    h->m[j] = p_One(r);
909    p_SetComp(h->m[j],j+1,r);
910    p_SetmComp(h->m[j],r);
911  }
912  return h;
913}
914
915/*2
916*computes recursively all monomials of a certain degree
917*in every step the actvar-th entry in the exponential
918*vector is incremented and the other variables are
919*computed by recursive calls of makemonoms
920*if the last variable is reached, the difference to the
921*degree is computed directly
922*vars is the number variables
923*actvar is the actual variable to handle
924*deg is the degree of the monomials to compute
925*monomdeg is the actual degree of the monomial in consideration
926*/
927static void makemonoms(int vars,int actvar,int deg,int monomdeg, const ring r)
928{
929  poly p;
930  int i=0;
931
932  if ((idpowerpoint == 0) && (actvar ==1))
933  {
934    idpower[idpowerpoint] = p_One(r);
935    monomdeg = 0;
936  }
937  while (i<=deg)
938  {
939    if (deg == monomdeg)
940    {
941      p_Setm(idpower[idpowerpoint],r);
942      idpowerpoint++;
943      return;
944    }
945    if (actvar == vars)
946    {
947      p_SetExp(idpower[idpowerpoint],actvar,deg-monomdeg,r);
948      p_Setm(idpower[idpowerpoint],r);
949      p_Test(idpower[idpowerpoint],r);
950      idpowerpoint++;
951      return;
952    }
953    else
954    {
955      p = p_Copy(idpower[idpowerpoint],r);
956      makemonoms(vars,actvar+1,deg,monomdeg,r);
957      idpower[idpowerpoint] = p;
958    }
959    monomdeg++;
960    p_SetExp(idpower[idpowerpoint],actvar,p_GetExp(idpower[idpowerpoint],actvar,r)+1,r);
961    p_Setm(idpower[idpowerpoint],r);
962    p_Test(idpower[idpowerpoint],r);
963    i++;
964  }
965}
966
967/*2
968*returns the deg-th power of the maximal ideal of 0
969*/
970ideal id_MaxIdeal(int deg, const ring r)
971{
972  if (deg < 0)
973  {
974    WarnS("maxideal: power must be non-negative");
975  }
976  if (deg < 1)
977  {
978    ideal I=idInit(1,1);
979    I->m[0]=p_One(r);
980    return I;
981  }
982  if (deg == 1)
983  {
984    return id_MaxIdeal(r);
985  }
986
987  int vars = rVar(r);
988  int i = binom(vars+deg-1,deg);
989  if (i<=0) return idInit(1,1);
990  ideal id=idInit(i,1);
991  idpower = id->m;
992  idpowerpoint = 0;
993  makemonoms(vars,1,deg,0,r);
994  idpower = NULL;
995  idpowerpoint = 0;
996  return id;
997}
998
999/*2
1000*computes recursively all generators of a certain degree
1001*of the ideal "givenideal"
1002*elms is the number elements in the given ideal
1003*actelm is the actual element to handle
1004*deg is the degree of the power to compute
1005*gendeg is the actual degree of the generator in consideration
1006*/
1007static void makepotence(int elms,int actelm,int deg,int gendeg, const ring r)
1008{
1009  poly p;
1010  int i=0;
1011
1012  if ((idpowerpoint == 0) && (actelm ==1))
1013  {
1014    idpower[idpowerpoint] = p_One(r);
1015    gendeg = 0;
1016  }
1017  while (i<=deg)
1018  {
1019    if (deg == gendeg)
1020    {
1021      idpowerpoint++;
1022      return;
1023    }
1024    if (actelm == elms)
1025    {
1026      p=p_Power(p_Copy(givenideal[actelm-1],r),deg-gendeg,r);
1027      idpower[idpowerpoint]=p_Mult_q(idpower[idpowerpoint],p,r);
1028      idpowerpoint++;
1029      return;
1030    }
1031    else
1032    {
1033      p = p_Copy(idpower[idpowerpoint],r);
1034      makepotence(elms,actelm+1,deg,gendeg,r);
1035      idpower[idpowerpoint] = p;
1036    }
1037    gendeg++;
1038    idpower[idpowerpoint]=p_Mult_q(idpower[idpowerpoint],p_Copy(givenideal[actelm-1],r),r);
1039    i++;
1040  }
1041}
1042
1043/*2
1044*returns the deg-th power of the ideal gid
1045*/
1046//ideal idPower(ideal gid,int deg)
1047//{
1048//  int i;
1049//  ideal id;
1050//
1051//  if (deg < 1) deg = 1;
1052//  i = binom(IDELEMS(gid)+deg-1,deg);
1053//  id=idInit(i,1);
1054//  idpower = id->m;
1055//  givenideal = gid->m;
1056//  idpowerpoint = 0;
1057//  makepotence(IDELEMS(gid),1,deg,0);
1058//  idpower = NULL;
1059//  givenideal = NULL;
1060//  idpowerpoint = 0;
1061//  return id;
1062//}
1063static void id_NextPotence(ideal given, ideal result,
1064  int begin, int end, int deg, int restdeg, poly ap, const ring r)
1065{
1066  poly p;
1067  int i;
1068
1069  p = p_Power(p_Copy(given->m[begin],r),restdeg,r);
1070  i = result->nrows;
1071  result->m[i] = p_Mult_q(p_Copy(ap,r),p,r);
1072//PrintS(".");
1073  (result->nrows)++;
1074  if (result->nrows >= IDELEMS(result))
1075  {
1076    pEnlargeSet(&(result->m),IDELEMS(result),16);
1077    IDELEMS(result) += 16;
1078  }
1079  if (begin == end) return;
1080  for (i=restdeg-1;i>0;i--)
1081  {
1082    p = p_Power(p_Copy(given->m[begin],r),i,r);
1083    p = p_Mult_q(p_Copy(ap,r),p,r);
1084    id_NextPotence(given, result, begin+1, end, deg, restdeg-i, p,r);
1085    p_Delete(&p,r);
1086  }
1087  id_NextPotence(given, result, begin+1, end, deg, restdeg, ap,r);
1088}
1089
1090ideal id_Power(ideal given,int exp, const ring r)
1091{
1092  ideal result,temp;
1093  poly p1;
1094  int i;
1095
1096  if (idIs0(given)) return idInit(1,1);
1097  temp = id_Copy(given,r);
1098  idSkipZeroes(temp);
1099  i = binom(IDELEMS(temp)+exp-1,exp);
1100  result = idInit(i,1);
1101  result->nrows = 0;
1102//Print("ideal contains %d elements\n",i);
1103  p1=p_One(r);
1104  id_NextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1,r);
1105  p_Delete(&p1,r);
1106  id_Delete(&temp,r);
1107  result->nrows = 1;
1108  id_DelEquals(result,r);
1109  idSkipZeroes(result);
1110  return result;
1111}
1112
1113/*2
1114*skips all zeroes and double elements, searches also for units
1115*/
1116void id_Compactify(ideal id, const ring r)
1117{
1118  int i;
1119  BOOLEAN b=FALSE;
1120
1121  i = IDELEMS(id)-1;
1122  while ((! b) && (i>=0))
1123  {
1124    b=p_IsUnit(id->m[i],r);
1125    i--;
1126  }
1127  if (b)
1128  {
1129    for(i=IDELEMS(id)-1;i>=0;i--) p_Delete(&id->m[i],r);
1130    id->m[0]=p_One(r);
1131  }
1132  else
1133  {
1134    id_DelMultiples(id,r);
1135  }
1136  idSkipZeroes(id);
1137}
1138
1139/*2
1140* returns the ideals of initial terms
1141*/
1142ideal id_Head(ideal h,const ring r)
1143{
1144  ideal m = idInit(IDELEMS(h),h->rank);
1145  int i;
1146
1147  for (i=IDELEMS(h)-1;i>=0; i--)
1148  {
1149    if (h->m[i]!=NULL) m->m[i]=p_Head(h->m[i],r);
1150  }
1151  return m;
1152}
1153
1154ideal id_Homogen(ideal h, int varnum,const ring r)
1155{
1156  ideal m = idInit(IDELEMS(h),h->rank);
1157  int i;
1158
1159  for (i=IDELEMS(h)-1;i>=0; i--)
1160  {
1161    m->m[i]=p_Homogen(h->m[i],varnum,r);
1162  }
1163  return m;
1164}
1165
1166/*------------------type conversions----------------*/
1167ideal id_Vec2Ideal(poly vec, const ring R)
1168{
1169   ideal result=idInit(1,1);
1170   omFree((ADDRESS)result->m);
1171   result->m=NULL; // remove later
1172   p_Vec2Polys(vec, &(result->m), &(IDELEMS(result)),R);
1173   return result;
1174}
1175
1176
1177// converts mat to module, destroys mat
1178ideal id_Matrix2Module(matrix mat, const ring R)
1179{
1180  int mc=MATCOLS(mat);
1181  int mr=MATROWS(mat);
1182  ideal result = idInit(si_max(mc,1),si_max(mr,1));
1183  int i,j,l;
1184  poly h;
1185  sBucket_pt bucket = sBucketCreate(R);
1186
1187  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
1188  {
1189    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
1190    {
1191      h = MATELEM(mat,i,j+1);
1192      if (h!=NULL)
1193      {
1194        l=pLength(h);
1195        MATELEM(mat,i,j+1)=NULL;
1196        p_SetCompP(h,i, R);
1197        sBucket_Merge_p(bucket, h, l);
1198      }
1199    }
1200    sBucketClearMerge(bucket, &(result->m[j]), &l);
1201  }
1202  sBucketDestroy(&bucket);
1203
1204  // obachman: need to clean this up
1205  id_Delete((ideal*) &mat,R);
1206  return result;
1207}
1208
1209/*2
1210* converts a module into a matrix, destroyes the input
1211*/
1212matrix id_Module2Matrix(ideal mod, const ring R)
1213{
1214  matrix result = mpNew(mod->rank,IDELEMS(mod));
1215  long i; long cp;
1216  poly p,h;
1217
1218  for(i=0;i<IDELEMS(mod);i++)
1219  {
1220    p=pReverse(mod->m[i]);
1221    mod->m[i]=NULL;
1222    while (p!=NULL)
1223    {
1224      h=p;
1225      pIter(p);
1226      pNext(h)=NULL;
1227      cp = si_max((long)1,p_GetComp(h, R));     // if used for ideals too
1228      //cp = p_GetComp(h,R);
1229      p_SetComp(h,0,R);
1230      p_SetmComp(h,R);
1231#ifdef TEST
1232      if (cp>mod->rank)
1233      {
1234        Print("## inv. rank %ld -> %ld\n",mod->rank,cp);
1235        int k,l,o=mod->rank;
1236        mod->rank=cp;
1237        matrix d=mpNew(mod->rank,IDELEMS(mod));
1238        for (l=1; l<=o; l++)
1239        {
1240          for (k=1; k<=IDELEMS(mod); k++)
1241          {
1242            MATELEM(d,l,k)=MATELEM(result,l,k);
1243            MATELEM(result,l,k)=NULL;
1244          }
1245        }
1246        id_Delete((ideal *)&result,R);
1247        result=d;
1248      }
1249#endif
1250      MATELEM(result,cp,i+1) = p_Add_q(MATELEM(result,cp,i+1),h,R);
1251    }
1252  }
1253  // obachman 10/99: added the following line, otherwise memory leack!
1254  id_Delete(&mod,R);
1255  return result;
1256}
1257
1258matrix id_Module2formatedMatrix(ideal mod,int rows, int cols, const ring R)
1259{
1260  matrix result = mpNew(rows,cols);
1261  int i,cp,r=id_RankFreeModule(mod,R),c=IDELEMS(mod);
1262  poly p,h;
1263
1264  if (r>rows) r = rows;
1265  if (c>cols) c = cols;
1266  for(i=0;i<c;i++)
1267  {
1268    p=pReverse(mod->m[i]);
1269    mod->m[i]=NULL;
1270    while (p!=NULL)
1271    {
1272      h=p;
1273      pIter(p);
1274      pNext(h)=NULL;
1275      cp = p_GetComp(h,R);
1276      if (cp<=r)
1277      {
1278        p_SetComp(h,0,R);
1279        p_SetmComp(h,R);
1280        MATELEM(result,cp,i+1) = p_Add_q(MATELEM(result,cp,i+1),h,R);
1281      }
1282      else
1283        p_Delete(&h,R);
1284    }
1285  }
1286  id_Delete(&mod,R);
1287  return result;
1288}
1289
1290/*2
1291* substitute the n-th variable by the monomial e in id
1292* destroy id
1293*/
1294ideal  id_Subst(ideal id, int n, poly e, const ring r)
1295{
1296  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
1297  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
1298
1299  res->rank = id->rank;
1300  for(k--;k>=0;k--)
1301  {
1302    res->m[k]=p_Subst(id->m[k],n,e,r);
1303    id->m[k]=NULL;
1304  }
1305  id_Delete(&id,r);
1306  return res;
1307}
1308
1309BOOLEAN id_HomModule(ideal m, ideal Q, intvec **w, const ring R)
1310{
1311  if (w!=NULL) *w=NULL;
1312  if ((Q!=NULL) && (!id_HomIdeal(Q,NULL,R))) return FALSE;
1313  if (idIs0(m))
1314  {
1315    if (w!=NULL) (*w)=new intvec(m->rank);
1316    return TRUE;
1317  }
1318
1319  long cmax=1,order=0,ord,* diff,diffmin=32000;
1320  int *iscom;
1321  int i;
1322  poly p=NULL;
1323  pFDegProc d;
1324  if (R->pLexOrder && (R->order[0]==ringorder_lp))
1325     d=p_Totaldegree;
1326  else
1327     d=R->pFDeg;
1328  int length=IDELEMS(m);
1329  poly* P=m->m;
1330  poly* F=(poly*)omAlloc(length*sizeof(poly));
1331  for (i=length-1;i>=0;i--)
1332  {
1333    p=F[i]=P[i];
1334    cmax=si_max(cmax,(long)p_MaxComp(p,R));
1335  }
1336  cmax++;
1337  diff = (long *)omAlloc0(cmax*sizeof(long));
1338  if (w!=NULL) *w=new intvec(cmax-1);
1339  iscom = (int *)omAlloc0(cmax*sizeof(int));
1340  i=0;
1341  while (i<=length)
1342  {
1343    if (i<length)
1344    {
1345      p=F[i];
1346      while ((p!=NULL) && (iscom[p_GetComp(p,R)]==0)) pIter(p);
1347    }
1348    if ((p==NULL) && (i<length))
1349    {
1350      i++;
1351    }
1352    else
1353    {
1354      if (p==NULL) /* && (i==length) */
1355      {
1356        i=0;
1357        while ((i<length) && (F[i]==NULL)) i++;
1358        if (i>=length) break;
1359        p = F[i];
1360      }
1361      //if (pLexOrder && (currRing->order[0]==ringorder_lp))
1362      //  order=pTotaldegree(p);
1363      //else
1364      //  order = p->order;
1365      //  order = pFDeg(p,currRing);
1366      order = d(p,R) +diff[p_GetComp(p,R)];
1367      //order += diff[pGetComp(p)];
1368      p = F[i];
1369//Print("Actual p=F[%d]: ",i);pWrite(p);
1370      F[i] = NULL;
1371      i=0;
1372    }
1373    while (p!=NULL)
1374    {
1375      if (R->pLexOrder && (R->order[0]==ringorder_lp))
1376        ord=p_Totaldegree(p,R);
1377      else
1378      //  ord = p->order;
1379        ord = R->pFDeg(p,R);
1380      if (iscom[p_GetComp(p,R)]==0)
1381      {
1382        diff[p_GetComp(p,R)] = order-ord;
1383        iscom[p_GetComp(p,R)] = 1;
1384/*
1385*PrintS("new diff: ");
1386*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
1387*PrintLn();
1388*PrintS("new iscom: ");
1389*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
1390*PrintLn();
1391*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
1392*/
1393      }
1394      else
1395      {
1396/*
1397*PrintS("new diff: ");
1398*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
1399*PrintLn();
1400*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
1401*/
1402        if (order != (ord+diff[p_GetComp(p,R)]))
1403        {
1404          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
1405          omFreeSize((ADDRESS) diff,cmax*sizeof(long));
1406          omFreeSize((ADDRESS) F,length*sizeof(poly));
1407          delete *w;*w=NULL;
1408          return FALSE;
1409        }
1410      }
1411      pIter(p);
1412    }
1413  }
1414  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
1415  omFreeSize((ADDRESS) F,length*sizeof(poly));
1416  for (i=1;i<cmax;i++) (**w)[i-1]=(int)(diff[i]);
1417  for (i=1;i<cmax;i++)
1418  {
1419    if (diff[i]<diffmin) diffmin=diff[i];
1420  }
1421  if (w!=NULL)
1422  {
1423    for (i=1;i<cmax;i++)
1424    {
1425      (**w)[i-1]=(int)(diff[i]-diffmin);
1426    }
1427  }
1428  omFreeSize((ADDRESS) diff,cmax*sizeof(long));
1429  return TRUE;
1430}
1431
1432ideal id_Jet(ideal i,int d, const ring R)
1433{
1434  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
1435  r->nrows = i-> nrows;
1436  r->ncols = i-> ncols;
1437  //r->rank = i-> rank;
1438  int k;
1439  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
1440  {
1441    r->m[k]=pp_Jet(i->m[k],d,R);
1442  }
1443  return r;
1444}
1445
1446ideal id_JetW(ideal i,int d, intvec * iv, const ring R)
1447{
1448  ideal r=idInit(IDELEMS(i),i->rank);
1449  if (ecartWeights!=NULL)
1450  {
1451    WerrorS("cannot compute weighted jets now");
1452  }
1453  else
1454  {
1455    short *w=iv2array(iv,R);
1456    int k;
1457    for(k=0; k<IDELEMS(i); k++)
1458    {
1459      r->m[k]=pp_JetW(i->m[k],d,w,R);
1460    }
1461    omFreeSize((ADDRESS)w,(rVar(R)+1)*sizeof(short));
1462  }
1463  return r;
1464}
1465
1466/*3
1467* searches for the next unit in the components of the module arg and
1468* returns the first one;
1469*/
1470int id_ReadOutPivot(ideal arg,int* comp, const ring r)
1471{
1472  if (idIs0(arg)) return -1;
1473  int i=0,j, generator=-1;
1474  int rk_arg=arg->rank; //idRankFreeModule(arg);
1475  int * componentIsUsed =(int *)omAlloc((rk_arg+1)*sizeof(int));
1476  poly p;
1477
1478  while ((generator<0) && (i<IDELEMS(arg)))
1479  {
1480    memset(componentIsUsed,0,(rk_arg+1)*sizeof(int));
1481    p = arg->m[i];
1482    while (p!=NULL)
1483    {
1484      j = p_GetComp(p,r);
1485      if (componentIsUsed[j]==0)
1486      {
1487#ifdef HAVE_RINGS
1488        if (p_LmIsConstantComp(p,r) &&
1489            (!rField_is_Ring(r) || n_IsUnit(pGetCoeff(p),r->cf)))
1490        {
1491#else
1492        if (p_LmIsConstantComp(p,r))
1493        {
1494#endif
1495          generator = i;
1496          componentIsUsed[j] = 1;
1497        }
1498        else
1499        {
1500          componentIsUsed[j] = -1;
1501        }
1502      }
1503      else if (componentIsUsed[j]>0)
1504      {
1505        (componentIsUsed[j])++;
1506      }
1507      pIter(p);
1508    }
1509    i++;
1510  }
1511  i = 0;
1512  *comp = -1;
1513  for (j=0;j<=rk_arg;j++)
1514  {
1515    if (componentIsUsed[j]>0)
1516    {
1517      if ((*comp==-1) || (componentIsUsed[j]<i))
1518      {
1519        *comp = j;
1520        i= componentIsUsed[j];
1521      }
1522    }
1523  }
1524  omFree(componentIsUsed);
1525  return generator;
1526}
1527
1528#if 0
1529static void idDeleteComp(ideal arg,int red_comp)
1530{
1531  int i,j;
1532  poly p;
1533
1534  for (i=IDELEMS(arg)-1;i>=0;i--)
1535  {
1536    p = arg->m[i];
1537    while (p!=NULL)
1538    {
1539      j = pGetComp(p);
1540      if (j>red_comp)
1541      {
1542        pSetComp(p,j-1);
1543        pSetm(p);
1544      }
1545      pIter(p);
1546    }
1547  }
1548  (arg->rank)--;
1549}
1550#endif
1551
1552intvec * id_QHomWeight(ideal id, const ring r)
1553{
1554  poly head, tail;
1555  int k;
1556  int in=IDELEMS(id)-1, ready=0, all=0,
1557      coldim=rVar(r), rowmax=2*coldim;
1558  if (in<0) return NULL;
1559  intvec *imat=new intvec(rowmax+1,coldim,0);
1560
1561  do
1562  {
1563    head = id->m[in--];
1564    if (head!=NULL)
1565    {
1566      tail = pNext(head);
1567      while (tail!=NULL)
1568      {
1569        all++;
1570        for (k=1;k<=coldim;k++)
1571          IMATELEM(*imat,all,k) = p_GetExpDiff(head,tail,k,r);
1572        if (all==rowmax)
1573        {
1574          ivTriangIntern(imat, ready, all);
1575          if (ready==coldim)
1576          {
1577            delete imat;
1578            return NULL;
1579          }
1580        }
1581        pIter(tail);
1582      }
1583    }
1584  } while (in>=0);
1585  if (all>ready)
1586  {
1587    ivTriangIntern(imat, ready, all);
1588    if (ready==coldim)
1589    {
1590      delete imat;
1591      return NULL;
1592    }
1593  }
1594  intvec *result = ivSolveKern(imat, ready);
1595  delete imat;
1596  return result;
1597}
1598
1599BOOLEAN id_IsZeroDim(ideal I, const ring r)
1600{
1601  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(rVar(r)*sizeof(BOOLEAN));
1602  int i,n;
1603  poly po;
1604  BOOLEAN res=TRUE;
1605  for(i=IDELEMS(I)-1;i>=0;i--)
1606  {
1607    po=I->m[i];
1608    if ((po!=NULL) &&((n=p_IsPurePower(po,r))!=0)) UsedAxis[n-1]=TRUE;
1609  }
1610  for(i=rVar(r)-1;i>=0;i--)
1611  {
1612    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
1613  }
1614  omFreeSize(UsedAxis,rVar(r)*sizeof(BOOLEAN));
1615  return res;
1616}
1617
1618void id_Normalize(ideal I,const ring r)
1619{
1620  if (rField_has_simple_inverse(r)) return; /* Z/p, GF(p,n), R, long R/C */
1621  int i;
1622  for(i=IDELEMS(I)-1;i>=0;i--)
1623  {
1624    p_Normalize(I->m[i],r);
1625  }
1626}
1627
1628int id_MinDegW(ideal M,intvec *w, const ring r)
1629{
1630  int d=-1;
1631  for(int i=0;i<IDELEMS(M);i++)
1632  {
1633    if (M->m[i]!=NULL)
1634    {
1635      int d0=p_MinDeg(M->m[i],w,r);
1636      if(-1<d0&&((d0<d)||(d==-1)))
1637        d=d0;
1638    }
1639  }
1640  return d;
1641}
1642
1643// #include <kernel/clapsing.h>
1644
1645/*2
1646* transpose a module
1647*/
1648ideal id_Transp(ideal a, const ring rRing)
1649{
1650  int r = a->rank, c = IDELEMS(a);
1651  ideal b =  idInit(r,c);
1652
1653  for (int i=c; i>0; i--)
1654  {
1655    poly p=a->m[i-1];
1656    while(p!=NULL)
1657    {
1658      poly h=p_Head(p, rRing);
1659      int co=p_GetComp(h, rRing)-1;
1660      p_SetComp(h, i, rRing);
1661      p_Setm(h, rRing);
1662      b->m[co] = p_Add_q(b->m[co], h, rRing);
1663      pIter(p);
1664    }
1665  }
1666  return b;
1667}
1668
1669
1670
1671/*2
1672* The following is needed to compute the image of certain map used in
1673* the computation of cohomologies via BGG
1674* let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
1675* assuming that nrows(M) <= m*n; the procedure computes:
1676* transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
1677* where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
1678* that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
1679
1680  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
1681*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
1682*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
1683+ =>
1684  f_i =
1685
1686   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
1687   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
1688                             ...
1689   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
1690
1691   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
1692*/
1693ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing)
1694{
1695// #ifdef DEBU
1696//  WarnS("tensorModuleMult!!!!");
1697
1698  assume(m > 0);
1699  assume(M != NULL);
1700
1701  const int n = rRing->N;
1702
1703  assume(M->rank <= m * n);
1704
1705  const int k = IDELEMS(M);
1706
1707  ideal idTemp =  idInit(k,m); // = {f_1, ..., f_k }
1708
1709  for( int i = 0; i < k; i++ ) // for every w \in M
1710  {
1711    poly pTempSum = NULL;
1712
1713    poly w = M->m[i];
1714
1715    while(w != NULL) // for each term of w...
1716    {
1717      poly h = p_Head(w, rRing);
1718
1719      const int  gen = p_GetComp(h, rRing); // 1 ...
1720
1721      assume(gen > 0);
1722      assume(gen <= n*m);
1723
1724      // TODO: write a formula with %, / instead of while!
1725      /*
1726      int c = gen;
1727      int v = 1;
1728      while(c > m)
1729      {
1730        c -= m;
1731        v++;
1732      }
1733      */
1734
1735      int cc = gen % m;
1736      if( cc == 0) cc = m;
1737      int vv = 1 + (gen - cc) / m;
1738
1739//      assume( cc == c );
1740//      assume( vv == v );
1741
1742      //  1<= c <= m
1743      assume( cc > 0 );
1744      assume( cc <= m );
1745
1746      assume( vv > 0 );
1747      assume( vv <= n );
1748
1749      assume( (cc + (vv-1)*m) == gen );
1750
1751      p_IncrExp(h, vv, rRing); // h *= var(j) && //      p_AddExp(h, vv, 1, rRing);
1752      p_SetComp(h, cc, rRing);
1753
1754      p_Setm(h, rRing);         // addjust degree after the previous steps!
1755
1756      pTempSum = p_Add_q(pTempSum, h, rRing); // it is slow since h will be usually put to the back of pTempSum!!!
1757
1758      pIter(w);
1759    }
1760
1761    idTemp->m[i] = pTempSum;
1762  }
1763
1764  // simplify idTemp???
1765
1766  ideal idResult = id_Transp(idTemp, rRing);
1767
1768  id_Delete(&idTemp, rRing);
1769
1770  return(idResult);
1771}
1772
1773ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring r)
1774{
1775  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
1776  ideal result=idInit(cnt,xx[0]->rank);
1777  result->nrows=xx[0]->nrows; // for lifting matrices
1778  result->ncols=xx[0]->ncols; // for lifting matrices
1779  int i,j;
1780  number *x=(number *)omAlloc(rl*sizeof(number));
1781  poly *p=(poly *)omAlloc(rl*sizeof(poly));
1782  for(i=cnt-1;i>=0;i--)
1783  {
1784    for(j=rl-1;j>=0;j--)
1785    {
1786      p[j]=xx[j]->m[i];
1787    }
1788    result->m[i]=p_ChineseRemainder(p,x,q,rl,r);
1789    for(j=rl-1;j>=0;j--)
1790    {
1791      xx[j]->m[i]=p[j];
1792    }
1793  }
1794  omFreeSize(p,rl*sizeof(poly));
1795  omFreeSize(x,rl*sizeof(number));
1796  for(i=rl-1;i>=0;i--) id_Delete(&(xx[i]),r);
1797  omFreeSize(xx,rl*sizeof(ideal));
1798  return result;
1799}
Note: See TracBrowser for help on using the repository browser.