source: git/kernel/ideals.cc @ e2a25e

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