source: git/Singular/ideals.cc @ ba4d53

spielwiese
Last change on this file since ba4d53 was ba4d53, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: normalize in assign git-svn-id: file:///usr/local/Singular/svn/trunk@5257 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 68.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: ideals.cc,v 1.122 2001-02-22 09:40:15 Singular Exp $ */
5/*
6* ABSTRACT - all basic methods to manipulate ideals
7*/
8
9/* includes */
10#include "mod2.h"
11#include "tok.h"
12#include "omalloc.h"
13#include "febase.h"
14#include "numbers.h"
15#include "polys.h"
16#include "ipid.h"
17#include "ring.h"
18#include "kstd1.h"
19#include "matpol.h"
20#include "weight.h"
21#include "intvec.h"
22#include "syz.h"
23#include "sparsmat.h"
24#include "ideals.h"
25#include "lists.h"
26#include "prCopy.h"
27
28
29/* #define WITH_OLD_MINOR */
30#define pCopy_noCheck(p) pCopy(p)
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*/
36static poly * givenideal;
37/*the ideal from which a power is computed*/
38
39/*0 implementation*/
40
41/*2
42* initialise an ideal
43*/
44#ifdef PDEBUG
45ideal idDBInit(int idsize, int rank, char *f, int l)
46#else
47ideal idInit(int idsize, int rank)
48#endif
49{
50  /*- initialise an ideal -*/
51  ideal hh = (ideal )omAllocBin(sip_sideal_bin);
52  hh->nrows = 1;
53  hh->rank = rank;
54  IDELEMS(hh) = idsize;
55  if (idsize>0)
56  {
57    hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
58  }
59  else
60    hh->m=NULL;
61  return hh;
62}
63
64//#ifndef __OPTIMIZE__
65// this is mainly for outputting an ideal within the debugger
66void idShow(ideal id)
67{
68  Print("Module of rank %d,real rank %d and %d generators.\n",
69         id->rank,idRankFreeModule(id),IDELEMS(id));
70  for (int i=0;i<id->ncols*id->nrows;i++)
71  {
72    if (id->m[i]!=NULL)
73    {
74      Print("generator %d: ",i);pWrite(id->m[i]);
75    }
76  }
77}
78//#endif
79
80/*2
81* initialise the maximal ideal (at 0)
82*/
83ideal idMaxIdeal (void)
84{
85  int l;
86  ideal hh=NULL;
87
88  hh=idInit(pVariables,1);
89  for (l=0; l<pVariables; l++)
90  {
91    hh->m[l] = pOne();
92    pSetExp(hh->m[l],l+1,1);
93    pSetm(hh->m[l]);
94  }
95  return hh;
96}
97
98/*2
99* deletes an ideal/matrix
100*/
101void id_Delete (ideal * h, ring r)
102{
103  int j,elems;
104  if (*h == NULL)
105    return;
106  elems=j=(*h)->nrows*(*h)->ncols;
107  if (j>0)
108  {
109    do
110    {
111      p_Delete(&((*h)->m[--j]), r);
112    }
113    while (j>0);
114    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
115  }
116  omFreeBin((ADDRESS)*h, sip_sideal_bin);
117  *h=NULL;
118}
119
120/*2
121*gives an ideal the minimal possible size
122*/
123void idSkipZeroes (ideal ide)
124{
125  int k;
126  int j = -1;
127  BOOLEAN change=FALSE;
128  for (k=0; k<IDELEMS(ide); k++)
129  {
130    if (ide->m[k] != NULL)
131    {
132      j++;
133      if (change)
134      {
135        ide->m[j] = ide->m[k];
136      }
137    }
138    else
139    {
140      change=TRUE;
141    }
142  }
143  if (change)
144  {
145    if (j == -1)
146      j = 0;
147    else
148    {
149      for (k=j+1; k<IDELEMS(ide); k++)
150        ide->m[k] = NULL;
151    }
152    pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
153    IDELEMS(ide) = j+1;
154  }
155}
156
157/*2
158* ideal id = (id[i])
159* result is leadcoeff(id[i]) = 1
160*/
161void idNorm(ideal id)
162{
163  for (int i=0; i<IDELEMS(id); i++)
164  {
165    if (id->m[i] != NULL)
166    {
167      pNorm(id->m[i]);
168    }
169  }
170}
171
172/*2
173* ideal id = (id[i]), c any number
174* if id[i] = c*id[j] then id[j] is deleted for j > i
175*/
176void idDelMultiples(ideal id)
177{
178  int i, j, t;
179  int k = IDELEMS(id), l = k;
180  for (i=k-2; i>=0; i--)
181  {
182    if (id->m[i]!=NULL)
183    {
184      for (j=l-1; j>i; j--)
185      {
186        if ((id->m[j]!=NULL)
187        && (pComparePolys(id->m[i], id->m[j])))
188        {
189          pDelete(&id->m[j]);
190          l--;
191          for(t=j; t<l; t++)
192          {
193            id->m[t] = id->m[t+1];
194          }
195        }
196      }
197    }
198  }
199  if (l != k)
200  {
201    pEnlargeSet(&id->m, k, l-k);
202    IDELEMS(id) = l;
203  }
204}
205
206/*2
207* ideal id = (id[i])
208* if id[i] = id[j] then id[j] is deleted for j > i
209*/
210void idDelEquals(ideal id)
211{
212  int i, j, t;
213  int k = IDELEMS(id), l = k;
214  for (i=k-2; i>=0; i--)
215  {
216    for (j=l-1; j>i; j--)
217    {
218      if (pEqualPolys(id->m[i], id->m[j]))
219      {
220        pDelete(&id->m[j]);
221        l--;
222        for(t=j; t<l; t++)
223        {
224          id->m[t] = id->m[t+1];
225        }
226      }
227    }
228  }
229  if (l != k)
230  {
231    pEnlargeSet(&id->m, k, l-k);
232    IDELEMS(id) = l;
233  }
234}
235
236//
237// Delete id[j], if Lm(j) == Lm(i) and j > i
238//
239void idDelLmEquals(ideal id)
240{
241  int i, j, t;
242  int k = IDELEMS(id), l = k;
243  for (i=k-2; i>=0; i--)
244  {
245    for (j=l-1; j>i; j--)
246    {
247      if (id->m[i] != NULL && id->m[j] != NULL && pLmEqual(id->m[i], id->m[j]))
248      {
249        pDelete(&id->m[j]);
250        l--;
251        for(t=j; t<l; t++)
252        {
253          id->m[t] = id->m[t+1];
254        }
255      }
256    }
257  }
258  if (l != k)
259  {
260    pEnlargeSet(&id->m, k, l-k);
261    IDELEMS(id) = l;
262  }
263}
264
265void idDelDiv(ideal id)
266{
267  int i, j, t;
268  int k = IDELEMS(id), l = k;
269  for (i=k-2; i>=0; i--)
270  {
271    for (j=l-1; j>i; j--)
272    {
273
274      if (((id->m[j] != NULL) && pDivisibleBy(id->m[i], id->m[j])) ||
275          (id->m[i] == NULL && id->m[j] == NULL))
276      {
277        pDelete(&id->m[j]);
278        l--;
279        for(t=j; t<l; t++)
280        {
281          id->m[t] = id->m[t+1];
282        }
283      }
284    }
285  }
286  if (l != k)
287  {
288    pEnlargeSet(&id->m, k, l-k);
289    IDELEMS(id) = l;
290  }
291}
292
293/*2
294*test if the ideal has only constant polynomials
295*/
296BOOLEAN idIsConstant(ideal id)
297{
298  int k;
299  for (k = IDELEMS(id)-1; k>=0; k--)
300  {
301    if (pIsConstantPoly(id->m[k]) == FALSE)
302      return FALSE;
303  }
304  return TRUE;
305}
306
307/*2
308* copy an ideal
309*/
310#ifdef PDEBUG
311ideal idDBCopy(ideal h1,char *f,int l)
312#else
313ideal idCopy (ideal h1)
314#endif
315{
316  int i;
317  ideal h2;
318
319#ifdef PDEBUG
320  idDBTest(h1,PDEBUG,f,l);
321#endif
322//#ifdef TEST
323  if (h1 == NULL)
324  {
325#ifdef PDEBUG
326    h2=idDBInit(1,1,f,l);
327#else
328    h2=idInit(1,1);
329#endif
330  }
331  else
332//#endif
333  {
334#ifdef PDEBUG
335    h2=idDBInit(IDELEMS(h1),h1->rank,f,l);
336#else
337    h2=idInit(IDELEMS(h1),h1->rank);
338#endif
339    for (i=IDELEMS(h1)-1; i>=0; i--)
340      h2->m[i] = pCopy(h1->m[i]);
341  }
342  return h2;
343}
344
345#ifdef PDEBUG
346void idDBTest(ideal h1, int level, char *f,int l)
347{
348  int i;
349
350  if (h1 != NULL)
351  {
352    // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
353    omCheckAddrSize(h1,sizeof(*h1));
354    omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
355    /* to be able to test matrices: */
356    for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
357      _p_Test(h1->m[i], currRing, level);
358    int new_rk=idRankFreeModule(h1);
359    if(new_rk > h1->rank)
360    {
361      dReportError("wrong rank %d (should be %d) in %s:%d\n",
362                   h1->rank, new_rk, f,l);
363      omPrintAddrInfo(stderr, h1, " for ideal");
364      h1->rank=new_rk;
365    }
366  }
367}
368#endif
369
370/*3
371* for idSort: compare a and b revlex inclusive module comp.
372*/
373static int pComp_RevLex(poly a, poly b,BOOLEAN nolex)
374{
375  if (b==NULL) return 1;
376  if (a==NULL) return -1;
377
378  if (nolex) return pLmCmp(a,b);
379  int l=pVariables;
380  while ((l>0) && (pGetExp(a,l)==pGetExp(b,l))) l--;
381  if (l==0)
382  {
383    if (pGetComp(a)==pGetComp(b)) return 0;
384    if (pGetComp(a)>pGetComp(b)) return 1;
385  }
386  else if (pGetExp(a,l)>pGetExp(b,l))
387    return 1;
388  return -1;
389}
390
391/*2
392*sorts the ideal w.r.t. the actual ringordering
393*uses lex-ordering when nolex = FALSE
394*/
395intvec *idSort(ideal id,BOOLEAN nolex)
396{
397  poly p,q;
398  intvec * result = new intvec(IDELEMS(id));
399  int i, j, actpos=0, newpos, l;
400  int diff, olddiff, lastcomp, newcomp;
401  BOOLEAN notFound;
402
403  for (i=0;i<IDELEMS(id);i++)
404  {
405    if (id->m[i]!=NULL)
406    {
407      notFound = TRUE;
408      newpos = actpos / 2;
409      diff = (actpos+1) / 2;
410      diff = (diff+1) / 2;
411      lastcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
412      if (lastcomp<0)
413      {
414        newpos -= diff;
415      }
416      else if (lastcomp>0)
417      {
418        newpos += diff;
419      }
420      else
421      {
422        notFound = FALSE;
423      }
424      //while ((newpos>=0) && (newpos<actpos) && (notFound))
425      while (notFound && (newpos>=0) && (newpos<actpos))
426      {
427        newcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
428        olddiff = diff;
429        if (diff>1)
430        {
431          diff = (diff+1) / 2;
432          if ((newcomp==1)
433          && (actpos-newpos>1)
434          && (diff>1)
435          && (newpos+diff>=actpos))
436          {
437            diff = actpos-newpos-1;
438          }
439          else if ((newcomp==-1)
440          && (diff>1)
441          && (newpos<diff))
442          {
443            diff = newpos;
444          }
445        }
446        if (newcomp<0)
447        {
448          if ((olddiff==1) && (lastcomp>0))
449            notFound = FALSE;
450          else
451            newpos -= diff;
452        }
453        else if (newcomp>0)
454        {
455          if ((olddiff==1) && (lastcomp<0))
456          {
457            notFound = FALSE;
458            newpos++;
459          }
460          else
461          {
462            newpos += diff;
463          }
464        }
465        else
466        {
467          notFound = FALSE;
468        }
469        lastcomp = newcomp;
470        if (diff==0) notFound=FALSE; /*hs*/
471      }
472      if (newpos<0) newpos = 0;
473      if (newpos>actpos) newpos = actpos;
474      while ((newpos<actpos) && (pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex)==0))
475        newpos++;
476      for (j=actpos;j>newpos;j--)
477      {
478        (*result)[j] = (*result)[j-1];
479      }
480      (*result)[newpos] = i;
481      actpos++;
482    }
483  }
484  for (j=0;j<actpos;j++) (*result)[j]++;
485  return result;
486}
487
488/*2
489* concat the lists h1 and h2 without zeros
490*/
491ideal idSimpleAdd (ideal h1,ideal h2)
492{
493  int i,j,r,l;
494  ideal result;
495
496  if (h1==NULL) return idCopy(h2);
497  if (h2==NULL) return idCopy(h1);
498  j = IDELEMS(h1)-1;
499  while ((j >= 0) && (h1->m[j] == NULL)) j--;
500  i = IDELEMS(h2)-1;
501  while ((i >= 0) && (h2->m[i] == NULL)) i--;
502  r = max(h1->rank,h2->rank);
503  if (i+j==(-2))
504    return idInit(1,r);
505  else
506    result=idInit(i+j+2,r);
507  for (l=j; l>=0; l--)
508  {
509    result->m[l] = pCopy(h1->m[l]);
510  }
511  r = i+j+1;
512  for (l=i; l>=0; l--, r--)
513  {
514    result->m[r] = pCopy(h2->m[l]);
515  }
516  return result;
517}
518
519/*2
520* h1 + h2
521*/
522ideal idAdd (ideal h1,ideal h2)
523{
524  ideal result = idSimpleAdd(h1,h2);
525  ideal tmp = idCompactify(result);
526
527  idDelete(&result);
528  return tmp;
529}
530
531/*2
532* h1 * h2
533*/
534ideal  idMult (ideal h1,ideal  h2)
535{
536  int i,j,k;
537  ideal  hh;
538
539  j = IDELEMS(h1);
540  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
541  i = IDELEMS(h2);
542  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
543  j = j * i;
544  if (j == 0)
545    hh = idInit(1,1);
546  else
547    hh=idInit(j,1);
548  if (h1->rank<h2->rank)
549    hh->rank = h2->rank;
550  else
551    hh->rank = h1->rank;
552  if (j==0) return hh;
553  k = 0;
554  for (i=0; i<IDELEMS(h1); i++)
555  {
556    if (h1->m[i] != NULL)
557    {
558      for (j=0; j<IDELEMS(h2); j++)
559      {
560        if (h2->m[j] != NULL)
561        {
562          hh->m[k] = ppMult_qq(h1->m[i],h2->m[j]);
563          k++;
564        }
565      }
566    }
567  }
568  {
569    ideal tmp = idCompactify(hh);
570    idDelete(&hh);
571    return tmp;
572    //return hh;
573  }
574}
575
576/*2
577*returns true if h is the zero ideal
578*/
579BOOLEAN idIs0 (ideal h)
580{
581  int i;
582
583  if (h == NULL) return TRUE;
584  i = IDELEMS(h);
585  while ((i > 0) && (h->m[i-1] == NULL))
586  {
587    i--;
588  }
589  if (i == 0)
590    return TRUE;
591  else
592    return FALSE;
593}
594
595/*2
596* return the maximal component number found in any polynomial in s
597*/
598long idRankFreeModule (ideal s, ring lmRing, ring tailRing)
599{
600  if (s!=NULL)
601  {
602    int  j=0;
603
604    if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
605    {
606      int  l=IDELEMS(s);
607      poly *p=s->m;
608      int  k;
609      for (; l != 0; l--)
610      {
611        if (*p!=NULL)
612        {
613          pp_Test(*p, lmRing, tailRing);
614          k = p_MaxComp(*p, lmRing, tailRing);
615          if (k>j) j = k;
616        }
617        p++;
618      }
619    }
620    return j;
621  }
622  return -1;
623}
624
625/*2
626*returns true if id is homogenous with respect to the aktual weights
627*/
628BOOLEAN idHomIdeal (ideal id, ideal Q)
629{
630  int i;
631  BOOLEAN     b;
632  if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
633  i = 0;
634  b = TRUE;
635  while ((i < IDELEMS(id)) && b)
636  {
637    b = pIsHomogeneous(id->m[i]);
638    i++;
639  }
640  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
641  {
642    i=0;
643    while ((i < IDELEMS(Q)) && b)
644    {
645      b = pIsHomogeneous(Q->m[i]);
646      i++;
647    }
648  }
649  return b;
650}
651
652/*2
653*returns a minimized set of generators of h1
654*/
655ideal idMinBase (ideal h1)
656{
657  ideal h2, h3,h4,e;
658  int j,k;
659  int i,l,ll;
660  intvec * wth;
661  BOOLEAN homog;
662
663  homog = idHomModule(h1,currQuotient,&wth);
664  if ((currRing->OrdSgn == 1) && (!homog))
665  {
666    Warn("minbase applies only to the local or homogeneous case");
667    e=idCopy(h1);
668    return e;
669  }
670  if ((currRing->OrdSgn == 1) && (homog))
671  {
672    lists re=min_std(h1,currQuotient,(tHomog)homog,&wth,NULL,0,3);
673    h2 = (ideal)re->m[1].data;
674    re->m[1].data = NULL;
675    re->m[1].rtyp = NONE;
676    re->Clean();
677    return h2;
678  }
679  e=idInit(1,h1->rank);
680  if (idIs0(h1))
681  {
682    return e;
683  }
684  pEnlargeSet(&(e->m),IDELEMS(e),15);
685  IDELEMS(e) = 16;
686  h2 = kStd(h1,currQuotient,isNotHomog,NULL);
687  h3 = idMaxIdeal();
688  h4=idMult(h2,h3);
689  idDelete(&h3);
690  h3=kStd(h4,currQuotient,isNotHomog,NULL);
691  k = IDELEMS(h3);
692  while ((k > 0) && (h3->m[k-1] == NULL)) k--;
693  j = -1;
694  l = IDELEMS(h2);
695  while ((l > 0) && (h2->m[l-1] == NULL)) l--;
696  for (i=l-1; i>=0; i--)
697  {
698    if (h2->m[i] != NULL)
699    {
700      ll = 0;
701      while ((ll < k) && ((h3->m[ll] == NULL)
702      || !pDivisibleBy(h3->m[ll],h2->m[i])))
703        ll++;
704      if (ll >= k)
705      {
706        j++;
707        if (j > IDELEMS(e)-1)
708        {
709          pEnlargeSet(&(e->m),IDELEMS(e),16);
710          IDELEMS(e) += 16;
711        }
712        e->m[j] = pCopy(h2->m[i]);
713      }
714    }
715  }
716  idDelete(&h2);
717  idDelete(&h3);
718  idDelete(&h4);
719  if (currQuotient!=NULL)
720  {
721    h3=idInit(1,e->rank);
722    h2=kNF(h3,currQuotient,e);
723    idDelete(&h3);
724    idDelete(&e);
725    e=h2;
726  }
727  idSkipZeroes(e);
728  return e;
729}
730
731/*2
732*the minimal index of used variables - 1
733*/
734int pLowVar (poly p)
735{
736  int k,l,lex;
737
738  if (p == NULL) return -1;
739
740  k = 32000;/*a very large dummy value*/
741  while (p != NULL)
742  {
743    l = 1;
744    lex = pGetExp(p,l);
745    while ((l < pVariables) && (lex == 0))
746    {
747      l++;
748      lex = pGetExp(p,l);
749    }
750    l--;
751    if (l < k) k = l;
752    pIter(p);
753  }
754  return k;
755}
756
757/*3
758*multiplies p with t (!cas) or  (t-1)
759*the index of t is:1, so we have to shift all variables
760*p is NOT in the actual ring, it has no t
761*/
762static poly pMultWithT (poly p,BOOLEAN cas)
763{
764  /*qp is the working pointer in p*/
765  /*result is the result, qresult is the working pointer*/
766  /*pp is p in the actual ring(shifted), qpp the working pointer*/
767  poly result,qp,pp;
768  poly qresult=NULL;
769  poly qpp=NULL;
770  int  i,j,lex;
771  number n;
772
773  pp = NULL;
774  result = NULL;
775  qp = p;
776  while (qp != NULL)
777  {
778    i = 0;
779    if (result == NULL)
780    {/*first monomial*/
781      result = pInit();
782      qresult = result;
783    }
784    else
785    {
786      qresult->next = pInit();
787      pIter(qresult);
788    }
789    for (j=pVariables-1; j>0; j--)
790    {
791      lex = pGetExp(qp,j);
792      pSetExp(qresult,j+1,lex);/*copy all variables*/
793    }
794    lex = pGetComp(qp);
795    pSetComp(qresult,lex);
796    n=nCopy(pGetCoeff(qp));
797    pSetCoeff0(qresult,n);
798    qresult->next = NULL;
799    pSetm(qresult);
800    /*qresult is now qp brought into the actual ring*/
801    if (cas)
802    { /*case: mult with t-1*/
803      pSetExp(qresult,1,0);
804      pSetm(qresult);
805      if (pp == NULL)
806      { /*first monomial*/
807        pp = pCopy(qresult);
808        qpp = pp;
809      }
810      else
811      {
812        qpp->next = pCopy(qresult);
813        pIter(qpp);
814      }
815      pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
816      /*now qpp contains -1*qp*/
817    }
818    pSetExp(qresult,1,1);/*this is mult. by t*/
819    pSetm(qresult);
820    pIter(qp);
821  }
822  /*
823  *now p is processed:
824  *result contains t*p
825  * if cas: pp contains -1*p (in the new ring)
826  */
827  if (cas)  qresult->next = pp;
828  /*  else      qresult->next = NULL;*/
829  return result;
830}
831
832/*3
833*deletes the place of t in p (t: variable with index 1)
834*p is NOT in the actual ring: it has pVariables+1 variables
835*/
836static poly pDivByT (poly * p,int size)
837{
838
839  poly result=NULL,
840       resultp=NULL , /** working pointer in result **/
841       pp;
842  int  i,j;
843
844  while (*p != NULL)
845  {
846    i = 0;
847    if (result == NULL)
848    {/*the first monomial*/
849      result = pInit();
850      resultp = result;
851      resultp->next = NULL;
852    }
853    else
854    {
855      resultp->next = pInit();
856      pIter(resultp);
857      resultp->next = NULL;
858    }
859    for (j=1; j<=pVariables; j++)
860    {
861      pSetExp(resultp,j,pGetExp(*p,j+1));
862    }
863    pSetComp(resultp,pGetComp(*p));
864    pSetCoeff0(resultp,pGetCoeff(*p));
865    pSetm(resultp);
866    pp = (*p)->next;
867    omFreeSize((ADDRESS)*p,size);
868    *p = pp;
869  }
870  return result;
871}
872
873/*2
874*dehomogenized the generators of the ideal id1 with the leading
875*monomial of p replaced by n
876*/
877ideal idDehomogen (ideal id1,poly p,number n)
878{
879  int i;
880  ideal result;
881
882  if (idIs0(id1))
883  {
884    return idInit(1,id1->rank);
885  }
886  result=idInit(IDELEMS(id1),id1->rank);
887  for (i=0; i<IDELEMS(id1); i++)
888  {
889    result->m[i] = pDehomogen(id1->m[i],p,n);
890  }
891  return result;
892}
893
894/*2
895* verschiebt die Indizees der Modulerzeugenden um i
896*/
897void pShift (poly * p,int i)
898{
899  poly qp1 = *p,qp2 = *p;/*working pointers*/
900  int     j = pMaxComp(*p),k = pMinComp(*p);
901
902  if (j+i < 0) return ;
903  while (qp1 != NULL)
904  {
905    if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
906    {
907      pSetComp(qp1,pGetComp(qp1)+i);
908      pSetmComp(qp1);
909      qp2 = qp1;
910      pIter(qp1);
911    }
912    else
913    {
914      if (qp2 == *p)
915      {
916        pIter(*p);
917        pDeleteLm(&qp2);
918        qp2 = *p;
919        qp1 = *p;
920      }
921      else
922      {
923        qp2->next = qp1->next;
924        pDeleteLm(&qp1);
925        qp1 = qp2->next;
926      }
927    }
928  }
929}
930
931/*2
932*initialized a field with r numbers between beg and end for the
933*procedure idNextChoise
934*/
935void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
936{
937  /*returns the first choise of r numbers between beg and end*/
938  int i;
939  for (i=0; i<r; i++)
940  {
941    choise[i] = 0;
942  }
943  if (r <= end-beg+1)
944    for (i=0; i<r; i++)
945    {
946      choise[i] = beg+i;
947    }
948  if (r > end-beg+1)
949    *endch = TRUE;
950  else
951    *endch = FALSE;
952}
953
954/*2
955*returns the next choise of r numbers between beg and end
956*/
957void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
958{
959  int i = r-1,j;
960  while ((i >= 0) && (choise[i] == end))
961  {
962    i--;
963    end--;
964  }
965  if (i == -1)
966    *endch = TRUE;
967  else
968  {
969    choise[i]++;
970    for (j=i+1; j<r; j++)
971    {
972      choise[j] = choise[i]+j-i;
973    }
974    *endch = FALSE;
975  }
976}
977
978/*2
979*takes the field choise of d numbers between beg and end, cancels the t-th
980*entree and searches for the ordinal number of that d-1 dimensional field
981* w.r.t. the algorithm of construction
982*/
983int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
984{
985  int * localchoise,i,result=0;
986  BOOLEAN b=FALSE;
987
988  if (d<=1) return 1;
989  localchoise=(int*)omAlloc((d-1)*sizeof(int));
990  idInitChoise(d-1,begin,end,&b,localchoise);
991  while (!b)
992  {
993    result++;
994    i = 0;
995    while ((i<t) && (localchoise[i]==choise[i])) i++;
996    if (i>=t)
997    {
998      i = t+1;
999      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
1000      if (i>=d)
1001      {
1002        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
1003        return result;
1004      }
1005    }
1006    idGetNextChoise(d-1,end,&b,localchoise);
1007  }
1008  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
1009  return 0;
1010}
1011
1012/*2
1013*computes the binomial coefficient
1014*/
1015int binom (int n,int r)
1016{
1017  int i,result;
1018
1019  if (r==0) return 1;
1020  if (n-r<r) return binom(n,n-r);
1021  result = n-r+1;
1022  for (i=2;i<=r;i++)
1023  {
1024    result *= n-r+i;
1025    result /= i;
1026  }
1027  return result;
1028}
1029
1030/*2
1031*the free module of rank i
1032*/
1033ideal idFreeModule (int i)
1034{
1035  int j;
1036  ideal h;
1037
1038  h=idInit(i,i);
1039  for (j=0; j<i; j++)
1040  {
1041    h->m[j] = pOne();
1042    pSetComp(h->m[j],j+1);
1043    pSetmComp(h->m[j]);
1044  }
1045  return h;
1046}
1047
1048/*2
1049* h3 := h1 intersect h2
1050*/
1051ideal idSect (ideal h1,ideal h2)
1052{
1053  ideal first=h2,second=h1,temp,temp1,result;
1054  int i,j,k,flength,slength,length,rank=min(h1->rank,h2->rank);
1055  intvec *w;
1056  poly p,q;
1057
1058  if ((idIs0(h1)) && (idIs0(h2)))  return idInit(1,rank);
1059  if (IDELEMS(h1)<IDELEMS(h2))
1060  {
1061    first = h1;
1062    second = h2;
1063  }
1064  flength = idRankFreeModule(first);
1065  slength = idRankFreeModule(second);
1066  length  = max(flength,slength);
1067  if (length==0)
1068  {
1069    length = 1;
1070  }
1071  j = IDELEMS(first);
1072  temp = idInit(j /*IDELEMS(first)*/,length+j);
1073
1074  ring orig_ring=currRing;
1075  ring syz_ring=rCurrRingAssure_SyzComp();
1076  rSetSyzComp(length);
1077
1078  while ((j>0) && (first->m[j-1]==NULL)) j--;
1079  k = 0;
1080  for (i=0;i<j;i++)
1081  {
1082    if (first->m[i]!=NULL)
1083    {
1084      if (syz_ring==orig_ring)
1085        temp->m[k] = pCopy(first->m[i]);
1086      else
1087        temp->m[k] = prCopyR(first->m[i], orig_ring);
1088      q = pOne();
1089      pSetComp(q,i+1+length);
1090      pSetmComp(q);
1091      if (flength==0) pShift(&(temp->m[k]),1);
1092      p = temp->m[k];
1093      while (pNext(p)!=NULL) pIter(p);
1094      pNext(p) = q;
1095      k++;
1096    }
1097  }
1098  pEnlargeSet(&(temp->m),IDELEMS(temp),j+IDELEMS(second)-IDELEMS(temp));
1099  IDELEMS(temp) = j+IDELEMS(second);
1100  for (i=0;i<IDELEMS(second);i++)
1101  {
1102    if (second->m[i]!=NULL)
1103    {
1104      if (syz_ring==orig_ring)
1105        temp->m[k] = pCopy(second->m[i]);
1106      else
1107        temp->m[k] = prCopyR(second->m[i], orig_ring);
1108      if (slength==0) pShift(&(temp->m[k]),1);
1109      k++;
1110    }
1111  }
1112  temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
1113  if (w!=NULL) delete w;
1114  idDelete(&temp);
1115
1116  if(syz_ring!=orig_ring)
1117    rChangeCurrRing(orig_ring);
1118
1119  result = idInit(IDELEMS(temp1),rank);
1120  j = 0;
1121  for (i=0;i<IDELEMS(temp1);i++)
1122  {
1123    if ((temp1->m[i]!=NULL)
1124    && (p_GetComp(temp1->m[i],syz_ring)>length))
1125    {
1126      if(syz_ring==orig_ring)
1127        p = pCopy(temp1->m[i]);
1128      else
1129        p = prCopyR(temp1->m[i], syz_ring);
1130      while (p!=NULL)
1131      {
1132        q = pNext(p);
1133        pNext(p) = NULL;
1134        k = pGetComp(p)-1-length;
1135        pSetComp(p,0);
1136        pSetmComp(p);
1137        result->m[j] = pAdd(result->m[j],pMult(pCopy(first->m[k]),p));
1138        p = q;
1139      }
1140      j++;
1141    }
1142  }
1143  if(syz_ring!=orig_ring)
1144  {
1145    rChangeCurrRing(syz_ring);
1146    idDelete(&temp1);
1147    rChangeCurrRing(orig_ring);
1148    rKill(syz_ring);
1149  }
1150  else
1151  {
1152    idDelete(&temp1);
1153  }
1154
1155  idSkipZeroes(result);
1156  return result;
1157}
1158
1159/*2
1160* ideal/module intersection for a list of objects
1161* given as 'resolvente'
1162*/
1163ideal idMultSect(resolvente arg, int length)
1164{
1165  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
1166  ideal bigmat,tempstd,result;
1167  poly p;
1168  int isIdeal=0;
1169  intvec * w=NULL;
1170
1171  /* find 0-ideals and max rank -----------------------------------*/
1172  for (i=0;i<length;i++)
1173  {
1174    if (!idIs0(arg[i]))
1175    {
1176      realrki=idRankFreeModule(arg[i]);
1177      k++;
1178      j += IDELEMS(arg[i]);
1179      if (realrki>maxrk) maxrk = realrki;
1180    }
1181    else
1182    {
1183      if (arg[i]!=NULL)
1184      {
1185        return idInit(1,arg[i]->rank);
1186      }
1187    }
1188  }
1189  if (maxrk == 0)
1190  {
1191    isIdeal = 1;
1192    maxrk = 1;
1193  }
1194  /* init -----------------------------------------------------------*/
1195  j += maxrk;
1196  syzComp = k*maxrk;
1197
1198  ring orig_ring=currRing;
1199  ring syz_ring=rCurrRingAssure_SyzComp();
1200  rSetSyzComp(syzComp);
1201
1202  bigmat = idInit(j,(k+1)*maxrk);
1203  /* create unit matrices ------------------------------------------*/
1204  for (i=0;i<maxrk;i++)
1205  {
1206    for (j=0;j<=k;j++)
1207    {
1208      p = pOne();
1209      pSetComp(p,i+1+j*maxrk);
1210      pSetmComp(p);
1211      bigmat->m[i] = pAdd(bigmat->m[i],p);
1212    }
1213  }
1214  /* enter given ideals ------------------------------------------*/
1215  i = maxrk;
1216  k = 0;
1217  for (j=0;j<length;j++)
1218  {
1219    if (arg[j]!=NULL)
1220    {
1221      for (l=0;l<IDELEMS(arg[j]);l++)
1222      {
1223        if (arg[j]->m[l]!=NULL)
1224        {
1225          if (syz_ring==orig_ring)
1226            bigmat->m[i] = pCopy(arg[j]->m[l]);
1227          else
1228            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring);
1229          pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
1230          i++;
1231        }
1232      }
1233      k++;
1234    }
1235  }
1236  /* std computation --------------------------------------------*/
1237  tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
1238  if (w!=NULL) delete w;
1239  idDelete(&bigmat);
1240
1241  if(syz_ring!=orig_ring)
1242    rChangeCurrRing(orig_ring);
1243
1244  /* interprete result ----------------------------------------*/
1245  result = idInit(8,maxrk);
1246  k = 0;
1247  for (j=0;j<IDELEMS(tempstd);j++)
1248  {
1249    if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
1250    {
1251      if (k>=IDELEMS(result))
1252      {
1253        pEnlargeSet(&(result->m),IDELEMS(result),8);
1254        IDELEMS(result) += 8;
1255      }
1256      if (syz_ring==orig_ring)
1257        p = pCopy(tempstd->m[j]);
1258      else
1259        p = prCopyR(tempstd->m[j], syz_ring);
1260      pShift(&p,-syzComp-isIdeal);
1261      result->m[k] = p;
1262      k++;
1263    }
1264  }
1265  /* clean up ----------------------------------------------------*/
1266  if(syz_ring!=orig_ring)
1267    rChangeCurrRing(syz_ring);
1268  idDelete(&tempstd);
1269  if(syz_ring!=orig_ring)
1270  {
1271    rChangeCurrRing(orig_ring);
1272    rKill(syz_ring);
1273  }
1274  idSkipZeroes(result);
1275  return result;
1276}
1277
1278/*2
1279*computes syzygies of h1,
1280*if quot != NULL it computes in the quotient ring modulo "quot"
1281*works always in a ring with ringorder_s
1282*/
1283static ideal idPrepare (ideal  h1, tHomog h, int syzcomp, intvec **w)
1284{
1285  ideal   h2, h3;
1286  int     i;
1287  int     j,jj=0,k;
1288  poly    p,q;
1289
1290  if (idIs0(h1)) return NULL;
1291  k = idRankFreeModule(h1);
1292  h2=idCopy(h1);
1293  i = IDELEMS(h2)-1;
1294  if (k == 0)
1295  {
1296    for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
1297    k = 1;
1298  }
1299  if (syzcomp<k)
1300  {
1301    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
1302    syzcomp = k;
1303    rSetSyzComp(k);
1304  }
1305  h2->rank = syzcomp+i+1;
1306  for (j=0; j<=i; j++)
1307  {
1308    p = h2->m[j];
1309    q = pOne();
1310    pSetComp(q,syzcomp+1+j);
1311    pSetmComp(q);
1312    if (p!=NULL)
1313    {
1314      while (pNext(p)) pIter(p);
1315      p->next = q;
1316    }
1317    else
1318      h2->m[j]=q;
1319  }
1320
1321#ifdef PDEBUG
1322  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
1323#endif
1324  h3=kStd(h2,currQuotient,h,w,NULL,syzcomp);
1325  idDelete(&h2);
1326  return h3;
1327}
1328
1329/*2
1330* compute the syzygies of h1 in R/quot,
1331* weights of components are in w
1332* if setRegularity, return the regularity in deg
1333* do not change h1,  w
1334*/
1335ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
1336                  BOOLEAN setRegularity, int *deg)
1337{
1338  ideal s_h1;
1339  poly  p;
1340  int   i, j, k, length=0,reg;
1341  BOOLEAN isMonomial=TRUE;
1342  int ii;
1343
1344#ifdef PDEBUG
1345  for(ii=0;ii<IDELEMS(h1);ii++) pTest(h1->m[ii]);
1346#endif
1347  if (idIs0(h1))
1348  {
1349    ideal result=idFreeModule(IDELEMS(h1));
1350    int curr_syz_limit=rGetCurrSyzLimit();
1351    if (curr_syz_limit>0)
1352    for (ii=0;ii<IDELEMS(h1);ii++)
1353    {
1354      if (h1->m[ii]!=NULL)
1355        pShift(&h1->m[ii],curr_syz_limit);
1356    }
1357    return result;
1358  }
1359  k=max(1,idRankFreeModule(h1));
1360
1361  assume(currRing != NULL);
1362  ring orig_ring=currRing;
1363  ring syz_ring=rCurrRingAssure_SyzComp();
1364
1365  if (setSyzComp)
1366    rSetSyzComp(k);
1367
1368  if (orig_ring != syz_ring)
1369  {
1370    s_h1=idrCopyR_NoSort(h1,orig_ring);
1371  }
1372  else
1373  {
1374    s_h1 = h1;
1375  }
1376
1377  ideal s_h3=idPrepare(s_h1,h,k,w);
1378
1379  if (s_h3==NULL)
1380  {
1381    return idFreeModule(IDELEMS(h1));
1382  }
1383
1384  if (orig_ring != syz_ring)
1385  {
1386    idDelete(&s_h1);
1387    for (j=0; j<IDELEMS(s_h3); j++)
1388    {
1389      if (s_h3->m[j] != NULL)
1390      {
1391        if (p_MinComp(s_h3->m[j],syz_ring) > k)
1392          pShift(&s_h3->m[j], -k);
1393        else
1394          pDelete(&s_h3->m[j]);
1395      }
1396    }
1397    idSkipZeroes(s_h3);
1398    s_h3->rank -= k;
1399    rChangeCurrRing(orig_ring);
1400    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
1401    rKill(syz_ring);
1402    idTest(s_h3);
1403    return s_h3;
1404  }
1405
1406  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
1407
1408  for (j=0; j<IDELEMS(s_h3); j++)
1409  {
1410    if (s_h3->m[j] != NULL)
1411    {
1412      if (p_MinComp(s_h3->m[j],syz_ring) <= k)
1413      {
1414        e->m[j] = s_h3->m[j];
1415        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
1416        pDelete(&pNext(s_h3->m[j]));
1417        s_h3->m[j] = NULL;
1418      }
1419    }
1420  }
1421
1422  idSkipZeroes(s_h3);
1423  idSkipZeroes(e);
1424
1425  if (deg != NULL
1426  && (!isMonomial)
1427  && (!TEST_OPT_NOTREGULARITY)
1428  && (setRegularity)
1429  && (h==isHomog))
1430  {
1431    ring dp_C_ring = rCurrRingAssure_dp_C();
1432    if (dp_C_ring != syz_ring)
1433      e = idrMoveR_NoSort(e, syz_ring);
1434    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
1435    intvec * dummy = syBetti(res,length,&reg, *w);
1436    *deg = reg+2;
1437    delete dummy;
1438    for (j=0;j<length;j++)
1439    {
1440      if (res[j]!=NULL) idDelete(&(res[j]));
1441    }
1442    omFreeSize((ADDRESS)res,length*sizeof(ideal));
1443    idDelete(&e);
1444    if (dp_C_ring != syz_ring)
1445    {
1446      rChangeCurrRing(syz_ring);
1447      rKill(dp_C_ring);
1448    }
1449  }
1450  else
1451  {
1452    idDelete(&e);
1453  }
1454  idTest(s_h3);
1455  if (currQuotient != NULL)
1456  {
1457    ideal ts_h3=kStd(s_h3,currQuotient,h,w);
1458    idDelete(&s_h3);
1459    s_h3 = ts_h3;
1460  }
1461  return s_h3;
1462}
1463
1464/*2
1465*/
1466ideal idXXX (ideal  h1, int k)
1467{
1468  ideal s_h1;
1469  int j;
1470  intvec *w=NULL;
1471
1472  assume(currRing != NULL);
1473  ring orig_ring=currRing;
1474  ring syz_ring=rCurrRingAssure_SyzComp();
1475
1476  rSetSyzComp(k);
1477
1478  if (orig_ring != syz_ring)
1479  {
1480    s_h1=idrCopyR_NoSort(h1,orig_ring);
1481  }
1482  else
1483  {
1484    s_h1 = h1;
1485  }
1486
1487  ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
1488
1489  if (s_h3==NULL)
1490  {
1491    return idFreeModule(IDELEMS(h1));
1492  }
1493
1494  if (orig_ring != syz_ring)
1495  {
1496    idDelete(&s_h1);
1497    idSkipZeroes(s_h3);
1498    rChangeCurrRing(orig_ring);
1499    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
1500    rKill(syz_ring);
1501    idTest(s_h3);
1502    return s_h3;
1503  }
1504
1505  idSkipZeroes(s_h3);
1506  idTest(s_h3);
1507  return s_h3;
1508}
1509
1510/*
1511*computes a standard basis for h1 and stores the transformation matrix
1512* in ma
1513*/
1514ideal idLiftStd (ideal  h1, matrix* ma, tHomog h)
1515{
1516  int   i, j, k, t, inputIsIdeal=idRankFreeModule(h1);
1517  poly  p=NULL, q, qq;
1518  intvec *w=NULL;
1519
1520  idDelete((ideal*)ma);
1521  *ma=mpNew(1,0);
1522  if (idIs0(h1))
1523    return idInit(1,h1->rank);
1524  k=max(1,idRankFreeModule(h1));
1525
1526  ring orig_ring=currRing;
1527  ring syz_ring=rCurrRingAssure_SyzComp();
1528  rSetSyzComp(k);
1529
1530  ideal s_h1=h1;
1531
1532  if (orig_ring != syz_ring)
1533    s_h1 = idrCopyR_NoSort(h1,orig_ring);
1534  else
1535    s_h1 = h1;
1536
1537  ideal s_h3=idPrepare(s_h1,h,k,&w);
1538  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
1539
1540  if (w!=NULL) delete w;
1541  i = 0;
1542  for (j=0; j<IDELEMS(s_h3); j++)
1543  {
1544    if ((s_h3->m[j] != NULL) && (p_MinComp(s_h3->m[j],syz_ring) <= k))
1545    {
1546      i++;
1547      q = s_h3->m[j];
1548      while (pNext(q) != NULL)
1549      {
1550        if (pGetComp(pNext(q)) > k)
1551        {
1552          s_h2->m[j] = pNext(q);
1553          pNext(q) = NULL;
1554        }
1555        else
1556        {
1557          pIter(q);
1558        }
1559      }
1560      if (!inputIsIdeal) pShift(&(s_h3->m[j]), -1);
1561    }
1562    else
1563    {
1564      pDelete(&(s_h3->m[j]));
1565    }
1566  }
1567
1568  idSkipZeroes(s_h3);
1569  j = IDELEMS(s_h1);
1570
1571  if (syz_ring!=orig_ring)
1572  {
1573    idDelete(&s_h1);
1574    rChangeCurrRing(orig_ring);
1575  }
1576
1577  idDelete((ideal*)ma);
1578  *ma = mpNew(j,i);
1579
1580  i = 1;
1581  for (j=0; j<IDELEMS(s_h2); j++)
1582  {
1583    if (s_h2->m[j] != NULL)
1584    {
1585      q = prMoveR( s_h2->m[j], syz_ring);
1586      s_h2->m[j] = NULL;
1587
1588      while (q != NULL)
1589      {
1590        p = q;
1591        pIter(q);
1592        pNext(p) = NULL;
1593        t=pGetComp(p);
1594        pSetComp(p,0);
1595        pSetmComp(p);
1596        MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
1597      }
1598      i++;
1599    }
1600  }
1601  idDelete(&s_h2);
1602
1603  for (i=0; i<IDELEMS(s_h3); i++)
1604  {
1605    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring);
1606  }
1607
1608  if (syz_ring!=orig_ring) rKill(syz_ring);
1609  return s_h3;
1610}
1611
1612static void idPrepareStd(ideal s_temp, int k)
1613{
1614  int j,rk=idRankFreeModule(s_temp);
1615  poly p,q;
1616
1617  if (rk == 0)
1618  {
1619    for (j=0; j<IDELEMS(s_temp); j++)
1620    {
1621      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
1622    }
1623    k = max(k,1);
1624  }
1625  for (j=0; j<IDELEMS(s_temp); j++)
1626  {
1627    if (s_temp->m[j]!=NULL)
1628    {
1629      p = s_temp->m[j];
1630      q = pOne();
1631      //pGetCoeff(q)=nNeg(pGetCoeff(q));   //set q to -1
1632      pSetComp(q,k+1+j);
1633      pSetmComp(q);
1634      while (pNext(p)) pIter(p);
1635      pNext(p) = q;
1636    }
1637  }
1638}
1639
1640/*2
1641*computes a representation of the generators of submod with respect to those
1642* of mod
1643*/
1644
1645ideal   idLift (ideal mod, ideal submod,ideal * rest, BOOLEAN goodShape,
1646               BOOLEAN isSB,BOOLEAN divide,matrix * unit)
1647{
1648  int lsmod =idRankFreeModule(submod), i, j, k;
1649  int comps_to_add=0;
1650  poly p;
1651
1652  if (idIs0(submod))
1653  {
1654    if (unit!=NULL)
1655    {
1656      *unit=mpNew(1,1);
1657      MATELEM(*unit,1,1)=pOne();
1658    }
1659    if (rest!=NULL)
1660    {
1661      *rest=idInit(1,mod->rank);
1662    }
1663    return idInit(1,mod->rank);
1664  }
1665  if (idIs0(mod))
1666  {
1667    if (unit!=NULL)
1668    {
1669      i=IDELEMS(submod);
1670      *unit=mpNew(i,i);
1671      for (j=i;j>0;j--)
1672      {
1673        MATELEM(*unit,j,j)=pOne();
1674      }
1675    }
1676    if (rest!=NULL)
1677    {
1678      *rest=idCopy(submod);
1679    }
1680    return idInit(1,mod->rank);
1681  }
1682  if (unit!=NULL)
1683  {
1684    comps_to_add = IDELEMS(submod);
1685    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
1686      comps_to_add--;
1687  }
1688  k=idRankFreeModule(mod);
1689  if  ((k!=0) && (lsmod==0)) lsmod=1;
1690  k=max(k,1);
1691
1692  ring orig_ring=currRing;
1693  ring syz_ring=rCurrRingAssure_SyzComp();
1694  rSetSyzComp(k);
1695
1696  ideal s_mod, s_temp;
1697  if (orig_ring != syz_ring)
1698  {
1699    s_mod = idrCopyR_NoSort(mod,orig_ring);
1700    s_temp = idrCopyR_NoSort(submod,orig_ring);
1701  }
1702  else
1703  {
1704    s_mod = mod;
1705    s_temp = idCopy(submod);
1706  }
1707  ideal s_h3;
1708  if (isSB)
1709  {
1710    s_h3 = idCopy(s_mod);
1711    idPrepareStd(s_h3, k+comps_to_add);
1712  }
1713  else
1714  {
1715    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
1716  }
1717  if (!goodShape)
1718  {
1719    for (j=0;j<IDELEMS(s_h3);j++)
1720    {
1721      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
1722        pDelete(&(s_h3->m[j]));
1723    }
1724  }
1725  idSkipZeroes(s_h3);
1726  if (lsmod==0)
1727  {
1728    for (j=IDELEMS(s_temp);j>0;j--)
1729    {
1730      if (s_temp->m[j-1]!=NULL)
1731        pShift(&(s_temp->m[j-1]),1);
1732    }
1733  }
1734  if (unit!=NULL)
1735  {
1736    for(j = 0;j<comps_to_add;j++)
1737    {
1738      p = s_temp->m[j];
1739      if (p!=NULL)
1740      {
1741        while (pNext(p)!=NULL) pIter(p);
1742        pNext(p) = pOne();
1743        pIter(p);
1744        pSetComp(p,1+j+k);
1745        pSetmComp(p);
1746        p = pNeg(p);
1747      }
1748    }
1749  }
1750  ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
1751  s_result->rank = s_h3->rank;
1752  ideal s_rest = idInit(IDELEMS(s_result),k);
1753  idDelete(&s_h3);
1754  idDelete(&s_temp);
1755
1756  for (j=0;j<IDELEMS(s_result);j++)
1757  {
1758    if (s_result->m[j]!=NULL)
1759    {
1760      if (pGetComp(s_result->m[j])<=k)
1761      {
1762        if (!divide)
1763        {
1764          if (isSB)
1765          {
1766            WarnS("first module not a standardbasis\n"
1767              "// ** or second not a proper submodule");
1768          }
1769          else
1770            WerrorS("2nd module lies not in the first");
1771          idDelete(&s_result);
1772          idDelete(&s_rest);
1773          s_result=idInit(IDELEMS(submod),submod->rank);
1774          break;
1775        }
1776        else
1777        {
1778          p = s_rest->m[j] = s_result->m[j];
1779          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1780          s_result->m[j] = pNext(p);
1781          pNext(p) = NULL;
1782        }
1783      }
1784      pShift(&(s_result->m[j]),-k);
1785      pNeg(s_result->m[j]);
1786    }
1787  }
1788  if ((lsmod==0) && (!idIs0(s_rest)))
1789  {
1790    for (j=IDELEMS(s_rest);j>0;j--)
1791    {
1792      if (s_rest->m[j-1]!=NULL)
1793      {
1794        pShift(&(s_rest->m[j-1]),-1);
1795        s_rest->m[j-1] = pNeg(s_rest->m[j-1]);
1796      }
1797    }
1798  }
1799  if(syz_ring!=orig_ring)
1800  {
1801    idDelete(&s_mod);
1802    rChangeCurrRing(orig_ring);
1803    s_result = idrMoveR_NoSort(s_result, syz_ring);
1804    s_rest = idrMoveR_NoSort(s_rest, syz_ring);
1805    rKill(syz_ring);
1806  }
1807  if (rest!=NULL)
1808    *rest = s_rest;
1809  else
1810    idDelete(&s_rest);
1811//idPrint(s_result);
1812  if (unit!=NULL)
1813  {
1814    *unit=mpNew(comps_to_add,comps_to_add);
1815    int i;
1816    for(i=0;i<IDELEMS(s_result);i++)
1817    {
1818      poly p=s_result->m[i];
1819      poly q=NULL;
1820      while(p!=NULL)
1821      {
1822        if(pGetComp(p)<=comps_to_add)
1823        {
1824          pSetComp(p,0);
1825          if (q!=NULL)
1826          {
1827            pNext(q)=pNext(p);
1828          }
1829          else
1830          {
1831            pIter(s_result->m[i]);
1832          }
1833          pNext(p)=NULL;
1834          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
1835          if(q!=NULL)   p=pNext(q);
1836          else          p=s_result->m[i];
1837        }
1838        else
1839        {
1840          q=p;
1841          pIter(p);
1842        }
1843      }
1844      pShift(&s_result->m[i],-comps_to_add);
1845    }
1846  }
1847  return s_result;
1848}
1849
1850/*2
1851*computes the quotient of h1,h2 : interanl routine for idQuot
1852*BEWARE: the returned ideals may contain incorrected orderd polys !
1853*
1854*/
1855static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
1856                               BOOLEAN *addOnlyOne, int *kkmax)
1857{
1858  ideal temph1;
1859  poly     p,q = NULL;
1860  int i,l,ll,k,kkk,kmax;
1861  int j = 0;
1862  int k1 = idRankFreeModule(h1);
1863  int k2 = idRankFreeModule(h2);
1864  tHomog   hom=isNotHomog;
1865
1866  k=max(k1,k2);
1867  if (k==0)
1868    k = 1;
1869  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
1870
1871  intvec * weights;
1872  hom = (tHomog)idHomModule(h1,currQuotient,&weights);
1873  if (addOnlyOne && (!h1IsStb))
1874    temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
1875  else
1876    temph1 = idCopy(h1);
1877  if (weights!=NULL) delete weights;
1878  idTest(temph1);
1879/*--- making a single vector from h2 ---------------------*/
1880  for (i=0; i<IDELEMS(h2); i++)
1881  {
1882    if (h2->m[i] != NULL)
1883    {
1884      p = pCopy(h2->m[i]);
1885      if (k2 == 0)
1886        pShift(&p,j*k+1);
1887      else
1888        pShift(&p,j*k);
1889      q = pAdd(q,p);
1890      j++;
1891    }
1892  }
1893  *kkmax = kmax = j*k+1;
1894/*--- adding a monomial for the result (syzygy) ----------*/
1895  p = q;
1896  while (pNext(p)!=NULL) pIter(p);
1897  pNext(p) = pOne();
1898  pIter(p);
1899  pSetComp(p,kmax);
1900  pSetmComp(p);
1901/*--- constructing the big matrix ------------------------*/
1902  ideal h4 = idInit(16,kmax+k-1);
1903  h4->m[0] = q;
1904  if (k2 == 0)
1905  {
1906    if (k > IDELEMS(h4))
1907    {
1908      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
1909      IDELEMS(h4) = k;
1910    }
1911    for (i=1; i<k; i++)
1912    {
1913      p = pCopy_noCheck(h4->m[i-1]);
1914      pShift(&p,1);
1915      h4->m[i] = p;
1916    }
1917  }
1918
1919  kkk = IDELEMS(h4);
1920  i = IDELEMS(temph1);
1921  while ((i>0) && (temph1->m[i-1]==NULL)) i--;
1922  for (l=0; l<i; l++)
1923  {
1924    if(temph1->m[l]!=NULL)
1925    {
1926      for (ll=0; ll<j; ll++)
1927      {
1928        p = pCopy(temph1->m[l]);
1929        if (k1 == 0)
1930          pShift(&p,ll*k+1);
1931        else
1932          pShift(&p,ll*k);
1933        if (kkk >= IDELEMS(h4))
1934        {
1935          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
1936          IDELEMS(h4) += 16;
1937        }
1938        h4->m[kkk] = p;
1939        kkk++;
1940      }
1941    }
1942  }
1943/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
1944  if (*addOnlyOne)
1945  {
1946    p = h4->m[0];
1947    for (i=0;i<IDELEMS(h4)-1;i++)
1948    {
1949      h4->m[i] = h4->m[i+1];
1950    }
1951    h4->m[IDELEMS(h4)-1] = p;
1952    idSkipZeroes(h4);
1953    test |= Sy_bit(OPT_SB_1);
1954  }
1955  idDelete(&temph1);
1956  return h4;
1957}
1958/*2
1959*computes the quotient of h1,h2
1960*/
1961ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
1962{
1963  // first check for special case h1:(0)
1964  if (idIs0(h2))
1965  {
1966    ideal res;
1967    if (resultIsIdeal)
1968    {
1969      res = idInit(1,1);
1970      res->m[0] = pOne();
1971    }
1972    else
1973      res = idFreeModule(h1->rank);
1974    return res;
1975  }
1976  BITSET old_test=test;
1977  poly     p,q = NULL;
1978  int i,l,ll,k,kkk,kmax;
1979  BOOLEAN  addOnlyOne=TRUE;
1980  tHomog   hom=isNotHomog;
1981  intvec * weights1;
1982
1983  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
1984
1985  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
1986
1987  ring orig_ring=currRing;
1988  ring syz_ring=rCurrRingAssure_SyzComp();
1989  rSetSyzComp(kmax-1);
1990  if (orig_ring!=syz_ring)
1991  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
1992    s_h4 = idrMoveR(s_h4,orig_ring);
1993  idTest(s_h4);
1994  ideal s_h3;
1995  if (addOnlyOne)
1996  {
1997    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1,IDELEMS(s_h4)-1);
1998  }
1999  else
2000  {
2001    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
2002  }
2003  idTest(s_h3);
2004  if (weights1!=NULL) delete weights1;
2005  idDelete(&s_h4);
2006
2007
2008  for (i=0;i<IDELEMS(s_h3);i++)
2009  {
2010    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
2011    {
2012      if (resultIsIdeal)
2013        pShift(&s_h3->m[i],-kmax);
2014      else
2015        pShift(&s_h3->m[i],-kmax+1);
2016    }
2017    else
2018      pDelete(&s_h3->m[i]);
2019  }
2020  if (resultIsIdeal)
2021    s_h3->rank = 1;
2022  else
2023    s_h3->rank = h1->rank;
2024  if(syz_ring!=orig_ring)
2025  {
2026//    pDelete(&q);
2027    rChangeCurrRing(orig_ring);
2028    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
2029    rKill(syz_ring);
2030  }
2031  idSkipZeroes(s_h3);
2032  test = old_test;
2033  idTest(s_h3);
2034  return s_h3;
2035}
2036
2037/*2
2038*computes recursively all monomials of a certain degree
2039*in every step the actvar-th entry in the exponential
2040*vector is incremented and the other variables are
2041*computed by recursive calls of makemonoms
2042*if the last variable is reached, the difference to the
2043*degree is computed directly
2044*vars is the number variables
2045*actvar is the actual variable to handle
2046*deg is the degree of the monomials to compute
2047*monomdeg is the actual degree of the monomial in consideration
2048*/
2049static void makemonoms(int vars,int actvar,int deg,int monomdeg)
2050{
2051  poly p;
2052  int i=0;
2053
2054  if ((idpowerpoint == 0) && (actvar ==1))
2055  {
2056    idpower[idpowerpoint] = pOne();
2057    monomdeg = 0;
2058  }
2059  while (i<=deg)
2060  {
2061    if (deg == monomdeg)
2062    {
2063      pSetm(idpower[idpowerpoint]);
2064      idpowerpoint++;
2065      return;
2066    }
2067    if (actvar == vars)
2068    {
2069      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
2070      pSetm(idpower[idpowerpoint]);
2071      pTest(idpower[idpowerpoint]);
2072      idpowerpoint++;
2073      return;
2074    }
2075    else
2076    {
2077      p = pCopy(idpower[idpowerpoint]);
2078      makemonoms(vars,actvar+1,deg,monomdeg);
2079      idpower[idpowerpoint] = p;
2080    }
2081    monomdeg++;
2082    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
2083    pSetm(idpower[idpowerpoint]);
2084    pTest(idpower[idpowerpoint]);
2085    i++;
2086  }
2087}
2088
2089/*2
2090*returns the deg-th power of the maximal ideal of 0
2091*/
2092ideal idMaxIdeal(int deg)
2093{
2094  if (deg < 0)
2095  {
2096    WarnS("maxideal: power must be non-negative");
2097  }
2098  if (deg < 1)
2099  {
2100    ideal I=idInit(1,1);
2101    I->m[0]=pOne();
2102    return I;
2103  }
2104  if (deg == 1)
2105  {
2106    return idMaxIdeal();
2107  }
2108
2109  int vars = currRing->N;
2110  int i = binom(vars+deg-1,deg);
2111  ideal id=idInit(i,1);
2112  idpower = id->m;
2113  idpowerpoint = 0;
2114  makemonoms(vars,1,deg,0);
2115  idpower = NULL;
2116  idpowerpoint = 0;
2117  return id;
2118}
2119
2120/*2
2121*computes recursively all generators of a certain degree
2122*of the ideal "givenideal"
2123*elms is the number elements in the given ideal
2124*actelm is the actual element to handle
2125*deg is the degree of the power to compute
2126*gendeg is the actual degree of the generator in consideration
2127*/
2128static void makepotence(int elms,int actelm,int deg,int gendeg)
2129{
2130  poly p;
2131  int i=0;
2132
2133  if ((idpowerpoint == 0) && (actelm ==1))
2134  {
2135    idpower[idpowerpoint] = pOne();
2136    gendeg = 0;
2137  }
2138  while (i<=deg)
2139  {
2140    if (deg == gendeg)
2141    {
2142      idpowerpoint++;
2143      return;
2144    }
2145    if (actelm == elms)
2146    {
2147      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
2148      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
2149      idpowerpoint++;
2150      return;
2151    }
2152    else
2153    {
2154      p = pCopy(idpower[idpowerpoint]);
2155      makepotence(elms,actelm+1,deg,gendeg);
2156      idpower[idpowerpoint] = p;
2157    }
2158    gendeg++;
2159    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
2160    i++;
2161  }
2162}
2163
2164/*2
2165*returns the deg-th power of the ideal gid
2166*/
2167//ideal idPower(ideal gid,int deg)
2168//{
2169//  int i;
2170//  ideal id;
2171//
2172//  if (deg < 1) deg = 1;
2173//  i = binom(IDELEMS(gid)+deg-1,deg);
2174//  id=idInit(i,1);
2175//  idpower = id->m;
2176//  givenideal = gid->m;
2177//  idpowerpoint = 0;
2178//  makepotence(IDELEMS(gid),1,deg,0);
2179//  idpower = NULL;
2180//  givenideal = NULL;
2181//  idpowerpoint = 0;
2182//  return id;
2183//}
2184static void idNextPotence(ideal given, ideal result,
2185  int begin, int end, int deg, int restdeg, poly ap)
2186{
2187  poly p;
2188  int i;
2189
2190  p = pPower(pCopy(given->m[begin]),restdeg);
2191  i = result->nrows;
2192  result->m[i] = pMult(pCopy(ap),p);
2193//PrintS(".");
2194  (result->nrows)++;
2195  if (result->nrows >= IDELEMS(result))
2196  {
2197    pEnlargeSet(&(result->m),IDELEMS(result),16);
2198    IDELEMS(result) += 16;
2199  }
2200  if (begin == end) return;
2201  for (i=restdeg-1;i>0;i--)
2202  {
2203    p = pPower(pCopy(given->m[begin]),i);
2204    p = pMult(pCopy(ap),p);
2205    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
2206    pDelete(&p);
2207  }
2208  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
2209}
2210
2211ideal idPower(ideal given,int exp)
2212{
2213  ideal result,temp;
2214  poly p1;
2215  int i;
2216
2217  if (idIs0(given)) return idInit(1,1);
2218  temp = idCopy(given);
2219  idSkipZeroes(temp);
2220  i = binom(IDELEMS(temp)+exp-1,exp);
2221  result = idInit(i,1);
2222  result->nrows = 0;
2223//Print("ideal contains %d elements\n",i);
2224  p1=pOne();
2225  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
2226  pDelete(&p1);
2227  idDelete(&temp);
2228  result->nrows = 1;
2229  idSkipZeroes(result);
2230  idDelEquals(result);
2231  return result;
2232}
2233
2234/*2
2235* eliminate delVar (product of vars) in h1
2236*/
2237ideal idElimination (ideal h1,poly delVar,intvec *hilb)
2238{
2239  int    i,j=0,k,l;
2240  ideal  h,hh, h3;
2241  int    *ord,*block0,*block1;
2242  int    ordersize=2;
2243  int    **wv;
2244  tHomog hom;
2245  intvec * w;
2246  sip_sring tmpR;
2247  ring origR = currRing;
2248
2249  if (delVar==NULL)
2250  {
2251    return idCopy(h1);
2252  }
2253  if (currQuotient!=NULL)
2254  {
2255    WerrorS("cannot eliminate in a qring");
2256    return idCopy(h1);
2257  }
2258  if (idIs0(h1)) return idInit(1,h1->rank);
2259  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
2260  h3=idInit(16,h1->rank);
2261  for (k=0;; k++)
2262  {
2263    if (currRing->order[k]!=0) ordersize++;
2264    else break;
2265  }
2266  ord=(int*)omAlloc0(ordersize*sizeof(int));
2267  block0=(int*)omAlloc(ordersize*sizeof(int));
2268  block1=(int*)omAlloc(ordersize*sizeof(int));
2269  for (k=0;; k++)
2270  {
2271    if (currRing->order[k]!=0)
2272    {
2273      block0[k+1] = currRing->block0[k];
2274      block1[k+1] = currRing->block1[k];
2275      ord[k+1] = currRing->order[k];
2276    }
2277    else
2278      break;
2279  }
2280  block0[0] = 1;
2281  block1[0] = pVariables;
2282  wv=(int**) omAlloc0(ordersize*sizeof(int**));
2283  memcpy4(wv+1,currRing->wvhdl,(ordersize-1)*sizeof(int**));
2284  wv[0]=(int*)omAlloc((pVariables+1)*sizeof(int));
2285  memset(wv[0],0,(pVariables+1)*sizeof(int));
2286  for (j=0;j<pVariables;j++)
2287    if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2288  // use this special ordering: like ringorder_a, except that pFDeg, pWeights
2289  // ignore it
2290  ord[0] = ringorder_aa;
2291
2292  // fill in tmp ring to get back the data later on
2293  tmpR  = *origR;
2294  tmpR.order = ord;
2295  tmpR.block0 = block0;
2296  tmpR.block1 = block1;
2297  tmpR.wvhdl = wv;
2298  rComplete(&tmpR, 1);
2299
2300  // change into the new ring
2301  //pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
2302  rChangeCurrRing(&tmpR);
2303  h = idInit(IDELEMS(h1),h1->rank);
2304  // fetch data from the old ring
2305  for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
2306  // compute kStd
2307  hh = kStd(h,NULL,hom,&w,hilb);
2308  idDelete(&h);
2309
2310  // go back to the original ring
2311  rChangeCurrRing(origR);
2312  i = IDELEMS(hh)-1;
2313  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2314  j = -1;
2315  // fetch data from temp ring
2316  for (k=0; k<=i; k++)
2317  {
2318    l=pVariables;
2319    while ((l>0) && (p_GetExp( hh->m[k],l,&tmpR)*pGetExp(delVar,l)==0)) l--;
2320    if (l==0)
2321    {
2322      j++;
2323      if (j >= IDELEMS(h3))
2324      {
2325        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2326        IDELEMS(h3) += 16;
2327      }
2328      h3->m[j] = prCopyR( hh->m[k], &tmpR);
2329    }
2330  }
2331  id_Delete(&hh, &tmpR);
2332  idSkipZeroes(h3);
2333  omFree((ADDRESS)wv[0]);
2334  omFreeSize((ADDRESS)wv,ordersize*sizeof(int**));
2335  omFreeSize((ADDRESS)ord,ordersize*sizeof(int));
2336  omFreeSize((ADDRESS)block0,ordersize*sizeof(int));
2337  omFreeSize((ADDRESS)block1,ordersize*sizeof(int));
2338  rUnComplete(&tmpR);
2339  if (w!=NULL)
2340    delete w;
2341  return h3;
2342}
2343
2344#ifdef WITH_OLD_MINOR
2345/*2
2346* compute all ar-minors of the matrix a
2347*/
2348ideal idMinors(matrix a, int ar, ideal R)
2349{
2350  int     i,j,k,size;
2351  int *rowchoise,*colchoise;
2352  BOOLEAN rowch,colch;
2353  ideal result;
2354  matrix tmp;
2355  poly p,q;
2356
2357  i = binom(a->rows(),ar);
2358  j = binom(a->cols(),ar);
2359
2360  rowchoise=(int *)omAlloc(ar*sizeof(int));
2361  colchoise=(int *)omAlloc(ar*sizeof(int));
2362  if ((i>512) || (j>512) || (i*j >512)) size=512;
2363  else size=i*j;
2364  result=idInit(size,1);
2365  tmp=mpNew(ar,ar);
2366  k = 0; /* the index in result*/
2367  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2368  while (!rowch)
2369  {
2370    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2371    while (!colch)
2372    {
2373      for (i=1; i<=ar; i++)
2374      {
2375        for (j=1; j<=ar; j++)
2376        {
2377          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2378        }
2379      }
2380      p = mpDetBareiss(tmp);
2381      if (p!=NULL)
2382      {
2383        if (R!=NULL)
2384        {
2385          q = p;
2386          p = kNF(R,currQuotient,q);
2387          pDelete(&q);
2388        }
2389        if (p!=NULL)
2390        {
2391          if (k>=size)
2392          {
2393            pEnlargeSet(&result->m,size,32);
2394            size += 32;
2395          }
2396          result->m[k] = p;
2397          k++;
2398        }
2399      }
2400      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2401    }
2402    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2403  }
2404  /*delete the matrix tmp*/
2405  for (i=1; i<=ar; i++)
2406  {
2407    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2408  }
2409  idDelete((ideal*)&tmp);
2410  if (k==0)
2411  {
2412    k=1;
2413    result->m[0]=NULL;
2414  }
2415  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2416  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2417  pEnlargeSet(&result->m,size,k-size);
2418  IDELEMS(result) = k;
2419  return (result);
2420}
2421#else
2422/*2
2423* compute all ar-minors of the matrix a
2424* the caller of mpRecMin
2425* the elements of the result are not in R (if R!=NULL)
2426*/
2427ideal idMinors(matrix a, int ar, ideal R)
2428{
2429  int elems=0;
2430  int r=a->nrows,c=a->ncols;
2431  int i;
2432  matrix b;
2433  ideal result,h;
2434  ring origR;
2435  sip_sring tmpR;
2436  Exponent_t bound;
2437
2438  if((ar<=0) || (ar>r) || (ar>c))
2439  {
2440    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
2441    return NULL;
2442  }
2443  h = idMatrix2Module(mpCopy(a));
2444  bound = smExpBound(h,c,r,ar);
2445  idDelete(&h);
2446  smRingChange(&origR,tmpR,bound);
2447  b = mpNew(r,c);
2448  for (i=r*c-1;i>=0;i--)
2449  {
2450    if (a->m[i])
2451      b->m[i] = prCopyR(a->m[i],origR);
2452  }
2453  if (R) R = idrCopyR(R,origR);
2454  result=idInit(32,1);
2455  if(ar>1) mpRecMin(ar-1,result,elems,b,r,c,NULL,R);
2456  else mpMinorToResult(result,elems,b,r,c,R);
2457  idDelete((ideal *)&b);
2458  if (R) idDelete(&R);
2459  idSkipZeroes(result);
2460  rChangeCurrRing(origR);
2461  result = idrMoveR(result,&tmpR);
2462  smRingClean(origR,tmpR);
2463  idTest(result);
2464  return result;
2465}
2466#endif
2467
2468/*2
2469*skips all zeroes and double elements, searches also for units
2470*/
2471ideal idCompactify(ideal id)
2472{
2473  int i,j;
2474  BOOLEAN b=FALSE;
2475
2476  i = IDELEMS(id)-1;
2477  while ((! b) && (i>=0))
2478  {
2479    b=pIsUnit(id->m[i]);
2480    i--;
2481  }
2482  if (b)
2483  {
2484    ideal result=idInit(1,id->rank);
2485    result->m[0]=pOne();
2486    return result;
2487  }
2488  else
2489  {
2490    ideal result=idCopy(id);
2491    //if (IDELEMS(result) < 1)
2492    {
2493      for (i=1;i<IDELEMS(result);i++)
2494      {
2495        if (result->m[i]!=NULL)
2496        {
2497          for (j=0;j<i;j++)
2498          {
2499            if ((result->m[j]!=NULL)
2500            && (pComparePolys(result->m[i],result->m[j])))
2501            {
2502              pDelete(&(result->m[j]));
2503            }
2504          }
2505        }
2506      }
2507    }
2508//    else
2509//    {
2510//      intvec *v=idSort(result,TRUE);
2511//      for(i=0;i<IDELEMS(result);i++)
2512//        (*v)[i]--;
2513//      for (i=0;i<IDELEMS(result)-1;i++)
2514//      {
2515//        if (((*v)[i]>=0)
2516//        && (result->m[(*v)[i]]!=NULL))
2517//        {
2518//          j=i+1;
2519//          while ((j<IDELEMS(result))
2520//          && ((*v)[j]>=0)
2521//          && (result->m[(*v)[j]]!=NULL)
2522//          && (pComparePolys(result->m[(*v)[i]],result->m[(*v)[j]])))
2523//          {
2524//            pDelete(&(result->m[(*v)[j]]));
2525//            j++;
2526//          }
2527//        }
2528//      }
2529//      delete v;
2530//    }
2531    idSkipZeroes(result);
2532    return result;
2533  }
2534}
2535
2536/*2
2537*returns TRUE if id1 is a submodule of id2
2538*/
2539BOOLEAN idIsSubModule(ideal id1,ideal id2)
2540{
2541  int i;
2542  poly p;
2543
2544  if (idIs0(id1)) return TRUE;
2545  for (i=0;i<IDELEMS(id1);i++)
2546  {
2547    if (id1->m[i] != NULL)
2548    {
2549      p = kNF(id2,currQuotient,id1->m[i]);
2550      if (p != NULL)
2551      {
2552        pDelete(&p);
2553        return FALSE;
2554      }
2555    }
2556  }
2557  return TRUE;
2558}
2559
2560/*2
2561* returns the ideals of initial terms
2562*/
2563ideal idHead(ideal h)
2564{
2565  ideal m = idInit(IDELEMS(h),h->rank);
2566  int i;
2567
2568  for (i=IDELEMS(h)-1;i>=0; i--)
2569  {
2570    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
2571  }
2572  return m;
2573}
2574
2575ideal idHomogen(ideal h, int varnum)
2576{
2577  ideal m = idInit(IDELEMS(h),h->rank);
2578  int i;
2579
2580  for (i=IDELEMS(h)-1;i>=0; i--)
2581  {
2582    m->m[i]=pHomogen(h->m[i],varnum);
2583  }
2584  return m;
2585}
2586
2587/*------------------type conversions----------------*/
2588ideal idVec2Ideal(poly vec)
2589{
2590   ideal result=idInit(1,1);
2591   omFree((ADDRESS)result->m);
2592   result->m=NULL; // remove later
2593   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2594   return result;
2595}
2596
2597// #define NEW_STUFF
2598#ifndef NEW_STUFF
2599// converts mat to module, destroys mat
2600ideal idMatrix2Module(matrix mat)
2601{
2602  ideal result = idInit(MATCOLS(mat),MATROWS(mat));
2603  int i,j;
2604  poly h;
2605#ifdef DRING
2606  poly p;
2607#endif
2608
2609  for(j=0;j<MATCOLS(mat);j++) /* j is also index in result->m */
2610  {
2611    for (i=1;i<=MATROWS(mat);i++)
2612    {
2613      h = MATELEM(mat,i,j+1);
2614      if (h!=NULL)
2615      {
2616        MATELEM(mat,i,j+1)=NULL;
2617        pSetCompP(h,i);
2618#ifdef DRING
2619        pdSetDFlagP(h,0);
2620#endif
2621        result->m[j] = pAdd(result->m[j],h);
2622      }
2623    }
2624  }
2625  // obachman: need to clean this up
2626  idDelete((ideal*) &mat);
2627  return result;
2628}
2629#else
2630
2631#include "sbuckets.h"
2632
2633// converts mat to module, destroys mat
2634ideal idMatrix2Module(matrix mat)
2635{
2636  ideal result = idInit(MATCOLS(mat),MATROWS(mat));
2637  int i,j, l;
2638  poly h;
2639  poly p;
2640  sBucket_pt bucket = sBucketInit(currRing);
2641
2642  for(j=0;j<MATCOLS(mat);j++) /* j is also index in result->m */
2643  {
2644    for (i=1;i<=MATROWS(mat);i++)
2645    {
2646      h = MATELEM(mat,i,j+1);
2647      if (h!=NULL)
2648      {
2649        MATELEM(mat,i,j+1)=NULL;
2650        p_SetCompP(h,i, currRing, &l);
2651        sBucket_Merge_p(bucket, h, l);
2652      }
2653    }
2654    sBucketClearMerge(bucket, &(result->m[j]), &l);
2655  }
2656
2657  // obachman: need to clean this up
2658  idDelete((ideal*) &mat);
2659  return result;
2660}
2661#endif
2662
2663/*2
2664* converts a module into a matrix, destroyes the input
2665*/
2666matrix idModule2Matrix(ideal mod)
2667{
2668  matrix result = mpNew(mod->rank,IDELEMS(mod));
2669  int i,cp;
2670  poly p,h;
2671
2672  for(i=0;i<IDELEMS(mod);i++)
2673  {
2674    p=mod->m[i];
2675    mod->m[i]=NULL;
2676    while (p!=NULL)
2677    {
2678      h=p;
2679      pIter(p);
2680      pNext(h)=NULL;
2681//      cp = max(1,pGetComp(h));     // if used for ideals too
2682      cp = pGetComp(h);
2683      pSetComp(h,0);
2684      pSetmComp(h);
2685#ifdef TEST
2686      if (cp>mod->rank)
2687      {
2688        Print("## inv. rank %d -> %d\n",mod->rank,cp);
2689        int k,l,o=mod->rank;
2690        mod->rank=cp;
2691        matrix d=mpNew(mod->rank,IDELEMS(mod));
2692        for (l=1; l<=o; l++)
2693        {
2694          for (k=1; k<=IDELEMS(mod); k++)
2695          {
2696            MATELEM(d,l,k)=MATELEM(result,l,k);
2697            MATELEM(result,l,k)=NULL;
2698          }
2699        }
2700        idDelete((ideal *)&result);
2701        result=d;
2702      }
2703#endif
2704      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2705    }
2706  }
2707  // obachman 10/99: added the following line, otherwise memory leack!
2708  idDelete(&mod);
2709  return result;
2710}
2711
2712matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
2713{
2714  matrix result = mpNew(rows,cols);
2715  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
2716  poly p,h;
2717
2718  if (r>rows) r = rows;
2719  if (c>cols) c = cols;
2720  for(i=0;i<c;i++)
2721  {
2722    p=mod->m[i];
2723    mod->m[i]=NULL;
2724    while (p!=NULL)
2725    {
2726      h=p;
2727      pIter(p);
2728      pNext(h)=NULL;
2729      cp = pGetComp(h);
2730      if (cp<=r)
2731      {
2732        pSetComp(h,0);
2733        pSetmComp(h);
2734        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2735      }
2736      else
2737        pDelete(&h);
2738    }
2739  }
2740  idDelete(&mod);
2741  return result;
2742}
2743
2744/*2
2745* substitute the n-th variable by the monomial e in id
2746* destroy id
2747*/
2748ideal  idSubst(ideal id, int n, poly e)
2749{
2750  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
2751  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
2752
2753  res->rank = id->rank;
2754  for(k--;k>=0;k--)
2755  {
2756    res->m[k]=pSubst(id->m[k],n,e);
2757    id->m[k]=NULL;
2758  }
2759  idDelete(&id);
2760  return res;
2761}
2762
2763BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
2764{
2765  if (w!=NULL) *w=NULL;
2766  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
2767  if (idIs0(m)) return TRUE;
2768
2769  int i,j,cmax=2,order=0,ord,* diff,* iscom,diffmin=32000;
2770  poly p=NULL;
2771  int length=IDELEMS(m);
2772  polyset P=m->m;
2773  polyset F=(polyset)omAlloc(length*sizeof(poly));
2774  for (i=length-1;i>=0;i--)
2775  {
2776    p=F[i]=P[i];
2777    cmax=max(cmax,pMaxComp(p)+1);
2778  }
2779  diff = (int *)omAlloc0(cmax*sizeof(int));
2780  if (w!=NULL) *w=new intvec(cmax-1);
2781  iscom = (int *)omAlloc0(cmax*sizeof(int));
2782  i=0;
2783  while (i<=length)
2784  {
2785    if (i<length)
2786    {
2787      p=F[i];
2788      while ((p!=NULL) && (!iscom[pGetComp(p)])) pIter(p);
2789    }
2790    if ((p==NULL) && (i<length))
2791    {
2792      i++;
2793    }
2794    else
2795    {
2796      if (p==NULL)
2797      {
2798        i=0;
2799        while ((i<length) && (F[i]==NULL)) i++;
2800        if (i>=length) break;
2801        p = F[i];
2802      }
2803      if (pLexOrder)
2804        order=pTotaldegree(p);
2805      else
2806      //  order = p->order;
2807        order = pFDeg(p);
2808      order += diff[pGetComp(p)];
2809      p = F[i];
2810//Print("Actual p=F[%d]: ",i);pWrite(p);
2811      F[i] = NULL;
2812      i=0;
2813    }
2814    while (p!=NULL)
2815    {
2816      //if (pLexOrder)
2817      //  ord=pTotaldegree(p);
2818      //else
2819      //  ord = p->order;
2820      ord = pFDeg(p);
2821      if (!iscom[pGetComp(p)])
2822      {
2823        diff[pGetComp(p)] = order-ord;
2824        iscom[pGetComp(p)] = 1;
2825/*
2826*PrintS("new diff: ");
2827*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2828*PrintLn();
2829*PrintS("new iscom: ");
2830*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
2831*PrintLn();
2832*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
2833*/
2834      }
2835      else
2836      {
2837/*
2838*PrintS("new diff: ");
2839*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2840*PrintLn();
2841*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
2842*/
2843        if (order != ord+diff[pGetComp(p)])
2844        {
2845          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
2846          omFreeSize((ADDRESS) diff,cmax*sizeof(int));
2847          omFreeSize((ADDRESS) F,length*sizeof(poly));
2848          delete *w;*w=NULL;
2849          return FALSE;
2850        }
2851      }
2852      pIter(p);
2853    }
2854  }
2855  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
2856  omFreeSize((ADDRESS) F,length*sizeof(poly));
2857  for (i=1;i<cmax;i++) (**w)[i-1]=diff[i];
2858  for (i=1;i<cmax;i++)
2859  {
2860    if (diff[i]<diffmin) diffmin=diff[i];
2861  }
2862  if (w!=NULL)
2863  {
2864    for (i=1;i<cmax;i++)
2865    {
2866      (**w)[i-1]=diff[i]-diffmin;
2867    }
2868  }
2869  omFreeSize((ADDRESS) diff,cmax*sizeof(int));
2870  return TRUE;
2871}
2872
2873ideal idJet(ideal i,int d)
2874{
2875  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
2876  r->nrows = i-> nrows;
2877  r->ncols = i-> ncols;
2878  //r->rank = i-> rank;
2879  int k;
2880  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
2881  {
2882    r->m[k]=ppJet(i->m[k],d);
2883  }
2884  return r;
2885}
2886
2887ideal idJetW(ideal i,int d, intvec * iv)
2888{
2889  ideal r=idInit(IDELEMS(i),i->rank);
2890  if (ecartWeights!=NULL)
2891  {
2892    WerrorS("cannot compute weighted jets now");
2893  }
2894  else
2895  {
2896    short *w=iv2array(iv);
2897    int k;
2898    for(k=0; k<IDELEMS(i); k++)
2899    {
2900      r->m[k]=ppJetW(i->m[k],d,w);
2901    }
2902    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
2903  }
2904  return r;
2905}
2906
2907ideal idSeries(int n,ideal M,matrix U=NULL)
2908{
2909  for(int i=IDELEMS(M)-1;i>=0;i--)
2910  {
2911    if(U==NULL)
2912      M->m[i]=pSeries(n,M->m[i]);
2913    else
2914    {
2915      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1));
2916      MATELEM(U,i+1,i+1)=NULL;
2917    }
2918  }
2919  if(U!=NULL)
2920    idDelete((ideal*)&U);
2921  return M;
2922}
2923
2924matrix idDiff(matrix i, int k)
2925{
2926  int e=MATCOLS(i)*MATROWS(i);
2927  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2928  int j;
2929  for(j=0; j<e; j++)
2930  {
2931    r->m[j]=pDiff(i->m[j],k);
2932  }
2933  return r;
2934}
2935
2936matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2937{
2938  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2939  int i,j;
2940  for(i=0; i<IDELEMS(I); i++)
2941  {
2942    for(j=0; j<IDELEMS(J); j++)
2943    {
2944      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2945    }
2946  }
2947  return r;
2948}
2949
2950/*3
2951*handles for some ideal operations the ring/syzcomp managment
2952*returns all syzygies (componentwise-)shifted by -syzcomp
2953*or -syzcomp-1 (in case of ideals as input)
2954static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
2955{
2956  ring orig_ring=currRing;
2957  ring syz_ring=rCurrRingAssure_SyzComp();
2958  rSetSyzComp(length);
2959
2960  ideal s_temp;
2961  if (orig_ring!=syz_ring)
2962    s_temp=idrMoveR_NoSort(arg,orig_ring);
2963  else
2964    s_temp=arg;
2965
2966  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
2967  if (w!=NULL) delete w;
2968
2969  if (syz_ring!=orig_ring)
2970  {
2971    idDelete(&s_temp);
2972    rChangeCurrRing(orig_ring);
2973  }
2974
2975  idDelete(&temp);
2976  ideal temp1=idRingCopy(s_temp1,syz_ring);
2977
2978  if (syz_ring!=orig_ring)
2979  {
2980    rChangeCurrRing(syz_ring);
2981    idDelete(&s_temp1);
2982    rChangeCurrRing(orig_ring);
2983    rKill(syz_ring);
2984  }
2985
2986  for (i=0;i<IDELEMS(temp1);i++)
2987  {
2988    if ((temp1->m[i]!=NULL)
2989    && (pGetComp(temp1->m[i])<=length))
2990    {
2991      pDelete(&(temp1->m[i]));
2992    }
2993    else
2994    {
2995      pShift(&(temp1->m[i]),-length);
2996    }
2997  }
2998  temp1->rank = rk;
2999  idSkipZeroes(temp1);
3000
3001  return temp1;
3002}
3003*/
3004/*2
3005* represents (h1+h2)/h2=h1/(h1 intersect h2)
3006*/
3007ideal idModulo (ideal h2,ideal h1)
3008{
3009  int i,j,k,rk,flength=0,slength,length;
3010  intvec * w;
3011  poly p,q;
3012
3013  if (idIs0(h2))
3014    return idFreeModule(max(1,h2->ncols));
3015  if (!idIs0(h1))
3016    flength = idRankFreeModule(h1);
3017  slength = idRankFreeModule(h2);
3018  length  = max(flength,slength);
3019  if (length==0)
3020  {
3021    length = 1;
3022  }
3023  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
3024  for (i=0;i<IDELEMS(h2);i++)
3025  {
3026    temp->m[i] = pCopy(h2->m[i]);
3027    q = pOne();
3028    pSetComp(q,i+1+length);
3029    pSetmComp(q);
3030    if(temp->m[i]!=NULL)
3031    {
3032      if (slength==0) pShift(&(temp->m[i]),1);
3033      p = temp->m[i];
3034      while (pNext(p)!=NULL) pIter(p);
3035      pNext(p) = q;
3036    }
3037    else
3038      temp->m[i]=q;
3039  }
3040  rk = k = IDELEMS(h2);
3041  if (!idIs0(h1))
3042  {
3043    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
3044    IDELEMS(temp) += IDELEMS(h1);
3045    for (i=0;i<IDELEMS(h1);i++)
3046    {
3047      if (h1->m[i]!=NULL)
3048      {
3049        temp->m[k] = pCopy(h1->m[i]);
3050        if (flength==0) pShift(&(temp->m[k]),1);
3051        k++;
3052      }
3053    }
3054  }
3055
3056  ring orig_ring=currRing;
3057  ring syz_ring=rCurrRingAssure_SyzComp();
3058  rSetSyzComp(length);
3059  ideal s_temp;
3060
3061  if (syz_ring != orig_ring)
3062  {
3063    s_temp = idrMoveR_NoSort(temp, orig_ring);
3064  }
3065  else
3066  {
3067    s_temp = temp;
3068  }
3069
3070  idTest(s_temp);
3071  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
3072  if (w!=NULL) delete w;
3073
3074  for (i=0;i<IDELEMS(s_temp1);i++)
3075  {
3076    if ((s_temp1->m[i]!=NULL)
3077    && (pGetComp(s_temp1->m[i])<=length))
3078    {
3079      pDelete(&(s_temp1->m[i]));
3080    }
3081    else
3082    {
3083      pShift(&(s_temp1->m[i]),-length);
3084    }
3085  }
3086  s_temp1->rank = rk;
3087  idSkipZeroes(s_temp1);
3088
3089  if (syz_ring!=orig_ring)
3090  {
3091    rChangeCurrRing(orig_ring);
3092    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
3093    rKill(syz_ring);
3094    // Hmm ... here seems to be a memory leak
3095    // However, simply deleting it causes memory trouble
3096    // idDelete(&s_temp);
3097  }
3098  else
3099  {
3100    idDelete(&temp);
3101  }
3102  idTest(s_temp1);
3103  return s_temp1;
3104}
3105
3106int idElem(ideal F)
3107{
3108  int i=0,j=0;
3109
3110  while(j<IDELEMS(F))
3111  {
3112   if ((F->m)[j]!=NULL) i++;
3113   j++;
3114  }
3115  return i;
3116}
3117
3118/*
3119*computes module-weights for liftings of homogeneous modules
3120*/
3121intvec * idMWLift(ideal mod,intvec * weights)
3122{
3123  if (idIs0(mod)) return new intvec(2);
3124  int i=IDELEMS(mod);
3125  while ((i>0) && (mod->m[i-1]==NULL)) i--;
3126  intvec *result = new intvec(i+1);
3127  while (i>0)
3128  {
3129    (*result)[i]=pFDeg(mod->m[i])+(*weights)[pGetComp(mod->m[i])];
3130  }
3131  return result;
3132}
3133
3134/*2
3135*sorts the kbase for idCoef* in a special way (lexicographically
3136*with x_max,...,x_1)
3137*/
3138ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
3139{
3140  int i;
3141  ideal result;
3142
3143  if (idIs0(kBase)) return NULL;
3144  result = idInit(IDELEMS(kBase),kBase->rank);
3145  *convert = idSort(kBase,FALSE);
3146  for (i=0;i<(*convert)->length();i++)
3147  {
3148    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
3149  }
3150  return result;
3151}
3152
3153/*2
3154*returns the index of a given monom in the list of the special kbase
3155*/
3156int idIndexOfKBase(poly monom, ideal kbase)
3157{
3158  int j=IDELEMS(kbase);
3159
3160  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
3161  if (j==0) return -1;
3162  int i=pVariables;
3163  while (i>0)
3164  {
3165    loop
3166    {
3167      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
3168      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
3169      j--;
3170      if (j==0) return -1;
3171    }
3172    if (i==1)
3173    {
3174      while(j>0)
3175      {
3176        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
3177        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
3178        j--;
3179      }
3180    }
3181    i--;
3182  }
3183  return -1;
3184}
3185
3186/*2
3187*decomposes the monom in a part of coefficients described by the
3188*complement of how and a monom in variables occuring in how, the
3189*index of which in kbase is returned as integer pos (-1 if it don't
3190*exists)
3191*/
3192poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3193{
3194  int i;
3195  poly coeff=pOne(), base=pOne();
3196
3197  for (i=1;i<=pVariables;i++)
3198  {
3199    if (pGetExp(how,i)>0)
3200    {
3201      pSetExp(base,i,pGetExp(monom,i));
3202    }
3203    else
3204    {
3205      pSetExp(coeff,i,pGetExp(monom,i));
3206    }
3207  }
3208  pSetComp(base,pGetComp(monom));
3209  pSetm(base);
3210  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3211  pSetm(coeff);
3212  *pos = idIndexOfKBase(base,kbase);
3213  if (*pos<0)
3214    pDelete(&coeff);
3215  pDelete(&base);
3216  return coeff;
3217}
3218
3219/*2
3220*returns a matrix A of coefficients with kbase*A=arg
3221*if all monomials in variables of how occur in kbase
3222*the other are deleted
3223*/
3224matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3225{
3226  matrix result;
3227  ideal tempKbase;
3228  poly p,q;
3229  intvec * convert;
3230  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3231#if 0
3232  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3233  if (idIs0(arg))
3234    return mpNew(i,1);
3235  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3236  result = mpNew(i,j);
3237#else
3238  result = mpNew(i, j);
3239  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3240#endif
3241
3242  tempKbase = idCreateSpecialKbase(kbase,&convert);
3243  for (k=0;k<j;k++)
3244  {
3245    p = arg->m[k];
3246    while (p!=NULL)
3247    {
3248      q = idDecompose(p,how,tempKbase,&pos);
3249      if (pos>=0)
3250      {
3251        MATELEM(result,(*convert)[pos],k+1) =
3252            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3253      }
3254      else
3255        pDelete(&q);
3256      pIter(p);
3257    }
3258  }
3259  idDelete(&tempKbase);
3260  return result;
3261}
3262
3263/*3
3264* searches for units in the components of the module arg and
3265* returns the first one
3266*/
3267static int idReadOutUnits(ideal arg,int* comp)
3268{
3269  if (idIs0(arg)) return -1;
3270  int i=0,j,rk_arg=idRankFreeModule(arg),generator=-1;
3271  intvec * componentIsUsed =new intvec(rk_arg+1);
3272  poly p,q;
3273
3274  while ((i<IDELEMS(arg)) && (generator<0))
3275  {
3276    for (j=rk_arg;j>=0;j--)
3277      (*componentIsUsed)[j]=0;
3278    p = arg->m[i];
3279    while (p!=NULL)
3280    {
3281      j = pGetComp(p);
3282      if ((*componentIsUsed)[j]==0)
3283      {
3284        if (pLmIsConstantComp(p))
3285        {
3286          generator = i;
3287          (*componentIsUsed)[j] = 1;
3288        }
3289        else
3290        {
3291          (*componentIsUsed)[j] = -1;
3292        }
3293      }
3294      else if ((*componentIsUsed)[j]>0)
3295      {
3296        ((*componentIsUsed)[j])++;
3297      }
3298      pIter(p);
3299    }
3300    i++;
3301  }
3302  i = 0;
3303  *comp = -1;
3304  for (j=0;j<=rk_arg;j++)
3305  {
3306    if ((*componentIsUsed)[j]>0)
3307    {
3308      if ((*comp==-1) || ((*componentIsUsed)[j]<i))
3309      {
3310        *comp = j;
3311        i= (*componentIsUsed)[j];
3312      }
3313    }
3314  }
3315  return generator;
3316}
3317
3318static void idDeleteComp(ideal arg,int red_comp)
3319{
3320  int i,j;
3321  poly p;
3322
3323  for (i=IDELEMS(arg)-1;i>=0;i--)
3324  {
3325    p = arg->m[i];
3326    while (p!=NULL)
3327    {
3328      j = pGetComp(p);
3329      if (j>red_comp)
3330      {
3331        pSetComp(p,j-1);
3332        pSetm(p);
3333      }
3334      pIter(p);
3335    }
3336  }
3337  (arg->rank)--;
3338}
3339
3340/*2
3341* returns the presentation of an isomorphic, minimally
3342* embedded  module (arg represents the quotient!)
3343*/
3344ideal idMinEmbedding(ideal arg,BOOLEAN inPlace)
3345{
3346  if (idIs0(arg)) return idInit(1,arg->rank);
3347  int next_gen,next_comp;
3348  ideal res=arg;
3349
3350  if (!inPlace) res = idCopy(arg);
3351  loop
3352  {
3353    next_gen = idReadOutUnits(res,&next_comp);
3354    if (next_gen<0) break;
3355    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
3356    idDeleteComp(res,next_comp);
3357  }
3358  idSkipZeroes(res);
3359  return res;
3360}
3361
3362/*2
3363* transpose a module
3364*/
3365ideal idTransp(ideal a)
3366{
3367  int r = a->rank, c = IDELEMS(a);
3368  ideal b =  idInit(r,c);
3369
3370  for (int i=c; i>0; i--)
3371  {
3372    poly p=a->m[i-1];
3373    while(p!=NULL)
3374    {
3375      poly h=pHead(p);
3376      int co=pGetComp(h)-1;
3377      pSetComp(h,i);
3378      pSetmComp(h);
3379      b->m[co]=pAdd(b->m[co],h);
3380      pIter(p);
3381    }
3382  }
3383  return b;
3384}
3385
3386intvec * idQHomWeight(ideal id)
3387{
3388  poly head, tail;
3389  int k;
3390  int in=IDELEMS(id)-1, ready=0, all=0,
3391      coldim=pVariables, rowmax=2*coldim;
3392  if (in<0) return NULL;
3393  intvec *imat=new intvec(rowmax+1,coldim,0);
3394
3395  do
3396  {
3397    head = id->m[in--];
3398    if (head!=NULL)
3399    {
3400      tail = pNext(head);
3401      while (tail!=NULL)
3402      {
3403        all++;
3404        for (k=1;k<=coldim;k++)
3405          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
3406        if (all==rowmax)
3407        {
3408          ivTriangIntern(imat, ready, all);
3409          if (ready==coldim)
3410          {
3411            delete imat;
3412            return NULL;
3413          }
3414        }
3415        pIter(tail);
3416      }
3417    }
3418  } while (in>=0);
3419  if (all>ready)
3420  {
3421    ivTriangIntern(imat, ready, all);
3422    if (ready==coldim)
3423    {
3424      delete imat;
3425      return NULL;
3426    }
3427  }
3428  intvec *result = ivSolveKern(imat, ready);
3429  delete imat;
3430  return result;
3431}
3432
3433BOOLEAN idIsZeroDim(ideal I)
3434{
3435  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(pVariables*sizeof(BOOLEAN));
3436  int i,n;
3437  poly po;
3438  BOOLEAN res=TRUE;
3439  for(i=IDELEMS(I)-1;i>=0;i--)
3440  {
3441    po=I->m[i];
3442    if ((po!=NULL) &&((n=pIsPurePower(po))!=0)) UsedAxis[n-1]=TRUE;
3443  }
3444  for(i=pVariables-1;i>=0;i--)
3445  {
3446    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
3447  }
3448  omFreeSize(UsedAxis,pVariables*sizeof(BOOLEAN));
3449  return res;
3450}
3451
3452void idNormalize(ideal I)
3453{
3454  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
3455  int i;
3456  poly p;
3457  for(i=IDELEMS(I)-1;i>=0;i--)
3458  {
3459    p=I->m[i] ;
3460    while(p!=NULL)
3461    {
3462      nNormalize(pGetCoeff(p));
3463      pIter(p);
3464    }
3465  }
3466}
Note: See TracBrowser for help on using the repository browser.