source: git/kernel/ideals.cc @ 171950

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