source: git/Singular/ideals.cc @ b011fc

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