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

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