source: git/libpolys/polys/simpleideals.cc @ f7a975

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