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

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