source: git/kernel/ideals.cc @ 8bb03b

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