source: git/Singular/ideals.cc @ 8f1473

spielwiese
Last change on this file since 8f1473 was 8f1473, checked in by Thomas Siebert <siebert@…>, 25 years ago
*** empty log message *** git-svn-id: file:///usr/local/Singular/svn/trunk@2528 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 63.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: ideals.cc,v 1.37 1998-09-29 21:14:43 siebert 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    idDelete((ideal*)&nextStep);
2322    return;
2323  }
2324/*--- we read out the r-1 x c-1 matrix for the next step--*/
2325  if ((a->nrows-1)*(a->ncols-1)>0)
2326  {
2327    matrix next = mpNew(a->nrows-1,a->ncols-1);
2328    for (i=a->nrows-1;i>0;i--)
2329    {
2330      for (j=a->ncols-1;j>0;j--)
2331      {
2332        MATELEM(next,i,j) = MATELEM(nextStep,i,j);
2333        MATELEM(nextStep,i,j) =NULL;
2334      }
2335    }
2336    idDelete((ideal*)&nextStep);
2337/*--- we call the next Step------------------------------*/
2338    idRecMin(next,ar-1,barDiv,result,nextPlace);
2339    next = NULL;
2340  }
2341/*--- now we have to take out the r-th row...------------*/
2342  if (((a->nrows)>1) && (rowToChose==0))
2343  {
2344    nextStep = mpNew(a->nrows-1,a->ncols);
2345    for (i=r-1;i>0;i--)
2346    {
2347      for (j=a->ncols;j>0;j--)
2348      {
2349        MATELEM(nextStep,i,j) = pCopy(MATELEM(a,i,j));
2350      }
2351    }
2352    for (i=a->nrows;i>r;i--)
2353    {
2354      for (j=a->ncols;j>0;j--)
2355      {
2356        MATELEM(nextStep,i-1,j) = pCopy(MATELEM(a,i,j));
2357      }
2358    }
2359/*--- and to perform the algorithm with the rest---------*/
2360    idRecMin(nextStep,ar,&p,result,nextPlace);
2361    nextStep = NULL;
2362  }
2363/*--- now we have to take out the c-th col...------------*/
2364  if ((a->nrows)>1)
2365  {
2366    nextStep = mpNew(a->nrows,a->ncols-1);
2367    for (i=a->nrows;i>0;i--)
2368    {
2369      for (j=c-1;j>0;j--)
2370      {
2371        MATELEM(nextStep,i,j) = MATELEM(a,i,j);
2372        MATELEM(a,i,j) = NULL;
2373      }
2374    }
2375    for (i=a->nrows;i>0;i--)
2376    {
2377      for (j=a->ncols;j>c;j--)
2378      {
2379        MATELEM(nextStep,i,j-1) = MATELEM(a,i,j);
2380        MATELEM(a,i,j) = NULL;
2381      }
2382    }
2383/*--- and to perform the algorithm with the rest---------*/
2384    idDelete((ideal*)&a);
2385    idRecMin(nextStep,ar,&p,result,nextPlace,r);
2386    nextStep = NULL;
2387  }
2388/*--- deleting temporary structures and returns----------*/
2389  pDelete(barDiv);
2390  pDelete(&p);
2391  pDelete(&pp);
2392  return;
2393}
2394
2395/*2
2396* compute all ar-minors of the matrix a
2397* the caller of idRecMin
2398*/
2399ideal idMinors(matrix a, int ar)
2400{
2401  if((ar<=0) || (ar>min(a->ncols,a->nrows)))
2402  {
2403    Werror("%d-th minor, matrix is %dx%d",ar,a->ncols,a->nrows);
2404    return NULL;
2405  }
2406  int i=0;
2407  poly barDiv=NULL;
2408  ideal result=idInit(16,1);
2409
2410  idRecMin(mpCopy(a),ar-1,&barDiv,result,&i);
2411  idSkipZeroes(result);
2412  return result;
2413}
2414
2415/*2
2416*returns TRUE if p is a unit element in the current ring
2417*/
2418BOOLEAN pIsUnit(poly p)
2419{
2420  int i;
2421
2422  if (p == NULL) return FALSE;
2423  i = 1;
2424  while (i<=pVariables && pGetExp(p,i) == 0) i++;
2425  if (i > pVariables && (pGetComp(p) == 0))
2426  {
2427    if (currRing->OrdSgn == 1 && pNext(p) !=NULL) return FALSE;
2428    return TRUE;
2429  }
2430  return FALSE;
2431}
2432
2433/*2
2434*skips all zeroes and double elements, searches also for units
2435*/
2436ideal idCompactify(ideal id)
2437{
2438  ideal result = NULL;
2439  int i,j;
2440  BOOLEAN b=FALSE;
2441
2442  result=idCopy(id);
2443  i = IDELEMS(result)-1;
2444  while ((! b) && (i>=0))
2445  {
2446    b=pIsUnit(result->m[i]);
2447    i--;
2448  }
2449  if (b)
2450  {
2451    for (i=IDELEMS(result)-1;i>=0;i--)
2452      pDelete(&result->m[i]);
2453    result->m[0]=pOne();
2454  }
2455  else
2456  {
2457    for (i=1;i<IDELEMS(result);i++)
2458    {
2459      if (result->m[i]!=NULL)
2460      {
2461        for (j=0;j<i;j++)
2462        {
2463          if ((result->m[j]!=NULL)
2464          && (pComparePolys(result->m[i],result->m[j])))
2465          {
2466            pDelete(&(result->m[j]));
2467          }
2468        }
2469      }
2470    }
2471  }
2472  idSkipZeroes(result);
2473  return result;
2474}
2475
2476/*2
2477*returns TRUE if id1 is a submodule of id2
2478*/
2479BOOLEAN idIsSubModule(ideal id1,ideal id2)
2480{
2481  int i;
2482  poly p;
2483
2484  if (idIs0(id1)) return TRUE;
2485  for (i=0;i<IDELEMS(id1);i++)
2486  {
2487    if (id1->m[i] != NULL)
2488    {
2489      p = kNF(id2,currQuotient,id1->m[i]);
2490      if (p != NULL)
2491      {
2492        pDelete(&p);
2493        return FALSE;
2494      }
2495    }
2496  }
2497  return TRUE;
2498}
2499
2500/*2
2501* returns the ideals of initial terms
2502*/
2503ideal idHead(ideal h)
2504{
2505  ideal m = idInit(IDELEMS(h),h->rank);
2506  int i;
2507
2508  for (i=IDELEMS(h)-1;i>=0; i--)
2509  {
2510    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
2511  }
2512  return m;
2513}
2514
2515ideal idHomogen(ideal h, int varnum)
2516{
2517  ideal m = idInit(IDELEMS(h),h->rank);
2518  int i;
2519
2520  for (i=IDELEMS(h)-1;i>=0; i--)
2521  {
2522    m->m[i]=pHomogen(h->m[i],varnum);
2523  }
2524  return m;
2525}
2526
2527/*------------------type conversions----------------*/
2528ideal idVec2Ideal(poly vec)
2529{
2530   ideal result=idInit(1,1);
2531   Free((ADDRESS)result->m,sizeof(poly));
2532   result->m=NULL; // remove later
2533   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2534   return result;
2535}
2536
2537ideal idMatrix2Module(matrix mat)
2538{
2539  ideal result = idInit(MATCOLS(mat),MATROWS(mat));
2540  int i,j;
2541  poly h;
2542#ifdef DRING
2543  poly p;
2544#endif
2545
2546  for(j=0;j<MATCOLS(mat);j++) /* j is also index in result->m */
2547  {
2548    for (i=1;i<=MATROWS(mat);i++)
2549    {
2550      h = MATELEM(mat,i,j+1);
2551      if (h!=NULL)
2552      {
2553        MATELEM(mat,i,j+1)=NULL;
2554        pSetCompP(h,i);
2555#ifdef DRING
2556        pdSetDFlagP(h,0);
2557#endif
2558        result->m[j] = pAdd(result->m[j],h);
2559      }
2560    }
2561  }
2562  return result;
2563}
2564
2565/*2
2566* converts a module into a matrix, destroyes the input
2567*/
2568matrix idModule2Matrix(ideal mod)
2569{
2570  matrix result = mpNew(mod->rank,IDELEMS(mod));
2571  int i,cp;
2572  poly p,h;
2573
2574  for(i=0;i<IDELEMS(mod);i++)
2575  {
2576    p=mod->m[i];
2577    mod->m[i]=NULL;
2578    while (p!=NULL)
2579    {
2580      h=p;
2581      pIter(p);
2582      pNext(h)=NULL;
2583//      cp = max(1,pGetComp(h));     // if used for ideals too
2584      cp = pGetComp(h);
2585      pSetComp(h,0);
2586#ifdef TEST
2587      if (cp>mod->rank)
2588      {
2589        Print("## inv. rank %d -> %d\n",mod->rank,cp);
2590        int k,l,o=mod->rank;
2591        mod->rank=cp;
2592        matrix d=mpNew(mod->rank,IDELEMS(mod));
2593        for (l=1; l<=o; l++)
2594        {
2595          for (k=1; k<=IDELEMS(mod); k++)
2596          {
2597            MATELEM(d,l,k)=MATELEM(result,l,k);
2598            MATELEM(result,l,k)=NULL;
2599          }
2600        }
2601        idDelete((ideal *)&result);
2602        result=d;
2603      }
2604#endif
2605      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2606    }
2607  }
2608  return result;
2609}
2610
2611matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
2612{
2613  matrix result = mpNew(rows,cols);
2614  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
2615  poly p,h;
2616
2617  if (r>rows) r = rows;
2618  if (c>cols) c = cols;
2619  for(i=0;i<c;i++)
2620  {
2621    p=mod->m[i];
2622    mod->m[i]=NULL;
2623    while (p!=NULL)
2624    {
2625      h=p;
2626      pIter(p);
2627      pNext(h)=NULL;
2628      cp = pGetComp(h);
2629      if (cp<=r)
2630      {
2631        pSetComp(h,0);
2632        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2633      }
2634      else
2635        pDelete(&h);
2636    }
2637  }
2638  idDelete(&mod);
2639  return result;
2640}
2641
2642/*2
2643* substitute the n-th variable by the monomial e in id
2644* destroy id
2645*/
2646ideal  idSubst(ideal id, int n, poly e)
2647{
2648  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
2649  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
2650
2651  res->rank = id->rank;
2652  for(k--;k>=0;k--)
2653  {
2654    res->m[k]=pSubst(id->m[k],n,e);
2655    id->m[k]=NULL;
2656  }
2657  idDelete(&id);
2658  return res;
2659}
2660
2661BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
2662{
2663  if (w!=NULL) *w=NULL;
2664  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
2665  if (idIs0(m)) return TRUE;
2666
2667  int i,j,cmax=2,order=0,ord,* diff,* iscom,diffmin=32000;
2668  poly p=NULL;
2669  int length=IDELEMS(m);
2670  polyset P=m->m;
2671  polyset F=(polyset)Alloc(length*sizeof(poly));
2672  for (i=length-1;i>=0;i--)
2673  {
2674    p=F[i]=P[i];
2675    cmax=max(cmax,pMaxComp(p)+1);
2676  }
2677  diff = (int *)Alloc0(cmax*sizeof(int));
2678  if (w!=NULL) *w=new intvec(cmax-1);
2679  iscom = (int *)Alloc0(cmax*sizeof(int));
2680  i=0;
2681  while (i<=length)
2682  {
2683    if (i<length)
2684    {
2685      p=F[i];
2686      while ((p!=NULL) && (!iscom[pGetComp(p)])) pIter(p);
2687    }
2688    if ((p==NULL) && (i<length))
2689    {
2690      i++;
2691    }
2692    else
2693    {
2694      if (p==NULL)
2695      {
2696        i=0;
2697        while ((i<length) && (F[i]==NULL)) i++;
2698        if (i>=length) break;
2699        p = F[i];
2700      }
2701      if (pLexOrder)
2702        order=pTotaldegree(p);
2703      else
2704      //  order = p->order;
2705        order = pFDeg(p);
2706      order += diff[pGetComp(p)];
2707      p = F[i];
2708//Print("Actual p=F[%d]: ",i);pWrite(p);
2709      F[i] = NULL;
2710      i=0;
2711    }
2712    while (p!=NULL)
2713    {
2714      //if (pLexOrder)
2715      //  ord=pTotaldegree(p);
2716      //else
2717      //  ord = p->order;
2718      ord = pFDeg(p);
2719      if (!iscom[pGetComp(p)])
2720      {
2721        diff[pGetComp(p)] = order-ord;
2722        iscom[pGetComp(p)] = 1;
2723/*
2724*PrintS("new diff: ");
2725*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2726*PrintLn();
2727*PrintS("new iscom: ");
2728*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
2729*PrintLn();
2730*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
2731*/
2732      }
2733      else
2734      {
2735/*
2736*PrintS("new diff: ");
2737*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2738*PrintLn();
2739*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
2740*/
2741        if (order != ord+diff[pGetComp(p)])
2742        {
2743          Free((ADDRESS) iscom,cmax*sizeof(int));
2744          Free((ADDRESS) diff,cmax*sizeof(int));
2745          Free((ADDRESS) F,length*sizeof(poly));
2746          delete *w;*w=NULL;
2747          return FALSE;
2748        }
2749      }
2750      pIter(p);
2751    }
2752  }
2753  Free((ADDRESS) iscom,cmax*sizeof(int));
2754  Free((ADDRESS) F,length*sizeof(poly));
2755  for (i=1;i<cmax;i++) (**w)[i-1]=diff[i];
2756  for (i=1;i<cmax;i++)
2757  {
2758    if (diff[i]<diffmin) diffmin=diff[i];
2759  }
2760  for (i=1;i<cmax;i++)
2761  {
2762    (**w)[i-1]=diff[i]-diffmin;
2763  }
2764  Free((ADDRESS) diff,cmax*sizeof(int));
2765  return TRUE;
2766}
2767
2768ideal idJet(ideal i,int d)
2769{
2770  ideal r=idInit(IDELEMS(i),i->rank);
2771  int k;
2772  for(k=0; k<IDELEMS(i); k++)
2773  {
2774    r->m[k]=pJet(i->m[k],d);
2775  }
2776  return r;
2777}
2778
2779ideal idJetW(ideal i,int d, intvec * iv)
2780{
2781  ideal r=idInit(IDELEMS(i),i->rank);
2782  if (ecartWeights!=NULL)
2783  {
2784    WerrorS("cannot compute weighted jets now");
2785  }
2786  else
2787  {
2788    short *w=iv2array(iv);
2789    int k;
2790    for(k=0; k<IDELEMS(i); k++)
2791    {
2792      r->m[k]=pJetW(i->m[k],d,w);
2793    }
2794    Free((ADDRESS)w,(pVariables+1)*sizeof(short));
2795  }
2796  return r;
2797}
2798
2799matrix idDiff(matrix i, int k)
2800{
2801  int e=MATCOLS(i)*MATROWS(i);
2802  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2803  int j;
2804  for(j=0; j<e; j++)
2805  {
2806    r->m[j]=pDiff(i->m[j],k);
2807  }
2808  return r;
2809}
2810
2811matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2812{
2813  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2814  int i,j;
2815  for(i=0; i<IDELEMS(I); i++)
2816  {
2817    for(j=0; j<IDELEMS(J); j++)
2818    {
2819      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2820    }
2821  }
2822  return r;
2823}
2824
2825/*2
2826* represents (h1+h2)/h2=h1/(h1 intersect h2)
2827*/
2828ideal idModulo (ideal h2,ideal h1)
2829{
2830  ideal temp,temp1;
2831  int i,j,k,rk,flength=0,slength,length;
2832  intvec * w;
2833  poly p,q;
2834
2835  if (idIs0(h2))
2836    return idFreeModule(max(1,h2->ncols));
2837  if (!idIs0(h1))
2838    flength = idRankFreeModule(h1);
2839  slength = idRankFreeModule(h2);
2840  length  = max(flength,slength);
2841  if (length==0)
2842  {
2843    length = 1;
2844  }
2845  temp = idInit(IDELEMS(h2),1);
2846  for (i=0;i<IDELEMS(h2);i++)
2847  {
2848    temp->m[i] = pCopy(h2->m[i]);
2849    q = pOne();
2850    pSetComp(q,i+1+length);
2851    if(temp->m[i]!=NULL)
2852    {
2853      if (slength==0) pShift(&(temp->m[i]),1);
2854      p = temp->m[i];
2855      while (pNext(p)!=NULL) pIter(p);
2856      pNext(p) = q;
2857    }
2858    else
2859      temp->m[i]=q;
2860  }
2861  rk = k = IDELEMS(h2);
2862  if (!idIs0(h1))
2863  {
2864    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
2865    IDELEMS(temp) += IDELEMS(h1);
2866    for (i=0;i<IDELEMS(h1);i++)
2867    {
2868      if (h1->m[i]!=NULL)
2869      {
2870        temp->m[k] = pCopy(h1->m[i]);
2871        if (flength==0) pShift(&(temp->m[k]),1);
2872        k++;
2873      }
2874    }
2875  }
2876  pSetSyzComp(length);
2877  temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
2878  pSetSyzComp(0);
2879  idDelete(&temp);
2880  if (w!=NULL) delete w;
2881  for (i=0;i<IDELEMS(temp1);i++)
2882  {
2883    if ((temp1->m[i]!=NULL)
2884    && (pGetComp(temp1->m[i])<=length))
2885    {
2886      pDelete(&(temp1->m[i]));
2887    }
2888    else
2889    {
2890      pShift(&(temp1->m[i]),-length);
2891    }
2892  }
2893  idSkipZeroes(temp1);
2894  temp1->rank = rk;
2895  return temp1;
2896}
2897
2898int idElem(ideal F)
2899{
2900  int i=0,j=0;
2901
2902  while(j<IDELEMS(F))
2903  {
2904   if ((F->m)[j]!=NULL) i++;
2905   j++;
2906  }
2907  return i;
2908}
2909
2910/*
2911*computes module-weights for liftings of homogeneous modules
2912*/
2913intvec * idMWLift(ideal mod,intvec * weights)
2914{
2915  if (idIs0(mod)) return new intvec(2);
2916  int i=IDELEMS(mod);
2917  while ((i>0) && (mod->m[i-1]==NULL)) i--;
2918  intvec *result = new intvec(i+1);
2919  while (i>0)
2920  {
2921    (*result)[i]=pFDeg(mod->m[i])+(*weights)[pGetComp(mod->m[i])];
2922  }
2923  return result;
2924}
2925
2926/*2
2927*sorts the kbase for idCoef* in a special way (lexicographically
2928*with x_max,...,x_1)
2929*/
2930ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
2931{
2932  int i;
2933  ideal result;
2934
2935  if (idIs0(kBase)) return NULL;
2936  result = idInit(IDELEMS(kBase),kBase->rank);
2937  *convert = idSort(kBase,FALSE);
2938  for (i=0;i<(*convert)->length();i++)
2939  {
2940    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
2941  }
2942  return result;
2943}
2944
2945/*2
2946*returns the index of a given monom in the list of the special kbase
2947*/
2948int idIndexOfKBase(poly monom, ideal kbase)
2949{
2950  int j=IDELEMS(kbase);
2951
2952  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
2953  if (j==0) return -1;
2954  int i=pVariables;
2955  while (i>0)
2956  {
2957    loop
2958    {
2959      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
2960      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
2961      j--;
2962      if (j==0) return -1;
2963    }
2964    if (i==1)
2965    {
2966      while(j>0)
2967      {
2968        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
2969        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
2970        j--;
2971      }
2972    }
2973    i--;
2974  }
2975  return -1;
2976}
2977
2978/*2
2979*decomposes the monom in a part of coefficients described by the
2980*complement of how and a monom in variables occuring in how, the
2981*index of which in kbase is returned as integer pos (-1 if it don't
2982*exists)
2983*/
2984poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
2985{
2986  int i;
2987  poly coeff=pOne(), base=pOne();
2988
2989  for (i=1;i<=pVariables;i++)
2990  {
2991    if (pGetExp(how,i)>0)
2992    {
2993      pSetExp(base,i,pGetExp(monom,i));
2994    }
2995    else
2996    {
2997      pSetExp(coeff,i,pGetExp(monom,i));
2998    }
2999  }
3000  pSetComp(base,pGetComp(monom));
3001  pSetm(base);
3002  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3003  pSetm(coeff);
3004  *pos = idIndexOfKBase(base,kbase);
3005  if (*pos<0)
3006    pDelete(&coeff);
3007  pDelete(&base);
3008  return coeff;
3009}
3010
3011/*2
3012*returns a matrix A of coefficients with kbase*A=arg
3013*if all monomials in variables of how occur in kbase
3014*the other are deleted
3015*/
3016matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3017{
3018  matrix result;
3019  ideal tempKbase;
3020  poly p,q;
3021  intvec * convert;
3022  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3023#if 0
3024  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3025  if (idIs0(arg))
3026    return mpNew(i,1);
3027  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3028  result = mpNew(i,j);
3029#else
3030  result = mpNew(i, j);
3031  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3032#endif
3033
3034  tempKbase = idCreateSpecialKbase(kbase,&convert);
3035  for (k=0;k<j;k++)
3036  {
3037    p = arg->m[k];
3038    while (p!=NULL)
3039    {
3040      q = idDecompose(p,how,tempKbase,&pos);
3041      if (pos>=0)
3042      {
3043        MATELEM(result,(*convert)[pos],k+1) =
3044            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3045      }
3046      else
3047        pDelete(&q);
3048      pIter(p);
3049    }
3050  }
3051  idDelete(&tempKbase);
3052  return result;
3053}
3054
3055intvec * idQHomWeights(ideal id)
3056{
3057  intvec * imat=new intvec(2*pVariables,pVariables,0);
3058  poly actHead=NULL,wPoint=NULL;
3059  int actIndex,i=-1,j=1,k;
3060  BOOLEAN notReady=TRUE;
3061
3062  while (notReady)
3063  {
3064    if (wPoint==NULL)
3065    {
3066      i++;
3067      while ((i<IDELEMS(id))
3068      && ((id->m[i]==NULL) || (pNext(id->m[i])==NULL)))
3069        i++;
3070      if (i<IDELEMS(id))
3071      {
3072        actHead = id->m[i];
3073        wPoint = pNext(actHead);
3074      }
3075    }
3076    while ((wPoint!=NULL) && (j<=2*pVariables))
3077    {
3078      for (k=1;k<=pVariables;k++)
3079        IMATELEM(*imat,j,k) += pGetExp(actHead,k)-pGetExp(wPoint,k);
3080      pIter(wPoint);
3081      j++;
3082    }
3083    if ((i>=IDELEMS(id)) || (j>2*pVariables))
3084    {
3085      ivTriangMat(imat,1,1);
3086      j = ivFirstEmptyRow(imat);
3087      if ((i>=IDELEMS(id)) || (j>pVariables)) notReady=FALSE;
3088    }
3089  }
3090  intvec *result=NULL;
3091  if (j<=pVariables)
3092  {
3093    result=ivSolveIntMat(imat);
3094  }
3095  //else
3096  //{
3097  //  WerrorS("not homogeneous");
3098  //}
3099  delete imat;
3100  return result;
3101}
3102
3103/*2
3104* returns the presentation of an isomorphic, minimally
3105* embedded  module
3106*/
3107ideal idMinEmbedding(ideal arg)
3108{
3109  if (idIs0(arg)) return idInit(1,arg->rank);
3110
3111  int i,j,k,pC;
3112  poly p,q;
3113  int rg=arg->rank;
3114  ideal res = idCopy(arg);
3115  intvec *indexMap=new intvec(rg+1);
3116  intvec *toKill=new intvec(rg+1);
3117
3118  loop
3119  {
3120    k = 0;
3121    for (i=indexMap->length()-1;i>0;i--)
3122    {
3123      (*indexMap)[i] = i;
3124      (*toKill)[i] = 0;
3125    }
3126    for (j=IDELEMS(res)-1;j>=0;j--)
3127    {
3128      if ((res->m[j]!=NULL) && (pIsConstantComp(res->m[j])) &&
3129           (pNext(res->m[j])==NULL))
3130      {
3131        pC = pGetComp(res->m[j]);
3132        if ((*toKill)[pC]==0)
3133        {
3134          rg--;
3135          (*toKill)[pC] = 1;
3136          for (i=indexMap->length()-1;i>=pC;i--)
3137            (*indexMap)[i]--;
3138        }
3139        pDelete(&(res->m[j]));
3140        k++;
3141      }
3142    }
3143    idSkipZeroes(res);
3144    if (k==0) break;
3145    if (rg>0)
3146    {
3147      res->rank=rg;
3148      for (j=IDELEMS(res)-1;j>=0;j--)
3149      {
3150        while ((res->m[j]!=NULL) && ((*toKill)[pGetComp(res->m[j])]==1))
3151          pDelete1(&res->m[j]);
3152        p = res->m[j];
3153        while ((p!=NULL) && (pNext(p)!=NULL))
3154        {
3155          pSetComp(p,(*indexMap)[pGetComp(p)]);
3156          while ((pNext(p)!=NULL) && ((*toKill)[pGetComp(pNext(p))]==1))
3157            pDelete1(&pNext(p));
3158          pIter(p);
3159        }
3160        if (p!=NULL) pSetComp(p,(*indexMap)[pGetComp(p)]);
3161      }
3162      idSkipZeroes(res);
3163    }
3164    else
3165    {
3166      idDelete(&res);
3167      res=idFreeModule(1);
3168      break;
3169    }
3170  }
3171  delete toKill;
3172  delete indexMap;
3173  return res;
3174}
3175
3176/*2
3177* transpose a module
3178*/
3179ideal idTransp(ideal a)
3180{
3181  int r = a->rank, c = IDELEMS(a);
3182  ideal b =  idInit(r,c);
3183
3184  for (int i=c; i>0; i--)
3185  {
3186    poly p=a->m[i-1];
3187    while(p!=NULL)
3188    {
3189      poly h=pHead(p);
3190      int co=pGetComp(h)-1;
3191      pSetComp(h,i);
3192      b->m[co]=pAdd(b->m[co],h);
3193      pIter(p);
3194    }
3195  }
3196  return b;
3197}
3198
Note: See TracBrowser for help on using the repository browser.