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

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