source: git/Singular/ideals.cc @ 47fed0

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