source: git/Singular/ideals.cc @ 6b32990

spielwiese
Last change on this file since 6b32990 was 6b32990, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* dynamic kernel modules for MP and DBM links * p_Procs improvements git-svn-id: file:///usr/local/Singular/svn/trunk@4865 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.117 2000-12-12 08:44:44 obachman 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  h = idInit(IDELEMS(h1),h1->rank);
2301  // fetch data from the old ring
2302  for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
2303  // compute kStd
2304  hh = kStd(h,NULL,hom,&w,hilb);
2305  idDelete(&h);
2306
2307  // go back to the original ring
2308  rChangeCurrRing(origR);
2309  i = IDELEMS(hh)-1;
2310  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2311  j = -1;
2312  // fetch data from temp ring
2313  for (k=0; k<=i; k++)
2314  {
2315    l=pVariables;
2316    while ((l>0) && (p_GetExp( hh->m[k],l,&tmpR)*pGetExp(delVar,l)==0)) l--;
2317    if (l==0)
2318    {
2319      j++;
2320      if (j >= IDELEMS(h3))
2321      {
2322        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2323        IDELEMS(h3) += 16;
2324      }
2325      h3->m[j] = prCopyR( hh->m[k], &tmpR);
2326    }
2327  }
2328  rChangeCurrRing(&tmpR);
2329  idDelete(&hh);
2330  rChangeCurrRing(origR);
2331  idSkipZeroes(h3);
2332  omFree((ADDRESS)wv[0]);
2333  omFreeSize((ADDRESS)wv,ordersize*sizeof(int**));
2334  omFreeSize((ADDRESS)ord,ordersize*sizeof(int));
2335  omFreeSize((ADDRESS)block0,ordersize*sizeof(int));
2336  omFreeSize((ADDRESS)block1,ordersize*sizeof(int));
2337  rUnComplete(&tmpR);
2338  if (w!=NULL)
2339    delete w;
2340  return h3;
2341}
2342
2343#ifdef WITH_OLD_MINOR
2344/*2
2345* compute all ar-minors of the matrix a
2346*/
2347ideal idMinors(matrix a, int ar, ideal R)
2348{
2349  int     i,j,k,size;
2350  int *rowchoise,*colchoise;
2351  BOOLEAN rowch,colch;
2352  ideal result;
2353  matrix tmp;
2354  poly p,q;
2355
2356  i = binom(a->rows(),ar);
2357  j = binom(a->cols(),ar);
2358
2359  rowchoise=(int *)omAlloc(ar*sizeof(int));
2360  colchoise=(int *)omAlloc(ar*sizeof(int));
2361  if ((i>512) || (j>512) || (i*j >512)) size=512;
2362  else size=i*j;
2363  result=idInit(size,1);
2364  tmp=mpNew(ar,ar);
2365  k = 0; /* the index in result*/
2366  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2367  while (!rowch)
2368  {
2369    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2370    while (!colch)
2371    {
2372      for (i=1; i<=ar; i++)
2373      {
2374        for (j=1; j<=ar; j++)
2375        {
2376          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2377        }
2378      }
2379      p = mpDetBareiss(tmp);
2380      if (p!=NULL)
2381      {
2382        if (R!=NULL)
2383        {
2384          q = p;
2385          p = kNF(R,currQuotient,q);
2386          pDelete(&q);
2387        }
2388        if (p!=NULL)
2389        {
2390          if (k>=size)
2391          {
2392            pEnlargeSet(&result->m,size,32);
2393            size += 32;
2394          }
2395          result->m[k] = p;
2396          k++;
2397        }
2398      }
2399      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2400    }
2401    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2402  }
2403  /*delete the matrix tmp*/
2404  for (i=1; i<=ar; i++)
2405  {
2406    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2407  }
2408  idDelete((ideal*)&tmp);
2409  if (k==0)
2410  {
2411    k=1;
2412    result->m[0]=NULL;
2413  }
2414  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2415  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2416  pEnlargeSet(&result->m,size,k-size);
2417  IDELEMS(result) = k;
2418  return (result);
2419}
2420#else
2421/*2
2422* compute all ar-minors of the matrix a
2423* the caller of mpRecMin
2424* the elements of the result are not in R (if R!=NULL)
2425*/
2426ideal idMinors(matrix a, int ar, ideal R)
2427{
2428  ideal result;
2429  int elems=0;
2430
2431  if((ar<=0) || (ar>min(a->ncols,a->nrows)))
2432  {
2433    Werror("%d-th minor, matrix is %dx%d",ar,a->ncols,a->nrows);
2434    return NULL;
2435  }
2436  a = mpCopy(a);
2437  result=idInit(32,1);
2438  if(ar>1) mpRecMin(ar-1,result,elems,a,a->nrows,a->ncols,NULL,R);
2439  else mpMinorToResult(result,elems,a,a->nrows,a->ncols,R);
2440  idDelete((ideal *)&a);
2441  idSkipZeroes(result);
2442  idTest(result);
2443  return result;
2444}
2445#endif
2446
2447/*2
2448*returns TRUE if p is a unit element in the current ring
2449*/
2450BOOLEAN pIsUnit(poly p)
2451{
2452  int i;
2453
2454  if (p == NULL) return FALSE;
2455  i = 1;
2456  while (i<=pVariables && pGetExp(p,i) == 0) i++;
2457  if (i > pVariables && (pGetComp(p) == 0))
2458  {
2459    if (currRing->OrdSgn == 1 && pNext(p) !=NULL) return FALSE;
2460    return TRUE;
2461  }
2462  return FALSE;
2463}
2464
2465/*2
2466*skips all zeroes and double elements, searches also for units
2467*/
2468ideal idCompactify(ideal id)
2469{
2470  int i,j;
2471  BOOLEAN b=FALSE;
2472
2473  i = IDELEMS(id)-1;
2474  while ((! b) && (i>=0))
2475  {
2476    b=pIsUnit(id->m[i]);
2477    i--;
2478  }
2479  if (b)
2480  {
2481    ideal result=idInit(1,id->rank);
2482    result->m[0]=pOne();
2483    return result;
2484  }
2485  else
2486  {
2487    ideal result=idCopy(id);
2488    //if (IDELEMS(result) < 1)
2489    {
2490      for (i=1;i<IDELEMS(result);i++)
2491      {
2492        if (result->m[i]!=NULL)
2493        {
2494          for (j=0;j<i;j++)
2495          {
2496            if ((result->m[j]!=NULL)
2497            && (pComparePolys(result->m[i],result->m[j])))
2498            {
2499              pDelete(&(result->m[j]));
2500            }
2501          }
2502        }
2503      }
2504    }
2505//    else
2506//    {
2507//      intvec *v=idSort(result,TRUE);
2508//      for(i=0;i<IDELEMS(result);i++)
2509//        (*v)[i]--;
2510//      for (i=0;i<IDELEMS(result)-1;i++)
2511//      {
2512//        if (((*v)[i]>=0)
2513//        && (result->m[(*v)[i]]!=NULL))
2514//        {
2515//          j=i+1;
2516//          while ((j<IDELEMS(result))
2517//          && ((*v)[j]>=0)
2518//          && (result->m[(*v)[j]]!=NULL)
2519//          && (pComparePolys(result->m[(*v)[i]],result->m[(*v)[j]])))
2520//          {
2521//            pDelete(&(result->m[(*v)[j]]));
2522//            j++;
2523//          }
2524//        }
2525//      }
2526//      delete v;
2527//    }
2528    idSkipZeroes(result);
2529    return result;
2530  }
2531}
2532
2533/*2
2534*returns TRUE if id1 is a submodule of id2
2535*/
2536BOOLEAN idIsSubModule(ideal id1,ideal id2)
2537{
2538  int i;
2539  poly p;
2540
2541  if (idIs0(id1)) return TRUE;
2542  for (i=0;i<IDELEMS(id1);i++)
2543  {
2544    if (id1->m[i] != NULL)
2545    {
2546      p = kNF(id2,currQuotient,id1->m[i]);
2547      if (p != NULL)
2548      {
2549        pDelete(&p);
2550        return FALSE;
2551      }
2552    }
2553  }
2554  return TRUE;
2555}
2556
2557/*2
2558* returns the ideals of initial terms
2559*/
2560ideal idHead(ideal h)
2561{
2562  ideal m = idInit(IDELEMS(h),h->rank);
2563  int i;
2564
2565  for (i=IDELEMS(h)-1;i>=0; i--)
2566  {
2567    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
2568  }
2569  return m;
2570}
2571
2572ideal idHomogen(ideal h, int varnum)
2573{
2574  ideal m = idInit(IDELEMS(h),h->rank);
2575  int i;
2576
2577  for (i=IDELEMS(h)-1;i>=0; i--)
2578  {
2579    m->m[i]=pHomogen(h->m[i],varnum);
2580  }
2581  return m;
2582}
2583
2584/*------------------type conversions----------------*/
2585ideal idVec2Ideal(poly vec)
2586{
2587   ideal result=idInit(1,1);
2588   omFree((ADDRESS)result->m);
2589   result->m=NULL; // remove later
2590   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2591   return result;
2592}
2593
2594// converts mat to module, destroys mat
2595ideal idMatrix2Module(matrix mat)
2596{
2597  ideal result = idInit(MATCOLS(mat),MATROWS(mat));
2598  int i,j;
2599  poly h;
2600#ifdef DRING
2601  poly p;
2602#endif
2603
2604  for(j=0;j<MATCOLS(mat);j++) /* j is also index in result->m */
2605  {
2606    for (i=1;i<=MATROWS(mat);i++)
2607    {
2608      h = MATELEM(mat,i,j+1);
2609      if (h!=NULL)
2610      {
2611        MATELEM(mat,i,j+1)=NULL;
2612        pSetCompP(h,i);
2613#ifdef DRING
2614        pdSetDFlagP(h,0);
2615#endif
2616        result->m[j] = pAdd(result->m[j],h);
2617      }
2618    }
2619  }
2620  // obachman: need to clean this up
2621  idDelete((ideal*) &mat);
2622  return result;
2623}
2624
2625/*2
2626* converts a module into a matrix, destroyes the input
2627*/
2628matrix idModule2Matrix(ideal mod)
2629{
2630  matrix result = mpNew(mod->rank,IDELEMS(mod));
2631  int i,cp;
2632  poly p,h;
2633
2634  for(i=0;i<IDELEMS(mod);i++)
2635  {
2636    p=mod->m[i];
2637    mod->m[i]=NULL;
2638    while (p!=NULL)
2639    {
2640      h=p;
2641      pIter(p);
2642      pNext(h)=NULL;
2643//      cp = max(1,pGetComp(h));     // if used for ideals too
2644      cp = pGetComp(h);
2645      pSetComp(h,0);
2646      pSetmComp(h);
2647#ifdef TEST
2648      if (cp>mod->rank)
2649      {
2650        Print("## inv. rank %d -> %d\n",mod->rank,cp);
2651        int k,l,o=mod->rank;
2652        mod->rank=cp;
2653        matrix d=mpNew(mod->rank,IDELEMS(mod));
2654        for (l=1; l<=o; l++)
2655        {
2656          for (k=1; k<=IDELEMS(mod); k++)
2657          {
2658            MATELEM(d,l,k)=MATELEM(result,l,k);
2659            MATELEM(result,l,k)=NULL;
2660          }
2661        }
2662        idDelete((ideal *)&result);
2663        result=d;
2664      }
2665#endif
2666      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2667    }
2668  }
2669// obachman 10/99: added the following line, otherwise memory lack!
2670  idDelete(&mod);
2671  return result;
2672}
2673
2674matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
2675{
2676  matrix result = mpNew(rows,cols);
2677  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
2678  poly p,h;
2679
2680  if (r>rows) r = rows;
2681  if (c>cols) c = cols;
2682  for(i=0;i<c;i++)
2683  {
2684    p=mod->m[i];
2685    mod->m[i]=NULL;
2686    while (p!=NULL)
2687    {
2688      h=p;
2689      pIter(p);
2690      pNext(h)=NULL;
2691      cp = pGetComp(h);
2692      if (cp<=r)
2693      {
2694        pSetComp(h,0);
2695        pSetmComp(h);
2696        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2697      }
2698      else
2699        pDelete(&h);
2700    }
2701  }
2702  idDelete(&mod);
2703  return result;
2704}
2705
2706/*2
2707* substitute the n-th variable by the monomial e in id
2708* destroy id
2709*/
2710ideal  idSubst(ideal id, int n, poly e)
2711{
2712  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
2713  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
2714
2715  res->rank = id->rank;
2716  for(k--;k>=0;k--)
2717  {
2718    res->m[k]=pSubst(id->m[k],n,e);
2719    id->m[k]=NULL;
2720  }
2721  idDelete(&id);
2722  return res;
2723}
2724
2725BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
2726{
2727  if (w!=NULL) *w=NULL;
2728  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
2729  if (idIs0(m)) return TRUE;
2730
2731  int i,j,cmax=2,order=0,ord,* diff,* iscom,diffmin=32000;
2732  poly p=NULL;
2733  int length=IDELEMS(m);
2734  polyset P=m->m;
2735  polyset F=(polyset)omAlloc(length*sizeof(poly));
2736  for (i=length-1;i>=0;i--)
2737  {
2738    p=F[i]=P[i];
2739    cmax=max(cmax,pMaxComp(p)+1);
2740  }
2741  diff = (int *)omAlloc0(cmax*sizeof(int));
2742  if (w!=NULL) *w=new intvec(cmax-1);
2743  iscom = (int *)omAlloc0(cmax*sizeof(int));
2744  i=0;
2745  while (i<=length)
2746  {
2747    if (i<length)
2748    {
2749      p=F[i];
2750      while ((p!=NULL) && (!iscom[pGetComp(p)])) pIter(p);
2751    }
2752    if ((p==NULL) && (i<length))
2753    {
2754      i++;
2755    }
2756    else
2757    {
2758      if (p==NULL)
2759      {
2760        i=0;
2761        while ((i<length) && (F[i]==NULL)) i++;
2762        if (i>=length) break;
2763        p = F[i];
2764      }
2765      if (pLexOrder)
2766        order=pTotaldegree(p);
2767      else
2768      //  order = p->order;
2769        order = pFDeg(p);
2770      order += diff[pGetComp(p)];
2771      p = F[i];
2772//Print("Actual p=F[%d]: ",i);pWrite(p);
2773      F[i] = NULL;
2774      i=0;
2775    }
2776    while (p!=NULL)
2777    {
2778      //if (pLexOrder)
2779      //  ord=pTotaldegree(p);
2780      //else
2781      //  ord = p->order;
2782      ord = pFDeg(p);
2783      if (!iscom[pGetComp(p)])
2784      {
2785        diff[pGetComp(p)] = order-ord;
2786        iscom[pGetComp(p)] = 1;
2787/*
2788*PrintS("new diff: ");
2789*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2790*PrintLn();
2791*PrintS("new iscom: ");
2792*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
2793*PrintLn();
2794*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
2795*/
2796      }
2797      else
2798      {
2799/*
2800*PrintS("new diff: ");
2801*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2802*PrintLn();
2803*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
2804*/
2805        if (order != ord+diff[pGetComp(p)])
2806        {
2807          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
2808          omFreeSize((ADDRESS) diff,cmax*sizeof(int));
2809          omFreeSize((ADDRESS) F,length*sizeof(poly));
2810          delete *w;*w=NULL;
2811          return FALSE;
2812        }
2813      }
2814      pIter(p);
2815    }
2816  }
2817  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
2818  omFreeSize((ADDRESS) F,length*sizeof(poly));
2819  for (i=1;i<cmax;i++) (**w)[i-1]=diff[i];
2820  for (i=1;i<cmax;i++)
2821  {
2822    if (diff[i]<diffmin) diffmin=diff[i];
2823  }
2824  if (w!=NULL)
2825  {
2826    for (i=1;i<cmax;i++)
2827    {
2828      (**w)[i-1]=diff[i]-diffmin;
2829    }
2830  }
2831  omFreeSize((ADDRESS) diff,cmax*sizeof(int));
2832  return TRUE;
2833}
2834
2835ideal idJet(ideal i,int d)
2836{
2837  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
2838  r->nrows = i-> nrows;
2839  r->ncols = i-> ncols;
2840  //r->rank = i-> rank;
2841  int k;
2842  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
2843  {
2844    r->m[k]=pJet(i->m[k],d);
2845  }
2846  return r;
2847}
2848
2849ideal idJetW(ideal i,int d, intvec * iv)
2850{
2851  ideal r=idInit(IDELEMS(i),i->rank);
2852  if (ecartWeights!=NULL)
2853  {
2854    WerrorS("cannot compute weighted jets now");
2855  }
2856  else
2857  {
2858    short *w=iv2array(iv);
2859    int k;
2860    for(k=0; k<IDELEMS(i); k++)
2861    {
2862      r->m[k]=pJetW(i->m[k],d,w);
2863    }
2864    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
2865  }
2866  return r;
2867}
2868
2869matrix idDiff(matrix i, int k)
2870{
2871  int e=MATCOLS(i)*MATROWS(i);
2872  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2873  int j;
2874  for(j=0; j<e; j++)
2875  {
2876    r->m[j]=pDiff(i->m[j],k);
2877  }
2878  return r;
2879}
2880
2881matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2882{
2883  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2884  int i,j;
2885  for(i=0; i<IDELEMS(I); i++)
2886  {
2887    for(j=0; j<IDELEMS(J); j++)
2888    {
2889      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2890    }
2891  }
2892  return r;
2893}
2894
2895/*3
2896*handles for some ideal operations the ring/syzcomp managment
2897*returns all syzygies (componentwise-)shifted by -syzcomp
2898*or -syzcomp-1 (in case of ideals as input)
2899static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
2900{
2901  ring orig_ring=currRing;
2902  ring syz_ring=rCurrRingAssure_SyzComp();
2903  rSetSyzComp(length);
2904
2905  ideal s_temp;
2906  if (orig_ring!=syz_ring)
2907    s_temp=idrMoveR_NoSort(arg,orig_ring);
2908  else
2909    s_temp=arg;
2910
2911  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
2912  if (w!=NULL) delete w;
2913
2914  if (syz_ring!=orig_ring)
2915  {
2916    idDelete(&s_temp);
2917    rChangeCurrRing(orig_ring);
2918  }
2919
2920  idDelete(&temp);
2921  ideal temp1=idRingCopy(s_temp1,syz_ring);
2922
2923  if (syz_ring!=orig_ring)
2924  {
2925    rChangeCurrRing(syz_ring);
2926    idDelete(&s_temp1);
2927    rChangeCurrRing(orig_ring);
2928    rKill(syz_ring);
2929  }
2930
2931  for (i=0;i<IDELEMS(temp1);i++)
2932  {
2933    if ((temp1->m[i]!=NULL)
2934    && (pGetComp(temp1->m[i])<=length))
2935    {
2936      pDelete(&(temp1->m[i]));
2937    }
2938    else
2939    {
2940      pShift(&(temp1->m[i]),-length);
2941    }
2942  }
2943  temp1->rank = rk;
2944  idSkipZeroes(temp1);
2945
2946  return temp1;
2947}
2948*/
2949/*2
2950* represents (h1+h2)/h2=h1/(h1 intersect h2)
2951*/
2952ideal idModulo (ideal h2,ideal h1)
2953{
2954  int i,j,k,rk,flength=0,slength,length;
2955  intvec * w;
2956  poly p,q;
2957
2958  if (idIs0(h2))
2959    return idFreeModule(max(1,h2->ncols));
2960  if (!idIs0(h1))
2961    flength = idRankFreeModule(h1);
2962  slength = idRankFreeModule(h2);
2963  length  = max(flength,slength);
2964  if (length==0)
2965  {
2966    length = 1;
2967  }
2968  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
2969  for (i=0;i<IDELEMS(h2);i++)
2970  {
2971    temp->m[i] = pCopy(h2->m[i]);
2972    q = pOne();
2973    pSetComp(q,i+1+length);
2974    pSetmComp(q);
2975    if(temp->m[i]!=NULL)
2976    {
2977      if (slength==0) pShift(&(temp->m[i]),1);
2978      p = temp->m[i];
2979      while (pNext(p)!=NULL) pIter(p);
2980      pNext(p) = q;
2981    }
2982    else
2983      temp->m[i]=q;
2984  }
2985  rk = k = IDELEMS(h2);
2986  if (!idIs0(h1))
2987  {
2988    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
2989    IDELEMS(temp) += IDELEMS(h1);
2990    for (i=0;i<IDELEMS(h1);i++)
2991    {
2992      if (h1->m[i]!=NULL)
2993      {
2994        temp->m[k] = pCopy(h1->m[i]);
2995        if (flength==0) pShift(&(temp->m[k]),1);
2996        k++;
2997      }
2998    }
2999  }
3000
3001  ring orig_ring=currRing;
3002  ring syz_ring=rCurrRingAssure_SyzComp();
3003  rSetSyzComp(length);
3004  ideal s_temp;
3005
3006  if (syz_ring != orig_ring)
3007  {
3008    s_temp = idrMoveR_NoSort(temp, orig_ring);
3009  }
3010  else
3011  {
3012    s_temp = temp;
3013  }
3014
3015  idTest(s_temp);
3016  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
3017  if (w!=NULL) delete w;
3018
3019  for (i=0;i<IDELEMS(s_temp1);i++)
3020  {
3021    if ((s_temp1->m[i]!=NULL)
3022    && (pGetComp(s_temp1->m[i])<=length))
3023    {
3024      pDelete(&(s_temp1->m[i]));
3025    }
3026    else
3027    {
3028      pShift(&(s_temp1->m[i]),-length);
3029    }
3030  }
3031  s_temp1->rank = rk;
3032  idSkipZeroes(s_temp1);
3033
3034  if (syz_ring!=orig_ring)
3035  {
3036    rChangeCurrRing(orig_ring);
3037    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
3038    rKill(syz_ring);
3039    // Hmm ... here seems to be a memory leak
3040    // However, simply deleting it causes memory trouble
3041    // idDelete(&s_temp);
3042  }
3043  else
3044  {
3045    idDelete(&temp);
3046  }
3047  idTest(s_temp1);
3048  return s_temp1;
3049}
3050
3051int idElem(ideal F)
3052{
3053  int i=0,j=0;
3054
3055  while(j<IDELEMS(F))
3056  {
3057   if ((F->m)[j]!=NULL) i++;
3058   j++;
3059  }
3060  return i;
3061}
3062
3063/*
3064*computes module-weights for liftings of homogeneous modules
3065*/
3066intvec * idMWLift(ideal mod,intvec * weights)
3067{
3068  if (idIs0(mod)) return new intvec(2);
3069  int i=IDELEMS(mod);
3070  while ((i>0) && (mod->m[i-1]==NULL)) i--;
3071  intvec *result = new intvec(i+1);
3072  while (i>0)
3073  {
3074    (*result)[i]=pFDeg(mod->m[i])+(*weights)[pGetComp(mod->m[i])];
3075  }
3076  return result;
3077}
3078
3079/*2
3080*sorts the kbase for idCoef* in a special way (lexicographically
3081*with x_max,...,x_1)
3082*/
3083ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
3084{
3085  int i;
3086  ideal result;
3087
3088  if (idIs0(kBase)) return NULL;
3089  result = idInit(IDELEMS(kBase),kBase->rank);
3090  *convert = idSort(kBase,FALSE);
3091  for (i=0;i<(*convert)->length();i++)
3092  {
3093    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
3094  }
3095  return result;
3096}
3097
3098/*2
3099*returns the index of a given monom in the list of the special kbase
3100*/
3101int idIndexOfKBase(poly monom, ideal kbase)
3102{
3103  int j=IDELEMS(kbase);
3104
3105  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
3106  if (j==0) return -1;
3107  int i=pVariables;
3108  while (i>0)
3109  {
3110    loop
3111    {
3112      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
3113      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
3114      j--;
3115      if (j==0) return -1;
3116    }
3117    if (i==1)
3118    {
3119      while(j>0)
3120      {
3121        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
3122        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
3123        j--;
3124      }
3125    }
3126    i--;
3127  }
3128  return -1;
3129}
3130
3131/*2
3132*decomposes the monom in a part of coefficients described by the
3133*complement of how and a monom in variables occuring in how, the
3134*index of which in kbase is returned as integer pos (-1 if it don't
3135*exists)
3136*/
3137poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3138{
3139  int i;
3140  poly coeff=pOne(), base=pOne();
3141
3142  for (i=1;i<=pVariables;i++)
3143  {
3144    if (pGetExp(how,i)>0)
3145    {
3146      pSetExp(base,i,pGetExp(monom,i));
3147    }
3148    else
3149    {
3150      pSetExp(coeff,i,pGetExp(monom,i));
3151    }
3152  }
3153  pSetComp(base,pGetComp(monom));
3154  pSetm(base);
3155  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3156  pSetm(coeff);
3157  *pos = idIndexOfKBase(base,kbase);
3158  if (*pos<0)
3159    pDelete(&coeff);
3160  pDelete(&base);
3161  return coeff;
3162}
3163
3164/*2
3165*returns a matrix A of coefficients with kbase*A=arg
3166*if all monomials in variables of how occur in kbase
3167*the other are deleted
3168*/
3169matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3170{
3171  matrix result;
3172  ideal tempKbase;
3173  poly p,q;
3174  intvec * convert;
3175  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3176#if 0
3177  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3178  if (idIs0(arg))
3179    return mpNew(i,1);
3180  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3181  result = mpNew(i,j);
3182#else
3183  result = mpNew(i, j);
3184  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3185#endif
3186
3187  tempKbase = idCreateSpecialKbase(kbase,&convert);
3188  for (k=0;k<j;k++)
3189  {
3190    p = arg->m[k];
3191    while (p!=NULL)
3192    {
3193      q = idDecompose(p,how,tempKbase,&pos);
3194      if (pos>=0)
3195      {
3196        MATELEM(result,(*convert)[pos],k+1) =
3197            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3198      }
3199      else
3200        pDelete(&q);
3201      pIter(p);
3202    }
3203  }
3204  idDelete(&tempKbase);
3205  return result;
3206}
3207
3208/*3
3209* searches for units in the components of the module arg and
3210* returns the first one
3211*/
3212static int idReadOutUnits(ideal arg,int* comp)
3213{
3214  if (idIs0(arg)) return -1;
3215  int i=0,j,rk_arg=idRankFreeModule(arg),generator=-1;
3216  intvec * componentIsUsed =new intvec(rk_arg+1);
3217  poly p,q;
3218
3219  while ((i<IDELEMS(arg)) && (generator<0))
3220  {
3221    for (j=rk_arg;j>=0;j--)
3222      (*componentIsUsed)[j]=0;
3223    p = arg->m[i];
3224    while (p!=NULL)
3225    {
3226      j = pGetComp(p);
3227      if ((*componentIsUsed)[j]==0)
3228      {
3229        if (pLmIsConstantComp(p))
3230        {
3231          generator = i;
3232          (*componentIsUsed)[j] = 1;
3233        }
3234        else
3235        {
3236          (*componentIsUsed)[j] = -1;
3237        }
3238      }
3239      else if ((*componentIsUsed)[j]>0)
3240      {
3241        ((*componentIsUsed)[j])++;
3242      }
3243      pIter(p);
3244    }
3245    i++;
3246  }
3247  i = 0;
3248  *comp = -1;
3249  for (j=0;j<=rk_arg;j++)
3250  {
3251    if ((*componentIsUsed)[j]>0)
3252    {
3253      if ((*comp==-1) || ((*componentIsUsed)[j]<i))
3254      {
3255        *comp = j;
3256        i= (*componentIsUsed)[j];
3257      }
3258    }
3259  }
3260  return generator;
3261}
3262
3263static void idDeleteComp(ideal arg,int red_comp)
3264{
3265  int i,j;
3266  poly p;
3267
3268  for (i=IDELEMS(arg)-1;i>=0;i--)
3269  {
3270    p = arg->m[i];
3271    while (p!=NULL)
3272    {
3273      j = pGetComp(p);
3274      if (j>red_comp)
3275      {
3276        pSetComp(p,j-1);
3277        pSetm(p);
3278      }
3279      pIter(p);
3280    }
3281  }
3282  (arg->rank)--;
3283}
3284
3285/*2
3286* returns the presentation of an isomorphic, minimally
3287* embedded  module (arg represents the quotient!)
3288*/
3289ideal idMinEmbedding(ideal arg,BOOLEAN inPlace)
3290{
3291  if (idIs0(arg)) return idInit(1,arg->rank);
3292  int next_gen,next_comp;
3293  ideal res=arg;
3294
3295  if (!inPlace) res = idCopy(arg);
3296  loop
3297  {
3298    next_gen = idReadOutUnits(res,&next_comp);
3299    if (next_gen<0) break;
3300    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
3301    idDeleteComp(res,next_comp);
3302  }
3303  idSkipZeroes(res);
3304  return res;
3305}
3306
3307/*2
3308* transpose a module
3309*/
3310ideal idTransp(ideal a)
3311{
3312  int r = a->rank, c = IDELEMS(a);
3313  ideal b =  idInit(r,c);
3314
3315  for (int i=c; i>0; i--)
3316  {
3317    poly p=a->m[i-1];
3318    while(p!=NULL)
3319    {
3320      poly h=pHead(p);
3321      int co=pGetComp(h)-1;
3322      pSetComp(h,i);
3323      pSetmComp(h);
3324      b->m[co]=pAdd(b->m[co],h);
3325      pIter(p);
3326    }
3327  }
3328  return b;
3329}
3330
3331intvec * idQHomWeight(ideal id)
3332{
3333  poly head, tail;
3334  int k;
3335  int in=IDELEMS(id)-1, ready=0, all=0,
3336      coldim=pVariables, rowmax=2*coldim;
3337  if (in<0) return NULL;
3338  intvec *imat=new intvec(rowmax+1,coldim,0);
3339
3340  do
3341  {
3342    head = id->m[in--];
3343    if (head!=NULL)
3344    {
3345      tail = pNext(head);
3346      while (tail!=NULL)
3347      {
3348        all++;
3349        for (k=1;k<=coldim;k++)
3350          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
3351        if (all==rowmax)
3352        {
3353          ivTriangIntern(imat, ready, all);
3354          if (ready==coldim)
3355          {
3356            delete imat;
3357            return NULL;
3358          }
3359        }
3360        pIter(tail);
3361      }
3362    }
3363  } while (in>=0);
3364  if (all>ready)
3365  {
3366    ivTriangIntern(imat, ready, all);
3367    if (ready==coldim)
3368    {
3369      delete imat;
3370      return NULL;
3371    }
3372  }
3373  intvec *result = ivSolveKern(imat, ready);
3374  delete imat;
3375  return result;
3376}
3377
Note: See TracBrowser for help on using the repository browser.