source: git/kernel/ideals.cc @ 73df93

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