source: git/libpolys/polys/simpleideals.cc @ 67e0dc

spielwiese
Last change on this file since 67e0dc was 67e0dc, checked in by Hans Schoenemann <hannes@…>, 8 years ago
Merge pull request #718 from adipopescu/STDChanes2 Std over rings
  • Property mode set to 100644
File size: 37.2 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#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) )
606  {
607    ideal res=id_Copy(h2,R);
608    if (res->rank<h1->rank) res->rank=h1->rank;
609    return res;
610  }
611  if ( idIs0(h2) )
612  {
613    ideal res=id_Copy(h1,R);
614    if (res->rank<h2->rank) res->rank=h2->rank;
615    return res;
616  }
617
618  int j = IDELEMS(h1)-1;
619  while ((j >= 0) && (h1->m[j] == NULL)) j--;
620
621  int i = IDELEMS(h2)-1;
622  while ((i >= 0) && (h2->m[i] == NULL)) i--;
623
624  const int r = si_max(h1->rank, h2->rank);
625
626  ideal result = idInit(i+j+2,r);
627
628  int l;
629
630  for (l=j; l>=0; l--)
631    result->m[l] = p_Copy(h1->m[l],R);
632
633  j = i+j+1;
634  for (l=i; l>=0; l--, j--)
635    result->m[j] = p_Copy(h2->m[l],R);
636
637  return result;
638}
639
640/// insert h2 into h1 (if h2 is not the zero polynomial)
641/// return TRUE iff h2 was indeed inserted
642BOOLEAN idInsertPoly (ideal h1, poly h2)
643{
644  if (h2==NULL) return FALSE;
645  assume (h1 != NULL);
646
647  int j = IDELEMS(h1) - 1;
648
649  while ((j >= 0) && (h1->m[j] == NULL)) j--;
650  j++;
651  if (j==IDELEMS(h1))
652  {
653    pEnlargeSet(&(h1->m),IDELEMS(h1),16);
654    IDELEMS(h1)+=16;
655  }
656  h1->m[j]=h2;
657  return TRUE;
658}
659
660
661/*! insert h2 into h1 depending on the two boolean parameters:
662 * - if zeroOk is true, then h2 will also be inserted when it is zero
663 * - if duplicateOk is true, then h2 will also be inserted when it is
664 *   already present in h1
665 * return TRUE iff h2 was indeed inserted
666 */
667BOOLEAN id_InsertPolyWithTests (ideal h1, const int validEntries,
668  const poly h2, const bool zeroOk, const bool duplicateOk, const ring r)
669{
670  id_Test(h1, r);
671  p_Test(h2, r);
672
673  if ((!zeroOk) && (h2 == NULL)) return FALSE;
674  if (!duplicateOk)
675  {
676    bool h2FoundInH1 = false;
677    int i = 0;
678    while ((i < validEntries) && (!h2FoundInH1))
679    {
680      h2FoundInH1 = p_EqualPolys(h1->m[i], h2,r);
681      i++;
682    }
683    if (h2FoundInH1) return FALSE;
684  }
685  if (validEntries == IDELEMS(h1))
686  {
687    pEnlargeSet(&(h1->m), IDELEMS(h1), 16);
688    IDELEMS(h1) += 16;
689  }
690  h1->m[validEntries] = h2;
691  return TRUE;
692}
693
694/// h1 + h2
695ideal id_Add (ideal h1,ideal h2, const ring r)
696{
697  id_Test(h1, r);
698  id_Test(h2, r);
699
700  ideal result = id_SimpleAdd(h1,h2,r);
701  id_Compactify(result,r);
702  return result;
703}
704
705/// h1 * h2
706/// one h_i must be an ideal (with at least one column)
707/// the other h_i may be a module (with no columns at all)
708ideal  id_Mult (ideal h1,ideal  h2, const ring R)
709{
710  id_Test(h1, R);
711  id_Test(h2, R);
712
713  int j = IDELEMS(h1);
714  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
715
716  int i = IDELEMS(h2);
717  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
718
719  j *= i;
720  int r = si_max( h2->rank, h1->rank );
721  if (j==0)
722  {
723    if ((IDELEMS(h1)>0) && (IDELEMS(h2)>0)) j=1;
724    return idInit(j, r);
725  }
726  ideal  hh = idInit(j, r);
727
728  int k = 0;
729  for (i=0; i<IDELEMS(h1); i++)
730  {
731    if (h1->m[i] != NULL)
732    {
733      for (j=0; j<IDELEMS(h2); j++)
734      {
735        if (h2->m[j] != NULL)
736        {
737          hh->m[k] = pp_Mult_qq(h1->m[i],h2->m[j],R);
738          k++;
739        }
740      }
741    }
742  }
743
744  id_Compactify(hh,R);
745  return hh;
746}
747
748/// returns true if h is the zero ideal
749BOOLEAN idIs0 (ideal h)
750{
751  assume (h != NULL); // will fail :(
752//  if (h == NULL) return TRUE;
753
754  for( int i = IDELEMS(h)-1; i >= 0; i-- )
755    if(h->m[i] != NULL)
756      return FALSE;
757
758  return TRUE;
759
760}
761
762/// return the maximal component number found in any polynomial in s
763long id_RankFreeModule (ideal s, ring lmRing, ring tailRing)
764{
765  id_TestTail(s, lmRing, tailRing);
766
767  long j = 0;
768
769  if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
770  {
771    poly *p=s->m;
772    for (unsigned int l=IDELEMS(s); l > 0; --l, ++p)
773      if (*p != NULL)
774      {
775        pp_Test(*p, lmRing, tailRing);
776        const long k = p_MaxComp(*p, lmRing, tailRing);
777        if (k>j) j = k;
778      }
779  }
780
781  return j; //  return -1;
782}
783
784/*2
785*returns true if id is homogenous with respect to the aktual weights
786*/
787BOOLEAN id_HomIdeal (ideal id, ideal Q, const ring r)
788{
789  int i;
790  BOOLEAN b;
791  i = 0;
792  b = TRUE;
793  while ((i < IDELEMS(id)) && b)
794  {
795    b = p_IsHomogeneous(id->m[i],r);
796    i++;
797  }
798  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
799  {
800    i=0;
801    while ((i < IDELEMS(Q)) && b)
802    {
803      b = p_IsHomogeneous(Q->m[i],r);
804      i++;
805    }
806  }
807  return b;
808}
809
810/*2
811*initialized a field with r numbers between beg and end for the
812*procedure idNextChoise
813*/
814void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
815{
816  /*returns the first choise of r numbers between beg and end*/
817  int i;
818  for (i=0; i<r; i++)
819  {
820    choise[i] = 0;
821  }
822  if (r <= end-beg+1)
823    for (i=0; i<r; i++)
824    {
825      choise[i] = beg+i;
826    }
827  if (r > end-beg+1)
828    *endch = TRUE;
829  else
830    *endch = FALSE;
831}
832
833/*2
834*returns the next choise of r numbers between beg and end
835*/
836void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
837{
838  int i = r-1,j;
839  while ((i >= 0) && (choise[i] == end))
840  {
841    i--;
842    end--;
843  }
844  if (i == -1)
845    *endch = TRUE;
846  else
847  {
848    choise[i]++;
849    for (j=i+1; j<r; j++)
850    {
851      choise[j] = choise[i]+j-i;
852    }
853    *endch = FALSE;
854  }
855}
856
857/*2
858*takes the field choise of d numbers between beg and end, cancels the t-th
859*entree and searches for the ordinal number of that d-1 dimensional field
860* w.r.t. the algorithm of construction
861*/
862int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
863{
864  int * localchoise,i,result=0;
865  BOOLEAN b=FALSE;
866
867  if (d<=1) return 1;
868  localchoise=(int*)omAlloc((d-1)*sizeof(int));
869  idInitChoise(d-1,begin,end,&b,localchoise);
870  while (!b)
871  {
872    result++;
873    i = 0;
874    while ((i<t) && (localchoise[i]==choise[i])) i++;
875    if (i>=t)
876    {
877      i = t+1;
878      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
879      if (i>=d)
880      {
881        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
882        return result;
883      }
884    }
885    idGetNextChoise(d-1,end,&b,localchoise);
886  }
887  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
888  return 0;
889}
890
891/*2
892*computes the binomial coefficient
893*/
894int binom (int n,int r)
895{
896  int i,result;
897
898  if (r==0) return 1;
899  if (n-r<r) return binom(n,n-r);
900  result = n-r+1;
901  for (i=2;i<=r;i++)
902  {
903    result *= n-r+i;
904    if (result<0)
905    {
906      WarnS("overflow in binomials");
907      return 0;
908    }
909    result /= i;
910  }
911  return result;
912}
913
914
915/// the free module of rank i
916ideal id_FreeModule (int i, const ring r)
917{
918  assume(i >= 0);
919  ideal h = idInit(i, i);
920
921  for (int j=0; j<i; j++)
922  {
923    h->m[j] = p_One(r);
924    p_SetComp(h->m[j],j+1,r);
925    p_SetmComp(h->m[j],r);
926  }
927
928  return h;
929}
930
931/*2
932*computes recursively all monomials of a certain degree
933*in every step the actvar-th entry in the exponential
934*vector is incremented and the other variables are
935*computed by recursive calls of makemonoms
936*if the last variable is reached, the difference to the
937*degree is computed directly
938*vars is the number variables
939*actvar is the actual variable to handle
940*deg is the degree of the monomials to compute
941*monomdeg is the actual degree of the monomial in consideration
942*/
943static void makemonoms(int vars,int actvar,int deg,int monomdeg, const ring r)
944{
945  poly p;
946  int i=0;
947
948  if ((idpowerpoint == 0) && (actvar ==1))
949  {
950    idpower[idpowerpoint] = p_One(r);
951    monomdeg = 0;
952  }
953  while (i<=deg)
954  {
955    if (deg == monomdeg)
956    {
957      p_Setm(idpower[idpowerpoint],r);
958      idpowerpoint++;
959      return;
960    }
961    if (actvar == vars)
962    {
963      p_SetExp(idpower[idpowerpoint],actvar,deg-monomdeg,r);
964      p_Setm(idpower[idpowerpoint],r);
965      p_Test(idpower[idpowerpoint],r);
966      idpowerpoint++;
967      return;
968    }
969    else
970    {
971      p = p_Copy(idpower[idpowerpoint],r);
972      makemonoms(vars,actvar+1,deg,monomdeg,r);
973      idpower[idpowerpoint] = p;
974    }
975    monomdeg++;
976    p_SetExp(idpower[idpowerpoint],actvar,p_GetExp(idpower[idpowerpoint],actvar,r)+1,r);
977    p_Setm(idpower[idpowerpoint],r);
978    p_Test(idpower[idpowerpoint],r);
979    i++;
980  }
981}
982
983/*2
984*returns the deg-th power of the maximal ideal of 0
985*/
986ideal id_MaxIdeal(int deg, const ring r)
987{
988  if (deg < 0)
989  {
990    WarnS("maxideal: power must be non-negative");
991  }
992  if (deg < 1)
993  {
994    ideal I=idInit(1,1);
995    I->m[0]=p_One(r);
996    return I;
997  }
998  if (deg == 1)
999  {
1000    return id_MaxIdeal(r);
1001  }
1002
1003  int vars = rVar(r);
1004  int i = binom(vars+deg-1,deg);
1005  if (i<=0) return idInit(1,1);
1006  ideal id=idInit(i,1);
1007  idpower = id->m;
1008  idpowerpoint = 0;
1009  makemonoms(vars,1,deg,0,r);
1010  idpower = NULL;
1011  idpowerpoint = 0;
1012  return id;
1013}
1014
1015static void id_NextPotence(ideal given, ideal result,
1016  int begin, int end, int deg, int restdeg, poly ap, const ring r)
1017{
1018  poly p;
1019  int i;
1020
1021  p = p_Power(p_Copy(given->m[begin],r),restdeg,r);
1022  i = result->nrows;
1023  result->m[i] = p_Mult_q(p_Copy(ap,r),p,r);
1024//PrintS(".");
1025  (result->nrows)++;
1026  if (result->nrows >= IDELEMS(result))
1027  {
1028    pEnlargeSet(&(result->m),IDELEMS(result),16);
1029    IDELEMS(result) += 16;
1030  }
1031  if (begin == end) return;
1032  for (i=restdeg-1;i>0;i--)
1033  {
1034    p = p_Power(p_Copy(given->m[begin],r),i,r);
1035    p = p_Mult_q(p_Copy(ap,r),p,r);
1036    id_NextPotence(given, result, begin+1, end, deg, restdeg-i, p,r);
1037    p_Delete(&p,r);
1038  }
1039  id_NextPotence(given, result, begin+1, end, deg, restdeg, ap,r);
1040}
1041
1042ideal id_Power(ideal given,int exp, const ring r)
1043{
1044  ideal result,temp;
1045  poly p1;
1046  int i;
1047
1048  if (idIs0(given)) return idInit(1,1);
1049  temp = id_Copy(given,r);
1050  idSkipZeroes(temp);
1051  i = binom(IDELEMS(temp)+exp-1,exp);
1052  result = idInit(i,1);
1053  result->nrows = 0;
1054//Print("ideal contains %d elements\n",i);
1055  p1=p_One(r);
1056  id_NextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1,r);
1057  p_Delete(&p1,r);
1058  id_Delete(&temp,r);
1059  result->nrows = 1;
1060  id_DelEquals(result,r);
1061  idSkipZeroes(result);
1062  return result;
1063}
1064
1065/*2
1066*skips all zeroes and double elements, searches also for units
1067*/
1068void id_Compactify(ideal id, const ring r)
1069{
1070  int i;
1071  BOOLEAN b=FALSE;
1072
1073  i = IDELEMS(id)-1;
1074  while ((! b) && (i>=0))
1075  {
1076    b=p_IsUnit(id->m[i],r);
1077    i--;
1078  }
1079  if (b)
1080  {
1081    for(i=IDELEMS(id)-1;i>=0;i--) p_Delete(&id->m[i],r);
1082    id->m[0]=p_One(r);
1083  }
1084  else
1085  {
1086    id_DelMultiples(id,r);
1087  }
1088  idSkipZeroes(id);
1089}
1090
1091/// returns the ideals of initial terms
1092ideal id_Head(ideal h,const ring r)
1093{
1094  ideal m = idInit(IDELEMS(h),h->rank);
1095
1096  for (int i=IDELEMS(h)-1;i>=0; i--)
1097    if (h->m[i]!=NULL)
1098      m->m[i]=p_Head(h->m[i],r);
1099
1100  return m;
1101}
1102
1103ideal id_Homogen(ideal h, int varnum,const ring r)
1104{
1105  ideal m = idInit(IDELEMS(h),h->rank);
1106  int i;
1107
1108  for (i=IDELEMS(h)-1;i>=0; i--)
1109  {
1110    m->m[i]=p_Homogen(h->m[i],varnum,r);
1111  }
1112  return m;
1113}
1114
1115/*------------------type conversions----------------*/
1116ideal id_Vec2Ideal(poly vec, const ring R)
1117{
1118   ideal result=idInit(1,1);
1119   omFree((ADDRESS)result->m);
1120   result->m=NULL; // remove later
1121   p_Vec2Polys(vec, &(result->m), &(IDELEMS(result)),R);
1122   return result;
1123}
1124
1125
1126// converts mat to module, destroys mat
1127ideal id_Matrix2Module(matrix mat, const ring R)
1128{
1129  int mc=MATCOLS(mat);
1130  int mr=MATROWS(mat);
1131  ideal result = idInit(mc,mr);
1132  int i,j,l;
1133  poly h;
1134  sBucket_pt bucket = sBucketCreate(R);
1135
1136  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
1137  {
1138    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
1139    {
1140      h = MATELEM(mat,i,j+1);
1141      if (h!=NULL)
1142      {
1143        l=pLength(h);
1144        MATELEM(mat,i,j+1)=NULL;
1145        p_SetCompP(h,i, R);
1146        sBucket_Merge_p(bucket, h, l);
1147      }
1148    }
1149    sBucketClearMerge(bucket, &(result->m[j]), &l);
1150  }
1151  sBucketDestroy(&bucket);
1152
1153  // obachman: need to clean this up
1154  id_Delete((ideal*) &mat,R);
1155  return result;
1156}
1157
1158/*2
1159* converts a module into a matrix, destroyes the input
1160*/
1161matrix id_Module2Matrix(ideal mod, const ring R)
1162{
1163  matrix result = mpNew(mod->rank,IDELEMS(mod));
1164  long i; long cp;
1165  poly p,h;
1166
1167  for(i=0;i<IDELEMS(mod);i++)
1168  {
1169    p=pReverse(mod->m[i]);
1170    mod->m[i]=NULL;
1171    while (p!=NULL)
1172    {
1173      h=p;
1174      pIter(p);
1175      pNext(h)=NULL;
1176      cp = si_max((long)1,p_GetComp(h, R));     // if used for ideals too
1177      //cp = p_GetComp(h,R);
1178      p_SetComp(h,0,R);
1179      p_SetmComp(h,R);
1180#ifdef TEST
1181      if (cp>mod->rank)
1182      {
1183        Print("## inv. rank %ld -> %ld\n",mod->rank,cp);
1184        int k,l,o=mod->rank;
1185        mod->rank=cp;
1186        matrix d=mpNew(mod->rank,IDELEMS(mod));
1187        for (l=1; l<=o; l++)
1188        {
1189          for (k=1; k<=IDELEMS(mod); k++)
1190          {
1191            MATELEM(d,l,k)=MATELEM(result,l,k);
1192            MATELEM(result,l,k)=NULL;
1193          }
1194        }
1195        id_Delete((ideal *)&result,R);
1196        result=d;
1197      }
1198#endif
1199      MATELEM(result,cp,i+1) = p_Add_q(MATELEM(result,cp,i+1),h,R);
1200    }
1201  }
1202  // obachman 10/99: added the following line, otherwise memory leack!
1203  id_Delete(&mod,R);
1204  return result;
1205}
1206
1207matrix id_Module2formatedMatrix(ideal mod,int rows, int cols, const ring R)
1208{
1209  matrix result = mpNew(rows,cols);
1210  int i,cp,r=id_RankFreeModule(mod,R),c=IDELEMS(mod);
1211  poly p,h;
1212
1213  if (r>rows) r = rows;
1214  if (c>cols) c = cols;
1215  for(i=0;i<c;i++)
1216  {
1217    p=pReverse(mod->m[i]);
1218    mod->m[i]=NULL;
1219    while (p!=NULL)
1220    {
1221      h=p;
1222      pIter(p);
1223      pNext(h)=NULL;
1224      cp = p_GetComp(h,R);
1225      if (cp<=r)
1226      {
1227        p_SetComp(h,0,R);
1228        p_SetmComp(h,R);
1229        MATELEM(result,cp,i+1) = p_Add_q(MATELEM(result,cp,i+1),h,R);
1230      }
1231      else
1232        p_Delete(&h,R);
1233    }
1234  }
1235  id_Delete(&mod,R);
1236  return result;
1237}
1238
1239/*2
1240* substitute the n-th variable by the monomial e in id
1241* destroy id
1242*/
1243ideal  id_Subst(ideal id, int n, poly e, const ring r)
1244{
1245  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
1246  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
1247
1248  res->rank = id->rank;
1249  for(k--;k>=0;k--)
1250  {
1251    res->m[k]=p_Subst(id->m[k],n,e,r);
1252    id->m[k]=NULL;
1253  }
1254  id_Delete(&id,r);
1255  return res;
1256}
1257
1258BOOLEAN id_HomModule(ideal m, ideal Q, intvec **w, const ring R)
1259{
1260  if (w!=NULL) *w=NULL;
1261  if ((Q!=NULL) && (!id_HomIdeal(Q,NULL,R))) return FALSE;
1262  if (idIs0(m))
1263  {
1264    if (w!=NULL) (*w)=new intvec(m->rank);
1265    return TRUE;
1266  }
1267
1268  long cmax=1,order=0,ord,* diff,diffmin=32000;
1269  int *iscom;
1270  int i;
1271  poly p=NULL;
1272  pFDegProc d;
1273  if (R->pLexOrder && (R->order[0]==ringorder_lp))
1274     d=p_Totaldegree;
1275  else
1276     d=R->pFDeg;
1277  int length=IDELEMS(m);
1278  poly* P=m->m;
1279  poly* F=(poly*)omAlloc(length*sizeof(poly));
1280  for (i=length-1;i>=0;i--)
1281  {
1282    p=F[i]=P[i];
1283    cmax=si_max(cmax,(long)p_MaxComp(p,R));
1284  }
1285  cmax++;
1286  diff = (long *)omAlloc0(cmax*sizeof(long));
1287  if (w!=NULL) *w=new intvec(cmax-1);
1288  iscom = (int *)omAlloc0(cmax*sizeof(int));
1289  i=0;
1290  while (i<=length)
1291  {
1292    if (i<length)
1293    {
1294      p=F[i];
1295      while ((p!=NULL) && (iscom[p_GetComp(p,R)]==0)) pIter(p);
1296    }
1297    if ((p==NULL) && (i<length))
1298    {
1299      i++;
1300    }
1301    else
1302    {
1303      if (p==NULL) /* && (i==length) */
1304      {
1305        i=0;
1306        while ((i<length) && (F[i]==NULL)) i++;
1307        if (i>=length) break;
1308        p = F[i];
1309      }
1310      //if (pLexOrder && (currRing->order[0]==ringorder_lp))
1311      //  order=pTotaldegree(p);
1312      //else
1313      //  order = p->order;
1314      //  order = pFDeg(p,currRing);
1315      order = d(p,R) +diff[p_GetComp(p,R)];
1316      //order += diff[pGetComp(p)];
1317      p = F[i];
1318//Print("Actual p=F[%d]: ",i);pWrite(p);
1319      F[i] = NULL;
1320      i=0;
1321    }
1322    while (p!=NULL)
1323    {
1324      if (R->pLexOrder && (R->order[0]==ringorder_lp))
1325        ord=p_Totaldegree(p,R);
1326      else
1327      //  ord = p->order;
1328        ord = R->pFDeg(p,R);
1329      if (iscom[p_GetComp(p,R)]==0)
1330      {
1331        diff[p_GetComp(p,R)] = order-ord;
1332        iscom[p_GetComp(p,R)] = 1;
1333/*
1334*PrintS("new diff: ");
1335*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
1336*PrintLn();
1337*PrintS("new iscom: ");
1338*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
1339*PrintLn();
1340*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
1341*/
1342      }
1343      else
1344      {
1345/*
1346*PrintS("new diff: ");
1347*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
1348*PrintLn();
1349*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
1350*/
1351        if (order != (ord+diff[p_GetComp(p,R)]))
1352        {
1353          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
1354          omFreeSize((ADDRESS) diff,cmax*sizeof(long));
1355          omFreeSize((ADDRESS) F,length*sizeof(poly));
1356          delete *w;*w=NULL;
1357          return FALSE;
1358        }
1359      }
1360      pIter(p);
1361    }
1362  }
1363  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
1364  omFreeSize((ADDRESS) F,length*sizeof(poly));
1365  for (i=1;i<cmax;i++) (**w)[i-1]=(int)(diff[i]);
1366  for (i=1;i<cmax;i++)
1367  {
1368    if (diff[i]<diffmin) diffmin=diff[i];
1369  }
1370  if (w!=NULL)
1371  {
1372    for (i=1;i<cmax;i++)
1373    {
1374      (**w)[i-1]=(int)(diff[i]-diffmin);
1375    }
1376  }
1377  omFreeSize((ADDRESS) diff,cmax*sizeof(long));
1378  return TRUE;
1379}
1380
1381ideal id_Jet(ideal i,int d, const ring R)
1382{
1383  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
1384  r->nrows = i-> nrows;
1385  r->ncols = i-> ncols;
1386  //r->rank = i-> rank;
1387
1388  for(int k=(i->nrows)*(i->ncols)-1;k>=0; k--)
1389    r->m[k]=pp_Jet(i->m[k],d,R);
1390
1391  return r;
1392}
1393
1394ideal id_JetW(ideal i,int d, intvec * iv, const ring R)
1395{
1396  ideal r=idInit(IDELEMS(i),i->rank);
1397  if (ecartWeights!=NULL)
1398  {
1399    WerrorS("cannot compute weighted jets now");
1400  }
1401  else
1402  {
1403    short *w=iv2array(iv,R);
1404    int k;
1405    for(k=0; k<IDELEMS(i); k++)
1406    {
1407      r->m[k]=pp_JetW(i->m[k],d,w,R);
1408    }
1409    omFreeSize((ADDRESS)w,(rVar(R)+1)*sizeof(short));
1410  }
1411  return r;
1412}
1413
1414/*3
1415* searches for the next unit in the components of the module arg and
1416* returns the first one;
1417*/
1418int id_ReadOutPivot(ideal arg,int* comp, const ring r)
1419{
1420  if (idIs0(arg)) return -1;
1421  int i=0,j, generator=-1;
1422  int rk_arg=arg->rank; //idRankFreeModule(arg);
1423  int * componentIsUsed =(int *)omAlloc((rk_arg+1)*sizeof(int));
1424  poly p;
1425
1426  while ((generator<0) && (i<IDELEMS(arg)))
1427  {
1428    memset(componentIsUsed,0,(rk_arg+1)*sizeof(int));
1429    p = arg->m[i];
1430    while (p!=NULL)
1431    {
1432      j = p_GetComp(p,r);
1433      if (componentIsUsed[j]==0)
1434      {
1435#ifdef HAVE_RINGS
1436        if (p_LmIsConstantComp(p,r) &&
1437            (!rField_is_Ring(r) || n_IsUnit(pGetCoeff(p),r->cf)))
1438        {
1439#else
1440        if (p_LmIsConstantComp(p,r))
1441        {
1442#endif
1443          generator = i;
1444          componentIsUsed[j] = 1;
1445        }
1446        else
1447        {
1448          componentIsUsed[j] = -1;
1449        }
1450      }
1451      else if (componentIsUsed[j]>0)
1452      {
1453        (componentIsUsed[j])++;
1454      }
1455      pIter(p);
1456    }
1457    i++;
1458  }
1459  i = 0;
1460  *comp = -1;
1461  for (j=0;j<=rk_arg;j++)
1462  {
1463    if (componentIsUsed[j]>0)
1464    {
1465      if ((*comp==-1) || (componentIsUsed[j]<i))
1466      {
1467        *comp = j;
1468        i= componentIsUsed[j];
1469      }
1470    }
1471  }
1472  omFree(componentIsUsed);
1473  return generator;
1474}
1475
1476#if 0
1477static void idDeleteComp(ideal arg,int red_comp)
1478{
1479  int i,j;
1480  poly p;
1481
1482  for (i=IDELEMS(arg)-1;i>=0;i--)
1483  {
1484    p = arg->m[i];
1485    while (p!=NULL)
1486    {
1487      j = pGetComp(p);
1488      if (j>red_comp)
1489      {
1490        pSetComp(p,j-1);
1491        pSetm(p);
1492      }
1493      pIter(p);
1494    }
1495  }
1496  (arg->rank)--;
1497}
1498#endif
1499
1500intvec * id_QHomWeight(ideal id, const ring r)
1501{
1502  poly head, tail;
1503  int k;
1504  int in=IDELEMS(id)-1, ready=0, all=0,
1505      coldim=rVar(r), rowmax=2*coldim;
1506  if (in<0) return NULL;
1507  intvec *imat=new intvec(rowmax+1,coldim,0);
1508
1509  do
1510  {
1511    head = id->m[in--];
1512    if (head!=NULL)
1513    {
1514      tail = pNext(head);
1515      while (tail!=NULL)
1516      {
1517        all++;
1518        for (k=1;k<=coldim;k++)
1519          IMATELEM(*imat,all,k) = p_GetExpDiff(head,tail,k,r);
1520        if (all==rowmax)
1521        {
1522          ivTriangIntern(imat, ready, all);
1523          if (ready==coldim)
1524          {
1525            delete imat;
1526            return NULL;
1527          }
1528        }
1529        pIter(tail);
1530      }
1531    }
1532  } while (in>=0);
1533  if (all>ready)
1534  {
1535    ivTriangIntern(imat, ready, all);
1536    if (ready==coldim)
1537    {
1538      delete imat;
1539      return NULL;
1540    }
1541  }
1542  intvec *result = ivSolveKern(imat, ready);
1543  delete imat;
1544  return result;
1545}
1546
1547BOOLEAN id_IsZeroDim(ideal I, const ring r)
1548{
1549  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(rVar(r)*sizeof(BOOLEAN));
1550  int i,n;
1551  poly po;
1552  BOOLEAN res=TRUE;
1553  for(i=IDELEMS(I)-1;i>=0;i--)
1554  {
1555    po=I->m[i];
1556    if ((po!=NULL) &&((n=p_IsPurePower(po,r))!=0)) UsedAxis[n-1]=TRUE;
1557  }
1558  for(i=rVar(r)-1;i>=0;i--)
1559  {
1560    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
1561  }
1562  omFreeSize(UsedAxis,rVar(r)*sizeof(BOOLEAN));
1563  return res;
1564}
1565
1566void id_Normalize(ideal I,const ring r) /* for ideal/matrix */
1567{
1568  if (rField_has_simple_inverse(r)) return; /* Z/p, GF(p,n), R, long R/C */
1569  int i;
1570  for(i=I->nrows*I->ncols-1;i>=0;i--)
1571  {
1572    p_Normalize(I->m[i],r);
1573  }
1574}
1575
1576int id_MinDegW(ideal M,intvec *w, const ring r)
1577{
1578  int d=-1;
1579  for(int i=0;i<IDELEMS(M);i++)
1580  {
1581    if (M->m[i]!=NULL)
1582    {
1583      int d0=p_MinDeg(M->m[i],w,r);
1584      if(-1<d0&&((d0<d)||(d==-1)))
1585        d=d0;
1586    }
1587  }
1588  return d;
1589}
1590
1591// #include <kernel/clapsing.h>
1592
1593/*2
1594* transpose a module
1595*/
1596ideal id_Transp(ideal a, const ring rRing)
1597{
1598  int r = a->rank, c = IDELEMS(a);
1599  ideal b =  idInit(r,c);
1600
1601  for (int i=c; i>0; i--)
1602  {
1603    poly p=a->m[i-1];
1604    while(p!=NULL)
1605    {
1606      poly h=p_Head(p, rRing);
1607      int co=p_GetComp(h, rRing)-1;
1608      p_SetComp(h, i, rRing);
1609      p_Setm(h, rRing);
1610      b->m[co] = p_Add_q(b->m[co], h, rRing);
1611      pIter(p);
1612    }
1613  }
1614  return b;
1615}
1616
1617
1618
1619/*2
1620* The following is needed to compute the image of certain map used in
1621* the computation of cohomologies via BGG
1622* let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
1623* assuming that nrows(M) <= m*n; the procedure computes:
1624* transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
1625* where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
1626* that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
1627
1628  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
1629*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
1630*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
1631+ =>
1632  f_i =
1633
1634   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
1635   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
1636                             ...
1637   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
1638
1639   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
1640*/
1641ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing)
1642{
1643// #ifdef DEBU
1644//  WarnS("tensorModuleMult!!!!");
1645
1646  assume(m > 0);
1647  assume(M != NULL);
1648
1649  const int n = rRing->N;
1650
1651  assume(M->rank <= m * n);
1652
1653  const int k = IDELEMS(M);
1654
1655  ideal idTemp =  idInit(k,m); // = {f_1, ..., f_k }
1656
1657  for( int i = 0; i < k; i++ ) // for every w \in M
1658  {
1659    poly pTempSum = NULL;
1660
1661    poly w = M->m[i];
1662
1663    while(w != NULL) // for each term of w...
1664    {
1665      poly h = p_Head(w, rRing);
1666
1667      const int  gen = p_GetComp(h, rRing); // 1 ...
1668
1669      assume(gen > 0);
1670      assume(gen <= n*m);
1671
1672      // TODO: write a formula with %, / instead of while!
1673      /*
1674      int c = gen;
1675      int v = 1;
1676      while(c > m)
1677      {
1678        c -= m;
1679        v++;
1680      }
1681      */
1682
1683      int cc = gen % m;
1684      if( cc == 0) cc = m;
1685      int vv = 1 + (gen - cc) / m;
1686
1687//      assume( cc == c );
1688//      assume( vv == v );
1689
1690      //  1<= c <= m
1691      assume( cc > 0 );
1692      assume( cc <= m );
1693
1694      assume( vv > 0 );
1695      assume( vv <= n );
1696
1697      assume( (cc + (vv-1)*m) == gen );
1698
1699      p_IncrExp(h, vv, rRing); // h *= var(j) && //      p_AddExp(h, vv, 1, rRing);
1700      p_SetComp(h, cc, rRing);
1701
1702      p_Setm(h, rRing);         // addjust degree after the previous steps!
1703
1704      pTempSum = p_Add_q(pTempSum, h, rRing); // it is slow since h will be usually put to the back of pTempSum!!!
1705
1706      pIter(w);
1707    }
1708
1709    idTemp->m[i] = pTempSum;
1710  }
1711
1712  // simplify idTemp???
1713
1714  ideal idResult = id_Transp(idTemp, rRing);
1715
1716  id_Delete(&idTemp, rRing);
1717
1718  return(idResult);
1719}
1720
1721ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring r)
1722{
1723  int cnt=0;int rw=0; int cl=0;
1724  int i,j;
1725  // find max. size of xx[.]:
1726  for(j=rl-1;j>=0;j--)
1727  {
1728    i=IDELEMS(xx[j])*xx[j]->nrows;
1729    if (i>cnt) cnt=i;
1730    if (xx[j]->nrows >rw) rw=xx[j]->nrows; // for lifting matrices
1731    if (xx[j]->ncols >cl) cl=xx[j]->ncols; // for lifting matrices
1732  }
1733  if (rw*cl !=cnt)
1734  {
1735    WerrorS("format mismatch in CRT");
1736    return NULL;
1737  }
1738  ideal result=idInit(cnt,xx[0]->rank);
1739  result->nrows=rw; // for lifting matrices
1740  result->ncols=cl; // for lifting matrices
1741  number *x=(number *)omAlloc(rl*sizeof(number));
1742  poly *p=(poly *)omAlloc(rl*sizeof(poly));
1743  CFArray inv_cache(rl);
1744  for(i=cnt-1;i>=0;i--)
1745  {
1746    for(j=rl-1;j>=0;j--)
1747    {
1748      if(i>=IDELEMS(xx[j])*xx[j]->nrows) // out of range of this ideal
1749        p[j]=NULL;
1750      else
1751        p[j]=xx[j]->m[i];
1752    }
1753    result->m[i]=p_ChineseRemainder(p,x,q,rl,inv_cache,r);
1754    for(j=rl-1;j>=0;j--)
1755    {
1756      if(i<IDELEMS(xx[j])*xx[j]->nrows) xx[j]->m[i]=p[j];
1757    }
1758  }
1759  omFreeSize(p,rl*sizeof(poly));
1760  omFreeSize(x,rl*sizeof(number));
1761  for(i=rl-1;i>=0;i--) id_Delete(&(xx[i]),r);
1762  omFreeSize(xx,rl*sizeof(ideal));
1763  return result;
1764}
1765
1766void id_Shift(ideal M, int s, const ring r)
1767{
1768//  id_Test( M, r );
1769
1770//  assume( s >= 0 ); // negative is also possible // TODO: verify input ideal in such a case!?
1771
1772  for(int i=IDELEMS(M)-1; i>=0;i--)
1773    p_Shift(&(M->m[i]),s,r);
1774
1775  M->rank += s;
1776
1777//  id_Test( M, r );
1778}
Note: See TracBrowser for help on using the repository browser.