source: git/kernel/ideals.cc @ c93fda

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