source: git/Singular/ideals.cc @ e974a2

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