source: git/kernel/ideals.cc @ 1505bd

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