source: git/kernel/ideals.cc @ 83a1939

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