source: git/kernel/ideals.cc @ d84a4d

spielwiese
Last change on this file since d84a4d was 38fc181, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
CHG: cleanup for id[_]*TestHomModule
  • Property mode set to 100644
File size: 59.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: ideals.cc 14320 2011-07-04 14:48:27Z hannes $ */
5/*
6* ABSTRACT - all basic methods to manipulate ideals
7*/
8
9/* includes */
10#include "mod2.h"
11
12#include <omalloc/omalloc.h>
13#include <misc/auxiliary.h>
14
15
16#ifndef NDEBUG
17# define MYTEST 0
18#else /* ifndef NDEBUG */
19# define MYTEST 0
20#endif /* ifndef NDEBUG */
21
22#include <omalloc/omalloc.h>
23
24#include <misc/options.h>
25#include <misc/intvec.h>
26
27#include <coeffs/coeffs.h>
28#include <coeffs/numbers.h>
29
30#include <kernel/polys.h>
31#include <polys/monomials/ring.h>
32#include <polys/matpol.h>
33#include <polys/weight.h>
34#include <polys/sparsmat.h>
35#include <polys/prCopy.h>
36#include <polys/nc/nc.h>
37
38
39#include <kernel/ideals.h>
40
41#include <kernel/febase.h>
42#include <kernel/kstd1.h>
43#include <kernel/syz.h>
44
45#include <kernel/longrat.h>
46
47
48/* #define WITH_OLD_MINOR */
49#define pCopy_noCheck(p) pCopy(p)
50
51static poly * idpower;
52/*collects the monomials in makemonoms, must be allocated befor*/
53static int idpowerpoint;
54/*index of the actual monomial in idpower*/
55static poly * givenideal;
56/*the ideal from which a power is computed*/
57
58/*0 implementation*/
59
60/*2
61*returns a minimized set of generators of h1
62*/
63ideal idMinBase (ideal h1)
64{
65  ideal h2, h3,h4,e;
66  int j,k;
67  int i,l,ll;
68  intvec * wth;
69  BOOLEAN homog;
70
71  homog = idHomModule(h1,currQuotient,&wth);
72  if (rHasGlobalOrdering(currRing))
73  {
74    if(!homog)
75    {
76      WarnS("minbase applies only to the local or homogeneous case");
77      e=idCopy(h1);
78      return e;
79    }
80    else
81    {
82      ideal re=kMin_std(h1,currQuotient,(tHomog)homog,&wth,h2,NULL,0,3);
83      idDelete(&re);
84      return h2;
85    }
86  }
87  e=idInit(1,h1->rank);
88  if (idIs0(h1))
89  {
90    return e;
91  }
92  pEnlargeSet(&(e->m),IDELEMS(e),15);
93  IDELEMS(e) = 16;
94  h2 = kStd(h1,currQuotient,isNotHomog,NULL);
95  h3 = idMaxIdeal(1);
96  h4=idMult(h2,h3);
97  idDelete(&h3);
98  h3=kStd(h4,currQuotient,isNotHomog,NULL);
99  k = IDELEMS(h3);
100  while ((k > 0) && (h3->m[k-1] == NULL)) k--;
101  j = -1;
102  l = IDELEMS(h2);
103  while ((l > 0) && (h2->m[l-1] == NULL)) l--;
104  for (i=l-1; i>=0; i--)
105  {
106    if (h2->m[i] != NULL)
107    {
108      ll = 0;
109      while ((ll < k) && ((h3->m[ll] == NULL)
110      || !pDivisibleBy(h3->m[ll],h2->m[i])))
111        ll++;
112      if (ll >= k)
113      {
114        j++;
115        if (j > IDELEMS(e)-1)
116        {
117          pEnlargeSet(&(e->m),IDELEMS(e),16);
118          IDELEMS(e) += 16;
119        }
120        e->m[j] = pCopy(h2->m[i]);
121      }
122    }
123  }
124  idDelete(&h2);
125  idDelete(&h3);
126  idDelete(&h4);
127  if (currQuotient!=NULL)
128  {
129    h3=idInit(1,e->rank);
130    h2=kNF(h3,currQuotient,e);
131    idDelete(&h3);
132    idDelete(&e);
133    e=h2;
134  }
135  idSkipZeroes(e);
136  return e;
137}
138
139
140/*3
141*multiplies p with t (!cas) or  (t-1)
142*the index of t is:1, so we have to shift all variables
143*p is NOT in the actual ring, it has no t
144*/
145static poly pMultWithT (poly p,BOOLEAN cas)
146{
147  /*qp is the working pointer in p*/
148  /*result is the result, qresult is the working pointer*/
149  /*pp is p in the actual ring(shifted), qpp the working pointer*/
150  poly result,qp,pp;
151  poly qresult=NULL;
152  poly qpp=NULL;
153  int  i,j,lex;
154  number n;
155
156  pp = NULL;
157  result = NULL;
158  qp = p;
159  while (qp != NULL)
160  {
161    i = 0;
162    if (result == NULL)
163    {/*first monomial*/
164      result = pInit();
165      qresult = result;
166    }
167    else
168    {
169      qresult->next = pInit();
170      pIter(qresult);
171    }
172    for (j=(currRing->N)-1; j>0; j--)
173    {
174      lex = pGetExp(qp,j);
175      pSetExp(qresult,j+1,lex);/*copy all variables*/
176    }
177    lex = pGetComp(qp);
178    pSetComp(qresult,lex);
179    n=nCopy(pGetCoeff(qp));
180    pSetCoeff0(qresult,n);
181    qresult->next = NULL;
182    pSetm(qresult);
183    /*qresult is now qp brought into the actual ring*/
184    if (cas)
185    { /*case: mult with t-1*/
186      pSetExp(qresult,1,0);
187      pSetm(qresult);
188      if (pp == NULL)
189      { /*first monomial*/
190        pp = pCopy(qresult);
191        qpp = pp;
192      }
193      else
194      {
195        qpp->next = pCopy(qresult);
196        pIter(qpp);
197      }
198      pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
199      /*now qpp contains -1*qp*/
200    }
201    pSetExp(qresult,1,1);/*this is mult. by t*/
202    pSetm(qresult);
203    pIter(qp);
204  }
205  /*
206  *now p is processed:
207  *result contains t*p
208  * if cas: pp contains -1*p (in the new ring)
209  */
210  if (cas)  qresult->next = pp;
211  /*  else      qresult->next = NULL;*/
212  return result;
213}
214
215/*2
216*initialized a field with r numbers between beg and end for the
217*procedure idNextChoise
218*/
219ideal idSectWithElim (ideal h1,ideal h2)
220// does not destroy h1,h2
221{
222  if (TEST_OPT_PROT) PrintS("intersect by elimination method\n");
223  assume(!idIs0(h1));
224  assume(!idIs0(h2));
225  assume(IDELEMS(h1)<=IDELEMS(h2));
226  assume(id_RankFreeModule(h1,currRing)==0);
227  assume(id_RankFreeModule(h2,currRing)==0);
228  // add a new variable:
229  int j;
230  ring origRing=currRing;
231  ring r=rCopy0(origRing);
232  r->N++;
233  r->block0[0]=1;
234  r->block1[0]= r->N;
235  omFree(r->order);
236  r->order=(int*)omAlloc0(3*sizeof(int*));
237  r->order[0]=ringorder_dp;
238  r->order[1]=ringorder_C;
239  char **names=(char**)omAlloc0(rVar(r) * sizeof(char_ptr));
240  for (j=0;j<r->N-1;j++) names[j]=r->names[j];
241  names[r->N-1]=omStrDup("@");
242  omFree(r->names);
243  r->names=names;
244  rComplete(r,TRUE);
245  // fetch h1, h2
246  ideal h;
247  h1=idrCopyR(h1,origRing,r);
248  h2=idrCopyR(h2,origRing,r);
249  // switch to temp. ring r
250  rChangeCurrRing(r);
251  // create 1-t, t
252  poly omt=p_One(currRing);
253  p_SetExp(omt,r->N,1,currRing);
254  poly t=p_Copy(omt,currRing);
255  p_Setm(omt,currRing);
256  omt=p_Neg(omt,currRing);
257  omt=p_Add_q(omt,pOne(),currRing);
258  // compute (1-t)*h1
259  h1=(ideal)mp_MultP((matrix)h1,omt,currRing);
260  // compute t*h2
261  h2=(ideal)mp_MultP((matrix)h2,pCopy(t),currRing);
262  // (1-t)h1 + t*h2
263  h=idInit(IDELEMS(h1)+IDELEMS(h2),1);
264  int l;
265  for (l=IDELEMS(h1)-1; l>=0; l--)
266  {
267    h->m[l] = h1->m[l];  h1->m[l]=NULL;
268  }
269  j=IDELEMS(h1);
270  for (l=IDELEMS(h2)-1; l>=0; l--)
271  {
272    h->m[l+j] = h2->m[l];  h2->m[l]=NULL;
273  }
274  idDelete(&h1);
275  idDelete(&h2);
276  // eliminate t:
277
278  ideal res=idElimination(h,t);
279  // cleanup
280  idDelete(&h);
281  res=idrMoveR(res,r,origRing);
282  rChangeCurrRing(origRing);
283  rDelete(r);
284  return res;
285}
286/*2
287* h3 := h1 intersect h2
288*/
289ideal idSect (ideal h1,ideal h2)
290{
291  int i,j,k,length;
292  int flength = id_RankFreeModule(h1,currRing);
293  int slength = id_RankFreeModule(h2,currRing);
294  int rank=si_min(flength,slength);
295  if ((idIs0(h1)) || (idIs0(h2)))  return idInit(1,rank);
296
297  ideal first,second,temp,temp1,result;
298  poly p,q;
299
300  if (IDELEMS(h1)<IDELEMS(h2))
301  {
302    first = h1;
303    second = h2;
304  }
305  else
306  {
307    first = h2;
308    second = h1;
309    int t=flength; flength=slength; slength=t;
310  }
311  length  = si_max(flength,slength);
312  if (length==0)
313  {
314    if ((currQuotient==NULL)
315    && (currRing->OrdSgn==1)
316    && (!rIsPluralRing(currRing))
317    && ((TEST_V_INTERSECT_ELIM) || (!TEST_V_INTERSECT_SYZ)))
318      return idSectWithElim(first,second);
319    else length = 1;
320  }
321  if (TEST_OPT_PROT) PrintS("intersect by syzygy methods\n");
322  j = IDELEMS(first);
323
324  ring orig_ring=currRing;
325  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
326  rSetSyzComp(length, syz_ring);
327
328  while ((j>0) && (first->m[j-1]==NULL)) j--;
329  temp = idInit(j /*IDELEMS(first)*/+IDELEMS(second),length+j);
330  k = 0;
331  for (i=0;i<j;i++)
332  {
333    if (first->m[i]!=NULL)
334    {
335      if (syz_ring==orig_ring)
336        temp->m[k] = pCopy(first->m[i]);
337      else
338        temp->m[k] = prCopyR(first->m[i], orig_ring, syz_ring);
339      q = pOne();
340      pSetComp(q,i+1+length);
341      pSetmComp(q);
342      if (flength==0) p_Shift(&(temp->m[k]),1,currRing);
343      p = temp->m[k];
344      while (pNext(p)!=NULL) pIter(p);
345      pNext(p) = q;
346      k++;
347    }
348  }
349  for (i=0;i<IDELEMS(second);i++)
350  {
351    if (second->m[i]!=NULL)
352    {
353      if (syz_ring==orig_ring)
354        temp->m[k] = pCopy(second->m[i]);
355      else
356        temp->m[k] = prCopyR(second->m[i], orig_ring,currRing);
357      if (slength==0) p_Shift(&(temp->m[k]),1,currRing);
358      k++;
359    }
360  }
361  intvec *w=NULL;
362  temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
363  if (w!=NULL) delete w;
364  idDelete(&temp);
365  if(syz_ring!=orig_ring)
366    rChangeCurrRing(orig_ring);
367
368  result = idInit(IDELEMS(temp1),rank);
369  j = 0;
370  for (i=0;i<IDELEMS(temp1);i++)
371  {
372    if ((temp1->m[i]!=NULL)
373    && (p_GetComp(temp1->m[i],syz_ring)>length))
374    {
375      if(syz_ring==orig_ring)
376      {
377        p = temp1->m[i];
378      }
379      else
380      {
381        p = prMoveR(temp1->m[i], syz_ring,orig_ring);
382      }
383      temp1->m[i]=NULL;
384      while (p!=NULL)
385      {
386        q = pNext(p);
387        pNext(p) = NULL;
388        k = pGetComp(p)-1-length;
389        pSetComp(p,0);
390        pSetmComp(p);
391        /* Warning! multiply only from the left! it's very important for Plural */
392        result->m[j] = pAdd(result->m[j],pMult(p,pCopy(first->m[k])));
393        p = q;
394      }
395      j++;
396    }
397  }
398  if(syz_ring!=orig_ring)
399  {
400    rChangeCurrRing(syz_ring);
401    idDelete(&temp1);
402    rChangeCurrRing(orig_ring);
403    rDelete(syz_ring);
404  }
405  else
406  {
407    idDelete(&temp1);
408  }
409
410  idSkipZeroes(result);
411  if (TEST_OPT_RETURN_SB)
412  {
413     w=NULL;
414     temp1=kStd(result,currQuotient,testHomog,&w);
415     if (w!=NULL) delete w;
416     idDelete(&result);
417     idSkipZeroes(temp1);
418     return temp1;
419  }
420  else //temp1=kInterRed(result,currQuotient);
421    return result;
422}
423
424/*2
425* ideal/module intersection for a list of objects
426* given as 'resolvente'
427*/
428ideal idMultSect(resolvente arg, int length)
429{
430  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
431  ideal bigmat,tempstd,result;
432  poly p;
433  int isIdeal=0;
434  intvec * w=NULL;
435
436  /* find 0-ideals and max rank -----------------------------------*/
437  for (i=0;i<length;i++)
438  {
439    if (!idIs0(arg[i]))
440    {
441      realrki=id_RankFreeModule(arg[i],currRing);
442      k++;
443      j += IDELEMS(arg[i]);
444      if (realrki>maxrk) maxrk = realrki;
445    }
446    else
447    {
448      if (arg[i]!=NULL)
449      {
450        return idInit(1,arg[i]->rank);
451      }
452    }
453  }
454  if (maxrk == 0)
455  {
456    isIdeal = 1;
457    maxrk = 1;
458  }
459  /* init -----------------------------------------------------------*/
460  j += maxrk;
461  syzComp = k*maxrk;
462
463  ring orig_ring=currRing;
464  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
465  rSetSyzComp(syzComp, syz_ring);
466
467  bigmat = idInit(j,(k+1)*maxrk);
468  /* create unit matrices ------------------------------------------*/
469  for (i=0;i<maxrk;i++)
470  {
471    for (j=0;j<=k;j++)
472    {
473      p = pOne();
474      pSetComp(p,i+1+j*maxrk);
475      pSetmComp(p);
476      bigmat->m[i] = pAdd(bigmat->m[i],p);
477    }
478  }
479  /* enter given ideals ------------------------------------------*/
480  i = maxrk;
481  k = 0;
482  for (j=0;j<length;j++)
483  {
484    if (arg[j]!=NULL)
485    {
486      for (l=0;l<IDELEMS(arg[j]);l++)
487      {
488        if (arg[j]->m[l]!=NULL)
489        {
490          if (syz_ring==orig_ring)
491            bigmat->m[i] = pCopy(arg[j]->m[l]);
492          else
493            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring,currRing);
494          p_Shift(&(bigmat->m[i]),k*maxrk+isIdeal,currRing);
495          i++;
496        }
497      }
498      k++;
499    }
500  }
501  /* std computation --------------------------------------------*/
502  tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
503  if (w!=NULL) delete w;
504  idDelete(&bigmat);
505
506  if(syz_ring!=orig_ring)
507    rChangeCurrRing(orig_ring);
508
509  /* interprete result ----------------------------------------*/
510  result = idInit(IDELEMS(tempstd),maxrk);
511  k = 0;
512  for (j=0;j<IDELEMS(tempstd);j++)
513  {
514    if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
515    {
516      if (syz_ring==orig_ring)
517        p = pCopy(tempstd->m[j]);
518      else
519        p = prCopyR(tempstd->m[j], syz_ring,currRing);
520      p_Shift(&p,-syzComp-isIdeal,currRing);
521      result->m[k] = p;
522      k++;
523    }
524  }
525  /* clean up ----------------------------------------------------*/
526  if(syz_ring!=orig_ring)
527    rChangeCurrRing(syz_ring);
528  idDelete(&tempstd);
529  if(syz_ring!=orig_ring)
530  {
531    rChangeCurrRing(orig_ring);
532    rDelete(syz_ring);
533  }
534  idSkipZeroes(result);
535  return result;
536}
537
538/*2
539*computes syzygies of h1,
540*if quot != NULL it computes in the quotient ring modulo "quot"
541*works always in a ring with ringorder_s
542*/
543static ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w)
544{
545  ideal   h2, h3;
546  int     i;
547  int     j,jj=0,k;
548  poly    p,q;
549
550  if (idIs0(h1)) return NULL;
551  k = id_RankFreeModule(h1,currRing);
552  h2=idCopy(h1);
553  i = IDELEMS(h2)-1;
554  if (k == 0)
555  {
556    for (j=0; j<=i; j++) p_Shift(&(h2->m[j]),1,currRing);
557    k = 1;
558  }
559  if (syzcomp<k)
560  {
561    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
562    syzcomp = k;
563    rSetSyzComp(k,currRing);
564  }
565  h2->rank = syzcomp+i+1;
566
567  //if (hom==testHomog)
568  //{
569  //  if(idHomIdeal(h1,currQuotient))
570  //  {
571  //    hom=TRUE;
572  //  }
573  //}
574
575#if MYTEST
576#ifdef RDEBUG
577  Print("Prepare::h2: ");
578  idPrint(h2);
579
580  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
581
582#endif
583#endif
584
585  for (j=0; j<=i; j++)
586  {
587    p = h2->m[j];
588    q = pOne();
589    pSetComp(q,syzcomp+1+j);
590    pSetmComp(q);
591    if (p!=NULL)
592    {
593      while (pNext(p)) pIter(p);
594      p->next = q;
595    }
596    else
597      h2->m[j]=q;
598  }
599
600#ifdef PDEBUG
601  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
602
603#if MYTEST
604#ifdef RDEBUG
605  Print("Prepare::Input: ");
606  idPrint(h2);
607
608  Print("Prepare::currQuotient: ");
609  idPrint(currQuotient);
610#endif
611#endif
612
613#endif
614
615  idTest(h2);
616
617  h3 = kStd(h2,currQuotient,hom,w,NULL,syzcomp);
618
619#if MYTEST
620#ifdef RDEBUG
621  Print("Prepare::Output: ");
622  idPrint(h3);
623  for(j=0;j<IDELEMS(h2);j++) pTest(h3->m[j]);
624#endif
625#endif
626
627
628  idDelete(&h2);
629  return h3;
630}
631
632/*2
633* compute the syzygies of h1 in R/quot,
634* weights of components are in w
635* if setRegularity, return the regularity in deg
636* do not change h1,  w
637*/
638ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
639                  BOOLEAN setRegularity, int *deg)
640{
641  ideal s_h1;
642  poly  p;
643  int   j, k, length=0,reg;
644  BOOLEAN isMonomial=TRUE;
645  int ii, idElemens_h1;
646
647  assume(h1 != NULL);
648
649  idElemens_h1=IDELEMS(h1);
650#ifdef PDEBUG
651  for(ii=0;ii<idElemens_h1 /*IDELEMS(h1)*/;ii++) pTest(h1->m[ii]);
652#endif
653  if (idIs0(h1))
654  {
655    ideal result=idFreeModule(idElemens_h1/*IDELEMS(h1)*/);
656    int curr_syz_limit=rGetCurrSyzLimit(currRing);
657    if (curr_syz_limit>0)
658    for (ii=0;ii<idElemens_h1/*IDELEMS(h1)*/;ii++)
659    {
660      if (h1->m[ii]!=NULL)
661        p_Shift(&h1->m[ii],curr_syz_limit,currRing);
662    }
663    return result;
664  }
665  int slength=(int)id_RankFreeModule(h1,currRing);
666  k=si_max(1,slength /*id_RankFreeModule(h1)*/);
667
668  assume(currRing != NULL);
669  ring orig_ring=currRing;
670  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
671
672  if (setSyzComp)
673    rSetSyzComp(k,syz_ring);
674
675  if (orig_ring != syz_ring)
676  {
677    s_h1=idrCopyR_NoSort(h1,orig_ring,syz_ring);
678  }
679  else
680  {
681    s_h1 = h1;
682  }
683
684  idTest(s_h1);
685
686  ideal s_h3=idPrepare(s_h1,h,k,w); // main (syz) GB computation
687
688  if (s_h3==NULL)
689  {
690    return idFreeModule( idElemens_h1 /*IDELEMS(h1)*/);
691  }
692
693  if (orig_ring != syz_ring)
694  {
695    idDelete(&s_h1);
696    for (j=0; j<IDELEMS(s_h3); j++)
697    {
698      if (s_h3->m[j] != NULL)
699      {
700        if (p_MinComp(s_h3->m[j],syz_ring) > k)
701          p_Shift(&s_h3->m[j], -k,syz_ring);
702        else
703          p_Delete(&s_h3->m[j],syz_ring);
704      }
705    }
706    idSkipZeroes(s_h3);
707    s_h3->rank -= k;
708    rChangeCurrRing(orig_ring);
709    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
710    rDelete(syz_ring);
711    #ifdef HAVE_PLURAL
712    if (rIsPluralRing(currRing))
713    {
714      idDelMultiples(s_h3);
715      idSkipZeroes(s_h3);
716    }
717    #endif
718    idTest(s_h3);
719    return s_h3;
720  }
721
722  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
723
724  for (j=IDELEMS(s_h3)-1; j>=0; j--)
725  {
726    if (s_h3->m[j] != NULL)
727    {
728      if (p_MinComp(s_h3->m[j],syz_ring) <= k)
729      {
730        e->m[j] = s_h3->m[j];
731        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
732        p_Delete(&pNext(s_h3->m[j]),syz_ring);
733        s_h3->m[j] = NULL;
734      }
735    }
736  }
737
738  idSkipZeroes(s_h3);
739  idSkipZeroes(e);
740
741  if ((deg != NULL)
742  && (!isMonomial)
743  && (!TEST_OPT_NOTREGULARITY)
744  && (setRegularity)
745  && (h==isHomog)
746  && (!rIsPluralRing(currRing))
747  )
748  {
749    ring dp_C_ring = rAssure_dp_C(syz_ring); // will do rChangeCurrRing later
750    if (dp_C_ring != syz_ring)
751    {
752      rChangeCurrRing(dp_C_ring);
753      e = idrMoveR_NoSort(e, syz_ring, dp_C_ring);
754    }
755    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
756    intvec * dummy = syBetti(res,length,&reg, *w);
757    *deg = reg+2;
758    delete dummy;
759    for (j=0;j<length;j++)
760    {
761      if (res[j]!=NULL) idDelete(&(res[j]));
762    }
763    omFreeSize((ADDRESS)res,length*sizeof(ideal));
764    idDelete(&e);
765    if (dp_C_ring != syz_ring)
766    {
767      rChangeCurrRing(syz_ring);
768      rDelete(dp_C_ring);
769    }
770  }
771  else
772  {
773    idDelete(&e);
774  }
775  idTest(s_h3);
776  if (currQuotient != NULL)
777  {
778    ideal ts_h3=kStd(s_h3,currQuotient,h,w);
779    idDelete(&s_h3);
780    s_h3 = ts_h3;
781  }
782  return s_h3;
783}
784
785/*2
786*/
787ideal idXXX (ideal  h1, int k)
788{
789  ideal s_h1;
790  int j;
791  intvec *w=NULL;
792
793  assume(currRing != NULL);
794  ring orig_ring=currRing;
795  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE); rChangeCurrRing(syz_ring);
796
797  rSetSyzComp(k,syz_ring);
798
799  if (orig_ring != syz_ring)
800  {
801    s_h1=idrCopyR_NoSort(h1,orig_ring, syz_ring);
802  }
803  else
804  {
805    s_h1 = h1;
806  }
807
808  ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
809
810  if (s_h3==NULL)
811  {
812    return idFreeModule(IDELEMS(h1));
813  }
814
815  if (orig_ring != syz_ring)
816  {
817    idDelete(&s_h1);
818    idSkipZeroes(s_h3);
819    rChangeCurrRing(orig_ring);
820    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
821    rDelete(syz_ring);
822    idTest(s_h3);
823    return s_h3;
824  }
825
826  idSkipZeroes(s_h3);
827  idTest(s_h3);
828  return s_h3;
829}
830
831/*
832*computes a standard basis for h1 and stores the transformation matrix
833* in ma
834*/
835ideal idLiftStd (ideal  h1, matrix* ma, tHomog hi, ideal * syz)
836{
837  int   i, j, k, t, inputIsIdeal=id_RankFreeModule(h1,currRing);
838  poly  p=NULL, q, qq;
839  intvec *w=NULL;
840
841  idDelete((ideal*)ma);
842  BOOLEAN lift3=FALSE;
843  if (syz!=NULL) { lift3=TRUE; idDelete(syz); }
844  if (idIs0(h1))
845  {
846    *ma=mpNew(1,0);
847    if (lift3)
848    {
849      *syz=idFreeModule(IDELEMS(h1));
850      int curr_syz_limit=rGetCurrSyzLimit(currRing);
851      if (curr_syz_limit>0)
852      for (int ii=0;ii<IDELEMS(h1);ii++)
853      {
854        if (h1->m[ii]!=NULL)
855          p_Shift(&h1->m[ii],curr_syz_limit,currRing);
856      }
857    }
858    return idInit(1,h1->rank);
859  }
860
861  BITSET save_verbose=verbose;
862
863  k=si_max(1,(int)id_RankFreeModule(h1,currRing));
864
865  if ((k==1) && (!lift3)) verbose |=Sy_bit(V_IDLIFT);
866
867  ring orig_ring = currRing;
868  ring syz_ring = rAssure_SyzComp(orig_ring,TRUE);  rChangeCurrRing(syz_ring);
869  rSetSyzComp(k,syz_ring);
870
871  ideal s_h1=h1;
872
873  if (orig_ring != syz_ring)
874    s_h1 = idrCopyR_NoSort(h1,orig_ring,syz_ring);
875  else
876    s_h1 = h1;
877
878  ideal s_h3=idPrepare(s_h1,hi,k,&w); // main (syz) GB computation
879
880  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
881
882  if (lift3) (*syz)=idInit(IDELEMS(s_h3),IDELEMS(h1));
883
884  if (w!=NULL) delete w;
885  i = 0;
886
887  // now sort the result, SB : leave in s_h3
888  //                      T:  put in s_h2
889  //                      syz: put in *syz
890  for (j=0; j<IDELEMS(s_h3); j++)
891  {
892    if (s_h3->m[j] != NULL)
893    {
894      //if (p_MinComp(s_h3->m[j],syz_ring) <= k)
895      if (pGetComp(s_h3->m[j]) <= k) // syz_ring == currRing
896      {
897        i++;
898        q = s_h3->m[j];
899        while (pNext(q) != NULL)
900        {
901          if (pGetComp(pNext(q)) > k)
902          {
903            s_h2->m[j] = pNext(q);
904            pNext(q) = NULL;
905          }
906          else
907          {
908            pIter(q);
909          }
910        }
911        if (!inputIsIdeal) p_Shift(&(s_h3->m[j]), -1,currRing);
912      }
913      else
914      {
915        // we a syzygy here:
916        if (lift3)
917        {
918          p_Shift(&s_h3->m[j], -k,currRing);
919          (*syz)->m[j]=s_h3->m[j];
920          s_h3->m[j]=NULL;
921        }
922        else
923          p_Delete(&(s_h3->m[j]),currRing);
924      }
925    }
926  }
927  idSkipZeroes(s_h3);
928  //extern char * iiStringMatrix(matrix im, int dim,char ch);
929  //PrintS("SB: ----------------------------------------\n");
930  //PrintS(iiStringMatrix((matrix)s_h3,k,'\n'));
931  //PrintLn();
932  //PrintS("T: ----------------------------------------\n");
933  //PrintS(iiStringMatrix((matrix)s_h2,h1->rank,'\n'));
934  //PrintLn();
935
936  if (lift3) idSkipZeroes(*syz);
937
938  j = IDELEMS(s_h1);
939
940
941  if (syz_ring!=orig_ring)
942  {
943    idDelete(&s_h1);
944    rChangeCurrRing(orig_ring);
945  }
946
947  *ma = mpNew(j,i);
948
949  i = 1;
950  for (j=0; j<IDELEMS(s_h2); j++)
951  {
952    if (s_h2->m[j] != NULL)
953    {
954      q = prMoveR( s_h2->m[j], syz_ring,orig_ring);
955      s_h2->m[j] = NULL;
956
957      while (q != NULL)
958      {
959        p = q;
960        pIter(q);
961        pNext(p) = NULL;
962        t=pGetComp(p);
963        pSetComp(p,0);
964        pSetmComp(p);
965        MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
966      }
967      i++;
968    }
969  }
970  idDelete(&s_h2);
971
972  for (i=0; i<IDELEMS(s_h3); i++)
973  {
974    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring,orig_ring);
975  }
976  if (lift3)
977  {
978    for (i=0; i<IDELEMS(*syz); i++)
979    {
980      (*syz)->m[i] = prMoveR_NoSort((*syz)->m[i], syz_ring,orig_ring);
981    }
982  }
983
984  if (syz_ring!=orig_ring) rDelete(syz_ring);
985  verbose = save_verbose;
986  return s_h3;
987}
988
989static void idPrepareStd(ideal s_temp, int k)
990{
991  int j,rk=id_RankFreeModule(s_temp,currRing);
992  poly p,q;
993
994  if (rk == 0)
995  {
996    for (j=0; j<IDELEMS(s_temp); j++)
997    {
998      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
999    }
1000    k = si_max(k,1);
1001  }
1002  for (j=0; j<IDELEMS(s_temp); j++)
1003  {
1004    if (s_temp->m[j]!=NULL)
1005    {
1006      p = s_temp->m[j];
1007      q = pOne();
1008      //pGetCoeff(q)=nNeg(pGetCoeff(q));   //set q to -1
1009      pSetComp(q,k+1+j);
1010      pSetmComp(q);
1011      while (pNext(p)) pIter(p);
1012      pNext(p) = q;
1013    }
1014  }
1015}
1016
1017/*2
1018*computes a representation of the generators of submod with respect to those
1019* of mod
1020*/
1021
1022ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
1023             BOOLEAN isSB, BOOLEAN divide, matrix *unit)
1024{
1025  int lsmod =id_RankFreeModule(submod,currRing), i, j, k;
1026  int comps_to_add=0;
1027  poly p;
1028
1029  if (idIs0(submod))
1030  {
1031    if (unit!=NULL)
1032    {
1033      *unit=mpNew(1,1);
1034      MATELEM(*unit,1,1)=pOne();
1035    }
1036    if (rest!=NULL)
1037    {
1038      *rest=idInit(1,mod->rank);
1039    }
1040    return idInit(1,mod->rank);
1041  }
1042  if (idIs0(mod)) /* and not idIs0(submod) */
1043  {
1044    WerrorS("2nd module does not lie in the first");
1045    #if 0
1046    if (unit!=NULL)
1047    {
1048      i=IDELEMS(submod);
1049      *unit=mpNew(i,i);
1050      for (j=i;j>0;j--)
1051      {
1052        MATELEM(*unit,j,j)=pOne();
1053      }
1054    }
1055    if (rest!=NULL)
1056    {
1057      *rest=idCopy(submod);
1058    }
1059    return idInit(1,mod->rank);
1060    #endif
1061    return idInit(IDELEMS(submod),submod->rank);
1062  }
1063  if (unit!=NULL)
1064  {
1065    comps_to_add = IDELEMS(submod);
1066    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
1067      comps_to_add--;
1068  }
1069  k=si_max(id_RankFreeModule(mod,currRing),id_RankFreeModule(submod,currRing));
1070  if  ((k!=0) && (lsmod==0)) lsmod=1;
1071  k=si_max(k,(int)mod->rank);
1072  if (k<submod->rank) { WarnS("rk(submod) > rk(mod) ?");k=submod->rank; }
1073
1074  ring orig_ring=currRing;
1075  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE);  rChangeCurrRing(syz_ring);
1076  rSetSyzComp(k,syz_ring);
1077
1078  ideal s_mod, s_temp;
1079  if (orig_ring != syz_ring)
1080  {
1081    s_mod = idrCopyR_NoSort(mod,orig_ring,syz_ring);
1082    s_temp = idrCopyR_NoSort(submod,orig_ring,syz_ring);
1083  }
1084  else
1085  {
1086    s_mod = mod;
1087    s_temp = idCopy(submod);
1088  }
1089  ideal s_h3;
1090  if (isSB)
1091  {
1092    s_h3 = idCopy(s_mod);
1093    idPrepareStd(s_h3, k+comps_to_add);
1094  }
1095  else
1096  {
1097    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
1098  }
1099  if (!goodShape)
1100  {
1101    for (j=0;j<IDELEMS(s_h3);j++)
1102    {
1103      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
1104        p_Delete(&(s_h3->m[j]),currRing);
1105    }
1106  }
1107  idSkipZeroes(s_h3);
1108  if (lsmod==0)
1109  {
1110    for (j=IDELEMS(s_temp);j>0;j--)
1111    {
1112      if (s_temp->m[j-1]!=NULL)
1113        p_Shift(&(s_temp->m[j-1]),1,currRing);
1114    }
1115  }
1116  if (unit!=NULL)
1117  {
1118    for(j = 0;j<comps_to_add;j++)
1119    {
1120      p = s_temp->m[j];
1121      if (p!=NULL)
1122      {
1123        while (pNext(p)!=NULL) pIter(p);
1124        pNext(p) = pOne();
1125        pIter(p);
1126        pSetComp(p,1+j+k);
1127        pSetmComp(p);
1128        p = pNeg(p);
1129      }
1130    }
1131  }
1132  ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
1133  s_result->rank = s_h3->rank;
1134  ideal s_rest = idInit(IDELEMS(s_result),k);
1135  idDelete(&s_h3);
1136  idDelete(&s_temp);
1137
1138  for (j=0;j<IDELEMS(s_result);j++)
1139  {
1140    if (s_result->m[j]!=NULL)
1141    {
1142      if (pGetComp(s_result->m[j])<=k)
1143      {
1144        if (!divide)
1145        {
1146          if (isSB)
1147          {
1148            WarnS("first module not a standardbasis\n"
1149              "// ** or second not a proper submodule");
1150          }
1151          else
1152            WerrorS("2nd module does not lie in the first");
1153          idDelete(&s_result);
1154          idDelete(&s_rest);
1155          s_result=idInit(IDELEMS(submod),submod->rank);
1156          break;
1157        }
1158        else
1159        {
1160          p = s_rest->m[j] = s_result->m[j];
1161          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1162          s_result->m[j] = pNext(p);
1163          pNext(p) = NULL;
1164        }
1165      }
1166      p_Shift(&(s_result->m[j]),-k,currRing);
1167      pNeg(s_result->m[j]);
1168    }
1169  }
1170  if ((lsmod==0) && (!idIs0(s_rest)))
1171  {
1172    for (j=IDELEMS(s_rest);j>0;j--)
1173    {
1174      if (s_rest->m[j-1]!=NULL)
1175      {
1176        p_Shift(&(s_rest->m[j-1]),-1,currRing);
1177        s_rest->m[j-1] = s_rest->m[j-1];
1178      }
1179    }
1180  }
1181  if(syz_ring!=orig_ring)
1182  {
1183    idDelete(&s_mod);
1184    rChangeCurrRing(orig_ring);
1185    s_result = idrMoveR_NoSort(s_result, syz_ring, orig_ring);
1186    s_rest = idrMoveR_NoSort(s_rest, syz_ring, orig_ring);
1187    rDelete(syz_ring);
1188  }
1189  if (rest!=NULL)
1190    *rest = s_rest;
1191  else
1192    idDelete(&s_rest);
1193//idPrint(s_result);
1194  if (unit!=NULL)
1195  {
1196    *unit=mpNew(comps_to_add,comps_to_add);
1197    int i;
1198    for(i=0;i<IDELEMS(s_result);i++)
1199    {
1200      poly p=s_result->m[i];
1201      poly q=NULL;
1202      while(p!=NULL)
1203      {
1204        if(pGetComp(p)<=comps_to_add)
1205        {
1206          pSetComp(p,0);
1207          if (q!=NULL)
1208          {
1209            pNext(q)=pNext(p);
1210          }
1211          else
1212          {
1213            pIter(s_result->m[i]);
1214          }
1215          pNext(p)=NULL;
1216          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
1217          if(q!=NULL)   p=pNext(q);
1218          else          p=s_result->m[i];
1219        }
1220        else
1221        {
1222          q=p;
1223          pIter(p);
1224        }
1225      }
1226      p_Shift(&s_result->m[i],-comps_to_add,currRing);
1227    }
1228  }
1229  return s_result;
1230}
1231
1232/*2
1233*computes division of P by Q with remainder up to (w-weighted) degree n
1234*P, Q, and w are not changed
1235*/
1236void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
1237{
1238  long N=0;
1239  int i;
1240  for(i=IDELEMS(Q)-1;i>=0;i--)
1241    if(w==NULL)
1242      N=si_max(N,pDeg(Q->m[i]));
1243    else
1244      N=si_max(N,pDegW(Q->m[i],w));
1245  N+=n;
1246
1247  T=mpNew(IDELEMS(Q),IDELEMS(P));
1248  R=idInit(IDELEMS(P),P->rank);
1249
1250  for(i=IDELEMS(P)-1;i>=0;i--)
1251  {
1252    poly p;
1253    if(w==NULL)
1254      p=ppJet(P->m[i],N);
1255    else
1256      p=ppJetW(P->m[i],N,w);
1257
1258    int j=IDELEMS(Q)-1;
1259    while(p!=NULL)
1260    {
1261      if(pDivisibleBy(Q->m[j],p))
1262      {
1263        poly p0=p_DivideM(pHead(p),pHead(Q->m[j]),currRing);
1264        if(w==NULL)
1265          p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
1266        else
1267          p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
1268        pNormalize(p);
1269        if((w==NULL)&&(pDeg(p0)>n)||(w!=NULL)&&(pDegW(p0,w)>n))
1270          p_Delete(&p0,currRing);
1271        else
1272          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
1273        j=IDELEMS(Q)-1;
1274      }
1275      else
1276      {
1277        if(j==0)
1278        {
1279          poly p0=p;
1280          pIter(p);
1281          pNext(p0)=NULL;
1282          if(((w==NULL)&&(pDeg(p0)>n))
1283          ||((w!=NULL)&&(pDegW(p0,w)>n)))
1284            p_Delete(&p0,currRing);
1285          else
1286            R->m[i]=pAdd(R->m[i],p0);
1287          j=IDELEMS(Q)-1;
1288        }
1289        else
1290          j--;
1291      }
1292    }
1293  }
1294}
1295
1296/*2
1297*computes the quotient of h1,h2 : internal routine for idQuot
1298*BEWARE: the returned ideals may contain incorrectly ordered polys !
1299*
1300*/
1301static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
1302                               BOOLEAN *addOnlyOne, int *kkmax)
1303{
1304  ideal temph1;
1305  poly     p,q = NULL;
1306  int i,l,ll,k,kkk,kmax;
1307  int j = 0;
1308  int k1 = id_RankFreeModule(h1,currRing);
1309  int k2 = id_RankFreeModule(h2,currRing);
1310  tHomog   hom=isNotHomog;
1311
1312  k=si_max(k1,k2);
1313  if (k==0)
1314    k = 1;
1315  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
1316
1317  intvec * weights;
1318  hom = (tHomog)idHomModule(h1,currQuotient,&weights);
1319  if (/**addOnlyOne &&*/ (!h1IsStb))
1320    temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
1321  else
1322    temph1 = idCopy(h1);
1323  if (weights!=NULL) delete weights;
1324  idTest(temph1);
1325/*--- making a single vector from h2 ---------------------*/
1326  for (i=0; i<IDELEMS(h2); i++)
1327  {
1328    if (h2->m[i] != NULL)
1329    {
1330      p = pCopy(h2->m[i]);
1331      if (k2 == 0)
1332        p_Shift(&p,j*k+1,currRing);
1333      else
1334        p_Shift(&p,j*k,currRing);
1335      q = pAdd(q,p);
1336      j++;
1337    }
1338  }
1339  *kkmax = kmax = j*k+1;
1340/*--- adding a monomial for the result (syzygy) ----------*/
1341  p = q;
1342  while (pNext(p)!=NULL) pIter(p);
1343  pNext(p) = pOne();
1344  pIter(p);
1345  pSetComp(p,kmax);
1346  pSetmComp(p);
1347/*--- constructing the big matrix ------------------------*/
1348  ideal h4 = idInit(16,kmax+k-1);
1349  h4->m[0] = q;
1350  if (k2 == 0)
1351  {
1352    if (k > IDELEMS(h4))
1353    {
1354      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
1355      IDELEMS(h4) = k;
1356    }
1357    for (i=1; i<k; i++)
1358    {
1359      if (h4->m[i-1]!=NULL)
1360      {
1361        p = pCopy_noCheck(h4->m[i-1]);
1362        p_Shift(&p,1,currRing);
1363        h4->m[i] = p;
1364      }
1365    }
1366  }
1367  idSkipZeroes(h4);
1368  kkk = IDELEMS(h4);
1369  i = IDELEMS(temph1);
1370  for (l=0; l<i; l++)
1371  {
1372    if(temph1->m[l]!=NULL)
1373    {
1374      for (ll=0; ll<j; ll++)
1375      {
1376        p = pCopy(temph1->m[l]);
1377        if (k1 == 0)
1378          p_Shift(&p,ll*k+1,currRing);
1379        else
1380          p_Shift(&p,ll*k,currRing);
1381        if (kkk >= IDELEMS(h4))
1382        {
1383          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
1384          IDELEMS(h4) += 16;
1385        }
1386        h4->m[kkk] = p;
1387        kkk++;
1388      }
1389    }
1390  }
1391/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
1392  if (*addOnlyOne)
1393  {
1394    idSkipZeroes(h4);
1395    p = h4->m[0];
1396    for (i=0;i<IDELEMS(h4)-1;i++)
1397    {
1398      h4->m[i] = h4->m[i+1];
1399    }
1400    h4->m[IDELEMS(h4)-1] = p;
1401    test |= Sy_bit(OPT_SB_1);
1402  }
1403  idDelete(&temph1);
1404  return h4;
1405}
1406/*2
1407*computes the quotient of h1,h2
1408*/
1409ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
1410{
1411  // first check for special case h1:(0)
1412  if (idIs0(h2))
1413  {
1414    ideal res;
1415    if (resultIsIdeal)
1416    {
1417      res = idInit(1,1);
1418      res->m[0] = pOne();
1419    }
1420    else
1421      res = idFreeModule(h1->rank);
1422    return res;
1423  }
1424  BITSET old_test=test;
1425  int i,l,ll,k,kkk,kmax;
1426  BOOLEAN  addOnlyOne=TRUE;
1427  tHomog   hom=isNotHomog;
1428  intvec * weights1;
1429
1430  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
1431
1432  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
1433
1434  ring orig_ring=currRing;
1435  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE);  rChangeCurrRing(syz_ring);
1436  rSetSyzComp(kmax-1,syz_ring);
1437  if (orig_ring!=syz_ring)
1438  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring, syz_ring);
1439    s_h4 = idrMoveR(s_h4,orig_ring, syz_ring);
1440  idTest(s_h4);
1441  #if 0
1442  void ipPrint_MA0(matrix m, const char *name);
1443  matrix m=idModule2Matrix(idCopy(s_h4));
1444  PrintS("start:\n");
1445  ipPrint_MA0(m,"Q");
1446  idDelete((ideal *)&m);
1447  PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
1448  #endif
1449  ideal s_h3;
1450  if (addOnlyOne)
1451  {
1452    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
1453  }
1454  else
1455  {
1456    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
1457  }
1458  test = old_test;
1459  #if 0
1460  // only together with the above debug stuff
1461  idSkipZeroes(s_h3);
1462  m=idModule2Matrix(idCopy(s_h3));
1463  Print("result, kmax=%d:\n",kmax);
1464  ipPrint_MA0(m,"S");
1465  idDelete((ideal *)&m);
1466  #endif
1467  idTest(s_h3);
1468  if (weights1!=NULL) delete weights1;
1469  idDelete(&s_h4);
1470
1471  for (i=0;i<IDELEMS(s_h3);i++)
1472  {
1473    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
1474    {
1475      if (resultIsIdeal)
1476        p_Shift(&s_h3->m[i],-kmax,currRing);
1477      else
1478        p_Shift(&s_h3->m[i],-kmax+1,currRing);
1479    }
1480    else
1481      p_Delete(&s_h3->m[i],currRing);
1482  }
1483  if (resultIsIdeal)
1484    s_h3->rank = 1;
1485  else
1486    s_h3->rank = h1->rank;
1487  if(syz_ring!=orig_ring)
1488  {
1489    rChangeCurrRing(orig_ring);
1490    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
1491    rDelete(syz_ring);
1492  }
1493  idSkipZeroes(s_h3);
1494  idTest(s_h3);
1495  return s_h3;
1496}
1497
1498/*2
1499* eliminate delVar (product of vars) in h1
1500*/
1501ideal idElimination (ideal h1,poly delVar,intvec *hilb)
1502{
1503  int    i,j=0,k,l;
1504  ideal  h,hh, h3;
1505  int    *ord,*block0,*block1;
1506  int    ordersize=2;
1507  int    **wv;
1508  tHomog hom;
1509  intvec * w;
1510  ring tmpR;
1511  ring origR = currRing;
1512
1513  if (delVar==NULL)
1514  {
1515    return idCopy(h1);
1516  }
1517  if ((currQuotient!=NULL) && rIsPluralRing(origR))
1518  {
1519    WerrorS("cannot eliminate in a qring");
1520    return idCopy(h1);
1521  }
1522  if (idIs0(h1)) return idInit(1,h1->rank);
1523#ifdef HAVE_PLURAL
1524  if (rIsPluralRing(origR))
1525    /* in the NC case, we have to check the admissibility of */
1526    /* the subalgebra to be intersected with */
1527  {
1528    if ((ncRingType(origR) != nc_skew) && (ncRingType(origR) != nc_exterior)) /* in (quasi)-commutative algebras every subalgebra is admissible */
1529    {
1530      if (nc_CheckSubalgebra(delVar,origR))
1531      {
1532        WerrorS("no elimination is possible: subalgebra is not admissible");
1533        return idCopy(h1);
1534      }
1535    }
1536  }
1537#endif
1538  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
1539  h3=idInit(16,h1->rank);
1540  for (k=0;; k++)
1541  {
1542    if (origR->order[k]!=0) ordersize++;
1543    else break;
1544  }
1545#if 0
1546  if (rIsPluralRing(origR)) // we have too keep the odering: it may be needed
1547                            // for G-algebra
1548  {
1549    for (k=0;k<ordersize-1; k++)
1550    {
1551      block0[k+1] = origR->block0[k];
1552      block1[k+1] = origR->block1[k];
1553      ord[k+1] = origR->order[k];
1554      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
1555    }
1556  }
1557  else
1558  {
1559    block0[1] = 1;
1560    block1[1] = (currRing->N);
1561    if (origR->OrdSgn==1) ord[1] = ringorder_wp;
1562    else                  ord[1] = ringorder_ws;
1563    wv[1]=(int*)omAlloc0((currRing->N)*sizeof(int));
1564    double wNsqr = (double)2.0 / (double)(currRing->N);
1565    wFunctional = wFunctionalBuch;
1566    int  *x= (int * )omAlloc(2 * ((currRing->N) + 1) * sizeof(int));
1567    int sl=IDELEMS(h1) - 1;
1568    wCall(h1->m, sl, x, wNsqr);
1569    for (sl = (currRing->N); sl!=0; sl--)
1570      wv[1][sl-1] = x[sl + (currRing->N) + 1];
1571    omFreeSize((ADDRESS)x, 2 * ((currRing->N) + 1) * sizeof(int));
1572
1573    ord[2]=ringorder_C;
1574    ord[3]=0;
1575  }
1576#else
1577#endif
1578  if ((hom==TRUE) && (origR->OrdSgn==1) && (!rIsPluralRing(origR)))
1579  {
1580    #if 1
1581    // we change to an ordering:
1582    // aa(1,1,1,...,0,0,0),wp(...),C
1583    // this seems to be better than version 2 below,
1584    // according to Tst/../elimiate_[3568].tat (- 17 %)
1585    ord=(int*)omAlloc0(4*sizeof(int));
1586    block0=(int*)omAlloc0(4*sizeof(int));
1587    block1=(int*)omAlloc0(4*sizeof(int));
1588    wv=(int**) omAlloc0(4*sizeof(int**));
1589    block0[0] = block0[1] = 1;
1590    block1[0] = block1[1] = rVar(origR);
1591    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1592    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
1593    // ignore it
1594    ord[0] = ringorder_aa;
1595    for (j=0;j<rVar(origR);j++)
1596      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
1597    BOOLEAN wp=FALSE;
1598    for (j=0;j<rVar(origR);j++)
1599      if (pWeight(j+1,origR)!=1) { wp=TRUE;break; }
1600    if (wp)
1601    {
1602      wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1603      for (j=0;j<rVar(origR);j++)
1604        wv[1][j]=pWeight(j+1,origR);
1605      ord[1] = ringorder_wp;
1606    }
1607    else
1608      ord[1] = ringorder_dp;
1609    #else
1610    // we change to an ordering:
1611    // a(w1,...wn),wp(1,...0.....),C
1612    ord=(int*)omAlloc0(4*sizeof(int));
1613    block0=(int*)omAlloc0(4*sizeof(int));
1614    block1=(int*)omAlloc0(4*sizeof(int));
1615    wv=(int**) omAlloc0(4*sizeof(int**));
1616    block0[0] = block0[1] = 1;
1617    block1[0] = block1[1] = rVar(origR);
1618    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1619    wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1620    ord[0] = ringorder_a;
1621    for (j=0;j<rVar(origR);j++)
1622      wv[0][j]=pWeight(j+1,origR);
1623    ord[1] = ringorder_wp;
1624    for (j=0;j<rVar(origR);j++)
1625      if (pGetExp(delVar,j+1)!=0) wv[1][j]=1;
1626    #endif
1627    ord[2] = ringorder_C;
1628    ord[3] = 0;
1629  }
1630  else
1631  {
1632    // we change to an ordering:
1633    // aa(....),orig_ordering
1634    ord=(int*)omAlloc0(ordersize*sizeof(int));
1635    block0=(int*)omAlloc0(ordersize*sizeof(int));
1636    block1=(int*)omAlloc0(ordersize*sizeof(int));
1637    wv=(int**) omAlloc0(ordersize*sizeof(int**));
1638    for (k=0;k<ordersize-1; k++)
1639    {
1640      block0[k+1] = origR->block0[k];
1641      block1[k+1] = origR->block1[k];
1642      ord[k+1] = origR->order[k];
1643      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
1644    }
1645    block0[0] = 1;
1646    block1[0] = rVar(origR);
1647    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1648    for (j=0;j<rVar(origR);j++)
1649      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
1650    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
1651    // ignore it
1652    ord[0] = ringorder_aa;
1653  }
1654  // fill in tmp ring to get back the data later on
1655  tmpR  = rCopy0(origR,FALSE,FALSE); // qring==NULL
1656  //rUnComplete(tmpR);
1657  tmpR->p_Procs=NULL;
1658  tmpR->order = ord;
1659  tmpR->block0 = block0;
1660  tmpR->block1 = block1;
1661  tmpR->wvhdl = wv;
1662  rComplete(tmpR, 1);
1663
1664#ifdef HAVE_PLURAL
1665  /* update nc structure on tmpR */
1666  if (rIsPluralRing(origR))
1667  {
1668    if ( nc_rComplete(origR, tmpR, false) ) // no quotient ideal!
1669    {
1670      Werror("no elimination is possible: ordering condition is violated");
1671      // cleanup
1672      rDelete(tmpR);
1673      if (w!=NULL)
1674        delete w;
1675      return idCopy(h1);
1676    }
1677  }
1678#endif
1679  // change into the new ring
1680  //pChangeRing((currRing->N),currRing->OrdSgn,ord,block0,block1,wv);
1681  rChangeCurrRing(tmpR);
1682
1683  //h = idInit(IDELEMS(h1),h1->rank);
1684  // fetch data from the old ring
1685  //for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
1686  h=idrCopyR(h1,origR,currRing);
1687  if (origR->qideal!=NULL)
1688  {
1689    WarnS("eliminate in q-ring: experimental");
1690    ideal q=idrCopyR(origR->qideal,origR,currRing);
1691    ideal s=idSimpleAdd(h,q);
1692    idDelete(&h);
1693    idDelete(&q);
1694    h=s;
1695  }
1696  // compute kStd
1697#if 1
1698  //rWrite(tmpR);PrintLn();
1699  BITSET save=test;
1700  //test |=1;
1701  //Print("h: %d gen, rk=%d\n",IDELEMS(h),h->rank);
1702  //extern char * showOption();
1703  //Print("%s\n",showOption());
1704  hh = kStd(h,NULL,hom,&w,hilb);
1705  test=save;
1706  idDelete(&h);
1707#else
1708  extern ideal kGroebner(ideal F, ideal Q);
1709  hh=kGroebner(h,NULL);
1710#endif
1711  // go back to the original ring
1712  rChangeCurrRing(origR);
1713  i = IDELEMS(hh)-1;
1714  while ((i >= 0) && (hh->m[i] == NULL)) i--;
1715  j = -1;
1716  // fetch data from temp ring
1717  for (k=0; k<=i; k++)
1718  {
1719    l=(currRing->N);
1720    while ((l>0) && (p_GetExp( hh->m[k],l,tmpR)*pGetExp(delVar,l)==0)) l--;
1721    if (l==0)
1722    {
1723      j++;
1724      if (j >= IDELEMS(h3))
1725      {
1726        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
1727        IDELEMS(h3) += 16;
1728      }
1729      h3->m[j] = prMoveR( hh->m[k], tmpR,origR);
1730      hh->m[k] = NULL;
1731    }
1732  }
1733  id_Delete(&hh, tmpR);
1734  idSkipZeroes(h3);
1735  rDelete(tmpR);
1736  if (w!=NULL)
1737    delete w;
1738  return h3;
1739}
1740
1741/*2
1742* compute the which-th ar-minor of the matrix a
1743*/
1744poly idMinor(matrix a, int ar, unsigned long which, ideal R)
1745{
1746  int     i,j,k,size;
1747  unsigned long curr;
1748  int *rowchoise,*colchoise;
1749  BOOLEAN rowch,colch;
1750  ideal result;
1751  matrix tmp;
1752  poly p,q;
1753
1754  i = binom(a->rows(),ar);
1755  j = binom(a->cols(),ar);
1756
1757  rowchoise=(int *)omAlloc(ar*sizeof(int));
1758  colchoise=(int *)omAlloc(ar*sizeof(int));
1759  if ((i>512) || (j>512) || (i*j >512)) size=512;
1760  else size=i*j;
1761  result=idInit(size,1);
1762  tmp=mpNew(ar,ar);
1763  k = 0; /* the index in result*/
1764  curr = 0; /* index of current minor */
1765  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
1766  while (!rowch)
1767  {
1768    idInitChoise(ar,1,a->cols(),&colch,colchoise);
1769    while (!colch)
1770    {
1771      if (curr == which)
1772      {
1773        for (i=1; i<=ar; i++)
1774        {
1775          for (j=1; j<=ar; j++)
1776          {
1777            MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
1778          }
1779        }
1780        p = mp_DetBareiss(tmp,currRing);
1781        if (p!=NULL)
1782        {
1783          if (R!=NULL)
1784          {
1785            q = p;
1786            p = kNF(R,currQuotient,q);
1787            p_Delete(&q,currRing);
1788          }
1789          /*delete the matrix tmp*/
1790          for (i=1; i<=ar; i++)
1791          {
1792            for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
1793          }
1794          idDelete((ideal*)&tmp);
1795          omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
1796          omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
1797          return (p);
1798        }
1799      }
1800      curr++;
1801      idGetNextChoise(ar,a->cols(),&colch,colchoise);
1802    }
1803    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
1804  }
1805  return (poly) 1;
1806}
1807
1808#ifdef WITH_OLD_MINOR
1809/*2
1810* compute all ar-minors of the matrix a
1811*/
1812ideal idMinors(matrix a, int ar, ideal R)
1813{
1814  int     i,j,k,size;
1815  int *rowchoise,*colchoise;
1816  BOOLEAN rowch,colch;
1817  ideal result;
1818  matrix tmp;
1819  poly p,q;
1820
1821  i = binom(a->rows(),ar);
1822  j = binom(a->cols(),ar);
1823
1824  rowchoise=(int *)omAlloc(ar*sizeof(int));
1825  colchoise=(int *)omAlloc(ar*sizeof(int));
1826  if ((i>512) || (j>512) || (i*j >512)) size=512;
1827  else size=i*j;
1828  result=idInit(size,1);
1829  tmp=mpNew(ar,ar);
1830  k = 0; /* the index in result*/
1831  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
1832  while (!rowch)
1833  {
1834    idInitChoise(ar,1,a->cols(),&colch,colchoise);
1835    while (!colch)
1836    {
1837      for (i=1; i<=ar; i++)
1838      {
1839        for (j=1; j<=ar; j++)
1840        {
1841          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
1842        }
1843      }
1844      p = mp_DetBareiss(tmp,vcurrRing);
1845      if (p!=NULL)
1846      {
1847        if (R!=NULL)
1848        {
1849          q = p;
1850          p = kNF(R,currQuotient,q);
1851          p_Delete(&q,currRing);
1852        }
1853        if (p!=NULL)
1854        {
1855          if (k>=size)
1856          {
1857            pEnlargeSet(&result->m,size,32);
1858            size += 32;
1859          }
1860          result->m[k] = p;
1861          k++;
1862        }
1863      }
1864      idGetNextChoise(ar,a->cols(),&colch,colchoise);
1865    }
1866    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
1867  }
1868  /*delete the matrix tmp*/
1869  for (i=1; i<=ar; i++)
1870  {
1871    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
1872  }
1873  idDelete((ideal*)&tmp);
1874  if (k==0)
1875  {
1876    k=1;
1877    result->m[0]=NULL;
1878  }
1879  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
1880  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
1881  pEnlargeSet(&result->m,size,k-size);
1882  IDELEMS(result) = k;
1883  return (result);
1884}
1885#else
1886/*2
1887* compute all ar-minors of the matrix a
1888* the caller of mpRecMin
1889* the elements of the result are not in R (if R!=NULL)
1890*/
1891ideal idMinors(matrix a, int ar, ideal R)
1892{
1893  int elems=0;
1894  int r=a->nrows,c=a->ncols;
1895  int i;
1896  matrix b;
1897  ideal result,h;
1898  ring origR;
1899  ring tmpR;
1900  long bound;
1901
1902  if((ar<=0) || (ar>r) || (ar>c))
1903  {
1904    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
1905    return NULL;
1906  }
1907  h = idMatrix2Module(mp_Copy(a,currRing));
1908  bound = sm_ExpBound(h,c,r,ar,currRing);
1909  idDelete(&h);
1910  tmpR=sm_RingChange(origR,bound);
1911  b = mpNew(r,c);
1912  for (i=r*c-1;i>=0;i--)
1913  {
1914    if (a->m[i])
1915      b->m[i] = prCopyR(a->m[i],origR,currRing);
1916  }
1917  if (R!=NULL)
1918  {
1919    R = idrCopyR(R,origR,currRing);
1920    //if (ar>1) // otherwise done in mpMinorToResult
1921    //{
1922    //  matrix bb=(matrix)kNF(R,currQuotient,(ideal)b);
1923    //  bb->rank=b->rank; bb->nrows=b->nrows; bb->ncols=b->ncols;
1924    //  idDelete((ideal*)&b); b=bb;
1925    //}
1926  }
1927  result=idInit(32,1);
1928  if(ar>1) mp_RecMin(ar-1,result,elems,b,r,c,NULL,R,currRing);
1929  else mp_MinorToResult(result,elems,b,r,c,R,currRing);
1930  idDelete((ideal *)&b);
1931  if (R!=NULL) idDelete(&R);
1932  idSkipZeroes(result);
1933  rChangeCurrRing(origR);
1934  result = idrMoveR(result,tmpR,origR);
1935  sm_KillModifiedRing(tmpR);
1936  idTest(result);
1937  return result;
1938}
1939#endif
1940
1941/*2
1942*returns TRUE if id1 is a submodule of id2
1943*/
1944BOOLEAN idIsSubModule(ideal id1,ideal id2)
1945{
1946  int i;
1947  poly p;
1948
1949  if (idIs0(id1)) return TRUE;
1950  for (i=0;i<IDELEMS(id1);i++)
1951  {
1952    if (id1->m[i] != NULL)
1953    {
1954      p = kNF(id2,currQuotient,id1->m[i]);
1955      if (p != NULL)
1956      {
1957        p_Delete(&p,currRing);
1958        return FALSE;
1959      }
1960    }
1961  }
1962  return TRUE;
1963}
1964
1965BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
1966{
1967  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
1968  if (idIs0(m)) return TRUE;
1969
1970  int cmax=-1;
1971  int i;
1972  poly p=NULL;
1973  int length=IDELEMS(m);
1974  polyset P=m->m;
1975  for (i=length-1;i>=0;i--)
1976  {
1977    p=P[i];
1978    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
1979  }
1980  if (w != NULL)
1981  if (w->length()+1 < cmax)
1982  {
1983    // Print("length: %d - %d \n", w->length(),cmax);
1984    return FALSE;
1985  }
1986
1987  if(w!=NULL)
1988    p_SetModDeg(w, currRing);
1989
1990  for (i=length-1;i>=0;i--)
1991  {
1992    p=P[i];
1993    poly q=p;
1994    if (p!=NULL)
1995    {
1996      int d=currRing->pFDeg(p,currRing);
1997      loop
1998      {
1999        pIter(p);
2000        if (p==NULL) break;
2001        if (d!=currRing->pFDeg(p,currRing))
2002        {
2003          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
2004          if(w!=NULL)
2005            p_SetModDeg(NULL, currRing);
2006          return FALSE;
2007        }
2008      }
2009    }
2010  }
2011
2012  if(w!=NULL)
2013    p_SetModDeg(NULL, currRing);
2014
2015  return TRUE;
2016}
2017
2018ideal idSeries(int n,ideal M,matrix U,intvec *w)
2019{
2020  for(int i=IDELEMS(M)-1;i>=0;i--)
2021  {
2022    if(U==NULL)
2023      M->m[i]=pSeries(n,M->m[i],NULL,w);
2024    else
2025    {
2026      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
2027      MATELEM(U,i+1,i+1)=NULL;
2028    }
2029  }
2030  if(U!=NULL)
2031    idDelete((ideal*)&U);
2032  return M;
2033}
2034
2035matrix idDiff(matrix i, int k)
2036{
2037  int e=MATCOLS(i)*MATROWS(i);
2038  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2039  r->rank=i->rank;
2040  int j;
2041  for(j=0; j<e; j++)
2042  {
2043    r->m[j]=pDiff(i->m[j],k);
2044  }
2045  return r;
2046}
2047
2048matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2049{
2050  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2051  int i,j;
2052  for(i=0; i<IDELEMS(I); i++)
2053  {
2054    for(j=0; j<IDELEMS(J); j++)
2055    {
2056      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2057    }
2058  }
2059  return r;
2060}
2061
2062/*3
2063*handles for some ideal operations the ring/syzcomp managment
2064*returns all syzygies (componentwise-)shifted by -syzcomp
2065*or -syzcomp-1 (in case of ideals as input)
2066static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
2067{
2068  ring orig_ring=currRing;
2069  ring syz_ring=rAssure_SyzComp(orig_ring, TRUE); rChangeCurrRing(syz_ring);
2070  rSetSyzComp(length, syz_ring);
2071
2072  ideal s_temp;
2073  if (orig_ring!=syz_ring)
2074    s_temp=idrMoveR_NoSort(arg,orig_ring, syz_ring);
2075  else
2076    s_temp=arg;
2077
2078  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
2079  if (w!=NULL) delete w;
2080
2081  if (syz_ring!=orig_ring)
2082  {
2083    idDelete(&s_temp);
2084    rChangeCurrRing(orig_ring);
2085  }
2086
2087  idDelete(&temp);
2088  ideal temp1=idRingCopy(s_temp1,syz_ring);
2089
2090  if (syz_ring!=orig_ring)
2091  {
2092    rChangeCurrRing(syz_ring);
2093    idDelete(&s_temp1);
2094    rChangeCurrRing(orig_ring);
2095    rDelete(syz_ring);
2096  }
2097
2098  for (i=0;i<IDELEMS(temp1);i++)
2099  {
2100    if ((temp1->m[i]!=NULL)
2101    && (pGetComp(temp1->m[i])<=length))
2102    {
2103      pDelete(&(temp1->m[i]));
2104    }
2105    else
2106    {
2107      p_Shift(&(temp1->m[i]),-length,currRing);
2108    }
2109  }
2110  temp1->rank = rk;
2111  idSkipZeroes(temp1);
2112
2113  return temp1;
2114}
2115*/
2116/*2
2117* represents (h1+h2)/h2=h1/(h1 intersect h2)
2118*/
2119//ideal idModulo (ideal h2,ideal h1)
2120ideal idModulo (ideal h2,ideal h1, tHomog hom, intvec ** w)
2121{
2122  intvec *wtmp=NULL;
2123
2124  int i,j,k,rk,flength=0,slength,length;
2125  poly p,q;
2126
2127  if (idIs0(h2))
2128    return idFreeModule(si_max(1,h2->ncols));
2129  if (!idIs0(h1))
2130    flength = id_RankFreeModule(h1,currRing);
2131  slength = id_RankFreeModule(h2,currRing);
2132  length  = si_max(flength,slength);
2133  if (length==0)
2134  {
2135    length = 1;
2136  }
2137  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
2138  if ((w!=NULL)&&((*w)!=NULL))
2139  {
2140    //Print("input weights:");(*w)->show(1);PrintLn();
2141    int d;
2142    int k;
2143    wtmp=new intvec(length+IDELEMS(h2));
2144    for (i=0;i<length;i++)
2145      ((*wtmp)[i])=(**w)[i];
2146    for (i=0;i<IDELEMS(h2);i++)
2147    {
2148      poly p=h2->m[i];
2149      if (p!=NULL)
2150      {
2151        d = pDeg(p);
2152        k= pGetComp(p);
2153        if (slength>0) k--;
2154        d +=((**w)[k]);
2155        ((*wtmp)[i+length]) = d;
2156      }
2157    }
2158    //Print("weights:");wtmp->show(1);PrintLn();
2159  }
2160  for (i=0;i<IDELEMS(h2);i++)
2161  {
2162    temp->m[i] = pCopy(h2->m[i]);
2163    q = pOne();
2164    pSetComp(q,i+1+length);
2165    pSetmComp(q);
2166    if(temp->m[i]!=NULL)
2167    {
2168      if (slength==0) p_Shift(&(temp->m[i]),1,currRing);
2169      p = temp->m[i];
2170      while (pNext(p)!=NULL) pIter(p);
2171      pNext(p) = q;
2172    }
2173    else
2174      temp->m[i]=q;
2175  }
2176  rk = k = IDELEMS(h2);
2177  if (!idIs0(h1))
2178  {
2179    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
2180    IDELEMS(temp) += IDELEMS(h1);
2181    for (i=0;i<IDELEMS(h1);i++)
2182    {
2183      if (h1->m[i]!=NULL)
2184      {
2185        temp->m[k] = pCopy(h1->m[i]);
2186        if (flength==0) p_Shift(&(temp->m[k]),1,currRing);
2187        k++;
2188      }
2189    }
2190  }
2191
2192  ring orig_ring=currRing;
2193  ring syz_ring=rAssure_SyzComp(orig_ring, TRUE); rChangeCurrRing(syz_ring);
2194  rSetSyzComp(length, syz_ring);
2195  ideal s_temp;
2196
2197  if (syz_ring != orig_ring)
2198  {
2199    s_temp = idrMoveR_NoSort(temp, orig_ring, syz_ring);
2200  }
2201  else
2202  {
2203    s_temp = temp;
2204  }
2205
2206  idTest(s_temp);
2207  ideal s_temp1 = kStd(s_temp,currQuotient,hom,&wtmp,NULL,length);
2208
2209  //if (wtmp!=NULL)  Print("output weights:");wtmp->show(1);PrintLn();
2210  if ((w!=NULL) && (*w !=NULL) && (wtmp!=NULL))
2211  {
2212    delete *w;
2213    *w=new intvec(IDELEMS(h2));
2214    for (i=0;i<IDELEMS(h2);i++)
2215      ((**w)[i])=(*wtmp)[i+length];
2216  }
2217  if (wtmp!=NULL) delete wtmp;
2218
2219  for (i=0;i<IDELEMS(s_temp1);i++)
2220  {
2221    if ((s_temp1->m[i]!=NULL)
2222    && (pGetComp(s_temp1->m[i])<=length))
2223    {
2224      p_Delete(&(s_temp1->m[i]),currRing);
2225    }
2226    else
2227    {
2228      p_Shift(&(s_temp1->m[i]),-length,currRing);
2229    }
2230  }
2231  s_temp1->rank = rk;
2232  idSkipZeroes(s_temp1);
2233
2234  if (syz_ring!=orig_ring)
2235  {
2236    rChangeCurrRing(orig_ring);
2237    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring, orig_ring);
2238    rDelete(syz_ring);
2239    // Hmm ... here seems to be a memory leak
2240    // However, simply deleting it causes memory trouble
2241    // idDelete(&s_temp);
2242  }
2243  else
2244  {
2245    idDelete(&temp);
2246  }
2247  idTest(s_temp1);
2248  return s_temp1;
2249}
2250
2251/*
2252*computes module-weights for liftings of homogeneous modules
2253*/
2254intvec * idMWLift(ideal mod,intvec * weights)
2255{
2256  if (idIs0(mod)) return new intvec(2);
2257  int i=IDELEMS(mod);
2258  while ((i>0) && (mod->m[i-1]==NULL)) i--;
2259  intvec *result = new intvec(i+1);
2260  while (i>0)
2261  {
2262    (*result)[i]=currRing->pFDeg(mod->m[i],currRing)+(*weights)[pGetComp(mod->m[i])];
2263  }
2264  return result;
2265}
2266
2267/*2
2268*sorts the kbase for idCoef* in a special way (lexicographically
2269*with x_max,...,x_1)
2270*/
2271ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
2272{
2273  int i;
2274  ideal result;
2275
2276  if (idIs0(kBase)) return NULL;
2277  result = idInit(IDELEMS(kBase),kBase->rank);
2278  *convert = idSort(kBase,FALSE);
2279  for (i=0;i<(*convert)->length();i++)
2280  {
2281    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
2282  }
2283  return result;
2284}
2285
2286/*2
2287*returns the index of a given monom in the list of the special kbase
2288*/
2289int idIndexOfKBase(poly monom, ideal kbase)
2290{
2291  int j=IDELEMS(kbase);
2292
2293  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
2294  if (j==0) return -1;
2295  int i=(currRing->N);
2296  while (i>0)
2297  {
2298    loop
2299    {
2300      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
2301      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
2302      j--;
2303      if (j==0) return -1;
2304    }
2305    if (i==1)
2306    {
2307      while(j>0)
2308      {
2309        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
2310        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
2311        j--;
2312      }
2313    }
2314    i--;
2315  }
2316  return -1;
2317}
2318
2319/*2
2320*decomposes the monom in a part of coefficients described by the
2321*complement of how and a monom in variables occuring in how, the
2322*index of which in kbase is returned as integer pos (-1 if it don't
2323*exists)
2324*/
2325poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
2326{
2327  int i;
2328  poly coeff=pOne(), base=pOne();
2329
2330  for (i=1;i<=(currRing->N);i++)
2331  {
2332    if (pGetExp(how,i)>0)
2333    {
2334      pSetExp(base,i,pGetExp(monom,i));
2335    }
2336    else
2337    {
2338      pSetExp(coeff,i,pGetExp(monom,i));
2339    }
2340  }
2341  pSetComp(base,pGetComp(monom));
2342  pSetm(base);
2343  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
2344  pSetm(coeff);
2345  *pos = idIndexOfKBase(base,kbase);
2346  if (*pos<0)
2347    p_Delete(&coeff,currRing);
2348  p_Delete(&base,currRing);
2349  return coeff;
2350}
2351
2352/*2
2353*returns a matrix A of coefficients with kbase*A=arg
2354*if all monomials in variables of how occur in kbase
2355*the other are deleted
2356*/
2357matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
2358{
2359  matrix result;
2360  ideal tempKbase;
2361  poly p,q;
2362  intvec * convert;
2363  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
2364#if 0
2365  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
2366  if (idIs0(arg))
2367    return mpNew(i,1);
2368  while ((j>0) && (arg->m[j-1]==NULL)) j--;
2369  result = mpNew(i,j);
2370#else
2371  result = mpNew(i, j);
2372  while ((j>0) && (arg->m[j-1]==NULL)) j--;
2373#endif
2374
2375  tempKbase = idCreateSpecialKbase(kbase,&convert);
2376  for (k=0;k<j;k++)
2377  {
2378    p = arg->m[k];
2379    while (p!=NULL)
2380    {
2381      q = idDecompose(p,how,tempKbase,&pos);
2382      if (pos>=0)
2383      {
2384        MATELEM(result,(*convert)[pos],k+1) =
2385            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
2386      }
2387      else
2388        p_Delete(&q,currRing);
2389      pIter(p);
2390    }
2391  }
2392  idDelete(&tempKbase);
2393  return result;
2394}
2395
2396static void idDeleteComps(ideal arg,int* red_comp,int del)
2397// red_comp is an array [0..args->rank]
2398{
2399  int i,j;
2400  poly p;
2401
2402  for (i=IDELEMS(arg)-1;i>=0;i--)
2403  {
2404    p = arg->m[i];
2405    while (p!=NULL)
2406    {
2407      j = pGetComp(p);
2408      if (red_comp[j]!=j)
2409      {
2410        pSetComp(p,red_comp[j]);
2411        pSetmComp(p);
2412      }
2413      pIter(p);
2414    }
2415  }
2416  (arg->rank) -= del;
2417}
2418
2419/*2
2420* returns the presentation of an isomorphic, minimally
2421* embedded  module (arg represents the quotient!)
2422*/
2423ideal idMinEmbedding(ideal arg,BOOLEAN inPlace, intvec **w)
2424{
2425  if (idIs0(arg)) return idInit(1,arg->rank);
2426  int i,next_gen,next_comp;
2427  ideal res=arg;
2428  if (!inPlace) res = idCopy(arg);
2429  res->rank=si_max(res->rank,id_RankFreeModule(res,currRing));
2430  int *red_comp=(int*)omAlloc((res->rank+1)*sizeof(int));
2431  for (i=res->rank;i>=0;i--) red_comp[i]=i;
2432
2433  int del=0;
2434  loop
2435  {
2436    next_gen = id_ReadOutPivot(res, &next_comp, currRing);
2437    if (next_gen<0) break;
2438    del++;
2439    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
2440    for(i=next_comp+1;i<=arg->rank;i++) red_comp[i]--;
2441    if ((w !=NULL)&&(*w!=NULL))
2442    {
2443      for(i=next_comp;i<(*w)->length();i++) (**w)[i-1]=(**w)[i];
2444    }
2445  }
2446
2447  idDeleteComps(res,red_comp,del);
2448  idSkipZeroes(res);
2449  omFree(red_comp);
2450
2451  if ((w !=NULL)&&(*w!=NULL) &&(del>0))
2452  {
2453    intvec *wtmp=new intvec((*w)->length()-del);
2454    for(i=0;i<res->rank;i++) (*wtmp)[i]=(**w)[i];
2455    delete *w;
2456    *w=wtmp;
2457  }
2458  return res;
2459}
2460
2461#include <polys/clapsing.h>
2462
2463#ifdef HAVE_FACTORY
2464#if 0
2465poly id_GCD(poly f, poly g, const ring r)
2466{
2467  ring save_r=currRing;
2468  rChangeCurrRing(r);
2469  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
2470  intvec *w = NULL;
2471  ideal S=idSyzygies(I,testHomog,&w);
2472  if (w!=NULL) delete w;
2473  poly gg=pTakeOutComp(&(S->m[0]),2);
2474  idDelete(&S);
2475  poly gcd_p=singclap_pdivide(f,gg,r);
2476  p_Delete(&gg,r);
2477  rChangeCurrRing(save_r);
2478  return gcd_p;
2479}
2480#else
2481poly id_GCD(poly f, poly g, const ring r)
2482{
2483  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
2484  intvec *w = NULL;
2485
2486  ring save_r = currRing; rChangeCurrRing(r); ideal S=idSyzygies(I,testHomog,&w); rChangeCurrRing(save_r);   
2487   
2488  if (w!=NULL) delete w;
2489  poly gg=p_TakeOutComp(&(S->m[0]), 2, r);
2490  id_Delete(&S, r);
2491  poly gcd_p=singclap_pdivide(f,gg, r);
2492  p_Delete(&gg, r);
2493   
2494  return gcd_p;
2495}
2496#endif
2497#endif
2498
2499/*2
2500* xx,q: arrays of length 0..rl-1
2501* xx[i]: SB mod q[i]
2502* assume: char=0
2503* assume: q[i]!=0
2504* destroys xx
2505*/
2506#ifdef HAVE_FACTORY
2507ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring R)
2508{
2509  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
2510  ideal result=idInit(cnt,xx[0]->rank);
2511  result->nrows=xx[0]->nrows; // for lifting matrices
2512  result->ncols=xx[0]->ncols; // for lifting matrices
2513  int i,j;
2514  poly r,h,hh,res_p;
2515  number *x=(number *)omAlloc(rl*sizeof(number));
2516  for(i=cnt-1;i>=0;i--)
2517  {
2518    res_p=NULL;
2519    loop
2520    {
2521      r=NULL;
2522      for(j=rl-1;j>=0;j--)
2523      {
2524        h=xx[j]->m[i];
2525        if ((h!=NULL)
2526        &&((r==NULL)||(p_LmCmp(r,h,R)==-1)))
2527          r=h;
2528      }
2529      if (r==NULL) break;
2530      h=p_Head(r,R);
2531      for(j=rl-1;j>=0;j--)
2532      {
2533        hh=xx[j]->m[i];
2534        if ((hh!=NULL) && (p_LmCmp(r,hh,R)==0))
2535        {
2536          x[j]=pGetCoeff(hh);
2537          hh=p_LmFreeAndNext(hh,R);
2538          xx[j]->m[i]=hh;
2539        }
2540        else
2541          x[j]=n_Init(0, R->cf);
2542      }
2543      number n=n_ChineseRemainder(x,q,rl,R->cf);
2544      for(j=rl-1;j>=0;j--)
2545      {
2546        x[j]=NULL; // nlInit(0...) takes no memory
2547      }
2548      if (n_IsZero(n,R->cf)) p_Delete(&h,R);
2549      else
2550      {
2551        p_SetCoeff(h,n,R);
2552        //Print("new mon:");pWrite(h);
2553        res_p=p_Add_q(res_p,h,R);
2554      }
2555    }
2556    result->m[i]=res_p;
2557  }
2558  omFree(x);
2559  for(i=rl-1;i>=0;i--) id_Delete(&(xx[i]),R);
2560  omFree(xx);
2561  return result;
2562}
2563#endif
2564
2565#if 0
2566/*2
2567* xx,q: arrays of length 0..rl-1
2568* xx[i]: SB mod q[i]
2569* assume: char=0
2570* assume: q[i]!=0
2571* destroys xx
2572*/
2573#ifdef HAVE_FACTORY
2574ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring R)
2575{
2576  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
2577  ideal result=idInit(cnt,xx[0]->rank);
2578  result->nrows=xx[0]->nrows; // for lifting matrices
2579  result->ncols=xx[0]->ncols; // for lifting matrices
2580  int i,j;
2581  poly r,h,hh,res_p;
2582  number *x=(number *)omAlloc(rl*sizeof(number));
2583  for(i=cnt-1;i>=0;i--)
2584  {
2585    res_p=NULL;
2586    loop
2587    {
2588      r=NULL;
2589      for(j=rl-1;j>=0;j--)
2590      {
2591        h=xx[j]->m[i];
2592        if ((h!=NULL)
2593        &&((r==NULL)||(p_LmCmp(r,h,R)==-1)))
2594          r=h;
2595      }
2596      if (r==NULL) break;
2597      h=p_Head(r, R);
2598      for(j=rl-1;j>=0;j--)
2599      {
2600        hh=xx[j]->m[i];
2601        if ((hh!=NULL) && (p_LmCmp(r,hh, R)==0))
2602        {
2603          x[j]=p_GetCoeff(hh, R);
2604          hh=p_LmFreeAndNext(hh, R);
2605          xx[j]->m[i]=hh;
2606        }
2607        else
2608          x[j]=n_Init(0, R->cf); // is R->cf really n_Q???, yes!
2609      }
2610       
2611      number n=nChineseRemainder(x,q,rl, R->cf);
2612
2613      for(j=rl-1;j>=0;j--)
2614      {
2615        x[j]=NULL; // nlInit(0...) takes no memory
2616      }
2617      if (n_IsZero(n, R->cf)) p_Delete(&h, R);
2618      else
2619      {
2620        p_SetCoeff(h,n, R);
2621        //Print("new mon:");pWrite(h);
2622        res_p=p_Add_q(res_p, h, R);
2623      }
2624    }
2625    result->m[i]=res_p;
2626  }
2627  omFree(x);
2628  for(i=rl-1;i>=0;i--) id_Delete(&(xx[i]), R);
2629  omFree(xx);
2630  return result;
2631}
2632#endif
2633#endif
2634/* currently unsed:
2635ideal idChineseRemainder(ideal *xx, intvec *iv)
2636{
2637  int rl=iv->length();
2638  number *q=(number *)omAlloc(rl*sizeof(number));
2639  int i;
2640  for(i=0; i<rl; i++)
2641  {
2642    q[i]=nInit((*iv)[i]);
2643  }
2644  return idChineseRemainder(xx,q,rl);
2645}
2646*/
2647/*
2648 * lift ideal with coeffs over Z (mod N) to Q via Farey
2649 */
2650ideal id_Farey(ideal x, number N, const ring r)
2651{
2652  int cnt=IDELEMS(x)*x->nrows;
2653  ideal result=idInit(cnt,x->rank);
2654  result->nrows=x->nrows; // for lifting matrices
2655  result->ncols=x->ncols; // for lifting matrices
2656
2657  int i;
2658  for(i=cnt-1;i>=0;i--)
2659  {
2660    poly h=p_Copy(x->m[i],r);
2661    result->m[i]=h;
2662    while(h!=NULL)
2663    {
2664      number c=pGetCoeff(h);
2665      pSetCoeff0(h,n_Farey(c,N,r->cf));
2666      n_Delete(&c,r->cf);
2667      pIter(h);
2668    }
2669    while((result->m[i]!=NULL)&&(n_IsZero(pGetCoeff(result->m[i]),r->cf)))
2670    {
2671      p_LmDelete(&(result->m[i]),r);
2672    }
2673    h=result->m[i];
2674    while((h!=NULL) && (pNext(h)!=NULL))
2675    {
2676      if(n_IsZero(pGetCoeff(pNext(h)),r->cf))
2677      {
2678        p_LmDelete(&pNext(h),r);
2679      }
2680      else pIter(h);
2681    }
2682  }
2683  return result;
2684}
2685
2686
2687
2688
2689// uses glabl vars via pSetModDeg
2690/*
2691BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
2692{
2693  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
2694  if (idIs0(m)) return TRUE;
2695
2696  int cmax=-1;
2697  int i;
2698  poly p=NULL;
2699  int length=IDELEMS(m);
2700  poly* P=m->m;
2701  for (i=length-1;i>=0;i--)
2702  {
2703    p=P[i];
2704    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
2705  }
2706  if (w != NULL)
2707  if (w->length()+1 < cmax)
2708  {
2709    // Print("length: %d - %d \n", w->length(),cmax);
2710    return FALSE;
2711  }
2712
2713  if(w!=NULL)
2714    p_SetModDeg(w, currRing);
2715
2716  for (i=length-1;i>=0;i--)
2717  {
2718    p=P[i];
2719    poly q=p;
2720    if (p!=NULL)
2721    {
2722      int d=p_FDeg(p,currRing);
2723      loop
2724      {
2725        pIter(p);
2726        if (p==NULL) break;
2727        if (d!=p_FDeg(p,currRing))
2728        {
2729          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
2730          if(w!=NULL)
2731            p_SetModDeg(NULL, currRing);
2732          return FALSE;
2733        }
2734      }
2735    }
2736  }
2737
2738  if(w!=NULL)
2739    p_SetModDeg(NULL, currRing);
2740
2741  return TRUE;
2742}
2743*/
2744
2745
2746
Note: See TracBrowser for help on using the repository browser.