source: git/Singular/ideals.cc @ ede4b1

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