source: git/Singular/ideals.cc @ cf42ab1

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