source: git/Singular/ideals.cc @ a70441f

fieker-DuValspielwiese
Last change on this file since a70441f was 250c24a, checked in by Hans Schönemann <hannes@…>, 24 years ago
*hannes: use pDelete1 instead of pDelete git-svn-id: file:///usr/local/Singular/svn/trunk@4179 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 64.9 KB
RevLine 
[0e1846]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[250c24a]4/* $Id: ideals.cc,v 1.93 2000-03-07 15:49:13 Singular Exp $ */
[0e1846]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"
[416465]25#include "prCopy.h"
[0e1846]26
27
[ef72ff3]28/* #define WITH_OLD_MINOR */
[416465]29#define pCopy_noCheck(p) pCopy(p)
[c616d1]30
[0e1846]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*/
[c616d1]43#ifdef PDEBUG
[0e1846]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 -*/
[c616d1]50#if defined(MDEBUG) && defined(PDEBUG)
[b7b08c]51  ideal hh = (ideal )mmDBAllocBlock(sizeof(sip_sideal),f,l);
[0e1846]52#else
[b7b08c]53  ideal hh = (ideal )AllocSizeOf(sip_sideal);
[0e1846]54#endif
55  hh->nrows = 1;
56  hh->rank = rank;
57  IDELEMS(hh) = idsize;
58  if (idsize>0)
59  {
[c616d1]60#if defined(MDEBUG) && defined(PDEBUG)
[0e1846]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
[0fcb82]71//#ifndef __OPTIMIZE__
[416465]72// this is mainly for outputting an ideal within the debugger
[0fcb82]73void idShow(ideal id)
[b982ef]74{
75  Print("Module of rank %d,real rank %d and %d generators.\n",
76         id->rank,idRankFreeModule(id),IDELEMS(id));
[df542e1]77  for (int i=0;i<id->ncols*id->nrows;i++)
[b982ef]78  {
79    if (id->m[i]!=NULL)
80    {
81      Print("generator %d: ",i);pWrite(id->m[i]);
82    }
83  }
84}
[0fcb82]85//#endif
[b982ef]86
[0e1846]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*/
[c616d1]108#ifdef PDEBUG
[25f470]109void idDBDelete (ideal* h, char *f, int l)
110#else
[0e1846]111void idDelete (ideal * h)
[25f470]112#endif
[0e1846]113{
[25f470]114  int j,elems;
115  if (*h == NULL)
116    return;
117  elems=j=(*h)->nrows*(*h)->ncols;
[0e1846]118  if (j>0)
119  {
120    do
121    {
[055a19]122      #if defined(MDEBUG) && defined(PDEBUG)
123      pDBDelete(&((*h)->m[--j]),mm_specHeap, f,l);
[25f470]124      #else
[0e1846]125      pDelete(&((*h)->m[--j]));
[25f470]126      #endif
[0e1846]127    }
128    while (j>0);
[c616d1]129    #if defined(MDEBUG) && defined(PDEBUG)
[25f470]130    mmDBFreeBlock((ADDRESS)((*h)->m),sizeof(poly)*elems,f,l);
131    #else
132    Free((ADDRESS)((*h)->m),sizeof(poly)*elems);
133    #endif
[0e1846]134  }
[c616d1]135  #if defined(MDEBUG) && defined(PDEBUG)
[b7b08c]136  mmDBFreeBlock((ADDRESS)(*h),sizeof(sip_sideal),f,l);
[25f470]137  #else
[b7b08c]138  FreeSizeOf((ADDRESS)*h,sip_sideal);
[25f470]139  #endif
[0e1846]140  *h=NULL;
141}
142
143/*2
144*gives an ideal the minimal possible size
145*/
146void idSkipZeroes (ideal ide)
147{
[25f470]148  int k;
149  int j = -1;
150  BOOLEAN change=FALSE;
[0e1846]151  for (k=0; k<IDELEMS(ide); k++)
152  {
153    if (ide->m[k] != NULL)
154    {
155      j++;
[25f470]156      if (change)
157      {
158        ide->m[j] = ide->m[k];
159      }
160    }
161    else
162    {
163      change=TRUE;
[0e1846]164    }
165  }
[25f470]166  if (change)
[0e1846]167  {
[25f470]168    if (j == -1)
169      j = 0;
170    else
[43580ac]171    {
[25f470]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;
[0e1846]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
[26ae12]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}
[eb816e]287
[26ae12]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    {
[eb816e]296
[26ae12]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}
[eb816e]315
[26ae12]316
[0e1846]317/*2
318* copy an ideal
319*/
[c616d1]320#ifdef PDEBUG
[0e1846]321ideal idDBCopy(ideal h1,char *f,int l)
322#else
323ideal idCopy (ideal h1)
324#endif
325{
326  int i;
327  ideal h2;
328
[9c7b9a]329#ifdef PDEBUG
330  idDBTest(h1,f,l);
331#endif
[667247]332//#ifdef TEST
[0e1846]333  if (h1 == NULL)
334  {
[c616d1]335#ifdef PDEBUG
[0e1846]336    h2=idDBInit(1,1,f,l);
337#else
338    h2=idInit(1,1);
339#endif
340  }
341  else
[667247]342//#endif
[0e1846]343  {
[c616d1]344#ifdef PDEBUG
[0e1846]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--)
[055a19]350#if defined(PDEBUG) && defined(MDEBUG)
[0e1846]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  {
[25f470]366    #ifdef MDEBUG
367    mmDBTestBlock(h1,sizeof(*h1),f,l);
[055a19]368    /* to be able to test matrices: */
369    mmDBTestBlock(h1->m,h1->ncols*h1->nrows*sizeof(poly),f,l);
[25f470]370    #endif
[e974a2]371    /* to be able to test matrices: */
[055a19]372    for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
[0e1846]373      pDBTest(h1->m[i],f,l);
[9c7b9a]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    }
[0e1846]381  }
382}
383#endif
384
385/*3
386* for idSort: compare a and b revlex inclusive module comp.
387*/
[83552f]388static int pComp_RevLex(poly a, poly b,BOOLEAN nolex)
[0e1846]389{
[83552f]390 if (nolex) return pComp0(a,b);
[0e1846]391 int l=pVariables;
[50619f7]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 }
[0e1846]398 else if (pGetExp(a,l)>pGetExp(b,l))
399   return 1;
[50619f7]400 return -1;
[0e1846]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;
[477993]410  intvec * result = NewIntvec1(IDELEMS(id));
[0e1846]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;
[392841]423      lastcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
[0e1846]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      {
[83552f]438        newcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
[0e1846]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;
[0e1284]484      if (newpos>actpos) newpos = actpos;
[83552f]485      while ((newpos<actpos) && (pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex)==0))
[0e1284]486        newpos++;
487      for (j=actpos;j>newpos;j--)
[0e1846]488      {
[0e1284]489        (*result)[j] = (*result)[j-1];
[0e1846]490      }
[0e1284]491      (*result)[newpos] = i;
[0e1846]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);
[4b5c87]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);
[0e1846]516  else
[4b5c87]517    result=idInit(i+j+2,r);
518  for (l=j; l>=0; l--)
[0e1846]519  {
[4b5c87]520    result->m[l] = pCopy(h1->m[l]);
[0e1846]521  }
[4b5c87]522  r = i+j+1;
523  for (l=i; l>=0; l--, r--)
[0e1846]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;
[5990ae]583    //return hh;
[0e1846]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  {
[7ae776]679    lists re=min_std(h1,currQuotient,(tHomog)homog,&wth,NULL,0,3);
[0e1846]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;
[a1c44e]693  h2 = kStd(h1,currQuotient,isNotHomog,NULL);
[0e1846]694  h3 = idMaxIdeal();
695  h4=idMult(h2,h3);
696  idDelete(&h3);
[a1c44e]697  h3=kStd(h4,currQuotient,isNotHomog,NULL);
[0e1846]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);
[58bbda]726  if (currQuotient!=NULL)
[0e1846]727  {
[58bbda]728    h3=idInit(1,e->rank);
729    h2=kNF(h3,currQuotient,e);
730    idDelete(&h3);
[0e1846]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);
[7b4121]752    while ((l < pVariables) && (lex == 0))
[0e1846]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*/
[e78cce]788      result = pInit();
[0e1846]789      qresult = result;
790    }
791    else
792    {
[e78cce]793      qresult->next = pInit();
[0e1846]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*/
[e78cce]856      result = pInit();
[0e1846]857      resultp = result;
858      resultp->next = NULL;
859    }
860    else
861    {
[e78cce]862      resultp->next = pInit();
[0e1846]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);
[b9a806]915      pSetmComp(qp1);
[0e1846]916      qp2 = qp1;
917      pIter(qp1);
918    }
919    else
920    {
921      if (qp2 == *p)
922      {
923        pIter(*p);
[250c24a]924        pDelete1(&qp2);
[0e1846]925        qp2 = *p;
926        qp1 = *p;
927      }
928      else
929      {
930        qp2->next = qp1->next;
[250c24a]931        pDelete1(&qp1);
[0e1846]932        qp1 = qp2->next;
933      }
934    }
935  }
936}
937
938/*2
939*initialized a field with r numbers between beg and end for the
940*procedure idNextChoise
941*/
942void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
943{
944  /*returns the first choise of r numbers between beg and end*/
945  int i;
946  for (i=0; i<r; i++)
947  {
948    choise[i] = 0;
949  }
950  if (r <= end-beg+1)
951    for (i=0; i<r; i++)
952    {
953      choise[i] = beg+i;
954    }
955  if (r > end-beg+1)
956    *endch = TRUE;
957  else
958    *endch = FALSE;
959}
960
961/*2
962*returns the next choise of r numbers between beg and end
963*/
964void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
965{
966  int i = r-1,j;
967  while ((i >= 0) && (choise[i] == end))
968  {
969    i--;
970    end--;
971  }
972  if (i == -1)
973    *endch = TRUE;
974  else
975  {
976    choise[i]++;
977    for (j=i+1; j<r; j++)
978    {
979      choise[j] = choise[i]+j-i;
980    }
981    *endch = FALSE;
982  }
983}
984
985/*2
986*takes the field choise of d numbers between beg and end, cancels the t-th
987*entree and searches for the ordinal number of that d-1 dimensional field
988* w.r.t. the algorithm of construction
989*/
990int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
991{
992  int * localchoise,i,result=0;
993  BOOLEAN b=FALSE;
994
995  if (d<=1) return 1;
996  localchoise=(int*)Alloc((d-1)*sizeof(int));
997  idInitChoise(d-1,begin,end,&b,localchoise);
998  while (!b)
999  {
1000    result++;
1001    i = 0;
1002    while ((i<t) && (localchoise[i]==choise[i])) i++;
1003    if (i>=t)
1004    {
1005      i = t+1;
1006      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
1007      if (i>=d)
1008      {
1009        Free((ADDRESS)localchoise,(d-1)*sizeof(int));
1010        return result;
1011      }
1012    }
1013    idGetNextChoise(d-1,end,&b,localchoise);
1014  }
1015  Free((ADDRESS)localchoise,(d-1)*sizeof(int));
1016  return 0;
1017}
1018
1019/*2
1020*computes the binomial coefficient
1021*/
1022int binom (int n,int r)
1023{
1024  int i,result;
1025
1026  if (r==0) return 1;
1027  if (n-r<r) return binom(n,n-r);
1028  result = n-r+1;
1029  for (i=2;i<=r;i++)
1030  {
1031    result *= n-r+i;
1032    result /= i;
1033  }
1034  return result;
1035}
1036
1037/*2
1038*the free module of rank i
1039*/
1040ideal idFreeModule (int i)
1041{
1042  int j;
1043  ideal h;
1044
1045  h=idInit(i,i);
1046  for (j=0; j<i; j++)
1047  {
1048    h->m[j] = pOne();
1049    pSetComp(h->m[j],j+1);
[66a672]1050    pSetmComp(h->m[j]);
[0e1846]1051  }
1052  return h;
1053}
1054
1055/*2
1056* h3 := h1 intersect h2
1057*/
1058ideal idSect (ideal h1,ideal h2)
1059{
1060  ideal first=h2,second=h1,temp,temp1,result;
1061  int i,j,k,flength,slength,length,rank=min(h1->rank,h2->rank);
[4c001a]1062  intvec *w;
[0e1846]1063  poly p,q;
1064
1065  if ((idIs0(h1)) && (idIs0(h2)))  return idInit(1,rank);
1066  if (IDELEMS(h1)<IDELEMS(h2))
1067  {
1068    first = h1;
1069    second = h2;
1070  }
1071  flength = idRankFreeModule(first);
1072  slength = idRankFreeModule(second);
1073  length  = max(flength,slength);
1074  if (length==0)
1075  {
1076    length = 1;
1077  }
[e960943]1078  j = IDELEMS(first);
[7bab5d]1079  temp = idInit(j /*IDELEMS(first)*/,length+j);
[e960943]1080
1081  ring orig_ring=currRing;
[0e002d]1082  ring syz_ring=rCurrRingAssure_SyzComp();
[416465]1083  rSetSyzComp(length);
[e960943]1084
[0e1846]1085  while ((j>0) && (first->m[j-1]==NULL)) j--;
1086  k = 0;
1087  for (i=0;i<j;i++)
1088  {
1089    if (first->m[i]!=NULL)
1090    {
[e960943]1091      if (syz_ring==orig_ring)
1092        temp->m[k] = pCopy(first->m[i]);
1093      else
[416465]1094        temp->m[k] = prCopyR(first->m[i], orig_ring);
[0e1846]1095      q = pOne();
1096      pSetComp(q,i+1+length);
[66a672]1097      pSetmComp(q);
[0e1846]1098      if (flength==0) pShift(&(temp->m[k]),1);
1099      p = temp->m[k];
[66a672]1100      while (pNext(p)!=NULL) pIter(p);
[0e1846]1101      pNext(p) = q;
1102      k++;
1103    }
1104  }
1105  pEnlargeSet(&(temp->m),IDELEMS(temp),j+IDELEMS(second)-IDELEMS(temp));
1106  IDELEMS(temp) = j+IDELEMS(second);
1107  for (i=0;i<IDELEMS(second);i++)
1108  {
1109    if (second->m[i]!=NULL)
1110    {
[e960943]1111      if (syz_ring==orig_ring)
1112        temp->m[k] = pCopy(second->m[i]);
1113      else
[416465]1114        temp->m[k] = prCopyR(second->m[i], orig_ring);
[0e1846]1115      if (slength==0) pShift(&(temp->m[k]),1);
1116      k++;
1117    }
1118  }
[a1c44e]1119  temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
[4c001a]1120  if (w!=NULL) delete w;
[0e1846]1121  idDelete(&temp);
[e960943]1122
1123  if(syz_ring!=orig_ring)
1124    rChangeCurrRing(orig_ring,TRUE);
1125
[0e1846]1126  result = idInit(IDELEMS(temp1),rank);
1127  j = 0;
1128  for (i=0;i<IDELEMS(temp1);i++)
1129  {
1130    if ((temp1->m[i]!=NULL)
[e960943]1131    && (pRingGetComp(syz_ring,temp1->m[i])>length))
[0e1846]1132    {
[e960943]1133      if(syz_ring==orig_ring)
1134        p = pCopy(temp1->m[i]);
1135      else
[416465]1136        p = prCopyR(temp1->m[i], syz_ring);
[0e1846]1137      while (p!=NULL)
1138      {
1139        q = pNext(p);
1140        pNext(p) = NULL;
1141        k = pGetComp(p)-1-length;
1142        pSetComp(p,0);
[66a672]1143        pSetmComp(p);
[0e1846]1144        result->m[j] = pAdd(result->m[j],pMult(pCopy(first->m[k]),p));
1145        p = q;
1146      }
1147      j++;
1148    }
1149  }
[e960943]1150  if(syz_ring!=orig_ring)
[87bef42]1151  {
[b9a806]1152    rChangeCurrRing(syz_ring,FALSE);
1153    idDelete(&temp1);
[e960943]1154    rChangeCurrRing(orig_ring,TRUE);
1155    rKill(syz_ring);
[87bef42]1156  }
[b9a806]1157  else
1158  {
1159    idDelete(&temp1);
1160  }
[e960943]1161
[0e1846]1162  idSkipZeroes(result);
1163  return result;
1164}
1165
1166/*2
1167* ideal/module intersection for a list of objects
1168* given as 'resolvente'
1169*/
1170ideal idMultSect(resolvente arg, int length)
1171{
1172  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
1173  ideal bigmat,tempstd,result;
1174  poly p;
1175  int isIdeal=0;
1176  intvec * w=NULL;
1177
1178  /* find 0-ideals and max rank -----------------------------------*/
1179  for (i=0;i<length;i++)
1180  {
1181    if (!idIs0(arg[i]))
1182    {
1183      realrki=idRankFreeModule(arg[i]);
1184      k++;
1185      j += IDELEMS(arg[i]);
1186      if (realrki>maxrk) maxrk = realrki;
1187    }
1188    else
1189    {
1190      if (arg[i]!=NULL)
1191      {
1192        return idInit(1,arg[i]->rank);
1193      }
1194    }
1195  }
1196  if (maxrk == 0)
1197  {
1198    isIdeal = 1;
1199    maxrk = 1;
1200  }
1201  /* init -----------------------------------------------------------*/
1202  j += maxrk;
1203  syzComp = k*maxrk;
[b9a806]1204
[e960943]1205  ring orig_ring=currRing;
[0e002d]1206  ring syz_ring=rCurrRingAssure_SyzComp();
[416465]1207  rSetSyzComp(syzComp);
[e960943]1208
1209  bigmat = idInit(j,(k+1)*maxrk);
[0e1846]1210  /* create unit matrices ------------------------------------------*/
1211  for (i=0;i<maxrk;i++)
1212  {
1213    for (j=0;j<=k;j++)
1214    {
1215      p = pOne();
1216      pSetComp(p,i+1+j*maxrk);
[b9a806]1217      pSetmComp(p);
[0e1846]1218      bigmat->m[i] = pAdd(bigmat->m[i],p);
1219    }
1220  }
1221  /* enter given ideals ------------------------------------------*/
1222  i = maxrk;
1223  k = 0;
1224  for (j=0;j<length;j++)
1225  {
1226    if (arg[j]!=NULL)
1227    {
1228      for (l=0;l<IDELEMS(arg[j]);l++)
1229      {
1230        if (arg[j]->m[l]!=NULL)
1231        {
[e960943]1232          if (syz_ring==orig_ring)
1233            bigmat->m[i] = pCopy(arg[j]->m[l]);
1234          else
[416465]1235            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring);
[0e1846]1236          pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
1237          i++;
1238        }
1239      }
1240      k++;
1241    }
1242  }
1243  /* std computation --------------------------------------------*/
[a1c44e]1244  tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
[0e1846]1245  if (w!=NULL) delete w;
1246  idDelete(&bigmat);
[e960943]1247
1248  if(syz_ring!=orig_ring)
1249    rChangeCurrRing(orig_ring,TRUE);
1250
[0e1846]1251  /* interprete result ----------------------------------------*/
1252  result = idInit(8,maxrk);
1253  k = 0;
1254  for (j=0;j<IDELEMS(tempstd);j++)
1255  {
[e960943]1256    if ((tempstd->m[j]!=NULL) && (pRingGetComp(syz_ring,tempstd->m[j])>syzComp))
[0e1846]1257    {
1258      if (k>=IDELEMS(result))
1259      {
1260        pEnlargeSet(&(result->m),IDELEMS(result),8);
1261        IDELEMS(result) += 8;
1262      }
[e960943]1263      if (syz_ring==orig_ring)
1264        p = pCopy(tempstd->m[j]);
1265      else
[416465]1266        p = prCopyR(tempstd->m[j], syz_ring);
[0e1846]1267      pShift(&p,-syzComp-isIdeal);
1268      result->m[k] = p;
1269      k++;
1270    }
1271  }
1272  /* clean up ----------------------------------------------------*/
[e960943]1273  if(syz_ring!=orig_ring)
1274    rChangeCurrRing(syz_ring,FALSE);
[0e1846]1275  idDelete(&tempstd);
[e960943]1276  if(syz_ring!=orig_ring)
1277  {
1278    rChangeCurrRing(orig_ring,TRUE);
1279    rKill(syz_ring);
1280  }
[0e1846]1281  idSkipZeroes(result);
1282  return result;
1283}
1284
1285/*2
1286*computes syzygies of h1,
1287*if quot != NULL it computes in the quotient ring modulo "quot"
[e960943]1288*works always in a ring with ringorder_s
[0e1846]1289*/
[416465]1290static ideal idPrepare (ideal  h1, tHomog h, int syzcomp, intvec **w)
[0e1846]1291{
1292  ideal   h2, h3;
1293  int     i;
[27f5f1e]1294  int     j,jj=0,k;
[0e1846]1295  poly    p,q;
1296
1297  if (idIs0(h1)) return NULL;
[b9a806]1298  k = idRankFreeModule(h1);
[0e1846]1299  h2=idCopy(h1);
1300  i = IDELEMS(h2)-1;
1301  if (k == 0)
1302  {
1303    for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
[e960943]1304    k = 1;
1305  }
1306  if (syzcomp<k)
1307  {
1308    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
1309    syzcomp = k;
[416465]1310    rSetSyzComp(k);
[0e1846]1311  }
[e960943]1312  h2->rank = syzcomp+i+1;
[0e1846]1313  for (j=0; j<=i; j++)
1314  {
1315    p = h2->m[j];
1316    q = pOne();
[e960943]1317    pSetComp(q,syzcomp+1+j);
[b9a806]1318    pSetmComp(q);
[0e1846]1319    if (p!=NULL)
1320    {
1321      while (pNext(p)) pIter(p);
1322      p->next = q;
1323    }
1324    else
1325      h2->m[j]=q;
1326  }
[27f5f1e]1327
[0e1846]1328#ifdef PDEBUG
1329  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
1330#endif
[416465]1331  h3=kStd(h2,currQuotient,h,w,NULL,syzcomp);
[0e1846]1332  idDelete(&h2);
1333  return h3;
1334}
1335
[87bef42]1336/*2
[b9a806]1337* compute the syzygies of h1 in R/quot,
[87bef42]1338* weights of components are in w
1339* if setRegularity, return the regularity in deg
[416465]1340* do not change h1,  w
[87bef42]1341*/
[416465]1342ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
[551fd7]1343                  BOOLEAN setRegularity, int *deg)
[0e1846]1344{
[416465]1345  ideal s_h1;
[0e1846]1346  poly  p;
[416465]1347  int   i, j, k, length=0,reg;
[0e1846]1348  BOOLEAN isMonomial=TRUE;
[84db93f]1349  int ii;
[0e1846]1350
1351#ifdef PDEBUG
1352  for(ii=0;ii<IDELEMS(h1);ii++) pTest(h1->m[ii]);
1353#endif
1354  if (idIs0(h1))
[84db93f]1355  {
1356    ideal result=idFreeModule(IDELEMS(h1));
1357    int curr_syz_limit=rGetCurrSyzLimit();
1358    if (curr_syz_limit>0)
[1bf317]1359    for (ii=0;ii<IDELEMS(h1);ii++)
[84db93f]1360    {
1361      if (h1->m[ii]!=NULL)
1362        pShift(&h1->m[ii],curr_syz_limit);
1363    }
1364    return result;
1365  }
[87bef42]1366  k=max(1,idRankFreeModule(h1));
[e960943]1367
[c54075]1368  assume(currRing != NULL);
[e960943]1369  ring orig_ring=currRing;
[0e002d]1370  ring syz_ring=rCurrRingAssure_SyzComp();
[7bab5d]1371
[416465]1372  if (setSyzComp)
1373    rSetSyzComp(k);
[87bef42]1374
[416465]1375  if (orig_ring != syz_ring)
1376  {
1377    s_h1=idrCopyR_NoSort(h1,orig_ring);
1378  }
1379  else
1380  {
1381    s_h1 = h1;
1382  }
[e960943]1383
[416465]1384  ideal s_h3=idPrepare(s_h1,h,k,w);
[e960943]1385
1386  if (s_h3==NULL)
1387  {
[0e1846]1388    return idFreeModule(IDELEMS(h1));
[e960943]1389  }
[416465]1390
1391  if (orig_ring != syz_ring)
[0e1846]1392  {
[416465]1393    idDelete(&s_h1);
1394    for (j=0; j<IDELEMS(s_h3); j++)
[0e1846]1395    {
[1bf317]1396      if (s_h3->m[j] != NULL)
[0e1846]1397      {
[416465]1398        if (pMinComp(s_h3->m[j],syz_ring) > k)
1399          pShift(&s_h3->m[j], -k);
[e960943]1400        else
[416465]1401          pDelete(&s_h3->m[j]);
[0e1846]1402      }
[416465]1403    }
1404    idSkipZeroes(s_h3);
1405    s_h3->rank -= k;
1406    rChangeCurrRing(orig_ring, TRUE);
1407    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
1408    rKill(syz_ring);
1409    idTest(s_h3);
1410    return s_h3;
1411  }
[1bf317]1412
[416465]1413  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
1414
1415  for (j=0; j<IDELEMS(s_h3); j++)
1416  {
1417    if (s_h3->m[j] != NULL)
1418    {
1419      if (pMinComp(s_h3->m[j],syz_ring) <= k)
[0e1846]1420      {
[416465]1421        e->m[j] = s_h3->m[j];
[e960943]1422        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
[416465]1423        pDelete(&pNext(s_h3->m[j]));
1424        s_h3->m[j] = NULL;
[0e1846]1425      }
1426    }
1427  }
[1bf317]1428
[416465]1429  idSkipZeroes(s_h3);
1430  idSkipZeroes(e);
[1bf317]1431
1432  if (deg != NULL
[551fd7]1433  && (!isMonomial)
[e960943]1434  && (!TEST_OPT_NOTREGULARITY)
1435  && (setRegularity)
1436  && (h==isHomog))
[0e1846]1437  {
[416465]1438    ring dp_C_ring = rCurrRingAssure_dp_C();
1439    if (dp_C_ring != syz_ring)
1440      e = idrMoveR_NoSort(e, syz_ring);
1441    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
[0e1846]1442    intvec * dummy = syBetti(res,length,&reg, *w);
[551fd7]1443    *deg = reg+2;
[0e1846]1444    delete dummy;
1445    for (j=0;j<length;j++)
1446    {
1447      if (res[j]!=NULL) idDelete(&(res[j]));
1448    }
1449    Free((ADDRESS)res,length*sizeof(ideal));
[416465]1450    idDelete(&e);
1451    if (dp_C_ring != syz_ring)
1452    {
1453      rChangeCurrRing(syz_ring, TRUE);
1454      rKill(dp_C_ring);
1455    }
[0e1846]1456  }
[416465]1457  else
[e960943]1458  {
[416465]1459    idDelete(&e);
[e960943]1460  }
[416465]1461  idTest(s_h3);
[84db93f]1462  if (currQuotient != NULL)
1463  {
1464    ideal ts_h3=kStd(s_h3,currQuotient,h,w);
1465    idDelete(&s_h3);
1466    s_h3 = ts_h3;
1467  }
[416465]1468  return s_h3;
[0e1846]1469}
1470
1471/*
1472*computes a standard basis for h1 and stores the transformation matrix
1473* in ma
1474*/
[416465]1475ideal idLiftStd (ideal  h1, matrix* ma, tHomog h)
[0e1846]1476{
[416465]1477  int   i, j, k, t, inputIsIdeal=idRankFreeModule(h1);
[0e1846]1478  poly  p=NULL, q, qq;
1479  intvec *w=NULL;
1480
1481  idDelete((ideal*)ma);
1482  *ma=mpNew(1,0);
1483  if (idIs0(h1))
1484    return idInit(1,h1->rank);
[87bef42]1485  k=max(1,idRankFreeModule(h1));
[b9a806]1486
1487  ring orig_ring=currRing;
[0e002d]1488  ring syz_ring=rCurrRingAssure_SyzComp();
[416465]1489  rSetSyzComp(k);
1490
1491  ideal s_h1=h1;
[b9a806]1492
[416465]1493  if (orig_ring != syz_ring)
1494    s_h1 = idrCopyR_NoSort(h1,orig_ring);
1495  else
1496    s_h1 = h1;
[b9a806]1497
[416465]1498  ideal s_h3=idPrepare(s_h1,h,k,&w);
[e1b9f91]1499  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
[b9a806]1500
[0e1846]1501  if (w!=NULL) delete w;
1502  i = 0;
[b9a806]1503  for (j=0; j<IDELEMS(s_h3); j++)
[0e1846]1504  {
[b9a806]1505    if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j],syz_ring) <= k))
[0e1846]1506    {
[e1b9f91]1507      i++;
1508      q = s_h3->m[j];
[0e1846]1509      while (pNext(q) != NULL)
1510      {
1511        if (pGetComp(pNext(q)) > k)
1512        {
[e1b9f91]1513          s_h2->m[j] = pNext(q);
1514          pNext(q) = NULL;
[0e1846]1515        }
1516        else
1517        {
1518          pIter(q);
1519        }
1520      }
[e1b9f91]1521      if (!inputIsIdeal) pShift(&(s_h3->m[j]), -1);
1522    }
1523    else
1524    {
1525      pDelete(&(s_h3->m[j]));
1526    }
1527  }
1528
1529  idSkipZeroes(s_h3);
1530  j = IDELEMS(s_h1);
[7bab5d]1531
[e1b9f91]1532  if (syz_ring!=orig_ring)
[416465]1533  {
1534    idDelete(&s_h1);
[e1b9f91]1535    rChangeCurrRing(orig_ring,TRUE);
[416465]1536  }
[1bf317]1537
[e1b9f91]1538  idDelete((ideal*)ma);
1539  *ma = mpNew(j,i);
1540
1541  i = 1;
1542  for (j=0; j<IDELEMS(s_h2); j++)
1543  {
1544    if (s_h2->m[j] != NULL)
1545    {
[416465]1546      q = prMoveR( s_h2->m[j], syz_ring);
[e1b9f91]1547      s_h2->m[j] = NULL;
[7bab5d]1548
[e1b9f91]1549      while (q != NULL)
[0e1846]1550      {
[e1b9f91]1551        p = q;
1552        pIter(q);
1553        pNext(p) = NULL;
1554        t=pGetComp(p);
1555        pSetComp(p,0);
1556        pSetmComp(p);
1557        MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
[0e1846]1558      }
[e1b9f91]1559      i++;
[0e1846]1560    }
1561  }
[e1b9f91]1562  idDelete(&s_h2);
1563
1564  for (i=0; i<IDELEMS(s_h3); i++)
[b9a806]1565  {
[416465]1566    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring);
[b9a806]1567  }
[e1b9f91]1568
1569  if (syz_ring!=orig_ring) rKill(syz_ring);
1570  return s_h3;
[0e1846]1571}
1572
[9d8e48]1573static void idPrepareStd(ideal s_temp, int k)
1574{
1575  int j,rk=idRankFreeModule(s_temp);
1576  poly p,q;
1577
1578  if (rk == 0)
1579  {
1580    for (j=0; j<IDELEMS(s_temp); j++)
1581    {
1582      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
1583    }
1584    k = max(k,1);
1585  }
1586  for (j=0; j<IDELEMS(s_temp); j++)
1587  {
1588    if (s_temp->m[j]!=NULL)
1589    {
1590      p = s_temp->m[j];
1591      q = pOne();
1592      //pGetCoeff(q)=nNeg(pGetCoeff(q));   //set q to -1
1593      pSetComp(q,k+1+j);
1594      pSetmComp(q);
1595      while (pNext(p)) pIter(p);
1596      pNext(p) = q;
1597    }
1598  }
1599}
1600
[0e1846]1601/*2
1602*computes a representation of the generators of submod with respect to those
1603* of mod
1604*/
[9d8e48]1605
[1bf317]1606ideal   idLift (ideal mod, ideal submod,ideal * rest, BOOLEAN goodShape,
1607               BOOLEAN isSB,BOOLEAN divide,matrix * unit)
[0e1846]1608{
[1bf317]1609  int lsmod =idRankFreeModule(submod), i, j, k;
[79f80f]1610  int comps_to_add=0;
1611  poly p;
[0e1846]1612
1613  if (idIs0(mod))
[1bf317]1614  {
1615    if (unit!=NULL)
1616    {
1617      *unit=mpNew(1,1);
1618      MATELEM(*unit,1,1)=pOne();
1619    }
1620    if (rest!=NULL)
1621    {
1622      *rest=idInit(1,mod->rank);
1623    }
[0e1846]1624    return idInit(1,mod->rank);
[1bf317]1625  }
1626  if (unit!=NULL)
[79f80f]1627  {
1628    comps_to_add = IDELEMS(submod);
[1bf317]1629    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
[79f80f]1630      comps_to_add--;
1631  }
[b9a806]1632  k=idRankFreeModule(mod);
1633  if  ((k!=0) && (lsmod==0)) lsmod=1;
1634  k=max(k,1);
1635
1636  ring orig_ring=currRing;
[0e002d]1637  ring syz_ring=rCurrRingAssure_SyzComp();
[416465]1638  rSetSyzComp(k);
[b9a806]1639
[416465]1640  ideal s_mod, s_temp;
1641  if (orig_ring != syz_ring)
1642  {
1643    s_mod = idrCopyR_NoSort(mod,orig_ring);
1644    s_temp = idrCopyR_NoSort(submod,orig_ring);
1645  }
1646  else
1647  {
1648    s_mod = mod;
1649    s_temp = idCopy(submod);
1650  }
[9d8e48]1651  ideal s_h3;
1652  if (isSB)
1653  {
1654    s_h3 = idCopy(s_mod);
[79f80f]1655    idPrepareStd(s_h3, k+comps_to_add);
[9d8e48]1656  }
1657  else
1658  {
[79f80f]1659    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
[9d8e48]1660  }
[b982ef]1661  if (!goodShape)
[0e1846]1662  {
[b9a806]1663    for (j=0;j<IDELEMS(s_h3);j++)
[b982ef]1664    {
[b9a806]1665      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
1666        pDelete(&(s_h3->m[j]));
[b982ef]1667    }
[0e1846]1668  }
[b9a806]1669  idSkipZeroes(s_h3);
[0e1846]1670  if (lsmod==0)
1671  {
[b9a806]1672    for (j=IDELEMS(s_temp);j>0;j--)
[0e1846]1673    {
[b9a806]1674      if (s_temp->m[j-1]!=NULL)
1675        pShift(&(s_temp->m[j-1]),1);
[0e1846]1676    }
1677  }
[1bf317]1678  if (unit!=NULL)
[79f80f]1679  {
1680    for(j = 0;j<comps_to_add;j++)
1681    {
1682      p = s_temp->m[j];
1683      if (p!=NULL)
1684      {
1685        while (pNext(p)!=NULL) pIter(p);
1686        pNext(p) = pOne();
1687        pIter(p);
1688        pSetComp(p,1+j+k);
1689        pSetmComp(p);
[878689]1690        p = pNeg(p);
[79f80f]1691      }
1692    }
1693  }
[b9a806]1694  ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
1695  s_result->rank = s_h3->rank;
[79f80f]1696  ideal s_rest = idInit(IDELEMS(s_result),k);
[b9a806]1697  idDelete(&s_h3);
1698  idDelete(&s_temp);
1699
1700  for (j=0;j<IDELEMS(s_result);j++)
[0e1846]1701  {
[b9a806]1702    if (s_result->m[j]!=NULL)
[0e1846]1703    {
[b9a806]1704      if (pGetComp(s_result->m[j])<=k)
[0e1846]1705      {
[79f80f]1706        if (!divide)
[9d8e48]1707        {
[79f80f]1708          if (isSB)
1709          {
1710            WarnS("first module not a standardbasis\n"
1711              "// ** or second not a proper submodule");
1712          }
1713          else
1714            WerrorS("2nd module lies not in the first");
1715          idDelete(&s_result);
1716          idDelete(&s_rest);
1717          s_result=idInit(IDELEMS(submod),submod->rank);
1718          break;
[9d8e48]1719        }
1720        else
[79f80f]1721        {
1722          p = s_rest->m[j] = s_result->m[j];
1723          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1724          s_result->m[j] = pNext(p);
1725          pNext(p) = NULL;
1726        }
[0e1846]1727      }
[79f80f]1728      pShift(&(s_result->m[j]),-k);
1729      pNeg(s_result->m[j]);
1730    }
1731  }
1732  if ((lsmod==0) && (!idIs0(s_rest)))
1733  {
1734    for (j=IDELEMS(s_rest);j>0;j--)
1735    {
1736      if (s_rest->m[j-1]!=NULL)
[0e1846]1737      {
[79f80f]1738        pShift(&(s_rest->m[j-1]),-1);
1739        s_rest->m[j-1] = pNeg(s_rest->m[j-1]);
[0e1846]1740      }
1741    }
1742  }
[b9a806]1743  if(syz_ring!=orig_ring)
1744  {
[416465]1745    idDelete(&s_mod);
[b9a806]1746    rChangeCurrRing(orig_ring,TRUE);
[416465]1747    s_result = idrMoveR_NoSort(s_result, syz_ring);
[79f80f]1748    s_rest = idrMoveR_NoSort(s_rest, syz_ring);
[b9a806]1749    rKill(syz_ring);
1750  }
[79f80f]1751  if (rest!=NULL)
1752    *rest = s_rest;
1753  else
1754    idDelete(&s_rest);
[d7d8cb2]1755//idPrint(s_result);
[1bf317]1756  if (unit!=NULL)
1757  {
1758    *unit=mpNew(comps_to_add,comps_to_add);
1759    int i;
1760    int comps=k+comps_to_add;
1761    for(i=0;i<IDELEMS(s_result);i++)
1762    {
1763      poly p=s_result->m[i];
1764      poly q=NULL;
1765      while(p!=NULL)
1766      {
[df542e1]1767        if(pGetComp(p)<comps)
[1bf317]1768        {
1769          pSetComp(p,0);
1770          if (q!=NULL)
1771          {
1772            pNext(q)=pNext(p);
1773          }
1774          else
1775          {
1776            pIter(s_result->m[i]);
1777          }
1778          pNext(p)=NULL;
1779          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
1780          if(q!=NULL)   p=pNext(q);
1781          else          p=s_result->m[i];
1782        }
1783        else
1784        {
1785          q=p;
1786          pIter(p);
1787        }
1788      }
[df542e1]1789      pShift(&s_result->m[i],-comps_to_add);
[1bf317]1790    }
1791  }
[416465]1792  return s_result;
[0e1846]1793}
1794
1795/*2
[d7d8cb2]1796*computes the quotient of h1,h2 : interanl routine for idQuot
1797*BEWARE: the returned ideals may contain incorrected orderd polys !
1798*
[0e1846]1799*/
[416465]1800static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
1801                               BOOLEAN *addOnlyOne, int *kkmax)
[0e1846]1802{
[416465]1803  ideal temph1;
[0e1846]1804  poly     p,q = NULL;
[416465]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;
[0e1846]1810
1811  k=max(k1,k2);
[416465]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 ---------------------*/
[0e1846]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  }
[416465]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);
[0e1846]1844  pSetComp(p,kmax);
[66a672]1845  pSetmComp(p);
[416465]1846/*--- constructing the big matrix ------------------------*/
1847  ideal h4 = idInit(16,kmax);
[0e1846]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    {
[416465]1858      p = pCopy_noCheck(h4->m[i-1]);
[0e1846]1859      pShift(&p,1);
1860      h4->m[i] = p;
1861    }
1862  }
[416465]1863
[0e1846]1864  kkk = IDELEMS(h4);
[416465]1865  i = IDELEMS(temph1);
1866  while ((i>0) && (temph1->m[i-1]==NULL)) i--;
[0e1846]1867  for (l=0; l<i; l++)
1868  {
[416465]1869    if(temph1->m[l]!=NULL)
[0e1846]1870    {
1871      for (ll=0; ll<j; ll++)
1872      {
[416465]1873        p = pCopy(temph1->m[l]);
[0e1846]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  }
[416465]1888/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
1889  if (*addOnlyOne)
[0e1846]1890  {
[416465]1891    p = h4->m[0];
1892    for (i=0;i<IDELEMS(h4)-1;i++)
[0e1846]1893    {
[416465]1894      h4->m[i] = h4->m[i+1];
[0e1846]1895    }
[416465]1896    h4->m[IDELEMS(h4)-1] = p;
1897    idSkipZeroes(h4);
1898    test |= Sy_bit(OPT_SB_1);
[0e1846]1899  }
[416465]1900  idDelete(&temph1);
[0e1846]1901  return h4;
1902}
[416465]1903/*2
1904*computes the quotient of h1,h2
1905*/
[761e9a5]1906ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
[0e1846]1907{
[761e9a5]1908  // first check for special case h1:(0)
[0e1846]1909  if (idIs0(h2))
1910  {
[b9a806]1911    ideal res;
[761e9a5]1912    if (resultIsIdeal)
[0e1846]1913    {
[b9a806]1914      res = idInit(1,1);
1915      res->m[0] = pOne();
[0e1846]1916    }
1917    else
[b9a806]1918      res = idFreeModule(h1->rank);
1919    return res;
[0e1846]1920  }
[761e9a5]1921  BITSET old_test=test;
1922  poly     p,q = NULL;
1923  int i,l,ll,k,kkk,kmax;
1924  BOOLEAN  addOnlyOne=TRUE;
1925  tHomog   hom=isNotHomog;
[416465]1926  intvec * weights1;
[761e9a5]1927
[416465]1928  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
1929  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
[b9a806]1930  ring orig_ring=currRing;
[0e002d]1931  ring syz_ring=rCurrRingAssure_SyzComp();
[416465]1932  rSetSyzComp(kmax-1);
1933  if (orig_ring!=syz_ring)
[82a8acc]1934    s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
[b9a806]1935
[f907fc]1936  idTest(s_h4);
[b9a806]1937  ideal s_h3;
[0e1846]1938  if (addOnlyOne)
1939  {
[b9a806]1940    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1,IDELEMS(s_h4)-1);
[0e1846]1941  }
1942  else
1943  {
[b9a806]1944    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
[0e1846]1945  }
[b9a806]1946  idTest(s_h3);
1947  if (weights1!=NULL) delete weights1;
1948  idDelete(&s_h4);
1949
1950
[416465]1951  for (i=0;i<IDELEMS(s_h3);i++)
[0e1846]1952  {
[416465]1953    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
[0e1846]1954    {
1955      if (resultIsIdeal)
[416465]1956        pShift(&s_h3->m[i],-kmax);
[0e1846]1957      else
[416465]1958        pShift(&s_h3->m[i],-kmax+1);
[0e1846]1959    }
1960    else
[416465]1961      pDelete(&s_h3->m[i]);
[0e1846]1962  }
[7bab5d]1963  if (resultIsIdeal)
[416465]1964    s_h3->rank = 1;
[7bab5d]1965  else
[416465]1966    s_h3->rank = h1->rank;
[b9a806]1967  if(syz_ring!=orig_ring)
1968  {
[416465]1969//    pDelete(&q);
[b9a806]1970    rChangeCurrRing(orig_ring,TRUE);
[416465]1971    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
[b9a806]1972    rKill(syz_ring);
1973  }
[416465]1974  idSkipZeroes(s_h3);
[0e1846]1975  test = old_test;
[416465]1976  idTest(s_h3);
1977  return s_h3;
[0e1846]1978}
1979
1980/*2
1981*computes recursively all monomials of a certain degree
1982*in every step the actvar-th entry in the exponential
1983*vector is incremented and the other variables are
1984*computed by recursive calls of makemonoms
1985*if the last variable is reached, the difference to the
1986*degree is computed directly
1987*vars is the number variables
1988*actvar is the actual variable to handle
1989*deg is the degree of the monomials to compute
1990*monomdeg is the actual degree of the monomial in consideration
1991*/
1992static void makemonoms(int vars,int actvar,int deg,int monomdeg)
1993{
1994  poly p;
1995  int i=0;
1996
1997  if ((idpowerpoint == 0) && (actvar ==1))
1998  {
1999    idpower[idpowerpoint] = pOne();
2000    monomdeg = 0;
2001  }
2002  while (i<=deg)
2003  {
2004    if (deg == monomdeg)
2005    {
2006      pSetm(idpower[idpowerpoint]);
2007      idpowerpoint++;
2008      return;
2009    }
2010    if (actvar == vars)
2011    {
2012      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
2013      pSetm(idpower[idpowerpoint]);
[055a19]2014      pTest(idpower[idpowerpoint]);
[0e1846]2015      idpowerpoint++;
2016      return;
2017    }
2018    else
2019    {
2020      p = pCopy(idpower[idpowerpoint]);
2021      makemonoms(vars,actvar+1,deg,monomdeg);
2022      idpower[idpowerpoint] = p;
2023    }
2024    monomdeg++;
2025    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
2026    pSetm(idpower[idpowerpoint]);
[055a19]2027    pTest(idpower[idpowerpoint]);
[0e1846]2028    i++;
2029  }
2030}
2031
2032/*2
2033*returns the deg-th power of the maximal ideal of 0
2034*/
2035ideal idMaxIdeal(int deg)
2036{
[163cb1]2037  if (deg < 0)
2038  {
2039    WarnS("maxideal: power must be non-negative");
2040  }
2041  if (deg < 1)
2042  {
2043    ideal I=idInit(1,1);
2044    I->m[0]=pOne();
[cf29809]2045    return I;
[163cb1]2046  }
2047  if (deg == 1)
[0e1846]2048  {
2049    return idMaxIdeal();
2050  }
[163cb1]2051
2052  int vars = currRing->N;
2053  int i = binom(vars+deg-1,deg);
2054  ideal id=idInit(i,1);
[0e1846]2055  idpower = id->m;
2056  idpowerpoint = 0;
2057  makemonoms(vars,1,deg,0);
2058  idpower = NULL;
2059  idpowerpoint = 0;
2060  return id;
2061}
2062
2063/*2
2064*computes recursively all generators of a certain degree
2065*of the ideal "givenideal"
2066*elms is the number elements in the given ideal
2067*actelm is the actual element to handle
2068*deg is the degree of the power to compute
2069*gendeg is the actual degree of the generator in consideration
2070*/
2071static void makepotence(int elms,int actelm,int deg,int gendeg)
2072{
2073  poly p;
2074  int i=0;
2075
2076  if ((idpowerpoint == 0) && (actelm ==1))
2077  {
2078    idpower[idpowerpoint] = pOne();
2079    gendeg = 0;
2080  }
2081  while (i<=deg)
2082  {
2083    if (deg == gendeg)
2084    {
2085      idpowerpoint++;
2086      return;
2087    }
2088    if (actelm == elms)
2089    {
2090      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
2091      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
2092      idpowerpoint++;
2093      return;
2094    }
2095    else
2096    {
2097      p = pCopy(idpower[idpowerpoint]);
2098      makepotence(elms,actelm+1,deg,gendeg);
2099      idpower[idpowerpoint] = p;
2100    }
2101    gendeg++;
2102    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
2103    i++;
2104  }
2105}
2106
2107/*2
2108*returns the deg-th power of the ideal gid
2109*/
2110//ideal idPower(ideal gid,int deg)
2111//{
2112//  int i;
2113//  ideal id;
2114//
2115//  if (deg < 1) deg = 1;
2116//  i = binom(IDELEMS(gid)+deg-1,deg);
2117//  id=idInit(i,1);
2118//  idpower = id->m;
2119//  givenideal = gid->m;
2120//  idpowerpoint = 0;
2121//  makepotence(IDELEMS(gid),1,deg,0);
2122//  idpower = NULL;
2123//  givenideal = NULL;
2124//  idpowerpoint = 0;
2125//  return id;
2126//}
2127static void idNextPotence(ideal given, ideal result,
2128  int begin, int end, int deg, int restdeg, poly ap)
2129{
2130  poly p;
2131  int i;
2132
2133  p = pPower(pCopy(given->m[begin]),restdeg);
2134  i = result->nrows;
2135  result->m[i] = pMult(pCopy(ap),p);
2136//PrintS(".");
2137  (result->nrows)++;
2138  if (result->nrows >= IDELEMS(result))
2139  {
2140    pEnlargeSet(&(result->m),IDELEMS(result),16);
2141    IDELEMS(result) += 16;
2142  }
2143  if (begin == end) return;
[0d5b99]2144  for (i=restdeg-1;i>0;i--)
[0e1846]2145  {
2146    p = pPower(pCopy(given->m[begin]),i);
2147    p = pMult(pCopy(ap),p);
2148    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
2149    pDelete(&p);
2150  }
[0d5b99]2151  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
[0e1846]2152}
2153
2154ideal idPower(ideal given,int exp)
2155{
2156  ideal result,temp;
2157  poly p1;
2158  int i;
2159
2160  if (idIs0(given)) return idInit(1,1);
2161  temp = idCopy(given);
2162  idSkipZeroes(temp);
2163  i = binom(IDELEMS(temp)+exp-1,exp);
2164  result = idInit(i,1);
2165  result->nrows = 0;
2166//Print("ideal contains %d elements\n",i);
2167  p1=pOne();
2168  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
2169  pDelete(&p1);
2170  idDelete(&temp);
2171  result->nrows = 1;
[5990ae]2172  idSkipZeroes(result);
2173  idDelEquals(result);
[0e1846]2174  return result;
2175}
2176
2177/*2
2178* eliminate delVar (product of vars) in h1
2179*/
2180ideal idElimination (ideal h1,poly delVar,intvec *hilb)
2181{
2182  int    i,j=0,k,l;
2183  ideal  h,hh, h3;
2184  int    *ord,*block0,*block1;
2185  int    ordersize=2;
[055a19]2186  int    **wv;
[0e1846]2187  tHomog hom;
2188  intvec * w;
[e78cce]2189  sip_sring tmpR;
[47faf56]2190  ring origR = currRing;
[0e1846]2191
2192  if (delVar==NULL)
2193  {
2194    return idCopy(h1);
2195  }
2196  if (currQuotient!=NULL)
2197  {
[da97958]2198    WerrorS("cannot eliminate in a qring");
[0e1846]2199    return idCopy(h1);
2200  }
2201  if (idIs0(h1)) return idInit(1,h1->rank);
2202  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
2203  h3=idInit(16,h1->rank);
2204  for (k=0;; k++)
2205  {
2206    if (currRing->order[k]!=0) ordersize++;
2207    else break;
2208  }
2209  ord=(int*)Alloc0(ordersize*sizeof(int));
2210  block0=(int*)Alloc(ordersize*sizeof(int));
2211  block1=(int*)Alloc(ordersize*sizeof(int));
2212  for (k=0;; k++)
2213  {
2214    if (currRing->order[k]!=0)
2215    {
2216      block0[k+1] = currRing->block0[k];
2217      block1[k+1] = currRing->block1[k];
2218      ord[k+1] = currRing->order[k];
2219    }
2220    else
2221      break;
2222  }
2223  block0[0] = 1;
2224  block1[0] = pVariables;
[055a19]2225  wv=(int**) Alloc0(ordersize*sizeof(int**));
2226  memcpy4(wv+1,currRing->wvhdl,(ordersize-1)*sizeof(int**));
2227  wv[0]=(int*)AllocL((pVariables+1)*sizeof(int));
2228  memset(wv[0],0,(pVariables+1)*sizeof(int));
[e78cce]2229  for (j=0;j<pVariables;j++)
[0e1846]2230    if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2231  ord[0] = ringorder_a;
[e78cce]2232
2233  // fill in tmp ring to get back the data later on
[47faf56]2234  tmpR  = *origR;
[e78cce]2235  tmpR.order = ord;
2236  tmpR.block0 = block0;
2237  tmpR.block1 = block1;
2238  tmpR.wvhdl = wv;
[055a19]2239  rComplete(&tmpR, 1);
[43580ac]2240
[e78cce]2241  // change into the new ring
[25003c]2242  //pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
2243  rChangeCurrRing(&tmpR, TRUE);
[47faf56]2244  currRing = &tmpR;
[b011fc]2245  h = idInit(IDELEMS(h1),h1->rank);
[e78cce]2246  // fetch data from the old ring
[416465]2247  for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
[a1c44e]2248  // compute kStd
2249  hh = kStd(h,NULL,hom,&w,hilb);
[0e1846]2250  idDelete(&h);
[e78cce]2251
2252  // go back to the original ring
[25003c]2253  rChangeCurrRing(origR,TRUE);
[0e1846]2254  i = IDELEMS(hh)-1;
2255  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2256  j = -1;
[e78cce]2257  // fetch data from temp ring
[0e1846]2258  for (k=0; k<=i; k++)
2259  {
2260    l=pVariables;
[e78cce]2261    while ((l>0) && (pRingGetExp(&tmpR, hh->m[k],l)*pGetExp(delVar,l)==0)) l--;
[0e1846]2262    if (l==0)
2263    {
2264      j++;
2265      if (j >= IDELEMS(h3))
2266      {
2267        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2268        IDELEMS(h3) += 16;
2269      }
[416465]2270      h3->m[j] = prCopyR( hh->m[k], &tmpR);
[0e1846]2271    }
2272  }
[055a19]2273  rChangeCurrRing(&tmpR, FALSE);
[0e1846]2274  idDelete(&hh);
[055a19]2275  rChangeCurrRing(origR, TRUE);
[0e1846]2276  idSkipZeroes(h3);
[055a19]2277  FreeL((ADDRESS)wv[0]);
2278  Free((ADDRESS)wv,ordersize*sizeof(int**));
[0e1846]2279  Free((ADDRESS)ord,ordersize*sizeof(int));
2280  Free((ADDRESS)block0,ordersize*sizeof(int));
2281  Free((ADDRESS)block1,ordersize*sizeof(int));
[055a19]2282  rUnComplete(&tmpR);
[0e1846]2283  if (w!=NULL)
2284    delete w;
2285  return h3;
2286}
2287
[c616d1]2288#ifdef WITH_OLD_MINOR
2289/*2
2290* compute all ar-minors of the matrix a
2291*/
[47fed0]2292ideal idMinors(matrix a, int ar, ideal R)
[c616d1]2293{
2294  int     i,j,k,size;
2295  int *rowchoise,*colchoise;
2296  BOOLEAN rowch,colch;
2297  ideal result;
2298  matrix tmp;
[47fed0]2299  poly p,q;
[c616d1]2300
2301  i = binom(a->rows(),ar);
2302  j = binom(a->cols(),ar);
2303
2304  rowchoise=(int *)Alloc(ar*sizeof(int));
2305  colchoise=(int *)Alloc(ar*sizeof(int));
2306  if ((i>512) || (j>512) || (i*j >512)) size=512;
2307  else size=i*j;
2308  result=idInit(size,1);
2309  tmp=mpNew(ar,ar);
2310  k = 0; /* the index in result*/
2311  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2312  while (!rowch)
2313  {
2314    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2315    while (!colch)
2316    {
2317      for (i=1; i<=ar; i++)
2318      {
2319        for (j=1; j<=ar; j++)
2320        {
2321          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2322        }
2323      }
2324      p = mpDetBareiss(tmp);
2325      if (p!=NULL)
2326      {
[47fed0]2327        if (R!=NULL)
[c616d1]2328        {
[47fed0]2329          q = p;
2330          p = kNF(R,currQuotient,q);
2331          pDelete(&q);
2332        }
2333        if (p!=NULL)
[1bf317]2334        {
[47fed0]2335          if (k>=size)
2336          {
2337            pEnlargeSet(&result->m,size,32);
2338            size += 32;
2339          }
2340          result->m[k] = p;
2341          k++;
[c616d1]2342        }
2343      }
2344      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2345    }
2346    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2347  }
2348  /*delete the matrix tmp*/
2349  for (i=1; i<=ar; i++)
2350  {
2351    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2352  }
2353  idDelete((ideal*)&tmp);
2354  if (k==0)
2355  {
2356    k=1;
2357    result->m[0]=NULL;
2358  }
2359  Free((ADDRESS)rowchoise,ar*sizeof(int));
2360  Free((ADDRESS)colchoise,ar*sizeof(int));
2361  pEnlargeSet(&result->m,size,k-size);
2362  IDELEMS(result) = k;
2363  return (result);
2364}
2365#else
[d353551]2366/*2
2367* compute all ar-minors of the matrix a
[ef72ff3]2368* the caller of mpRecMin
[47fed0]2369* the elements of the result are not in R (if R!=NULL)
[d353551]2370*/
[47fed0]2371ideal idMinors(matrix a, int ar, ideal R)
[d353551]2372{
[ef72ff3]2373  ideal result;
2374  int elems=0;
2375
[d353551]2376  if((ar<=0) || (ar>min(a->ncols,a->nrows)))
2377  {
[74ec24c]2378    Werror("%d-th minor, matrix is %dx%d",ar,a->ncols,a->nrows);
[d353551]2379    return NULL;
2380  }
[ef72ff3]2381  a = mpCopy(a);
[87ff23]2382  result=idInit(32,1);
[47fed0]2383  if(ar>1) mpRecMin(ar-1,result,elems,a,a->nrows,a->ncols,NULL,R);
2384  else mpMinorToResult(result,elems,a,a->nrows,a->ncols,R);
[ef72ff3]2385  idDelete((ideal *)&a);
[d353551]2386  idSkipZeroes(result);
[ef72ff3]2387  idTest(result);
[d353551]2388  return result;
2389}
[c616d1]2390#endif
2391
[0e1846]2392/*2
2393*returns TRUE if p is a unit element in the current ring
2394*/
2395BOOLEAN pIsUnit(poly p)
2396{
[e78cce]2397  int i;
[0e1846]2398
2399  if (p == NULL) return FALSE;
[e78cce]2400  i = 1;
2401  while (i<=pVariables && pGetExp(p,i) == 0) i++;
2402  if (i > pVariables && (pGetComp(p) == 0))
[0e1846]2403  {
[e78cce]2404    if (currRing->OrdSgn == 1 && pNext(p) !=NULL) return FALSE;
2405    return TRUE;
[0e1846]2406  }
[e78cce]2407  return FALSE;
[0e1846]2408}
2409
2410/*2
2411*skips all zeroes and double elements, searches also for units
2412*/
2413ideal idCompactify(ideal id)
2414{
2415  int i,j;
2416  BOOLEAN b=FALSE;
2417
[b711e1]2418  i = IDELEMS(id)-1;
[4b5c87]2419  while ((! b) && (i>=0))
[0e1846]2420  {
[b711e1]2421    b=pIsUnit(id->m[i]);
[4b5c87]2422    i--;
[0e1846]2423  }
2424  if (b)
2425  {
[b711e1]2426    ideal result=idInit(1,id->rank);
[0e1846]2427    result->m[0]=pOne();
[b711e1]2428    return result;
[0e1846]2429  }
2430  else
2431  {
[b711e1]2432    ideal result=idCopy(id);
[0e1846]2433    for (i=1;i<IDELEMS(result);i++)
2434    {
2435      if (result->m[i]!=NULL)
2436      {
2437        for (j=0;j<i;j++)
2438        {
2439          if ((result->m[j]!=NULL)
2440          && (pComparePolys(result->m[i],result->m[j])))
2441          {
2442            pDelete(&(result->m[j]));
2443          }
2444        }
2445      }
2446    }
[b711e1]2447    idSkipZeroes(result);
2448    return result;
[0e1846]2449  }
2450}
2451
2452/*2
2453*returns TRUE if id1 is a submodule of id2
2454*/
2455BOOLEAN idIsSubModule(ideal id1,ideal id2)
2456{
2457  int i;
2458  poly p;
2459
2460  if (idIs0(id1)) return TRUE;
2461  for (i=0;i<IDELEMS(id1);i++)
2462  {
2463    if (id1->m[i] != NULL)
2464    {
2465      p = kNF(id2,currQuotient,id1->m[i]);
2466      if (p != NULL)
2467      {
2468        pDelete(&p);
2469        return FALSE;
2470      }
2471    }
2472  }
2473  return TRUE;
2474}
2475
2476/*2
2477* returns the ideals of initial terms
2478*/
2479ideal idHead(ideal h)
2480{
2481  ideal m = idInit(IDELEMS(h),h->rank);
2482  int i;
2483
[4b5c87]2484  for (i=IDELEMS(h)-1;i>=0; i--)
[0e1846]2485  {
[4b5c87]2486    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
[0e1846]2487  }
2488  return m;
2489}
2490
2491ideal idHomogen(ideal h, int varnum)
2492{
2493  ideal m = idInit(IDELEMS(h),h->rank);
2494  int i;
2495
[4b5c87]2496  for (i=IDELEMS(h)-1;i>=0; i--)
[0e1846]2497  {
2498    m->m[i]=pHomogen(h->m[i],varnum);
2499  }
2500  return m;
2501}
2502
2503/*------------------type conversions----------------*/
2504ideal idVec2Ideal(poly vec)
2505{
2506   ideal result=idInit(1,1);
[b7b08c]2507   FreeSizeOf((ADDRESS)result->m,poly);
[0e1846]2508   result->m=NULL; // remove later
2509   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2510   return result;
2511}
2512
[87bef42]2513// converts mat to module, destroys mat
[0e1846]2514ideal idMatrix2Module(matrix mat)
2515{
2516  ideal result = idInit(MATCOLS(mat),MATROWS(mat));
2517  int i,j;
2518  poly h;
2519#ifdef DRING
2520  poly p;
2521#endif
2522
2523  for(j=0;j<MATCOLS(mat);j++) /* j is also index in result->m */
2524  {
2525    for (i=1;i<=MATROWS(mat);i++)
2526    {
2527      h = MATELEM(mat,i,j+1);
2528      if (h!=NULL)
2529      {
2530        MATELEM(mat,i,j+1)=NULL;
2531        pSetCompP(h,i);
2532#ifdef DRING
[311499]2533        pdSetDFlagP(h,0);
[0e1846]2534#endif
2535        result->m[j] = pAdd(result->m[j],h);
2536      }
2537    }
2538  }
[b7b08c]2539  // obachman: need to clean this up
2540  idDelete((ideal*) &mat);
[0e1846]2541  return result;
2542}
2543
2544/*2
2545* converts a module into a matrix, destroyes the input
2546*/
2547matrix idModule2Matrix(ideal mod)
2548{
2549  matrix result = mpNew(mod->rank,IDELEMS(mod));
2550  int i,cp;
2551  poly p,h;
2552
2553  for(i=0;i<IDELEMS(mod);i++)
2554  {
2555    p=mod->m[i];
2556    mod->m[i]=NULL;
2557    while (p!=NULL)
2558    {
2559      h=p;
2560      pIter(p);
2561      pNext(h)=NULL;
2562//      cp = max(1,pGetComp(h));     // if used for ideals too
2563      cp = pGetComp(h);
2564      pSetComp(h,0);
[66a672]2565      pSetmComp(h);
[0e1846]2566#ifdef TEST
2567      if (cp>mod->rank)
2568      {
2569        Print("## inv. rank %d -> %d\n",mod->rank,cp);
2570        int k,l,o=mod->rank;
2571        mod->rank=cp;
2572        matrix d=mpNew(mod->rank,IDELEMS(mod));
2573        for (l=1; l<=o; l++)
2574        {
2575          for (k=1; k<=IDELEMS(mod); k++)
2576          {
2577            MATELEM(d,l,k)=MATELEM(result,l,k);
2578            MATELEM(result,l,k)=NULL;
2579          }
2580        }
2581        idDelete((ideal *)&result);
2582        result=d;
2583      }
2584#endif
2585      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2586    }
2587  }
[87bef42]2588// obachman 10/99: added the following line, otherwise memory lack!
[b7b08c]2589  idDelete(&mod);
[0e1846]2590  return result;
2591}
2592
2593matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
2594{
2595  matrix result = mpNew(rows,cols);
2596  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
2597  poly p,h;
2598
2599  if (r>rows) r = rows;
2600  if (c>cols) c = cols;
2601  for(i=0;i<c;i++)
2602  {
2603    p=mod->m[i];
2604    mod->m[i]=NULL;
2605    while (p!=NULL)
2606    {
2607      h=p;
2608      pIter(p);
2609      pNext(h)=NULL;
2610      cp = pGetComp(h);
2611      if (cp<=r)
2612      {
2613        pSetComp(h,0);
[66a672]2614        pSetmComp(h);
[0e1846]2615        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2616      }
2617      else
2618        pDelete(&h);
2619    }
2620  }
2621  idDelete(&mod);
2622  return result;
2623}
2624
2625/*2
2626* substitute the n-th variable by the monomial e in id
2627* destroy id
2628*/
2629ideal  idSubst(ideal id, int n, poly e)
2630{
2631  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
2632  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
2633
2634  res->rank = id->rank;
2635  for(k--;k>=0;k--)
2636  {
2637    res->m[k]=pSubst(id->m[k],n,e);
2638    id->m[k]=NULL;
2639  }
2640  idDelete(&id);
2641  return res;
2642}
2643
2644BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
2645{
[9734571]2646  if (w!=NULL) *w=NULL;
2647  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
2648  if (idIs0(m)) return TRUE;
2649
[0e1846]2650  int i,j,cmax=2,order=0,ord,* diff,* iscom,diffmin=32000;
2651  poly p=NULL;
2652  int length=IDELEMS(m);
2653  polyset P=m->m;
[9734571]2654  polyset F=(polyset)Alloc(length*sizeof(poly));
[0e1846]2655  for (i=length-1;i>=0;i--)
2656  {
2657    p=F[i]=P[i];
2658    cmax=max(cmax,pMaxComp(p)+1);
2659  }
2660  diff = (int *)Alloc0(cmax*sizeof(int));
[477993]2661  if (w!=NULL) *w=NewIntvec1(cmax-1);
[0e1846]2662  iscom = (int *)Alloc0(cmax*sizeof(int));
2663  i=0;
2664  while (i<=length)
2665  {
2666    if (i<length)
2667    {
2668      p=F[i];
2669      while ((p!=NULL) && (!iscom[pGetComp(p)])) pIter(p);
2670    }
2671    if ((p==NULL) && (i<length))
2672    {
2673      i++;
2674    }
2675    else
2676    {
2677      if (p==NULL)
2678      {
2679        i=0;
2680        while ((i<length) && (F[i]==NULL)) i++;
2681        if (i>=length) break;
2682        p = F[i];
2683      }
[9734571]2684      if (pLexOrder)
2685        order=pTotaldegree(p);
2686      else
[0e1846]2687      //  order = p->order;
[9734571]2688        order = pFDeg(p);
[0e1846]2689      order += diff[pGetComp(p)];
2690      p = F[i];
2691//Print("Actual p=F[%d]: ",i);pWrite(p);
2692      F[i] = NULL;
2693      i=0;
2694    }
2695    while (p!=NULL)
2696    {
2697      //if (pLexOrder)
2698      //  ord=pTotaldegree(p);
2699      //else
2700      //  ord = p->order;
2701      ord = pFDeg(p);
2702      if (!iscom[pGetComp(p)])
2703      {
2704        diff[pGetComp(p)] = order-ord;
2705        iscom[pGetComp(p)] = 1;
2706/*
2707*PrintS("new diff: ");
2708*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2709*PrintLn();
2710*PrintS("new iscom: ");
2711*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
2712*PrintLn();
2713*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
2714*/
2715      }
2716      else
2717      {
2718/*
2719*PrintS("new diff: ");
2720*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2721*PrintLn();
2722*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
2723*/
2724        if (order != ord+diff[pGetComp(p)])
2725        {
2726          Free((ADDRESS) iscom,cmax*sizeof(int));
2727          Free((ADDRESS) diff,cmax*sizeof(int));
2728          Free((ADDRESS) F,length*sizeof(poly));
2729          delete *w;*w=NULL;
2730          return FALSE;
2731        }
2732      }
2733      pIter(p);
2734    }
2735  }
2736  Free((ADDRESS) iscom,cmax*sizeof(int));
2737  Free((ADDRESS) F,length*sizeof(poly));
2738  for (i=1;i<cmax;i++) (**w)[i-1]=diff[i];
2739  for (i=1;i<cmax;i++)
2740  {
2741    if (diff[i]<diffmin) diffmin=diff[i];
2742  }
[dc87300]2743  if (w!=NULL)
[0e1846]2744  {
[dc87300]2745    for (i=1;i<cmax;i++)
2746    {
2747      (**w)[i-1]=diff[i]-diffmin;
2748    }
[0e1846]2749  }
2750  Free((ADDRESS) diff,cmax*sizeof(int));
2751  return TRUE;
2752}
2753
2754ideal idJet(ideal i,int d)
2755{
[f70c18]2756  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
[473707b]2757  r->nrows = i-> nrows;
[f70c18]2758  r->ncols = i-> ncols;
[473707b]2759  //r->rank = i-> rank;
[0e1846]2760  int k;
[473707b]2761  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
[0e1846]2762  {
2763    r->m[k]=pJet(i->m[k],d);
2764  }
2765  return r;
2766}
2767
2768ideal idJetW(ideal i,int d, intvec * iv)
2769{
2770  ideal r=idInit(IDELEMS(i),i->rank);
2771  if (ecartWeights!=NULL)
2772  {
[da97958]2773    WerrorS("cannot compute weighted jets now");
[0e1846]2774  }
2775  else
2776  {
2777    short *w=iv2array(iv);
2778    int k;
2779    for(k=0; k<IDELEMS(i); k++)
2780    {
2781      r->m[k]=pJetW(i->m[k],d,w);
2782    }
2783    Free((ADDRESS)w,(pVariables+1)*sizeof(short));
2784  }
2785  return r;
2786}
2787
2788matrix idDiff(matrix i, int k)
2789{
2790  int e=MATCOLS(i)*MATROWS(i);
2791  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2792  int j;
2793  for(j=0; j<e; j++)
2794  {
2795    r->m[j]=pDiff(i->m[j],k);
2796  }
2797  return r;
2798}
2799
2800matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2801{
2802  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2803  int i,j;
2804  for(i=0; i<IDELEMS(I); i++)
2805  {
2806    for(j=0; j<IDELEMS(J); j++)
2807    {
2808      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2809    }
2810  }
2811  return r;
2812}
2813
[416465]2814/*3
2815*handles for some ideal operations the ring/syzcomp managment
2816*returns all syzygies (componentwise-)shifted by -syzcomp
2817*or -syzcomp-1 (in case of ideals as input)
2818static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
2819{
2820  ring orig_ring=currRing;
[0e002d]2821  ring syz_ring=rCurrRingAssure_SyzComp();
[416465]2822  rSetSyzComp(length);
2823
2824  ideal s_temp;
2825  if (orig_ring!=syz_ring)
2826    s_temp=idrMoveR_NoSort(arg,orig_ring);
2827  else
2828    s_temp=arg;
2829
2830  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
2831  if (w!=NULL) delete w;
2832
2833  if (syz_ring!=orig_ring)
2834  {
2835    idDelete(&s_temp);
2836    rChangeCurrRing(orig_ring,TRUE);
2837  }
2838
2839  idDelete(&temp);
2840  ideal temp1=idRingCopy(s_temp1,syz_ring);
2841
2842  if (syz_ring!=orig_ring)
2843  {
2844    rChangeCurrRing(syz_ring,FALSE);
2845    idDelete(&s_temp1);
2846    rChangeCurrRing(orig_ring,TRUE);
2847    rKill(syz_ring);
2848  }
2849
2850  for (i=0;i<IDELEMS(temp1);i++)
2851  {
2852    if ((temp1->m[i]!=NULL)
2853    && (pGetComp(temp1->m[i])<=length))
2854    {
2855      pDelete(&(temp1->m[i]));
2856    }
2857    else
2858    {
2859      pShift(&(temp1->m[i]),-length);
2860    }
2861  }
2862  temp1->rank = rk;
2863  idSkipZeroes(temp1);
2864
2865  return temp1;
2866}
2867*/
[0e1846]2868/*2
2869* represents (h1+h2)/h2=h1/(h1 intersect h2)
2870*/
2871ideal idModulo (ideal h2,ideal h1)
2872{
2873  int i,j,k,rk,flength=0,slength,length;
[4c001a]2874  intvec * w;
[0e1846]2875  poly p,q;
2876
2877  if (idIs0(h2))
2878    return idFreeModule(max(1,h2->ncols));
2879  if (!idIs0(h1))
2880    flength = idRankFreeModule(h1);
2881  slength = idRankFreeModule(h2);
2882  length  = max(flength,slength);
2883  if (length==0)
2884  {
2885    length = 1;
2886  }
[7bab5d]2887  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
[0e1846]2888  for (i=0;i<IDELEMS(h2);i++)
2889  {
2890    temp->m[i] = pCopy(h2->m[i]);
2891    q = pOne();
2892    pSetComp(q,i+1+length);
[66a672]2893    pSetmComp(q);
[0e1846]2894    if(temp->m[i]!=NULL)
2895    {
2896      if (slength==0) pShift(&(temp->m[i]),1);
2897      p = temp->m[i];
2898      while (pNext(p)!=NULL) pIter(p);
2899      pNext(p) = q;
2900    }
2901    else
2902      temp->m[i]=q;
2903  }
2904  rk = k = IDELEMS(h2);
2905  if (!idIs0(h1))
2906  {
2907    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
2908    IDELEMS(temp) += IDELEMS(h1);
2909    for (i=0;i<IDELEMS(h1);i++)
2910    {
2911      if (h1->m[i]!=NULL)
2912      {
2913        temp->m[k] = pCopy(h1->m[i]);
2914        if (flength==0) pShift(&(temp->m[k]),1);
2915        k++;
2916      }
2917    }
2918  }
[b9a806]2919
2920  ring orig_ring=currRing;
[0e002d]2921  ring syz_ring=rCurrRingAssure_SyzComp();
[416465]2922  rSetSyzComp(length);
2923  ideal s_temp;
[1bf317]2924
[416465]2925  if (syz_ring != orig_ring)
[b9a806]2926  {
[6f1610]2927    s_temp = idrMoveR_NoSort(temp, orig_ring);
[b9a806]2928  }
[416465]2929  else
[b9a806]2930  {
[416465]2931    s_temp = temp;
[b9a806]2932  }
[1bf317]2933
[6f1610]2934  idTest(s_temp);
[416465]2935  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
2936  if (w!=NULL) delete w;
[b9a806]2937
[416465]2938  for (i=0;i<IDELEMS(s_temp1);i++)
[0e1846]2939  {
[416465]2940    if ((s_temp1->m[i]!=NULL)
2941    && (pGetComp(s_temp1->m[i])<=length))
[0e1846]2942    {
[416465]2943      pDelete(&(s_temp1->m[i]));
[0e1846]2944    }
2945    else
2946    {
[416465]2947      pShift(&(s_temp1->m[i]),-length);
[0e1846]2948    }
2949  }
[416465]2950  s_temp1->rank = rk;
2951  idSkipZeroes(s_temp1);
[b9a806]2952
[416465]2953  if (syz_ring!=orig_ring)
2954  {
2955    rChangeCurrRing(orig_ring,TRUE);
[6f1610]2956    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
[416465]2957    rKill(syz_ring);
2958  }
[6f1610]2959  else
2960  {
2961    idDelete(&temp);
2962  }
2963  idTest(s_temp1);
[416465]2964  return s_temp1;
[0e1846]2965}
2966
2967int idElem(ideal F)
2968{
2969  int i=0,j=0;
2970
2971  while(j<IDELEMS(F))
2972  {
2973   if ((F->m)[j]!=NULL) i++;
2974   j++;
2975  }
2976  return i;
2977}
2978
2979/*
2980*computes module-weights for liftings of homogeneous modules
2981*/
2982intvec * idMWLift(ideal mod,intvec * weights)
2983{
[477993]2984  if (idIs0(mod)) return NewIntvec1(2);
[0e1846]2985  int i=IDELEMS(mod);
2986  while ((i>0) && (mod->m[i-1]==NULL)) i--;
[477993]2987  intvec *result = NewIntvec1(i+1);
[0e1846]2988  while (i>0)
2989  {
2990    (*result)[i]=pFDeg(mod->m[i])+(*weights)[pGetComp(mod->m[i])];
2991  }
2992  return result;
2993}
2994
2995/*2
2996*sorts the kbase for idCoef* in a special way (lexicographically
2997*with x_max,...,x_1)
2998*/
2999ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
3000{
3001  int i;
3002  ideal result;
3003
3004  if (idIs0(kBase)) return NULL;
3005  result = idInit(IDELEMS(kBase),kBase->rank);
3006  *convert = idSort(kBase,FALSE);
3007  for (i=0;i<(*convert)->length();i++)
3008  {
3009    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
3010  }
3011  return result;
3012}
3013
3014/*2
3015*returns the index of a given monom in the list of the special kbase
3016*/
3017int idIndexOfKBase(poly monom, ideal kbase)
3018{
3019  int j=IDELEMS(kbase);
3020
3021  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
3022  if (j==0) return -1;
3023  int i=pVariables;
[50619f7]3024  while (i>0)
[0e1846]3025  {
[50619f7]3026    loop
3027    {
3028      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
3029      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
3030      j--;
3031      if (j==0) return -1;
3032    }
3033    if (i==1)
3034    {
3035      while(j>0)
3036      {
3037        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
3038        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
3039        j--;
3040      }
3041    }
3042    i--;
[0e1846]3043  }
3044  return -1;
3045}
3046
3047/*2
3048*decomposes the monom in a part of coefficients described by the
3049*complement of how and a monom in variables occuring in how, the
3050*index of which in kbase is returned as integer pos (-1 if it don't
3051*exists)
3052*/
3053poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3054{
3055  int i;
3056  poly coeff=pOne(), base=pOne();
3057
3058  for (i=1;i<=pVariables;i++)
3059  {
3060    if (pGetExp(how,i)>0)
3061    {
3062      pSetExp(base,i,pGetExp(monom,i));
3063    }
3064    else
3065    {
3066      pSetExp(coeff,i,pGetExp(monom,i));
3067    }
3068  }
3069  pSetComp(base,pGetComp(monom));
3070  pSetm(base);
3071  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3072  pSetm(coeff);
3073  *pos = idIndexOfKBase(base,kbase);
3074  if (*pos<0)
3075    pDelete(&coeff);
3076  pDelete(&base);
3077  return coeff;
3078}
3079
3080/*2
3081*returns a matrix A of coefficients with kbase*A=arg
3082*if all monomials in variables of how occur in kbase
3083*the other are deleted
3084*/
3085matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3086{
3087  matrix result;
3088  ideal tempKbase;
3089  poly p,q;
3090  intvec * convert;
3091  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
[16262b7]3092#if 0
[0e1846]3093  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3094  if (idIs0(arg))
3095    return mpNew(i,1);
3096  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3097  result = mpNew(i,j);
[16262b7]3098#else
3099  result = mpNew(i, j);
3100  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3101#endif
3102
[0e1846]3103  tempKbase = idCreateSpecialKbase(kbase,&convert);
3104  for (k=0;k<j;k++)
3105  {
3106    p = arg->m[k];
3107    while (p!=NULL)
3108    {
3109      q = idDecompose(p,how,tempKbase,&pos);
3110      if (pos>=0)
3111      {
3112        MATELEM(result,(*convert)[pos],k+1) =
3113            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3114      }
3115      else
3116        pDelete(&q);
[50619f7]3117      pIter(p);
[0e1846]3118    }
3119  }
3120  idDelete(&tempKbase);
3121  return result;
3122}
3123
3124intvec * idQHomWeights(ideal id)
3125{
[477993]3126  intvec * imat=NewIntvec3(2*pVariables,pVariables,0);
[0e1846]3127  poly actHead=NULL,wPoint=NULL;
3128  int actIndex,i=-1,j=1,k;
3129  BOOLEAN notReady=TRUE;
3130
3131  while (notReady)
3132  {
3133    if (wPoint==NULL)
3134    {
3135      i++;
3136      while ((i<IDELEMS(id))
3137      && ((id->m[i]==NULL) || (pNext(id->m[i])==NULL)))
3138        i++;
3139      if (i<IDELEMS(id))
3140      {
3141        actHead = id->m[i];
3142        wPoint = pNext(actHead);
3143      }
3144    }
3145    while ((wPoint!=NULL) && (j<=2*pVariables))
3146    {
3147      for (k=1;k<=pVariables;k++)
3148        IMATELEM(*imat,j,k) += pGetExp(actHead,k)-pGetExp(wPoint,k);
3149      pIter(wPoint);
3150      j++;
3151    }
3152    if ((i>=IDELEMS(id)) || (j>2*pVariables))
3153    {
3154      ivTriangMat(imat,1,1);
3155      j = ivFirstEmptyRow(imat);
3156      if ((i>=IDELEMS(id)) || (j>pVariables)) notReady=FALSE;
3157    }
3158  }
3159  intvec *result=NULL;
3160  if (j<=pVariables)
3161  {
3162    result=ivSolveIntMat(imat);
3163  }
3164  //else
3165  //{
[da97958]3166  //  WerrorS("not homogeneous");
[0e1846]3167  //}
3168  delete imat;
3169  return result;
3170}
3171
[416465]3172/*3
3173* searches for units in the components of the module arg and
3174* returns the first one
[0e1846]3175*/
[416465]3176static int idReadOutUnits(ideal arg,int* comp)
[0e1846]3177{
[416465]3178  if (idIs0(arg)) return -1;
3179  int i=0,j,rk_arg=idRankFreeModule(arg),generator=-1;
3180  intvec * componentIsUsed =new intvec(rk_arg+1);
[0e1846]3181  poly p,q;
3182
[416465]3183  while ((i<IDELEMS(arg)) && (generator<0))
[0e1846]3184  {
[1bf317]3185    for (j=rk_arg;j>=0;j--)
[416465]3186      (*componentIsUsed)[j]=0;
3187    p = arg->m[i];
3188    while (p!=NULL)
[1bf317]3189    {
[416465]3190      j = pGetComp(p);
3191      if ((*componentIsUsed)[j]==0)
[0e1846]3192      {
[416465]3193        if (pIsConstantComp(p))
[0e1846]3194        {
[416465]3195          generator = i;
3196          (*componentIsUsed)[j] = 1;
3197        }
3198        else
3199        {
3200          (*componentIsUsed)[j] = -1;
[0e1846]3201        }
3202      }
[416465]3203      else if ((*componentIsUsed)[j]>0)
3204      {
3205        ((*componentIsUsed)[j])++;
3206      }
3207      pIter(p);
[0e1846]3208    }
[416465]3209    i++;
3210  }
3211  i = 0;
3212  *comp = -1;
3213  for (j=0;j<=rk_arg;j++)
3214  {
3215    if ((*componentIsUsed)[j]>0)
[0e1846]3216    {
[416465]3217      if ((*comp==-1) || ((*componentIsUsed)[j]<i))
[0e1846]3218      {
[416465]3219        *comp = j;
3220        i= (*componentIsUsed)[j];
[0e1846]3221      }
[dc32d42]3222    }
[416465]3223  }
3224  return generator;
3225}
3226
3227static void idDeleteComp(ideal arg,int red_comp)
3228{
3229  int i,j;
3230  poly p;
3231
3232  for (i=IDELEMS(arg)-1;i>=0;i--)
3233  {
3234    p = arg->m[i];
3235    while (p!=NULL)
[dc32d42]3236    {
[416465]3237      j = pGetComp(p);
3238      if (j>red_comp)
3239      {
3240        pSetComp(p,j-1);
3241        pSetm(p);
3242      }
3243      pIter(p);
[0e1846]3244    }
3245  }
[416465]3246  (arg->rank)--;
3247}
3248
3249/*2
3250* returns the presentation of an isomorphic, minimally
[84db93f]3251* embedded  module (arg represents the quotient!)
[416465]3252*/
3253ideal idMinEmbedding(ideal arg,BOOLEAN inPlace)
3254{
3255  if (idIs0(arg)) return idInit(1,arg->rank);
3256  int next_gen,next_comp;
3257  ideal res=arg;
3258
3259  if (!inPlace) res = idCopy(arg);
3260  loop
3261  {
3262    next_gen = idReadOutUnits(res,&next_comp);
3263    if (next_gen<0) break;
3264    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
3265    idDeleteComp(res,next_comp);
3266  }
3267  idSkipZeroes(res);
[0e1846]3268  return res;
3269}
[43580ac]3270
[dfc64d9]3271/*2
3272* transpose a module
3273*/
3274ideal idTransp(ideal a)
3275{
3276  int r = a->rank, c = IDELEMS(a);
3277  ideal b =  idInit(r,c);
3278
3279  for (int i=c; i>0; i--)
3280  {
3281    poly p=a->m[i-1];
3282    while(p!=NULL)
3283    {
3284      poly h=pHead(p);
3285      int co=pGetComp(h)-1;
3286      pSetComp(h,i);
[66a672]3287      pSetmComp(h);
[dfc64d9]3288      b->m[co]=pAdd(b->m[co],h);
3289      pIter(p);
3290    }
3291  }
3292  return b;
3293}
3294
Note: See TracBrowser for help on using the repository browser.