source: git/kernel/ideals.cc @ 731d628

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