source: git/kernel/ideals.cc @ 308757

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