source: git/kernel/ideals.cc @ bead81

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