source: git/libpolys/polys/simpleideals.cc @ 91a72f

spielwiese
Last change on this file since 91a72f was 91a72f, checked in by Hans Schoenemann <hannes@…>, 13 years ago
fix intvec *id_Sort(ideal id,BOOLEAN nolex, const ring r)
  • Property mode set to 100644
File size: 54.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT - all basic methods to manipulate ideals
7*/
8
9
10/* includes */
11#include "config.h"
12#include <misc/auxiliary.h>
13#include <misc/options.h>
14#include <omalloc/omalloc.h>
15#include <polys/monomials/p_polys.h>
16#include <misc/intvec.h>
17
18#include "simpleideals.h"
19
20/*2
21* initialise an ideal
22*/
23ideal idInit(int idsize, int rank)
24{
25  /*- initialise an ideal -*/
26  ideal hh = (ideal )omAllocBin(sip_sideal_bin);
27  hh->nrows = 1;
28  hh->rank = rank;
29  IDELEMS(hh) = idsize;
30  if (idsize>0)
31  {
32    hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
33  }
34  else
35    hh->m=NULL;
36  return hh;
37}
38
39#ifdef PDEBUG
40// this is only for outputting an ideal within the debugger
41void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
42{
43  assume( debugPrint >= 0 );
44
45  if( id == NULL )
46    PrintS("(NULL)");
47  else
48  {
49    Print("Module of rank %ld,real rank %ld and %d generators.\n",
50          id->rank,id_RankFreeModule(id, lmRing, tailRing),IDELEMS(id));
51
52    int j = (id->ncols*id->nrows) - 1;
53    while ((j > 0) && (id->m[j]==NULL)) j--;
54    for (int i = 0; i <= j; i++)
55    {
56      Print("generator %d: ",i); p_DebugPrint(id->m[i], lmRing, tailRing, debugPrint);
57    }
58  }
59}
60#endif
61
62/* index of generator with leading term in ground ring (if any);
63   otherwise -1 */
64int id_PosConstant(ideal id, const ring r)
65{
66  int k;
67  for (k = IDELEMS(id)-1; k>=0; k--)
68  {
69    if (p_LmIsConstantComp(id->m[k], r) == TRUE)
70      return k;
71  }
72  return -1;
73}
74
75/*2
76* initialise the maximal ideal (at 0)
77*/
78ideal id_MaxIdeal (const ring r)
79{
80  int l;
81  ideal hh=NULL;
82
83  hh=idInit(rVar(r),1);
84  for (l=0; l<rVar(r); l++)
85  {
86    hh->m[l] = p_One(r);
87    p_SetExp(hh->m[l],l+1,1,r);
88    p_Setm(hh->m[l],r);
89  }
90  return hh;
91}
92
93/*2
94* deletes an ideal/matrix
95*/
96void id_Delete (ideal * h, ring r)
97{
98  int j,elems;
99  if (*h == NULL)
100    return;
101  elems=j=(*h)->nrows*(*h)->ncols;
102  if (j>0)
103  {
104    do
105    {
106      p_Delete(&((*h)->m[--j]), r);
107    }
108    while (j>0);
109    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
110  }
111  omFreeBin((ADDRESS)*h, sip_sideal_bin);
112  *h=NULL;
113}
114
115
116/*2
117* Shallowdeletes an ideal/matrix
118*/
119void id_ShallowDelete (ideal *h, ring r)
120{
121  int j,elems;
122  if (*h == NULL)
123    return;
124  elems=j=(*h)->nrows*(*h)->ncols;
125  if (j>0)
126  {
127    do
128    {
129      p_ShallowDelete(&((*h)->m[--j]), r);
130    }
131    while (j>0);
132    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
133  }
134  omFreeBin((ADDRESS)*h, sip_sideal_bin);
135  *h=NULL;
136}
137
138/*2
139*gives an ideal the minimal possible size
140*/
141void idSkipZeroes (ideal ide)
142{
143  int k;
144  int j = -1;
145  BOOLEAN change=FALSE;
146  for (k=0; k<IDELEMS(ide); k++)
147  {
148    if (ide->m[k] != NULL)
149    {
150      j++;
151      if (change)
152      {
153        ide->m[j] = ide->m[k];
154      }
155    }
156    else
157    {
158      change=TRUE;
159    }
160  }
161  if (change)
162  {
163    if (j == -1)
164      j = 0;
165    else
166    {
167      for (k=j+1; k<IDELEMS(ide); k++)
168        ide->m[k] = NULL;
169    }
170    pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
171    IDELEMS(ide) = j+1;
172  }
173}
174
175/*2
176* copies the first k (>= 1) entries of the given ideal
177* and returns these as a new ideal
178* (Note that the copied polynomials may be zero.)
179*/
180ideal id_CopyFirstK (const ideal ide, const int k,const ring r)
181{
182  ideal newI = idInit(k, 0);
183  for (int i = 0; i < k; i++)
184    newI->m[i] = p_Copy(ide->m[i],r);
185  return newI;
186}
187
188/*2
189* ideal id = (id[i])
190* result is leadcoeff(id[i]) = 1
191*/
192void id_Norm(ideal id, const ring r)
193{
194  for (int i=IDELEMS(id)-1; i>=0; i--)
195  {
196    if (id->m[i] != NULL)
197    {
198      p_Norm(id->m[i],r);
199    }
200  }
201}
202
203/*2
204* ideal id = (id[i]), c any unit
205* if id[i] = c*id[j] then id[j] is deleted for j > i
206*/
207void id_DelMultiples(ideal id, const ring r)
208{
209  int i, j;
210  int k = IDELEMS(id)-1;
211  for (i=k; i>=0; i--)
212  {
213    if (id->m[i]!=NULL)
214    {
215      for (j=k; j>i; j--)
216      {
217        if (id->m[j]!=NULL)
218        {
219#ifdef HAVE_RINGS
220          if (rField_is_Ring(r))
221          {
222            /* if id[j] = c*id[i] then delete id[j].
223               In the below cases of a ground field, we
224               check whether id[i] = c*id[j] and, if so,
225               delete id[j] for historical reasons (so
226               that previous output does not change) */
227            if (p_ComparePolys(id->m[j], id->m[i],r)) p_Delete(&id->m[j],r);
228          }
229          else
230          {
231            if (p_ComparePolys(id->m[i], id->m[j],r)) p_Delete(&id->m[j],r);
232          }
233#else
234          if (p_ComparePolys(id->m[i], id->m[j],r)) p_Delete(&id->m[j],r);
235#endif   
236        }
237      }
238    }
239  }
240}
241
242/*2
243* ideal id = (id[i])
244* if id[i] = id[j] then id[j] is deleted for j > i
245*/
246void id_DelEquals(ideal id, const ring r)
247{
248  int i, j;
249  int k = IDELEMS(id)-1;
250  for (i=k; i>=0; i--)
251  {
252    if (id->m[i]!=NULL)
253    {
254      for (j=k; j>i; j--)
255      {
256        if ((id->m[j]!=NULL)
257        && (p_EqualPolys(id->m[i], id->m[j],r)))
258        {
259          p_Delete(&id->m[j],r);
260        }
261      }
262    }
263  }
264}
265
266//
267// Delete id[j], if Lm(j) == Lm(i) and both LC(j), LC(i) are units and j > i
268//
269void id_DelLmEquals(ideal id, const ring r)
270{
271  int i, j;
272  int k = IDELEMS(id)-1;
273  for (i=k; i>=0; i--)
274  {
275    if (id->m[i] != NULL)
276    {
277      for (j=k; j>i; j--)
278      {
279        if ((id->m[j] != NULL)
280        && p_LmEqual(id->m[i], id->m[j],r)
281#ifdef HAVE_RINGS
282        && n_IsUnit(pGetCoeff(id->m[i]),r->cf) && n_IsUnit(pGetCoeff(id->m[j]),r->cf)
283#endif
284        )
285        {
286          p_Delete(&id->m[j],r);
287        }
288      }
289    }
290  }
291}
292
293//
294// delete id[j], if LT(j) == coeff*mon*LT(i) and vice versa, i.e.,
295// delete id[i], if LT(i) == coeff*mon*LT(j)
296//
297void id_DelDiv(ideal id, const ring r)
298{
299  int i, j;
300  int k = IDELEMS(id)-1;
301  for (i=k; i>=0; i--)
302  {
303    if (id->m[i] != NULL)
304    {
305      for (j=k; j>i; j--)
306      {
307        if (id->m[j]!=NULL)
308        {
309#ifdef HAVE_RINGS
310          if (rField_is_Ring(r))
311          {
312            if (p_DivisibleByRingCase(id->m[i], id->m[j],r))
313            {
314              p_Delete(&id->m[j],r);
315            }
316            else if (p_DivisibleByRingCase(id->m[j], id->m[i],r))
317            {
318              p_Delete(&id->m[i],r);
319              break;
320            }
321          }
322          else
323          {
324#endif
325          /* the case of a ground field: */
326          if (p_DivisibleBy(id->m[i], id->m[j],r))
327          {
328            p_Delete(&id->m[j],r);
329          }
330          else if (p_DivisibleBy(id->m[j], id->m[i],r))
331          {
332            p_Delete(&id->m[i],r);
333            break;
334          }
335#ifdef HAVE_RINGS
336          }
337#endif   
338        }
339      }
340    }
341  }
342}
343
344/*2
345*test if the ideal has only constant polynomials
346*/
347BOOLEAN id_IsConstant(ideal id, const ring r)
348{
349  int k;
350  for (k = IDELEMS(id)-1; k>=0; k--)
351  {
352    if (!p_IsConstantPoly(id->m[k],r))
353      return FALSE;
354  }
355  return TRUE;
356}
357
358/*2
359* copy an ideal
360*/
361#ifdef PDEBUG
362ideal id_DBCopy(ideal h1,const char *f,int l, const ring r)
363{
364  int i;
365  ideal h2;
366
367  id_DBTest(h1,PDEBUG,f,l,r);
368//#ifdef TEST
369  if (h1 == NULL)
370  {
371    h2=idDBInit(1,1,f,l);
372  }
373  else
374//#endif
375  {
376    h2=idDBInit(IDELEMS(h1),h1->rank,f,l);
377    for (i=IDELEMS(h1)-1; i>=0; i--)
378      h2->m[i] = p_Copy(h1->m[i],r);
379  }
380  return h2;
381}
382#else
383ideal id_Copy(ideal h1, const ring r)
384{
385  int i;
386  ideal h2;
387
388//#ifdef TEST
389  if (h1 == NULL)
390  {
391    h2=idInit(1,1);
392  }
393  else
394//#endif
395  {
396    h2=idInit(IDELEMS(h1),h1->rank);
397    for (i=IDELEMS(h1)-1; i>=0; i--)
398      h2->m[i] = p_Copy(h1->m[i],r);
399  }
400  return h2;
401}
402#endif
403
404#ifdef PDEBUG
405void id_DBTest(ideal h1, int level, const char *f,const int l, const ring r)
406{
407  int i;
408
409  if (h1 != NULL)
410  {
411    // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
412    omCheckAddrSize(h1,sizeof(*h1));
413    omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
414    /* to be able to test matrices: */
415    for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
416      _p_Test(h1->m[i], r, level);
417    int new_rk=id_RankFreeModule(h1,r);
418    if(new_rk > h1->rank)
419    {
420      dReportError("wrong rank %d (should be %d) in %s:%d\n",
421                   h1->rank, new_rk, f,l);
422      omPrintAddrInfo(stderr, h1, " for ideal");
423      h1->rank=new_rk;
424    }
425  }
426}
427#endif
428
429/*3
430* for idSort: compare a and b revlex inclusive module comp.
431*/
432static int p_Comp_RevLex(poly a, poly b,BOOLEAN nolex, const ring r)
433{
434  if (b==NULL) return 1;
435  if (a==NULL) return -1;
436
437  if (nolex)
438  {
439    int r=p_LmCmp(a,b,r);
440    if (r!=0) return r;
441    number h=n_Sub(pGetCoeff(a),pGetCoeff(b),r->cf);
442    r = -1+n_IsZero(h,r->cf)+2*n_GreaterZero(h,r->cf); /* -1: <, 0:==, 1: > */
443    n_Delete(&h, r->cf);
444    return r;
445  }
446  int l=rVar(r);
447  while ((l>0) && (p_GetExp(a,l,r)==pGetExp(b,l,r))) l--;
448  if (l==0)
449  {
450    if (p_GetComp(a,r)==p_GetComp(b,r))
451    {
452      number h=n_Sub(pGetCoeff(a),pGetCoeff(b),r->cf);
453      int r = -1+n_IsZero(h,r->cf)+2*n_GreaterZero(h,r->cf); /* -1: <, 0:==, 1: > */
454      n_Delete(&h,r->cf);
455      return r;
456    }
457    if (p_GetComp(a,r)>p_GetComp(b,r)) return 1;
458  }
459  else if (p_GetExp(a,l,r)>p_GetExp(b,l,r))
460    return 1;
461  return -1;
462}
463
464/*2
465*sorts the ideal w.r.t. the actual ringordering
466*uses lex-ordering when nolex = FALSE
467*/
468intvec *id_Sort(ideal id,BOOLEAN nolex, const ring r)
469{
470  poly p,q;
471  intvec * result = new intvec(IDELEMS(id));
472  int i, j, actpos=0, newpos, l;
473  int diff, olddiff, lastcomp, newcomp;
474  BOOLEAN notFound;
475
476  for (i=0;i<IDELEMS(id);i++)
477  {
478    if (id->m[i]!=NULL)
479    {
480      notFound = TRUE;
481      newpos = actpos / 2;
482      diff = (actpos+1) / 2;
483      diff = (diff+1) / 2;
484      lastcomp = p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r);
485      if (lastcomp<0)
486      {
487        newpos -= diff;
488      }
489      else if (lastcomp>0)
490      {
491        newpos += diff;
492      }
493      else
494      {
495        notFound = FALSE;
496      }
497      //while ((newpos>=0) && (newpos<actpos) && (notFound))
498      while (notFound && (newpos>=0) && (newpos<actpos))
499      {
500        newcomp = p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r);
501        olddiff = diff;
502        if (diff>1)
503        {
504          diff = (diff+1) / 2;
505          if ((newcomp==1)
506          && (actpos-newpos>1)
507          && (diff>1)
508          && (newpos+diff>=actpos))
509          {
510            diff = actpos-newpos-1;
511          }
512          else if ((newcomp==-1)
513          && (diff>1)
514          && (newpos<diff))
515          {
516            diff = newpos;
517          }
518        }
519        if (newcomp<0)
520        {
521          if ((olddiff==1) && (lastcomp>0))
522            notFound = FALSE;
523          else
524            newpos -= diff;
525        }
526        else if (newcomp>0)
527        {
528          if ((olddiff==1) && (lastcomp<0))
529          {
530            notFound = FALSE;
531            newpos++;
532          }
533          else
534          {
535            newpos += diff;
536          }
537        }
538        else
539        {
540          notFound = FALSE;
541        }
542        lastcomp = newcomp;
543        if (diff==0) notFound=FALSE; /*hs*/
544      }
545      if (newpos<0) newpos = 0;
546      if (newpos>actpos) newpos = actpos;
547      while ((newpos<actpos) && (p_Comp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex,r)==0))
548        newpos++;
549      for (j=actpos;j>newpos;j--)
550      {
551        (*result)[j] = (*result)[j-1];
552      }
553      (*result)[newpos] = i;
554      actpos++;
555    }
556  }
557  for (j=0;j<actpos;j++) (*result)[j]++;
558  return result;
559}
560
561/*2
562* concat the lists h1 and h2 without zeros
563*/
564ideal idSimpleAdd (ideal h1,ideal h2)
565{
566  int i,j,r,l;
567  ideal result;
568
569  if (h1==NULL) return idCopy(h2);
570  if (h2==NULL) return idCopy(h1);
571  j = IDELEMS(h1)-1;
572  while ((j >= 0) && (h1->m[j] == NULL)) j--;
573  i = IDELEMS(h2)-1;
574  while ((i >= 0) && (h2->m[i] == NULL)) i--;
575  r = si_max(h1->rank,h2->rank);
576  if (i+j==(-2))
577    return idInit(1,r);
578  else
579    result=idInit(i+j+2,r);
580  for (l=j; l>=0; l--)
581  {
582    result->m[l] = pCopy(h1->m[l]);
583  }
584  r = i+j+1;
585  for (l=i; l>=0; l--, r--)
586  {
587    result->m[r] = pCopy(h2->m[l]);
588  }
589  return result;
590}
591
592/*2
593* insert h2 into h1 (if h2 is not the zero polynomial)
594* return TRUE iff h2 was indeed inserted
595*/
596BOOLEAN idInsertPoly (ideal h1, poly h2)
597{
598  if (h2==NULL) return FALSE;
599  int j = IDELEMS(h1)-1;
600  while ((j >= 0) && (h1->m[j] == NULL)) j--;
601  j++;
602  if (j==IDELEMS(h1))
603  {
604    pEnlargeSet(&(h1->m),IDELEMS(h1),16);
605    IDELEMS(h1)+=16;
606  }
607  h1->m[j]=h2;
608  return TRUE;
609}
610
611/*2
612* insert h2 into h1 depending on the two boolean parameters:
613* - if zeroOk is true, then h2 will also be inserted when it is zero
614* - if duplicateOk is true, then h2 will also be inserted when it is
615*   already present in h1
616* return TRUE iff h2 was indeed inserted
617*/
618BOOLEAN idInsertPolyWithTests (ideal h1, const int validEntries,
619  const poly h2, const bool zeroOk, const bool duplicateOk)
620{
621  if ((!zeroOk) && (h2 == NULL)) return FALSE;
622  if (!duplicateOk)
623  {
624    bool h2FoundInH1 = false;
625    int i = 0;
626    while ((i < validEntries) && (!h2FoundInH1))
627    {
628      h2FoundInH1 = pEqualPolys(h1->m[i], h2);
629      i++;
630    }
631    if (h2FoundInH1) return FALSE;
632  }
633  if (validEntries == IDELEMS(h1))
634  {
635    pEnlargeSet(&(h1->m), IDELEMS(h1), 16);
636    IDELEMS(h1) += 16;
637  }
638  h1->m[validEntries] = h2;
639  return TRUE;
640}
641
642/*2
643* h1 + h2
644*/
645ideal idAdd (ideal h1,ideal h2)
646{
647  ideal result = idSimpleAdd(h1,h2);
648  idCompactify(result);
649  return result;
650}
651
652/*2
653* h1 * h2
654*/
655ideal  idMult (ideal h1,ideal  h2)
656{
657  int i,j,k;
658  ideal  hh;
659
660  j = IDELEMS(h1);
661  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
662  i = IDELEMS(h2);
663  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
664  j = j * i;
665  if (j == 0)
666    hh = idInit(1,1);
667  else
668    hh=idInit(j,1);
669  if (h1->rank<h2->rank)
670    hh->rank = h2->rank;
671  else
672    hh->rank = h1->rank;
673  if (j==0) return hh;
674  k = 0;
675  for (i=0; i<IDELEMS(h1); i++)
676  {
677    if (h1->m[i] != NULL)
678    {
679      for (j=0; j<IDELEMS(h2); j++)
680      {
681        if (h2->m[j] != NULL)
682        {
683          hh->m[k] = ppMult_qq(h1->m[i],h2->m[j]);
684          k++;
685        }
686      }
687    }
688  }
689  {
690    idCompactify(hh);
691    return hh;
692  }
693}
694
695/*2
696*returns true if h is the zero ideal
697*/
698BOOLEAN idIs0 (ideal h)
699{
700  int i;
701
702  if (h == NULL) return TRUE;
703  i = IDELEMS(h)-1;
704  while ((i >= 0) && (h->m[i] == NULL))
705  {
706    i--;
707  }
708  if (i < 0)
709    return TRUE;
710  else
711    return FALSE;
712}
713
714/*2
715* return the maximal component number found in any polynomial in s
716*/
717long idRankFreeModule (ideal s, ring lmRing, ring tailRing)
718{
719  if (s!=NULL)
720  {
721    int  j=0;
722
723    if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
724    {
725      int  l=IDELEMS(s);
726      poly *p=s->m;
727      int  k;
728      for (; l != 0; l--)
729      {
730        if (*p!=NULL)
731        {
732          pp_Test(*p, lmRing, tailRing);
733          k = p_MaxComp(*p, lmRing, tailRing);
734          if (k>j) j = k;
735        }
736        p++;
737      }
738    }
739    return j;
740  }
741  return -1;
742}
743
744BOOLEAN idIsModule(ideal id, ring r)
745{
746  if (id != NULL && rRing_has_Comp(r))
747  {
748    int j, l = IDELEMS(id);
749    for (j=0; j<l; j++)
750    {
751      if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0) return TRUE;
752    }
753  }
754  return FALSE;
755}
756
757
758/*2
759*returns true if id is homogenous with respect to the aktual weights
760*/
761BOOLEAN idHomIdeal (ideal id, ideal Q)
762{
763  int i;
764  BOOLEAN     b;
765  if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
766  i = 0;
767  b = TRUE;
768  while ((i < IDELEMS(id)) && b)
769  {
770    b = pIsHomogeneous(id->m[i]);
771    i++;
772  }
773  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
774  {
775    i=0;
776    while ((i < IDELEMS(Q)) && b)
777    {
778      b = pIsHomogeneous(Q->m[i]);
779      i++;
780    }
781  }
782  return b;
783}
784
785/*2
786*the minimal index of used variables - 1
787*/
788int pLowVar (poly p)
789{
790  int k,l,lex;
791
792  if (p == NULL) return -1;
793
794  k = 32000;/*a very large dummy value*/
795  while (p != NULL)
796  {
797    l = 1;
798    lex = pGetExp(p,l);
799    while ((l < pVariables) && (lex == 0))
800    {
801      l++;
802      lex = pGetExp(p,l);
803    }
804    l--;
805    if (l < k) k = l;
806    pIter(p);
807  }
808  return k;
809}
810
811/*3
812*multiplies p with t (!cas) or  (t-1)
813*the index of t is:1, so we have to shift all variables
814*p is NOT in the actual ring, it has no t
815*/
816static poly pMultWithT (poly p,BOOLEAN cas)
817{
818  /*qp is the working pointer in p*/
819  /*result is the result, qresult is the working pointer*/
820  /*pp is p in the actual ring(shifted), qpp the working pointer*/
821  poly result,qp,pp;
822  poly qresult=NULL;
823  poly qpp=NULL;
824  int  i,j,lex;
825  number n;
826
827  pp = NULL;
828  result = NULL;
829  qp = p;
830  while (qp != NULL)
831  {
832    i = 0;
833    if (result == NULL)
834    {/*first monomial*/
835      result = pInit();
836      qresult = result;
837    }
838    else
839    {
840      qresult->next = pInit();
841      pIter(qresult);
842    }
843    for (j=pVariables-1; j>0; j--)
844    {
845      lex = pGetExp(qp,j);
846      pSetExp(qresult,j+1,lex);/*copy all variables*/
847    }
848    lex = pGetComp(qp);
849    pSetComp(qresult,lex);
850    n=nCopy(pGetCoeff(qp));
851    pSetCoeff0(qresult,n);
852    qresult->next = NULL;
853    pSetm(qresult);
854    /*qresult is now qp brought into the actual ring*/
855    if (cas)
856    { /*case: mult with t-1*/
857      pSetExp(qresult,1,0);
858      pSetm(qresult);
859      if (pp == NULL)
860      { /*first monomial*/
861        pp = pCopy(qresult);
862        qpp = pp;
863      }
864      else
865      {
866        qpp->next = pCopy(qresult);
867        pIter(qpp);
868      }
869      pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
870      /*now qpp contains -1*qp*/
871    }
872    pSetExp(qresult,1,1);/*this is mult. by t*/
873    pSetm(qresult);
874    pIter(qp);
875  }
876  /*
877  *now p is processed:
878  *result contains t*p
879  * if cas: pp contains -1*p (in the new ring)
880  */
881  if (cas)  qresult->next = pp;
882  /*  else      qresult->next = NULL;*/
883  return result;
884}
885
886/*2
887* verschiebt die Indizees der Modulerzeugenden um i
888*/
889void pShift (poly * p,int i)
890{
891  poly qp1 = *p,qp2 = *p;/*working pointers*/
892  int     j = pMaxComp(*p),k = pMinComp(*p);
893
894  if (j+i < 0) return ;
895  while (qp1 != NULL)
896  {
897    if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
898    {
899      pAddComp(qp1,i);
900      pSetmComp(qp1);
901      qp2 = qp1;
902      pIter(qp1);
903    }
904    else
905    {
906      if (qp2 == *p)
907      {
908        pIter(*p);
909        pLmDelete(&qp2);
910        qp2 = *p;
911        qp1 = *p;
912      }
913      else
914      {
915        qp2->next = qp1->next;
916        if (qp1!=NULL) pLmDelete(&qp1);
917        qp1 = qp2->next;
918      }
919    }
920  }
921}
922
923/*2
924*initialized a field with r numbers between beg and end for the
925*procedure idNextChoise
926*/
927void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
928{
929  /*returns the first choise of r numbers between beg and end*/
930  int i;
931  for (i=0; i<r; i++)
932  {
933    choise[i] = 0;
934  }
935  if (r <= end-beg+1)
936    for (i=0; i<r; i++)
937    {
938      choise[i] = beg+i;
939    }
940  if (r > end-beg+1)
941    *endch = TRUE;
942  else
943    *endch = FALSE;
944}
945
946/*2
947*returns the next choise of r numbers between beg and end
948*/
949void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
950{
951  int i = r-1,j;
952  while ((i >= 0) && (choise[i] == end))
953  {
954    i--;
955    end--;
956  }
957  if (i == -1)
958    *endch = TRUE;
959  else
960  {
961    choise[i]++;
962    for (j=i+1; j<r; j++)
963    {
964      choise[j] = choise[i]+j-i;
965    }
966    *endch = FALSE;
967  }
968}
969
970/*2
971*takes the field choise of d numbers between beg and end, cancels the t-th
972*entree and searches for the ordinal number of that d-1 dimensional field
973* w.r.t. the algorithm of construction
974*/
975int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
976{
977  int * localchoise,i,result=0;
978  BOOLEAN b=FALSE;
979
980  if (d<=1) return 1;
981  localchoise=(int*)omAlloc((d-1)*sizeof(int));
982  idInitChoise(d-1,begin,end,&b,localchoise);
983  while (!b)
984  {
985    result++;
986    i = 0;
987    while ((i<t) && (localchoise[i]==choise[i])) i++;
988    if (i>=t)
989    {
990      i = t+1;
991      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
992      if (i>=d)
993      {
994        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
995        return result;
996      }
997    }
998    idGetNextChoise(d-1,end,&b,localchoise);
999  }
1000  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
1001  return 0;
1002}
1003
1004/*2
1005*computes the binomial coefficient
1006*/
1007int binom (int n,int r)
1008{
1009  int i,result;
1010
1011  if (r==0) return 1;
1012  if (n-r<r) return binom(n,n-r);
1013  result = n-r+1;
1014  for (i=2;i<=r;i++)
1015  {
1016    result *= n-r+i;
1017    if (result<0)
1018    {
1019      WarnS("overflow in binomials");
1020      return 0;
1021    }
1022    result /= i;
1023  }
1024  return result;
1025}
1026
1027/*2
1028*the free module of rank i
1029*/
1030ideal idFreeModule (int i)
1031{
1032  int j;
1033  ideal h;
1034
1035  h=idInit(i,i);
1036  for (j=0; j<i; j++)
1037  {
1038    h->m[j] = pOne();
1039    pSetComp(h->m[j],j+1);
1040    pSetmComp(h->m[j]);
1041  }
1042  return h;
1043}
1044
1045ideal idSectWithElim (ideal h1,ideal h2)
1046// does not destroy h1,h2
1047{
1048  if (TEST_OPT_PROT) PrintS("intersect by elimination method\n");
1049  assume(!idIs0(h1));
1050  assume(!idIs0(h2));
1051  assume(IDELEMS(h1)<=IDELEMS(h2));
1052  assume(idRankFreeModule(h1)==0);
1053  assume(idRankFreeModule(h2)==0);
1054  // add a new variable:
1055  int j;
1056  ring origRing=currRing;
1057  ring r=rCopy0(origRing);
1058  r->N++;
1059  r->block0[0]=1;
1060  r->block1[0]= r->N;
1061  omFree(r->order);
1062  r->order=(int*)omAlloc0(3*sizeof(int*));
1063  r->order[0]=ringorder_dp;
1064  r->order[1]=ringorder_C;
1065  char **names=(char**)omAlloc0(rVar(r) * sizeof(char_ptr));
1066  for (j=0;j<r->N-1;j++) names[j]=r->names[j];
1067  names[r->N-1]=omStrDup("@");
1068  omFree(r->names);
1069  r->names=names;
1070  rComplete(r,TRUE);
1071  // fetch h1, h2
1072  ideal h;
1073  h1=idrCopyR(h1,origRing,r);
1074  h2=idrCopyR(h2,origRing,r);
1075  // switch to temp. ring r
1076  rChangeCurrRing(r);
1077  // create 1-t, t
1078  poly omt=pOne();
1079  pSetExp(omt,r->N,1);
1080  poly t=pCopy(omt);
1081  pSetm(omt);
1082  omt=pNeg(omt);
1083  omt=pAdd(omt,pOne());
1084  // compute (1-t)*h1
1085  h1=(ideal)mpMultP((matrix)h1,omt);
1086  // compute t*h2
1087  h2=(ideal)mpMultP((matrix)h2,pCopy(t));
1088  // (1-t)h1 + t*h2
1089  h=idInit(IDELEMS(h1)+IDELEMS(h2),1);
1090  int l;
1091  for (l=IDELEMS(h1)-1; l>=0; l--)
1092  {
1093    h->m[l] = h1->m[l];  h1->m[l]=NULL;
1094  }
1095  j=IDELEMS(h1);
1096  for (l=IDELEMS(h2)-1; l>=0; l--)
1097  {
1098    h->m[l+j] = h2->m[l];  h2->m[l]=NULL;
1099  }
1100  idDelete(&h1);
1101  idDelete(&h2);
1102  // eliminate t:
1103
1104  ideal res=idElimination(h,t);
1105  // cleanup
1106  idDelete(&h);
1107  res=idrMoveR(res,r,origRing);
1108  rChangeCurrRing(origRing);
1109  rKill(r);
1110  return res;
1111}
1112
1113/*2
1114*computes recursively all monomials of a certain degree
1115*in every step the actvar-th entry in the exponential
1116*vector is incremented and the other variables are
1117*computed by recursive calls of makemonoms
1118*if the last variable is reached, the difference to the
1119*degree is computed directly
1120*vars is the number variables
1121*actvar is the actual variable to handle
1122*deg is the degree of the monomials to compute
1123*monomdeg is the actual degree of the monomial in consideration
1124*/
1125static void makemonoms(int vars,int actvar,int deg,int monomdeg)
1126{
1127  poly p;
1128  int i=0;
1129
1130  if ((idpowerpoint == 0) && (actvar ==1))
1131  {
1132    idpower[idpowerpoint] = pOne();
1133    monomdeg = 0;
1134  }
1135  while (i<=deg)
1136  {
1137    if (deg == monomdeg)
1138    {
1139      pSetm(idpower[idpowerpoint]);
1140      idpowerpoint++;
1141      return;
1142    }
1143    if (actvar == vars)
1144    {
1145      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
1146      pSetm(idpower[idpowerpoint]);
1147      pTest(idpower[idpowerpoint]);
1148      idpowerpoint++;
1149      return;
1150    }
1151    else
1152    {
1153      p = pCopy(idpower[idpowerpoint]);
1154      makemonoms(vars,actvar+1,deg,monomdeg);
1155      idpower[idpowerpoint] = p;
1156    }
1157    monomdeg++;
1158    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
1159    pSetm(idpower[idpowerpoint]);
1160    pTest(idpower[idpowerpoint]);
1161    i++;
1162  }
1163}
1164
1165/*2
1166*returns the deg-th power of the maximal ideal of 0
1167*/
1168ideal idMaxIdeal(int deg)
1169{
1170  if (deg < 0)
1171  {
1172    WarnS("maxideal: power must be non-negative");
1173  }
1174  if (deg < 1)
1175  {
1176    ideal I=idInit(1,1);
1177    I->m[0]=pOne();
1178    return I;
1179  }
1180  if (deg == 1)
1181  {
1182    return idMaxIdeal();
1183  }
1184
1185  int vars = currRing->N;
1186  int i = binom(vars+deg-1,deg);
1187  if (i<=0) return idInit(1,1);
1188  ideal id=idInit(i,1);
1189  idpower = id->m;
1190  idpowerpoint = 0;
1191  makemonoms(vars,1,deg,0);
1192  idpower = NULL;
1193  idpowerpoint = 0;
1194  return id;
1195}
1196
1197/*2
1198*computes recursively all generators of a certain degree
1199*of the ideal "givenideal"
1200*elms is the number elements in the given ideal
1201*actelm is the actual element to handle
1202*deg is the degree of the power to compute
1203*gendeg is the actual degree of the generator in consideration
1204*/
1205static void makepotence(int elms,int actelm,int deg,int gendeg)
1206{
1207  poly p;
1208  int i=0;
1209
1210  if ((idpowerpoint == 0) && (actelm ==1))
1211  {
1212    idpower[idpowerpoint] = pOne();
1213    gendeg = 0;
1214  }
1215  while (i<=deg)
1216  {
1217    if (deg == gendeg)
1218    {
1219      idpowerpoint++;
1220      return;
1221    }
1222    if (actelm == elms)
1223    {
1224      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
1225      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
1226      idpowerpoint++;
1227      return;
1228    }
1229    else
1230    {
1231      p = pCopy(idpower[idpowerpoint]);
1232      makepotence(elms,actelm+1,deg,gendeg);
1233      idpower[idpowerpoint] = p;
1234    }
1235    gendeg++;
1236    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
1237    i++;
1238  }
1239}
1240
1241/*2
1242*returns the deg-th power of the ideal gid
1243*/
1244//ideal idPower(ideal gid,int deg)
1245//{
1246//  int i;
1247//  ideal id;
1248//
1249//  if (deg < 1) deg = 1;
1250//  i = binom(IDELEMS(gid)+deg-1,deg);
1251//  id=idInit(i,1);
1252//  idpower = id->m;
1253//  givenideal = gid->m;
1254//  idpowerpoint = 0;
1255//  makepotence(IDELEMS(gid),1,deg,0);
1256//  idpower = NULL;
1257//  givenideal = NULL;
1258//  idpowerpoint = 0;
1259//  return id;
1260//}
1261static void idNextPotence(ideal given, ideal result,
1262  int begin, int end, int deg, int restdeg, poly ap)
1263{
1264  poly p;
1265  int i;
1266
1267  p = pPower(pCopy(given->m[begin]),restdeg);
1268  i = result->nrows;
1269  result->m[i] = pMult(pCopy(ap),p);
1270//PrintS(".");
1271  (result->nrows)++;
1272  if (result->nrows >= IDELEMS(result))
1273  {
1274    pEnlargeSet(&(result->m),IDELEMS(result),16);
1275    IDELEMS(result) += 16;
1276  }
1277  if (begin == end) return;
1278  for (i=restdeg-1;i>0;i--)
1279  {
1280    p = pPower(pCopy(given->m[begin]),i);
1281    p = pMult(pCopy(ap),p);
1282    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
1283    pDelete(&p);
1284  }
1285  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
1286}
1287
1288ideal idPower(ideal given,int exp)
1289{
1290  ideal result,temp;
1291  poly p1;
1292  int i;
1293
1294  if (idIs0(given)) return idInit(1,1);
1295  temp = idCopy(given);
1296  idSkipZeroes(temp);
1297  i = binom(IDELEMS(temp)+exp-1,exp);
1298  result = idInit(i,1);
1299  result->nrows = 0;
1300//Print("ideal contains %d elements\n",i);
1301  p1=pOne();
1302  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
1303  pDelete(&p1);
1304  idDelete(&temp);
1305  result->nrows = 1;
1306  idDelEquals(result);
1307  idSkipZeroes(result);
1308  return result;
1309}
1310
1311/*2
1312* compute the which-th ar-minor of the matrix a
1313*/
1314poly idMinor(matrix a, int ar, unsigned long which, ideal R)
1315{
1316  int     i,j,k,size;
1317  unsigned long curr;
1318  int *rowchoise,*colchoise;
1319  BOOLEAN rowch,colch;
1320  ideal result;
1321  matrix tmp;
1322  poly p,q;
1323
1324  i = binom(a->rows(),ar);
1325  j = binom(a->cols(),ar);
1326
1327  rowchoise=(int *)omAlloc(ar*sizeof(int));
1328  colchoise=(int *)omAlloc(ar*sizeof(int));
1329  if ((i>512) || (j>512) || (i*j >512)) size=512;
1330  else size=i*j;
1331  result=idInit(size,1);
1332  tmp=mpNew(ar,ar);
1333  k = 0; /* the index in result*/
1334  curr = 0; /* index of current minor */
1335  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
1336  while (!rowch)
1337  {
1338    idInitChoise(ar,1,a->cols(),&colch,colchoise);
1339    while (!colch)
1340    {
1341      if (curr == which)
1342      {
1343        for (i=1; i<=ar; i++)
1344        {
1345          for (j=1; j<=ar; j++)
1346          {
1347            MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
1348          }
1349        }
1350        p = mpDetBareiss(tmp);
1351        if (p!=NULL)
1352        {
1353          if (R!=NULL)
1354          {
1355            q = p;
1356            p = kNF(R,currQuotient,q);
1357            pDelete(&q);
1358          }
1359          /*delete the matrix tmp*/
1360          for (i=1; i<=ar; i++)
1361          {
1362            for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
1363          }
1364          idDelete((ideal*)&tmp);
1365          omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
1366          omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
1367          return (p);
1368        }
1369      }
1370      curr++;
1371      idGetNextChoise(ar,a->cols(),&colch,colchoise);
1372    }
1373    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
1374  }
1375  return (poly) 1;
1376}
1377
1378#ifdef WITH_OLD_MINOR
1379/*2
1380* compute all ar-minors of the matrix a
1381*/
1382ideal idMinors(matrix a, int ar, ideal R)
1383{
1384  int     i,j,k,size;
1385  int *rowchoise,*colchoise;
1386  BOOLEAN rowch,colch;
1387  ideal result;
1388  matrix tmp;
1389  poly p,q;
1390
1391  i = binom(a->rows(),ar);
1392  j = binom(a->cols(),ar);
1393
1394  rowchoise=(int *)omAlloc(ar*sizeof(int));
1395  colchoise=(int *)omAlloc(ar*sizeof(int));
1396  if ((i>512) || (j>512) || (i*j >512)) size=512;
1397  else size=i*j;
1398  result=idInit(size,1);
1399  tmp=mpNew(ar,ar);
1400  k = 0; /* the index in result*/
1401  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
1402  while (!rowch)
1403  {
1404    idInitChoise(ar,1,a->cols(),&colch,colchoise);
1405    while (!colch)
1406    {
1407      for (i=1; i<=ar; i++)
1408      {
1409        for (j=1; j<=ar; j++)
1410        {
1411          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
1412        }
1413      }
1414      p = mpDetBareiss(tmp);
1415      if (p!=NULL)
1416      {
1417        if (R!=NULL)
1418        {
1419          q = p;
1420          p = kNF(R,currQuotient,q);
1421          pDelete(&q);
1422        }
1423        if (p!=NULL)
1424        {
1425          if (k>=size)
1426          {
1427            pEnlargeSet(&result->m,size,32);
1428            size += 32;
1429          }
1430          result->m[k] = p;
1431          k++;
1432        }
1433      }
1434      idGetNextChoise(ar,a->cols(),&colch,colchoise);
1435    }
1436    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
1437  }
1438  /*delete the matrix tmp*/
1439  for (i=1; i<=ar; i++)
1440  {
1441    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
1442  }
1443  idDelete((ideal*)&tmp);
1444  if (k==0)
1445  {
1446    k=1;
1447    result->m[0]=NULL;
1448  }
1449  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
1450  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
1451  pEnlargeSet(&result->m,size,k-size);
1452  IDELEMS(result) = k;
1453  return (result);
1454}
1455#else
1456/*2
1457* compute all ar-minors of the matrix a
1458* the caller of mpRecMin
1459* the elements of the result are not in R (if R!=NULL)
1460*/
1461ideal idMinors(matrix a, int ar, ideal R)
1462{
1463  int elems=0;
1464  int r=a->nrows,c=a->ncols;
1465  int i;
1466  matrix b;
1467  ideal result,h;
1468  ring origR;
1469  ring tmpR;
1470  long bound;
1471
1472  if((ar<=0) || (ar>r) || (ar>c))
1473  {
1474    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
1475    return NULL;
1476  }
1477  h = idMatrix2Module(mpCopy(a));
1478  bound = smExpBound(h,c,r,ar);
1479  idDelete(&h);
1480  tmpR=smRingChange(&origR,bound);
1481  b = mpNew(r,c);
1482  for (i=r*c-1;i>=0;i--)
1483  {
1484    if (a->m[i])
1485      b->m[i] = prCopyR(a->m[i],origR);
1486  }
1487  if (R!=NULL)
1488  {
1489    R = idrCopyR(R,origR);
1490    //if (ar>1) // otherwise done in mpMinorToResult
1491    //{
1492    //  matrix bb=(matrix)kNF(R,currQuotient,(ideal)b);
1493    //  bb->rank=b->rank; bb->nrows=b->nrows; bb->ncols=b->ncols;
1494    //  idDelete((ideal*)&b); b=bb;
1495    //}
1496  }
1497  result=idInit(32,1);
1498  if(ar>1) mpRecMin(ar-1,result,elems,b,r,c,NULL,R);
1499  else mpMinorToResult(result,elems,b,r,c,R);
1500  idDelete((ideal *)&b);
1501  if (R!=NULL) idDelete(&R);
1502  idSkipZeroes(result);
1503  rChangeCurrRing(origR);
1504  result = idrMoveR(result,tmpR);
1505  smKillModifiedRing(tmpR);
1506  idTest(result);
1507  return result;
1508}
1509#endif
1510
1511/*2
1512*skips all zeroes and double elements, searches also for units
1513*/
1514void idCompactify(ideal id)
1515{
1516  int i,j;
1517  BOOLEAN b=FALSE;
1518
1519  i = IDELEMS(id)-1;
1520  while ((! b) && (i>=0))
1521  {
1522    b=pIsUnit(id->m[i]);
1523    i--;
1524  }
1525  if (b)
1526  {
1527    for(i=IDELEMS(id)-1;i>=0;i--) pDelete(&id->m[i]);
1528    id->m[0]=pOne();
1529  }
1530  else
1531  {
1532    idDelMultiples(id);
1533  }
1534  idSkipZeroes(id);
1535}
1536
1537/*2
1538*returns TRUE if id1 is a submodule of id2
1539*/
1540BOOLEAN idIsSubModule(ideal id1,ideal id2)
1541{
1542  int i;
1543  poly p;
1544
1545  if (idIs0(id1)) return TRUE;
1546  for (i=0;i<IDELEMS(id1);i++)
1547  {
1548    if (id1->m[i] != NULL)
1549    {
1550      p = kNF(id2,currQuotient,id1->m[i]);
1551      if (p != NULL)
1552      {
1553        pDelete(&p);
1554        return FALSE;
1555      }
1556    }
1557  }
1558  return TRUE;
1559}
1560
1561/*2
1562* returns the ideals of initial terms
1563*/
1564ideal idHead(ideal h)
1565{
1566  ideal m = idInit(IDELEMS(h),h->rank);
1567  int i;
1568
1569  for (i=IDELEMS(h)-1;i>=0; i--)
1570  {
1571    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
1572  }
1573  return m;
1574}
1575
1576ideal idHomogen(ideal h, int varnum)
1577{
1578  ideal m = idInit(IDELEMS(h),h->rank);
1579  int i;
1580
1581  for (i=IDELEMS(h)-1;i>=0; i--)
1582  {
1583    m->m[i]=pHomogen(h->m[i],varnum);
1584  }
1585  return m;
1586}
1587
1588/*------------------type conversions----------------*/
1589ideal idVec2Ideal(poly vec)
1590{
1591   ideal result=idInit(1,1);
1592   omFree((ADDRESS)result->m);
1593   result->m=NULL; // remove later
1594   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
1595   return result;
1596}
1597
1598#define NEW_STUFF
1599#ifndef NEW_STUFF
1600// converts mat to module, destroys mat
1601ideal idMatrix2Module(matrix mat)
1602{
1603  int mc=MATCOLS(mat);
1604  int mr=MATROWS(mat);
1605  ideal result = idInit(si_max(mc,1),si_max(mr,1));
1606  int i,j;
1607  poly h;
1608
1609  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
1610  {
1611    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
1612    {
1613      h = MATELEM(mat,i,j+1);
1614      if (h!=NULL)
1615      {
1616        MATELEM(mat,i,j+1)=NULL;
1617        pSetCompP(h,i);
1618        result->m[j] = pAdd(result->m[j],h);
1619      }
1620    }
1621  }
1622  // obachman: need to clean this up
1623  idDelete((ideal*) &mat);
1624  return result;
1625}
1626#else
1627
1628#include "sbuckets.h"
1629
1630// converts mat to module, destroys mat
1631ideal idMatrix2Module(matrix mat)
1632{
1633  int mc=MATCOLS(mat);
1634  int mr=MATROWS(mat);
1635  ideal result = idInit(si_max(mc,1),si_max(mr,1));
1636  int i,j, l;
1637  poly h;
1638  poly p;
1639  sBucket_pt bucket = sBucketCreate(currRing);
1640
1641  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
1642  {
1643    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
1644    {
1645      h = MATELEM(mat,i,j+1);
1646      if (h!=NULL)
1647      {
1648        l=pLength(h);
1649        MATELEM(mat,i,j+1)=NULL;
1650        p_SetCompP(h,i, currRing);
1651        sBucket_Merge_p(bucket, h, l);
1652      }
1653    }
1654    sBucketClearMerge(bucket, &(result->m[j]), &l);
1655  }
1656  sBucketDestroy(&bucket);
1657
1658  // obachman: need to clean this up
1659  idDelete((ideal*) &mat);
1660  return result;
1661}
1662#endif
1663
1664/*2
1665* converts a module into a matrix, destroyes the input
1666*/
1667matrix idModule2Matrix(ideal mod)
1668{
1669  matrix result = mpNew(mod->rank,IDELEMS(mod));
1670  int i,cp;
1671  poly p,h;
1672
1673  for(i=0;i<IDELEMS(mod);i++)
1674  {
1675    p=pReverse(mod->m[i]);
1676    mod->m[i]=NULL;
1677    while (p!=NULL)
1678    {
1679      h=p;
1680      pIter(p);
1681      pNext(h)=NULL;
1682//      cp = si_max(1,pGetComp(h));     // if used for ideals too
1683      cp = pGetComp(h);
1684      pSetComp(h,0);
1685      pSetmComp(h);
1686#ifdef TEST
1687      if (cp>mod->rank)
1688      {
1689        Print("## inv. rank %ld -> %d\n",mod->rank,cp);
1690        int k,l,o=mod->rank;
1691        mod->rank=cp;
1692        matrix d=mpNew(mod->rank,IDELEMS(mod));
1693        for (l=1; l<=o; l++)
1694        {
1695          for (k=1; k<=IDELEMS(mod); k++)
1696          {
1697            MATELEM(d,l,k)=MATELEM(result,l,k);
1698            MATELEM(result,l,k)=NULL;
1699          }
1700        }
1701        idDelete((ideal *)&result);
1702        result=d;
1703      }
1704#endif
1705      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
1706    }
1707  }
1708  // obachman 10/99: added the following line, otherwise memory leack!
1709  idDelete(&mod);
1710  return result;
1711}
1712
1713matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
1714{
1715  matrix result = mpNew(rows,cols);
1716  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
1717  poly p,h;
1718
1719  if (r>rows) r = rows;
1720  if (c>cols) c = cols;
1721  for(i=0;i<c;i++)
1722  {
1723    p=pReverse(mod->m[i]);
1724    mod->m[i]=NULL;
1725    while (p!=NULL)
1726    {
1727      h=p;
1728      pIter(p);
1729      pNext(h)=NULL;
1730      cp = pGetComp(h);
1731      if (cp<=r)
1732      {
1733        pSetComp(h,0);
1734        pSetmComp(h);
1735        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
1736      }
1737      else
1738        pDelete(&h);
1739    }
1740  }
1741  idDelete(&mod);
1742  return result;
1743}
1744
1745/*2
1746* substitute the n-th variable by the monomial e in id
1747* destroy id
1748*/
1749ideal  idSubst(ideal id, int n, poly e)
1750{
1751  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
1752  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
1753
1754  res->rank = id->rank;
1755  for(k--;k>=0;k--)
1756  {
1757    res->m[k]=pSubst(id->m[k],n,e);
1758    id->m[k]=NULL;
1759  }
1760  idDelete(&id);
1761  return res;
1762}
1763
1764BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
1765{
1766  if (w!=NULL) *w=NULL;
1767  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
1768  if (idIs0(m))
1769  {
1770    if (w!=NULL) (*w)=new intvec(m->rank);
1771    return TRUE;
1772  }
1773
1774  long cmax=1,order=0,ord,* diff,diffmin=32000;
1775  int *iscom;
1776  int i,j;
1777  poly p=NULL;
1778  pFDegProc d;
1779  if (pLexOrder && (currRing->order[0]==ringorder_lp))
1780     d=p_Totaldegree;
1781  else
1782     d=pFDeg;
1783  int length=IDELEMS(m);
1784  polyset P=m->m;
1785  polyset F=(polyset)omAlloc(length*sizeof(poly));
1786  for (i=length-1;i>=0;i--)
1787  {
1788    p=F[i]=P[i];
1789    cmax=si_max(cmax,(long)pMaxComp(p));
1790  }
1791  cmax++;
1792  diff = (long *)omAlloc0(cmax*sizeof(long));
1793  if (w!=NULL) *w=new intvec(cmax-1);
1794  iscom = (int *)omAlloc0(cmax*sizeof(int));
1795  i=0;
1796  while (i<=length)
1797  {
1798    if (i<length)
1799    {
1800      p=F[i];
1801      while ((p!=NULL) && (iscom[pGetComp(p)]==0)) pIter(p);
1802    }
1803    if ((p==NULL) && (i<length))
1804    {
1805      i++;
1806    }
1807    else
1808    {
1809      if (p==NULL) /* && (i==length) */
1810      {
1811        i=0;
1812        while ((i<length) && (F[i]==NULL)) i++;
1813        if (i>=length) break;
1814        p = F[i];
1815      }
1816      //if (pLexOrder && (currRing->order[0]==ringorder_lp))
1817      //  order=pTotaldegree(p);
1818      //else
1819      //  order = p->order;
1820      //  order = pFDeg(p,currRing);
1821      order = d(p,currRing) +diff[pGetComp(p)];
1822      //order += diff[pGetComp(p)];
1823      p = F[i];
1824//Print("Actual p=F[%d]: ",i);pWrite(p);
1825      F[i] = NULL;
1826      i=0;
1827    }
1828    while (p!=NULL)
1829    {
1830      if (pLexOrder && (currRing->order[0]==ringorder_lp))
1831        ord=pTotaldegree(p);
1832      else
1833      //  ord = p->order;
1834        ord = pFDeg(p,currRing);
1835      if (iscom[pGetComp(p)]==0)
1836      {
1837        diff[pGetComp(p)] = order-ord;
1838        iscom[pGetComp(p)] = 1;
1839/*
1840*PrintS("new diff: ");
1841*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
1842*PrintLn();
1843*PrintS("new iscom: ");
1844*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
1845*PrintLn();
1846*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
1847*/
1848      }
1849      else
1850      {
1851/*
1852*PrintS("new diff: ");
1853*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
1854*PrintLn();
1855*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
1856*/
1857        if (order != (ord+diff[pGetComp(p)]))
1858        {
1859          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
1860          omFreeSize((ADDRESS) diff,cmax*sizeof(long));
1861          omFreeSize((ADDRESS) F,length*sizeof(poly));
1862          delete *w;*w=NULL;
1863          return FALSE;
1864        }
1865      }
1866      pIter(p);
1867    }
1868  }
1869  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
1870  omFreeSize((ADDRESS) F,length*sizeof(poly));
1871  for (i=1;i<cmax;i++) (**w)[i-1]=(int)(diff[i]);
1872  for (i=1;i<cmax;i++)
1873  {
1874    if (diff[i]<diffmin) diffmin=diff[i];
1875  }
1876  if (w!=NULL)
1877  {
1878    for (i=1;i<cmax;i++)
1879    {
1880      (**w)[i-1]=(int)(diff[i]-diffmin);
1881    }
1882  }
1883  omFreeSize((ADDRESS) diff,cmax*sizeof(long));
1884  return TRUE;
1885}
1886
1887BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
1888{
1889  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
1890  if (idIs0(m)) return TRUE;
1891
1892  int cmax=-1;
1893  int i;
1894  poly p=NULL;
1895  int length=IDELEMS(m);
1896  polyset P=m->m;
1897  for (i=length-1;i>=0;i--)
1898  {
1899    p=P[i];
1900    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
1901  }
1902  if (w != NULL)
1903  if (w->length()+1 < cmax)
1904  {
1905    // Print("length: %d - %d \n", w->length(),cmax);
1906    return FALSE;
1907  }
1908
1909  if(w!=NULL)
1910    pSetModDeg(w);
1911
1912  for (i=length-1;i>=0;i--)
1913  {
1914    p=P[i];
1915    poly q=p;
1916    if (p!=NULL)
1917    {
1918      int d=pFDeg(p,currRing);
1919      loop
1920      {
1921        pIter(p);
1922        if (p==NULL) break;
1923        if (d!=pFDeg(p,currRing))
1924        {
1925          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
1926          if(w!=NULL)
1927            pSetModDeg(NULL);
1928          return FALSE;
1929        }
1930      }
1931    }
1932  }
1933
1934  if(w!=NULL)
1935    pSetModDeg(NULL);
1936
1937  return TRUE;
1938}
1939
1940ideal idJet(ideal i,int d)
1941{
1942  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
1943  r->nrows = i-> nrows;
1944  r->ncols = i-> ncols;
1945  //r->rank = i-> rank;
1946  int k;
1947  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
1948  {
1949    r->m[k]=ppJet(i->m[k],d);
1950  }
1951  return r;
1952}
1953
1954ideal idJetW(ideal i,int d, intvec * iv)
1955{
1956  ideal r=idInit(IDELEMS(i),i->rank);
1957  if (ecartWeights!=NULL)
1958  {
1959    WerrorS("cannot compute weighted jets now");
1960  }
1961  else
1962  {
1963    short *w=iv2array(iv);
1964    int k;
1965    for(k=0; k<IDELEMS(i); k++)
1966    {
1967      r->m[k]=ppJetW(i->m[k],d,w);
1968    }
1969    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
1970  }
1971  return r;
1972}
1973
1974int idMinDegW(ideal M,intvec *w)
1975{
1976  int d=-1;
1977  for(int i=0;i<IDELEMS(M);i++)
1978  {
1979    int d0=pMinDeg(M->m[i],w);
1980    if(-1<d0&&(d0<d||d==-1))
1981      d=d0;
1982  }
1983  return d;
1984}
1985
1986ideal idSeries(int n,ideal M,matrix U,intvec *w)
1987{
1988  for(int i=IDELEMS(M)-1;i>=0;i--)
1989  {
1990    if(U==NULL)
1991      M->m[i]=pSeries(n,M->m[i],NULL,w);
1992    else
1993    {
1994      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
1995      MATELEM(U,i+1,i+1)=NULL;
1996    }
1997  }
1998  if(U!=NULL)
1999    idDelete((ideal*)&U);
2000  return M;
2001}
2002
2003matrix idDiff(matrix i, int k)
2004{
2005  int e=MATCOLS(i)*MATROWS(i);
2006  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2007  r->rank=i->rank;
2008  int j;
2009  for(j=0; j<e; j++)
2010  {
2011    r->m[j]=pDiff(i->m[j],k);
2012  }
2013  return r;
2014}
2015
2016matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2017{
2018  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2019  int i,j;
2020  for(i=0; i<IDELEMS(I); i++)
2021  {
2022    for(j=0; j<IDELEMS(J); j++)
2023    {
2024      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2025    }
2026  }
2027  return r;
2028}
2029
2030int idElem(const ideal F)
2031{
2032  int i=0,j=IDELEMS(F)-1;
2033
2034  while(j>=0)
2035  {
2036    if ((F->m)[j]!=NULL) i++;
2037    j--;
2038  }
2039  return i;
2040}
2041
2042/*
2043*computes module-weights for liftings of homogeneous modules
2044*/
2045intvec * idMWLift(ideal mod,intvec * weights)
2046{
2047  if (idIs0(mod)) return new intvec(2);
2048  int i=IDELEMS(mod);
2049  while ((i>0) && (mod->m[i-1]==NULL)) i--;
2050  intvec *result = new intvec(i+1);
2051  while (i>0)
2052  {
2053    (*result)[i]=pFDeg(mod->m[i],currRing)+(*weights)[pGetComp(mod->m[i])];
2054  }
2055  return result;
2056}
2057
2058/*2
2059*sorts the kbase for idCoef* in a special way (lexicographically
2060*with x_max,...,x_1)
2061*/
2062ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
2063{
2064  int i;
2065  ideal result;
2066
2067  if (idIs0(kBase)) return NULL;
2068  result = idInit(IDELEMS(kBase),kBase->rank);
2069  *convert = idSort(kBase,FALSE);
2070  for (i=0;i<(*convert)->length();i++)
2071  {
2072    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
2073  }
2074  return result;
2075}
2076
2077/*2
2078*returns the index of a given monom in the list of the special kbase
2079*/
2080int idIndexOfKBase(poly monom, ideal kbase)
2081{
2082  int j=IDELEMS(kbase);
2083
2084  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
2085  if (j==0) return -1;
2086  int i=pVariables;
2087  while (i>0)
2088  {
2089    loop
2090    {
2091      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
2092      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
2093      j--;
2094      if (j==0) return -1;
2095    }
2096    if (i==1)
2097    {
2098      while(j>0)
2099      {
2100        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
2101        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
2102        j--;
2103      }
2104    }
2105    i--;
2106  }
2107  return -1;
2108}
2109
2110/*2
2111*decomposes the monom in a part of coefficients described by the
2112*complement of how and a monom in variables occuring in how, the
2113*index of which in kbase is returned as integer pos (-1 if it don't
2114*exists)
2115*/
2116poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
2117{
2118  int i;
2119  poly coeff=pOne(), base=pOne();
2120
2121  for (i=1;i<=pVariables;i++)
2122  {
2123    if (pGetExp(how,i)>0)
2124    {
2125      pSetExp(base,i,pGetExp(monom,i));
2126    }
2127    else
2128    {
2129      pSetExp(coeff,i,pGetExp(monom,i));
2130    }
2131  }
2132  pSetComp(base,pGetComp(monom));
2133  pSetm(base);
2134  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
2135  pSetm(coeff);
2136  *pos = idIndexOfKBase(base,kbase);
2137  if (*pos<0)
2138    pDelete(&coeff);
2139  pDelete(&base);
2140  return coeff;
2141}
2142
2143/*2
2144*returns a matrix A of coefficients with kbase*A=arg
2145*if all monomials in variables of how occur in kbase
2146*the other are deleted
2147*/
2148matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
2149{
2150  matrix result;
2151  ideal tempKbase;
2152  poly p,q;
2153  intvec * convert;
2154  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
2155#if 0
2156  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
2157  if (idIs0(arg))
2158    return mpNew(i,1);
2159  while ((j>0) && (arg->m[j-1]==NULL)) j--;
2160  result = mpNew(i,j);
2161#else
2162  result = mpNew(i, j);
2163  while ((j>0) && (arg->m[j-1]==NULL)) j--;
2164#endif
2165
2166  tempKbase = idCreateSpecialKbase(kbase,&convert);
2167  for (k=0;k<j;k++)
2168  {
2169    p = arg->m[k];
2170    while (p!=NULL)
2171    {
2172      q = idDecompose(p,how,tempKbase,&pos);
2173      if (pos>=0)
2174      {
2175        MATELEM(result,(*convert)[pos],k+1) =
2176            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
2177      }
2178      else
2179        pDelete(&q);
2180      pIter(p);
2181    }
2182  }
2183  idDelete(&tempKbase);
2184  return result;
2185}
2186
2187/*3
2188* searches for the next unit in the components of the module arg and
2189* returns the first one;
2190*/
2191static int idReadOutPivot(ideal arg,int* comp)
2192{
2193  if (idIs0(arg)) return -1;
2194  int i=0,j, generator=-1;
2195  int rk_arg=arg->rank; //idRankFreeModule(arg);
2196  int * componentIsUsed =(int *)omAlloc((rk_arg+1)*sizeof(int));
2197  poly p;
2198
2199  while ((generator<0) && (i<IDELEMS(arg)))
2200  {
2201    memset(componentIsUsed,0,(rk_arg+1)*sizeof(int));
2202    p = arg->m[i];
2203    while (p!=NULL)
2204    {
2205      j = pGetComp(p);
2206      if (componentIsUsed[j]==0)
2207      {
2208#ifdef HAVE_RINGS
2209        if (pLmIsConstantComp(p) &&
2210            (!rField_is_Ring(currRing) || nIsUnit(pGetCoeff(p))))
2211        {
2212#else
2213        if (pLmIsConstantComp(p))
2214        {
2215#endif
2216          generator = i;
2217          componentIsUsed[j] = 1;
2218        }
2219        else
2220        {
2221          componentIsUsed[j] = -1;
2222        }
2223      }
2224      else if (componentIsUsed[j]>0)
2225      {
2226        (componentIsUsed[j])++;
2227      }
2228      pIter(p);
2229    }
2230    i++;
2231  }
2232  i = 0;
2233  *comp = -1;
2234  for (j=0;j<=rk_arg;j++)
2235  {
2236    if (componentIsUsed[j]>0)
2237    {
2238      if ((*comp==-1) || (componentIsUsed[j]<i))
2239      {
2240        *comp = j;
2241        i= componentIsUsed[j];
2242      }
2243    }
2244  }
2245  omFree(componentIsUsed);
2246  return generator;
2247}
2248
2249#if 0
2250static void idDeleteComp(ideal arg,int red_comp)
2251{
2252  int i,j;
2253  poly p;
2254
2255  for (i=IDELEMS(arg)-1;i>=0;i--)
2256  {
2257    p = arg->m[i];
2258    while (p!=NULL)
2259    {
2260      j = pGetComp(p);
2261      if (j>red_comp)
2262      {
2263        pSetComp(p,j-1);
2264        pSetm(p);
2265      }
2266      pIter(p);
2267    }
2268  }
2269  (arg->rank)--;
2270}
2271#endif
2272
2273static void idDeleteComps(ideal arg,int* red_comp,int del)
2274// red_comp is an array [0..args->rank]
2275{
2276  int i,j;
2277  poly p;
2278
2279  for (i=IDELEMS(arg)-1;i>=0;i--)
2280  {
2281    p = arg->m[i];
2282    while (p!=NULL)
2283    {
2284      j = pGetComp(p);
2285      if (red_comp[j]!=j)
2286      {
2287        pSetComp(p,red_comp[j]);
2288        pSetmComp(p);
2289      }
2290      pIter(p);
2291    }
2292  }
2293  (arg->rank) -= del;
2294}
2295
2296/*2
2297* returns the presentation of an isomorphic, minimally
2298* embedded  module (arg represents the quotient!)
2299*/
2300ideal idMinEmbedding(ideal arg,BOOLEAN inPlace, intvec **w)
2301{
2302  if (idIs0(arg)) return idInit(1,arg->rank);
2303  int i,next_gen,next_comp;
2304  ideal res=arg;
2305  if (!inPlace) res = idCopy(arg);
2306  res->rank=si_max(res->rank,idRankFreeModule(res));
2307  int *red_comp=(int*)omAlloc((res->rank+1)*sizeof(int));
2308  for (i=res->rank;i>=0;i--) red_comp[i]=i;
2309
2310  int del=0;
2311  loop
2312  {
2313    next_gen = idReadOutPivot(res,&next_comp);
2314    if (next_gen<0) break;
2315    del++;
2316    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
2317    for(i=next_comp+1;i<=arg->rank;i++) red_comp[i]--;
2318    if ((w !=NULL)&&(*w!=NULL))
2319    {
2320      for(i=next_comp;i<(*w)->length();i++) (**w)[i-1]=(**w)[i];
2321    }
2322  }
2323
2324  idDeleteComps(res,red_comp,del);
2325  idSkipZeroes(res);
2326  omFree(red_comp);
2327
2328  if ((w !=NULL)&&(*w!=NULL) &&(del>0))
2329  {
2330    intvec *wtmp=new intvec((*w)->length()-del);
2331    for(i=0;i<res->rank;i++) (*wtmp)[i]=(**w)[i];
2332    delete *w;
2333    *w=wtmp;
2334  }
2335  return res;
2336}
2337
2338/*2
2339* transpose a module
2340*/
2341ideal idTransp(ideal a)
2342{
2343  int r = a->rank, c = IDELEMS(a);
2344  ideal b =  idInit(r,c);
2345
2346  for (int i=c; i>0; i--)
2347  {
2348    poly p=a->m[i-1];
2349    while(p!=NULL)
2350    {
2351      poly h=pHead(p);
2352      int co=pGetComp(h)-1;
2353      pSetComp(h,i);
2354      pSetmComp(h);
2355      b->m[co]=pAdd(b->m[co],h);
2356      pIter(p);
2357    }
2358  }
2359  return b;
2360}
2361
2362intvec * idQHomWeight(ideal id)
2363{
2364  poly head, tail;
2365  int k;
2366  int in=IDELEMS(id)-1, ready=0, all=0,
2367      coldim=pVariables, rowmax=2*coldim;
2368  if (in<0) return NULL;
2369  intvec *imat=new intvec(rowmax+1,coldim,0);
2370
2371  do
2372  {
2373    head = id->m[in--];
2374    if (head!=NULL)
2375    {
2376      tail = pNext(head);
2377      while (tail!=NULL)
2378      {
2379        all++;
2380        for (k=1;k<=coldim;k++)
2381          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
2382        if (all==rowmax)
2383        {
2384          ivTriangIntern(imat, ready, all);
2385          if (ready==coldim)
2386          {
2387            delete imat;
2388            return NULL;
2389          }
2390        }
2391        pIter(tail);
2392      }
2393    }
2394  } while (in>=0);
2395  if (all>ready)
2396  {
2397    ivTriangIntern(imat, ready, all);
2398    if (ready==coldim)
2399    {
2400      delete imat;
2401      return NULL;
2402    }
2403  }
2404  intvec *result = ivSolveKern(imat, ready);
2405  delete imat;
2406  return result;
2407}
2408
2409BOOLEAN idIsZeroDim(ideal I)
2410{
2411  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(pVariables*sizeof(BOOLEAN));
2412  int i,n;
2413  poly po;
2414  BOOLEAN res=TRUE;
2415  for(i=IDELEMS(I)-1;i>=0;i--)
2416  {
2417    po=I->m[i];
2418    if ((po!=NULL) &&((n=pIsPurePower(po))!=0)) UsedAxis[n-1]=TRUE;
2419  }
2420  for(i=pVariables-1;i>=0;i--)
2421  {
2422    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
2423  }
2424  omFreeSize(UsedAxis,pVariables*sizeof(BOOLEAN));
2425  return res;
2426}
2427
2428void idNormalize(ideal I)
2429{
2430  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
2431  int i;
2432  for(i=IDELEMS(I)-1;i>=0;i--)
2433  {
2434    pNormalize(I->m[i]);
2435  }
2436}
2437
2438// #include <kernel/clapsing.h>
2439
2440#ifdef HAVE_FACTORY
2441poly id_GCD(poly f, poly g, const ring r)
2442{
2443  ring save_r=currRing;
2444  rChangeCurrRing(r);
2445  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
2446  intvec *w = NULL;
2447  ideal S=idSyzygies(I,testHomog,&w);
2448  if (w!=NULL) delete w;
2449  poly gg=pTakeOutComp(&(S->m[0]),2);
2450  idDelete(&S);
2451  poly gcd_p=singclap_pdivide(f,gg);
2452  pDelete(&gg);
2453  rChangeCurrRing(save_r);
2454  return gcd_p;
2455}
2456#endif
2457
2458/*2
2459* xx,q: arrays of length 0..rl-1
2460* xx[i]: SB mod q[i]
2461* assume: char=0
2462* assume: q[i]!=0
2463* destroys xx
2464*/
2465#ifdef HAVE_FACTORY
2466ideal idChineseRemainder(ideal *xx, number *q, int rl)
2467{
2468  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
2469  ideal result=idInit(cnt,xx[0]->rank);
2470  result->nrows=xx[0]->nrows; // for lifting matrices
2471  result->ncols=xx[0]->ncols; // for lifting matrices
2472  int i,j;
2473  poly r,h,hh,res_p;
2474  number *x=(number *)omAlloc(rl*sizeof(number));
2475  for(i=cnt-1;i>=0;i--)
2476  {
2477    res_p=NULL;
2478    loop
2479    {
2480      r=NULL;
2481      for(j=rl-1;j>=0;j--)
2482      {
2483        h=xx[j]->m[i];
2484        if ((h!=NULL)
2485        &&((r==NULL)||(pLmCmp(r,h)==-1)))
2486          r=h;
2487      }
2488      if (r==NULL) break;
2489      h=pHead(r);
2490      for(j=rl-1;j>=0;j--)
2491      {
2492        hh=xx[j]->m[i];
2493        if ((hh!=NULL) && (pLmCmp(r,hh)==0))
2494        {
2495          x[j]=pGetCoeff(hh);
2496          hh=pLmFreeAndNext(hh);
2497          xx[j]->m[i]=hh;
2498        }
2499        else
2500          x[j]=nlInit(0, currRing);
2501      }
2502      number n=nlChineseRemainder(x,q,rl);
2503      for(j=rl-1;j>=0;j--)
2504      {
2505        x[j]=NULL; // nlInit(0...) takes no memory
2506      }
2507      if (nlIsZero(n)) pDelete(&h);
2508      else
2509      {
2510        pSetCoeff(h,n);
2511        //Print("new mon:");pWrite(h);
2512        res_p=pAdd(res_p,h);
2513      }
2514    }
2515    result->m[i]=res_p;
2516  }
2517  omFree(x);
2518  for(i=rl-1;i>=0;i--) idDelete(&(xx[i]));
2519  omFree(xx);
2520  return result;
2521}
2522#endif
2523/* currently unsed:
2524ideal idChineseRemainder(ideal *xx, intvec *iv)
2525{
2526  int rl=iv->length();
2527  number *q=(number *)omAlloc(rl*sizeof(number));
2528  int i;
2529  for(i=0; i<rl; i++)
2530  {
2531    q[i]=nInit((*iv)[i]);
2532  }
2533  return idChineseRemainder(xx,q,rl);
2534}
2535*/
2536/*
2537 * lift ideal with coeffs over Z (mod N) to Q via Farey
2538 */
2539ideal idFarey(ideal x, number N)
2540{
2541  int cnt=IDELEMS(x)*x->nrows;
2542  ideal result=idInit(cnt,x->rank);
2543  result->nrows=x->nrows; // for lifting matrices
2544  result->ncols=x->ncols; // for lifting matrices
2545
2546  int i;
2547  for(i=cnt-1;i>=0;i--)
2548  {
2549    poly h=pCopy(x->m[i]);
2550    result->m[i]=h;
2551    while(h!=NULL)
2552    {
2553      number c=pGetCoeff(h);
2554      pSetCoeff0(h,nlFarey(c,N));
2555      nDelete(&c);
2556      pIter(h);
2557    }
2558    while((result->m[i]!=NULL)&&(nIsZero(pGetCoeff(result->m[i]))))
2559    {
2560      pLmDelete(&(result->m[i]));
2561    }
2562    h=result->m[i];
2563    while((h!=NULL) && (pNext(h)!=NULL))
2564    {
2565      if(nIsZero(pGetCoeff(pNext(h))))
2566      {
2567        pLmDelete(&pNext(h));
2568      }
2569      else pIter(h);
2570    }
2571  }
2572  return result;
2573}
2574
2575/*2
2576* transpose a module
2577* NOTE: just a version of "ideal idTransp(ideal)" which works within specified ring.
2578*/
2579ideal id_Transp(ideal a, const ring rRing)
2580{
2581  int r = a->rank, c = IDELEMS(a);
2582  ideal b =  idInit(r,c);
2583
2584  for (int i=c; i>0; i--)
2585  {
2586    poly p=a->m[i-1];
2587    while(p!=NULL)
2588    {
2589      poly h=p_Head(p, rRing);
2590      int co=p_GetComp(h, rRing)-1;
2591      p_SetComp(h, i, rRing);
2592      p_Setm(h, rRing);
2593      b->m[co] = p_Add_q(b->m[co], h, rRing);
2594      pIter(p);
2595    }
2596  }
2597  return b;
2598}
2599
2600
2601
2602/*2
2603* The following is needed to compute the image of certain map used in
2604* the computation of cohomologies via BGG
2605* let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
2606* assuming that nrows(M) <= m*n; the procedure computes:
2607* transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
2608* where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
2609* that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
2610
2611  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
2612*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
2613*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
2614+ =>
2615  f_i =
2616
2617   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
2618   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
2619                             ...
2620   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
2621
2622   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
2623*/
2624ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing)
2625{
2626// #ifdef DEBU
2627//  WarnS("tensorModuleMult!!!!");
2628
2629  assume(m > 0);
2630  assume(M != NULL);
2631
2632  const int n = rRing->N;
2633
2634  assume(M->rank <= m * n);
2635
2636  const int k = IDELEMS(M);
2637
2638  ideal idTemp =  idInit(k,m); // = {f_1, ..., f_k }
2639
2640  for( int i = 0; i < k; i++ ) // for every w \in M
2641  {
2642    poly pTempSum = NULL;
2643
2644    poly w = M->m[i];
2645
2646    while(w != NULL) // for each term of w...
2647    {
2648      poly h = p_Head(w, rRing);
2649
2650      const int  gen = p_GetComp(h, rRing); // 1 ...
2651
2652      assume(gen > 0);
2653      assume(gen <= n*m);
2654
2655      // TODO: write a formula with %, / instead of while!
2656      /*
2657      int c = gen;
2658      int v = 1;
2659      while(c > m)
2660      {
2661        c -= m;
2662        v++;
2663      }
2664      */
2665
2666      int cc = gen % m;
2667      if( cc == 0) cc = m;
2668      int vv = 1 + (gen - cc) / m;
2669
2670//      assume( cc == c );
2671//      assume( vv == v );
2672
2673      //  1<= c <= m
2674      assume( cc > 0 );
2675      assume( cc <= m );
2676
2677      assume( vv > 0 );
2678      assume( vv <= n );
2679
2680      assume( (cc + (vv-1)*m) == gen );
2681
2682      p_IncrExp(h, vv, rRing); // h *= var(j) && //      p_AddExp(h, vv, 1, rRing);
2683      p_SetComp(h, cc, rRing);
2684
2685      p_Setm(h, rRing);         // addjust degree after the previous steps!
2686
2687      pTempSum = p_Add_q(pTempSum, h, rRing); // it is slow since h will be usually put to the back of pTempSum!!!
2688
2689      pIter(w);
2690    }
2691
2692    idTemp->m[i] = pTempSum;
2693  }
2694
2695  // simplify idTemp???
2696
2697  ideal idResult = id_Transp(idTemp, rRing);
2698
2699  id_Delete(&idTemp, rRing);
2700
2701  return(idResult);
2702}
Note: See TracBrowser for help on using the repository browser.