source: git/Singular/ideals.cc @ a1c9c02

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