source: git/libpolys/polys/simpleideals.cc @ bf7dfc

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