source: git/kernel/ideals.cc @ 8eabf99

spielwiese
Last change on this file since 8eabf99 was bafaec0, checked in by Hans Schönemann <hannes@…>, 14 years ago
module -> matrix optimized git-svn-id: file:///usr/local/Singular/svn/trunk@12694 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 85.8 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))
1849  {
1850    if (unit!=NULL)
1851    {
1852      i=IDELEMS(submod);
1853      *unit=mpNew(i,i);
1854      for (j=i;j>0;j--)
1855      {
1856        MATELEM(*unit,j,j)=pOne();
1857      }
1858    }
1859    if (rest!=NULL)
1860    {
1861      *rest=idCopy(submod);
1862    }
1863    return idInit(1,mod->rank);
1864  }
1865  if (unit!=NULL)
1866  {
1867    comps_to_add = IDELEMS(submod);
1868    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
1869      comps_to_add--;
1870  }
1871  k=idRankFreeModule(mod);
1872  if  ((k!=0) && (lsmod==0)) lsmod=1;
1873  k=si_max(k,(int)mod->rank);
1874
1875  ring orig_ring=currRing;
1876  ring syz_ring=rCurrRingAssure_SyzComp();
1877  rSetSyzComp(k);
1878
1879  ideal s_mod, s_temp;
1880  if (orig_ring != syz_ring)
1881  {
1882    s_mod = idrCopyR_NoSort(mod,orig_ring);
1883    s_temp = idrCopyR_NoSort(submod,orig_ring);
1884  }
1885  else
1886  {
1887    s_mod = mod;
1888    s_temp = idCopy(submod);
1889  }
1890  ideal s_h3;
1891  if (isSB)
1892  {
1893    s_h3 = idCopy(s_mod);
1894    idPrepareStd(s_h3, k+comps_to_add);
1895  }
1896  else
1897  {
1898    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
1899  }
1900  if (!goodShape)
1901  {
1902    for (j=0;j<IDELEMS(s_h3);j++)
1903    {
1904      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
1905        pDelete(&(s_h3->m[j]));
1906    }
1907  }
1908  idSkipZeroes(s_h3);
1909  if (lsmod==0)
1910  {
1911    for (j=IDELEMS(s_temp);j>0;j--)
1912    {
1913      if (s_temp->m[j-1]!=NULL)
1914        pShift(&(s_temp->m[j-1]),1);
1915    }
1916  }
1917  if (unit!=NULL)
1918  {
1919    for(j = 0;j<comps_to_add;j++)
1920    {
1921      p = s_temp->m[j];
1922      if (p!=NULL)
1923      {
1924        while (pNext(p)!=NULL) pIter(p);
1925        pNext(p) = pOne();
1926        pIter(p);
1927        pSetComp(p,1+j+k);
1928        pSetmComp(p);
1929        p = pNeg(p);
1930      }
1931    }
1932  }
1933  ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
1934  s_result->rank = s_h3->rank;
1935  ideal s_rest = idInit(IDELEMS(s_result),k);
1936  idDelete(&s_h3);
1937  idDelete(&s_temp);
1938
1939  for (j=0;j<IDELEMS(s_result);j++)
1940  {
1941    if (s_result->m[j]!=NULL)
1942    {
1943      if (pGetComp(s_result->m[j])<=k)
1944      {
1945        if (!divide)
1946        {
1947          if (isSB)
1948          {
1949            WarnS("first module not a standardbasis\n"
1950              "// ** or second not a proper submodule");
1951          }
1952          else
1953            WerrorS("2nd module does not lie in the first");
1954          idDelete(&s_result);
1955          idDelete(&s_rest);
1956          s_result=idInit(IDELEMS(submod),submod->rank);
1957          break;
1958        }
1959        else
1960        {
1961          p = s_rest->m[j] = s_result->m[j];
1962          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1963          s_result->m[j] = pNext(p);
1964          pNext(p) = NULL;
1965        }
1966      }
1967      pShift(&(s_result->m[j]),-k);
1968      pNeg(s_result->m[j]);
1969    }
1970  }
1971  if ((lsmod==0) && (!idIs0(s_rest)))
1972  {
1973    for (j=IDELEMS(s_rest);j>0;j--)
1974    {
1975      if (s_rest->m[j-1]!=NULL)
1976      {
1977        pShift(&(s_rest->m[j-1]),-1);
1978        s_rest->m[j-1] = s_rest->m[j-1];
1979      }
1980    }
1981  }
1982  if(syz_ring!=orig_ring)
1983  {
1984    idDelete(&s_mod);
1985    rChangeCurrRing(orig_ring);
1986    s_result = idrMoveR_NoSort(s_result, syz_ring);
1987    s_rest = idrMoveR_NoSort(s_rest, syz_ring);
1988    rKill(syz_ring);
1989  }
1990  if (rest!=NULL)
1991    *rest = s_rest;
1992  else
1993    idDelete(&s_rest);
1994//idPrint(s_result);
1995  if (unit!=NULL)
1996  {
1997    *unit=mpNew(comps_to_add,comps_to_add);
1998    int i;
1999    for(i=0;i<IDELEMS(s_result);i++)
2000    {
2001      poly p=s_result->m[i];
2002      poly q=NULL;
2003      while(p!=NULL)
2004      {
2005        if(pGetComp(p)<=comps_to_add)
2006        {
2007          pSetComp(p,0);
2008          if (q!=NULL)
2009          {
2010            pNext(q)=pNext(p);
2011          }
2012          else
2013          {
2014            pIter(s_result->m[i]);
2015          }
2016          pNext(p)=NULL;
2017          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
2018          if(q!=NULL)   p=pNext(q);
2019          else          p=s_result->m[i];
2020        }
2021        else
2022        {
2023          q=p;
2024          pIter(p);
2025        }
2026      }
2027      pShift(&s_result->m[i],-comps_to_add);
2028    }
2029  }
2030  return s_result;
2031}
2032
2033/*2
2034*computes division of P by Q with remainder up to (w-weighted) degree n
2035*P, Q, and w are not changed
2036*/
2037void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
2038{
2039  long N=0;
2040  int i;
2041  for(i=IDELEMS(Q)-1;i>=0;i--)
2042    if(w==NULL)
2043      N=si_max(N,pDeg(Q->m[i]));
2044    else
2045      N=si_max(N,pDegW(Q->m[i],w));
2046  N+=n;
2047
2048  T=mpNew(IDELEMS(Q),IDELEMS(P));
2049  R=idInit(IDELEMS(P),P->rank);
2050
2051  for(i=IDELEMS(P)-1;i>=0;i--)
2052  {
2053    poly p;
2054    if(w==NULL)
2055      p=ppJet(P->m[i],N);
2056    else
2057      p=ppJetW(P->m[i],N,w);
2058
2059    int j=IDELEMS(Q)-1;
2060    while(p!=NULL)
2061    {
2062      if(pDivisibleBy(Q->m[j],p))
2063      {
2064        poly p0=pDivideM(pHead(p),pHead(Q->m[j]));
2065        if(w==NULL)
2066          p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
2067        else
2068          p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
2069        pNormalize(p);
2070        if((w==NULL)&&(pDeg(p0)>n)||(w!=NULL)&&(pDegW(p0,w)>n))
2071          pDelete(&p0);
2072        else
2073          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
2074        j=IDELEMS(Q)-1;
2075      }
2076      else
2077      {
2078        if(j==0)
2079        {
2080          poly p0=p;
2081          pIter(p);
2082          pNext(p0)=NULL;
2083          if(((w==NULL)&&(pDeg(p0)>n))
2084          ||((w!=NULL)&&(pDegW(p0,w)>n)))
2085            pDelete(&p0);
2086          else
2087            R->m[i]=pAdd(R->m[i],p0);
2088          j=IDELEMS(Q)-1;
2089        }
2090        else
2091          j--;
2092      }
2093    }
2094  }
2095}
2096
2097/*2
2098*computes the quotient of h1,h2 : internal routine for idQuot
2099*BEWARE: the returned ideals may contain incorrectly ordered polys !
2100*
2101*/
2102static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
2103                               BOOLEAN *addOnlyOne, int *kkmax)
2104{
2105  ideal temph1;
2106  poly     p,q = NULL;
2107  int i,l,ll,k,kkk,kmax;
2108  int j = 0;
2109  int k1 = idRankFreeModule(h1);
2110  int k2 = idRankFreeModule(h2);
2111  tHomog   hom=isNotHomog;
2112
2113  k=si_max(k1,k2);
2114  if (k==0)
2115    k = 1;
2116  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
2117
2118  intvec * weights;
2119  hom = (tHomog)idHomModule(h1,currQuotient,&weights);
2120  if (/**addOnlyOne &&*/ (!h1IsStb))
2121    temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
2122  else
2123    temph1 = idCopy(h1);
2124  if (weights!=NULL) delete weights;
2125  idTest(temph1);
2126/*--- making a single vector from h2 ---------------------*/
2127  for (i=0; i<IDELEMS(h2); i++)
2128  {
2129    if (h2->m[i] != NULL)
2130    {
2131      p = pCopy(h2->m[i]);
2132      if (k2 == 0)
2133        pShift(&p,j*k+1);
2134      else
2135        pShift(&p,j*k);
2136      q = pAdd(q,p);
2137      j++;
2138    }
2139  }
2140  *kkmax = kmax = j*k+1;
2141/*--- adding a monomial for the result (syzygy) ----------*/
2142  p = q;
2143  while (pNext(p)!=NULL) pIter(p);
2144  pNext(p) = pOne();
2145  pIter(p);
2146  pSetComp(p,kmax);
2147  pSetmComp(p);
2148/*--- constructing the big matrix ------------------------*/
2149  ideal h4 = idInit(16,kmax+k-1);
2150  h4->m[0] = q;
2151  if (k2 == 0)
2152  {
2153    if (k > IDELEMS(h4))
2154    {
2155      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
2156      IDELEMS(h4) = k;
2157    }
2158    for (i=1; i<k; i++)
2159    {
2160      if (h4->m[i-1]!=NULL)
2161      {
2162        p = pCopy_noCheck(h4->m[i-1]);
2163        pShift(&p,1);
2164        h4->m[i] = p;
2165      }
2166    }
2167  }
2168  idSkipZeroes(h4);
2169  kkk = IDELEMS(h4);
2170  i = IDELEMS(temph1);
2171  for (l=0; l<i; l++)
2172  {
2173    if(temph1->m[l]!=NULL)
2174    {
2175      for (ll=0; ll<j; ll++)
2176      {
2177        p = pCopy(temph1->m[l]);
2178        if (k1 == 0)
2179          pShift(&p,ll*k+1);
2180        else
2181          pShift(&p,ll*k);
2182        if (kkk >= IDELEMS(h4))
2183        {
2184          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
2185          IDELEMS(h4) += 16;
2186        }
2187        h4->m[kkk] = p;
2188        kkk++;
2189      }
2190    }
2191  }
2192/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
2193  if (*addOnlyOne)
2194  {
2195    idSkipZeroes(h4);
2196    p = h4->m[0];
2197    for (i=0;i<IDELEMS(h4)-1;i++)
2198    {
2199      h4->m[i] = h4->m[i+1];
2200    }
2201    h4->m[IDELEMS(h4)-1] = p;
2202    test |= Sy_bit(OPT_SB_1);
2203  }
2204  idDelete(&temph1);
2205  return h4;
2206}
2207/*2
2208*computes the quotient of h1,h2
2209*/
2210ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
2211{
2212  // first check for special case h1:(0)
2213  if (idIs0(h2))
2214  {
2215    ideal res;
2216    if (resultIsIdeal)
2217    {
2218      res = idInit(1,1);
2219      res->m[0] = pOne();
2220    }
2221    else
2222      res = idFreeModule(h1->rank);
2223    return res;
2224  }
2225  BITSET old_test=test;
2226  int i,l,ll,k,kkk,kmax;
2227  BOOLEAN  addOnlyOne=TRUE;
2228  tHomog   hom=isNotHomog;
2229  intvec * weights1;
2230
2231  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
2232
2233  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
2234
2235  ring orig_ring=currRing;
2236  ring syz_ring=rCurrRingAssure_SyzComp();
2237  rSetSyzComp(kmax-1);
2238  if (orig_ring!=syz_ring)
2239  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
2240    s_h4 = idrMoveR(s_h4,orig_ring);
2241  idTest(s_h4);
2242  #if 0
2243  void ipPrint_MA0(matrix m, const char *name);
2244  matrix m=idModule2Matrix(idCopy(s_h4));
2245  PrintS("start:\n");
2246  ipPrint_MA0(m,"Q");
2247  idDelete((ideal *)&m);
2248  PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
2249  #endif
2250  ideal s_h3;
2251  if (addOnlyOne)
2252  {
2253    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
2254  }
2255  else
2256  {
2257    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
2258  }
2259  test = old_test;
2260  #if 0
2261  // only together with the above debug stuff
2262  idSkipZeroes(s_h3);
2263  m=idModule2Matrix(idCopy(s_h3));
2264  Print("result, kmax=%d:\n",kmax);
2265  ipPrint_MA0(m,"S");
2266  idDelete((ideal *)&m);
2267  #endif
2268  idTest(s_h3);
2269  if (weights1!=NULL) delete weights1;
2270  idDelete(&s_h4);
2271
2272  for (i=0;i<IDELEMS(s_h3);i++)
2273  {
2274    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
2275    {
2276      if (resultIsIdeal)
2277        pShift(&s_h3->m[i],-kmax);
2278      else
2279        pShift(&s_h3->m[i],-kmax+1);
2280    }
2281    else
2282      pDelete(&s_h3->m[i]);
2283  }
2284  if (resultIsIdeal)
2285    s_h3->rank = 1;
2286  else
2287    s_h3->rank = h1->rank;
2288  if(syz_ring!=orig_ring)
2289  {
2290    rChangeCurrRing(orig_ring);
2291    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
2292    rKill(syz_ring);
2293  }
2294  idSkipZeroes(s_h3);
2295  idTest(s_h3);
2296  return s_h3;
2297}
2298
2299/*2
2300*computes recursively all monomials of a certain degree
2301*in every step the actvar-th entry in the exponential
2302*vector is incremented and the other variables are
2303*computed by recursive calls of makemonoms
2304*if the last variable is reached, the difference to the
2305*degree is computed directly
2306*vars is the number variables
2307*actvar is the actual variable to handle
2308*deg is the degree of the monomials to compute
2309*monomdeg is the actual degree of the monomial in consideration
2310*/
2311static void makemonoms(int vars,int actvar,int deg,int monomdeg)
2312{
2313  poly p;
2314  int i=0;
2315
2316  if ((idpowerpoint == 0) && (actvar ==1))
2317  {
2318    idpower[idpowerpoint] = pOne();
2319    monomdeg = 0;
2320  }
2321  while (i<=deg)
2322  {
2323    if (deg == monomdeg)
2324    {
2325      pSetm(idpower[idpowerpoint]);
2326      idpowerpoint++;
2327      return;
2328    }
2329    if (actvar == vars)
2330    {
2331      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
2332      pSetm(idpower[idpowerpoint]);
2333      pTest(idpower[idpowerpoint]);
2334      idpowerpoint++;
2335      return;
2336    }
2337    else
2338    {
2339      p = pCopy(idpower[idpowerpoint]);
2340      makemonoms(vars,actvar+1,deg,monomdeg);
2341      idpower[idpowerpoint] = p;
2342    }
2343    monomdeg++;
2344    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
2345    pSetm(idpower[idpowerpoint]);
2346    pTest(idpower[idpowerpoint]);
2347    i++;
2348  }
2349}
2350
2351/*2
2352*returns the deg-th power of the maximal ideal of 0
2353*/
2354ideal idMaxIdeal(int deg)
2355{
2356  if (deg < 0)
2357  {
2358    WarnS("maxideal: power must be non-negative");
2359  }
2360  if (deg < 1)
2361  {
2362    ideal I=idInit(1,1);
2363    I->m[0]=pOne();
2364    return I;
2365  }
2366  if (deg == 1)
2367  {
2368    return idMaxIdeal();
2369  }
2370
2371  int vars = currRing->N;
2372  int i = binom(vars+deg-1,deg);
2373  if (i<=0) return idInit(1,1);
2374  ideal id=idInit(i,1);
2375  idpower = id->m;
2376  idpowerpoint = 0;
2377  makemonoms(vars,1,deg,0);
2378  idpower = NULL;
2379  idpowerpoint = 0;
2380  return id;
2381}
2382
2383/*2
2384*computes recursively all generators of a certain degree
2385*of the ideal "givenideal"
2386*elms is the number elements in the given ideal
2387*actelm is the actual element to handle
2388*deg is the degree of the power to compute
2389*gendeg is the actual degree of the generator in consideration
2390*/
2391static void makepotence(int elms,int actelm,int deg,int gendeg)
2392{
2393  poly p;
2394  int i=0;
2395
2396  if ((idpowerpoint == 0) && (actelm ==1))
2397  {
2398    idpower[idpowerpoint] = pOne();
2399    gendeg = 0;
2400  }
2401  while (i<=deg)
2402  {
2403    if (deg == gendeg)
2404    {
2405      idpowerpoint++;
2406      return;
2407    }
2408    if (actelm == elms)
2409    {
2410      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
2411      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
2412      idpowerpoint++;
2413      return;
2414    }
2415    else
2416    {
2417      p = pCopy(idpower[idpowerpoint]);
2418      makepotence(elms,actelm+1,deg,gendeg);
2419      idpower[idpowerpoint] = p;
2420    }
2421    gendeg++;
2422    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
2423    i++;
2424  }
2425}
2426
2427/*2
2428*returns the deg-th power of the ideal gid
2429*/
2430//ideal idPower(ideal gid,int deg)
2431//{
2432//  int i;
2433//  ideal id;
2434//
2435//  if (deg < 1) deg = 1;
2436//  i = binom(IDELEMS(gid)+deg-1,deg);
2437//  id=idInit(i,1);
2438//  idpower = id->m;
2439//  givenideal = gid->m;
2440//  idpowerpoint = 0;
2441//  makepotence(IDELEMS(gid),1,deg,0);
2442//  idpower = NULL;
2443//  givenideal = NULL;
2444//  idpowerpoint = 0;
2445//  return id;
2446//}
2447static void idNextPotence(ideal given, ideal result,
2448  int begin, int end, int deg, int restdeg, poly ap)
2449{
2450  poly p;
2451  int i;
2452
2453  p = pPower(pCopy(given->m[begin]),restdeg);
2454  i = result->nrows;
2455  result->m[i] = pMult(pCopy(ap),p);
2456//PrintS(".");
2457  (result->nrows)++;
2458  if (result->nrows >= IDELEMS(result))
2459  {
2460    pEnlargeSet(&(result->m),IDELEMS(result),16);
2461    IDELEMS(result) += 16;
2462  }
2463  if (begin == end) return;
2464  for (i=restdeg-1;i>0;i--)
2465  {
2466    p = pPower(pCopy(given->m[begin]),i);
2467    p = pMult(pCopy(ap),p);
2468    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
2469    pDelete(&p);
2470  }
2471  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
2472}
2473
2474ideal idPower(ideal given,int exp)
2475{
2476  ideal result,temp;
2477  poly p1;
2478  int i;
2479
2480  if (idIs0(given)) return idInit(1,1);
2481  temp = idCopy(given);
2482  idSkipZeroes(temp);
2483  i = binom(IDELEMS(temp)+exp-1,exp);
2484  result = idInit(i,1);
2485  result->nrows = 0;
2486//Print("ideal contains %d elements\n",i);
2487  p1=pOne();
2488  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
2489  pDelete(&p1);
2490  idDelete(&temp);
2491  result->nrows = 1;
2492  idDelEquals(result);
2493  idSkipZeroes(result);
2494  return result;
2495}
2496
2497/*2
2498* eliminate delVar (product of vars) in h1
2499*/
2500ideal idElimination (ideal h1,poly delVar,intvec *hilb)
2501{
2502  int    i,j=0,k,l;
2503  ideal  h,hh, h3;
2504  int    *ord,*block0,*block1;
2505  int    ordersize=2;
2506  int    **wv;
2507  tHomog hom;
2508  intvec * w;
2509  ring tmpR;
2510  ring origR = currRing;
2511
2512  if (delVar==NULL)
2513  {
2514    return idCopy(h1);
2515  }
2516  if (currQuotient!=NULL)
2517  {
2518    WerrorS("cannot eliminate in a qring");
2519    return idCopy(h1);
2520  }
2521  if (idIs0(h1)) return idInit(1,h1->rank);
2522#ifdef HAVE_PLURAL
2523  if (rIsPluralRing(origR))
2524    /* in the NC case, we have to check the admissibility of */
2525    /* the subalgebra to be intersected with */
2526  {
2527    if ((ncRingType(origR) != nc_skew) && (ncRingType(origR) != nc_exterior)) /* in (quasi)-commutative algebras every subalgebra is admissible */
2528    {
2529      if (nc_CheckSubalgebra(delVar,origR))
2530      {
2531        WerrorS("no elimination is possible: subalgebra is not admissible");
2532        return idCopy(h1);
2533      }
2534    }
2535  }
2536#endif
2537  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
2538  h3=idInit(16,h1->rank);
2539  for (k=0;; k++)
2540  {
2541    if (origR->order[k]!=0) ordersize++;
2542    else break;
2543  }
2544  ord=(int*)omAlloc0(ordersize*sizeof(int));
2545  block0=(int*)omAlloc0(ordersize*sizeof(int));
2546  block1=(int*)omAlloc0(ordersize*sizeof(int));
2547  wv=(int**) omAlloc0(ordersize*sizeof(int**));
2548#if 0
2549  if (rIsPluralRing(origR)) // we have too keep the odering: it may be needed
2550                            // for G-algebra
2551  {
2552    for (k=0;k<ordersize-1; k++)
2553    {
2554      block0[k+1] = origR->block0[k];
2555      block1[k+1] = origR->block1[k];
2556      ord[k+1] = origR->order[k];
2557      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
2558    }
2559  }
2560  else
2561  {
2562    block0[1] = 1;
2563    block1[1] = pVariables;
2564    if (origR->OrdSgn==1) ord[1] = ringorder_wp;
2565    else                  ord[1] = ringorder_ws;
2566    wv[1]=(int*)omAlloc0(pVariables*sizeof(int));
2567    double wNsqr = (double)2.0 / (double)pVariables;
2568    wFunctional = wFunctionalBuch;
2569    int  *x= (int * )omAlloc(2 * (pVariables + 1) * sizeof(int));
2570    int sl=IDELEMS(h1) - 1;
2571    wCall(h1->m, sl, x, wNsqr);
2572    for (sl = pVariables; sl!=0; sl--)
2573      wv[1][sl-1] = x[sl + pVariables + 1];
2574    omFreeSize((ADDRESS)x, 2 * (pVariables + 1) * sizeof(int));
2575
2576    ord[2]=ringorder_C;
2577    ord[3]=0;
2578  }
2579#else
2580  for (k=0;k<ordersize-1; k++)
2581  {
2582    block0[k+1] = origR->block0[k];
2583    block1[k+1] = origR->block1[k];
2584    ord[k+1] = origR->order[k];
2585    if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
2586  }
2587#endif
2588  block0[0] = 1;
2589  block1[0] = rVar(origR);
2590  wv[0]=(int*)omAlloc((rVar(origR) + 1)*sizeof(int));
2591  memset(wv[0],0,(rVar(origR) + 1)*sizeof(int));
2592  for (j=0;j<rVar(origR);j++)
2593    if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2594  // use this special ordering: like ringorder_a, except that pFDeg, pWeights
2595  // ignore it
2596  ord[0] = ringorder_aa;
2597  // fill in tmp ring to get back the data later on
2598  tmpR  = rCopy0(origR,FALSE,FALSE); // qring==NULL
2599  //rUnComplete(tmpR);
2600  tmpR->p_Procs=NULL;
2601  tmpR->order = ord;
2602  tmpR->block0 = block0;
2603  tmpR->block1 = block1;
2604  tmpR->wvhdl = wv;
2605  rComplete(tmpR, 1);
2606
2607#ifdef HAVE_PLURAL
2608  /* update nc structure on tmpR */
2609  if (rIsPluralRing(origR))
2610  {
2611    if ( nc_rComplete(origR, tmpR, false) ) // no quotient ideal!
2612    {
2613      Werror("no elimination is possible: ordering condition is violated");
2614      // cleanup
2615      rDelete(tmpR);
2616      if (w!=NULL)
2617        delete w;
2618      return idCopy(h1);
2619    }
2620  }
2621#endif
2622  // change into the new ring
2623  //pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
2624  rChangeCurrRing(tmpR);
2625
2626  //h = idInit(IDELEMS(h1),h1->rank);
2627  // fetch data from the old ring
2628  //for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
2629  h=idrCopyR(h1,origR,currRing);
2630  // compute kStd
2631#if 1
2632  //rWrite(tmpR);PrintLn();
2633  BITSET save=test;
2634  //test |=1;
2635  //Print("h: %d gen, rk=%d\n",IDELEMS(h),h->rank);
2636  //extern char * showOption();
2637  //Print("%s\n",showOption());
2638  hh = kStd(h,NULL,hom,&w,hilb);
2639  test=save;
2640  idDelete(&h);
2641#else
2642  extern ideal kGroebner(ideal F, ideal Q);
2643  hh=kGroebner(h,NULL);
2644#endif
2645  // go back to the original ring
2646  rChangeCurrRing(origR);
2647  i = IDELEMS(hh)-1;
2648  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2649  j = -1;
2650  // fetch data from temp ring
2651  for (k=0; k<=i; k++)
2652  {
2653    l=pVariables;
2654    while ((l>0) && (p_GetExp( hh->m[k],l,tmpR)*pGetExp(delVar,l)==0)) l--;
2655    if (l==0)
2656    {
2657      j++;
2658      if (j >= IDELEMS(h3))
2659      {
2660        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2661        IDELEMS(h3) += 16;
2662      }
2663      h3->m[j] = prMoveR( hh->m[k], tmpR);
2664      hh->m[k] = NULL;
2665    }
2666  }
2667  id_Delete(&hh, tmpR);
2668  idSkipZeroes(h3);
2669  rDelete(tmpR);
2670  if (w!=NULL)
2671    delete w;
2672  return h3;
2673}
2674
2675/*2
2676* compute the which-th ar-minor of the matrix a
2677*/
2678poly idMinor(matrix a, int ar, unsigned long which, ideal R)
2679{
2680  int     i,j,k,size;
2681  unsigned long curr;
2682  int *rowchoise,*colchoise;
2683  BOOLEAN rowch,colch;
2684  ideal result;
2685  matrix tmp;
2686  poly p,q;
2687
2688  i = binom(a->rows(),ar);
2689  j = binom(a->cols(),ar);
2690
2691  rowchoise=(int *)omAlloc(ar*sizeof(int));
2692  colchoise=(int *)omAlloc(ar*sizeof(int));
2693  if ((i>512) || (j>512) || (i*j >512)) size=512;
2694  else size=i*j;
2695  result=idInit(size,1);
2696  tmp=mpNew(ar,ar);
2697  k = 0; /* the index in result*/
2698  curr = 0; /* index of current minor */
2699  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2700  while (!rowch)
2701  {
2702    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2703    while (!colch)
2704    {
2705      if (curr == which)
2706      {
2707        for (i=1; i<=ar; i++)
2708        {
2709          for (j=1; j<=ar; j++)
2710          {
2711            MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2712          }
2713        }
2714        p = mpDetBareiss(tmp);
2715        if (p!=NULL)
2716        {
2717          if (R!=NULL)
2718          {
2719            q = p;
2720            p = kNF(R,currQuotient,q);
2721            pDelete(&q);
2722          }
2723          /*delete the matrix tmp*/
2724          for (i=1; i<=ar; i++)
2725          {
2726            for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2727          }
2728          idDelete((ideal*)&tmp);
2729          omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2730          omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2731          return (p);
2732        }
2733      }
2734      curr++;
2735      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2736    }
2737    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2738  }
2739  return (poly) 1;
2740}
2741
2742#ifdef WITH_OLD_MINOR
2743/*2
2744* compute all ar-minors of the matrix a
2745*/
2746ideal idMinors(matrix a, int ar, ideal R)
2747{
2748  int     i,j,k,size;
2749  int *rowchoise,*colchoise;
2750  BOOLEAN rowch,colch;
2751  ideal result;
2752  matrix tmp;
2753  poly p,q;
2754
2755  i = binom(a->rows(),ar);
2756  j = binom(a->cols(),ar);
2757
2758  rowchoise=(int *)omAlloc(ar*sizeof(int));
2759  colchoise=(int *)omAlloc(ar*sizeof(int));
2760  if ((i>512) || (j>512) || (i*j >512)) size=512;
2761  else size=i*j;
2762  result=idInit(size,1);
2763  tmp=mpNew(ar,ar);
2764  k = 0; /* the index in result*/
2765  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2766  while (!rowch)
2767  {
2768    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2769    while (!colch)
2770    {
2771      for (i=1; i<=ar; i++)
2772      {
2773        for (j=1; j<=ar; j++)
2774        {
2775          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2776        }
2777      }
2778      p = mpDetBareiss(tmp);
2779      if (p!=NULL)
2780      {
2781        if (R!=NULL)
2782        {
2783          q = p;
2784          p = kNF(R,currQuotient,q);
2785          pDelete(&q);
2786        }
2787        if (p!=NULL)
2788        {
2789          if (k>=size)
2790          {
2791            pEnlargeSet(&result->m,size,32);
2792            size += 32;
2793          }
2794          result->m[k] = p;
2795          k++;
2796        }
2797      }
2798      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2799    }
2800    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2801  }
2802  /*delete the matrix tmp*/
2803  for (i=1; i<=ar; i++)
2804  {
2805    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2806  }
2807  idDelete((ideal*)&tmp);
2808  if (k==0)
2809  {
2810    k=1;
2811    result->m[0]=NULL;
2812  }
2813  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2814  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2815  pEnlargeSet(&result->m,size,k-size);
2816  IDELEMS(result) = k;
2817  return (result);
2818}
2819#else
2820/*2
2821* compute all ar-minors of the matrix a
2822* the caller of mpRecMin
2823* the elements of the result are not in R (if R!=NULL)
2824*/
2825ideal idMinors(matrix a, int ar, ideal R)
2826{
2827  int elems=0;
2828  int r=a->nrows,c=a->ncols;
2829  int i;
2830  matrix b;
2831  ideal result,h;
2832  ring origR;
2833  sip_sring tmpR;
2834  long bound;
2835
2836  if((ar<=0) || (ar>r) || (ar>c))
2837  {
2838    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
2839    return NULL;
2840  }
2841  h = idMatrix2Module(mpCopy(a));
2842  bound = smExpBound(h,c,r,ar);
2843  idDelete(&h);
2844  smRingChange(&origR,tmpR,bound);
2845  b = mpNew(r,c);
2846  for (i=r*c-1;i>=0;i--)
2847  {
2848    if (a->m[i])
2849      b->m[i] = prCopyR(a->m[i],origR);
2850  }
2851  if (R!=NULL)
2852  {
2853    R = idrCopyR(R,origR);
2854    //if (ar>1) // otherwise done in mpMinorToResult
2855    //{
2856    //  matrix bb=(matrix)kNF(R,currQuotient,(ideal)b);
2857    //  bb->rank=b->rank; bb->nrows=b->nrows; bb->ncols=b->ncols;
2858    //  idDelete((ideal*)&b); b=bb;
2859    //}
2860  }
2861  result=idInit(32,1);
2862  if(ar>1) mpRecMin(ar-1,result,elems,b,r,c,NULL,R);
2863  else mpMinorToResult(result,elems,b,r,c,R);
2864  idDelete((ideal *)&b);
2865  if (R!=NULL) idDelete(&R);
2866  idSkipZeroes(result);
2867  rChangeCurrRing(origR);
2868  result = idrMoveR(result,&tmpR);
2869  smRingClean(origR,tmpR);
2870  idTest(result);
2871  return result;
2872}
2873#endif
2874
2875/*2
2876*skips all zeroes and double elements, searches also for units
2877*/
2878void idCompactify(ideal id)
2879{
2880  int i,j;
2881  BOOLEAN b=FALSE;
2882
2883  i = IDELEMS(id)-1;
2884  while ((! b) && (i>=0))
2885  {
2886    b=pIsUnit(id->m[i]);
2887    i--;
2888  }
2889  if (b)
2890  {
2891    for(i=IDELEMS(id)-1;i>=0;i--) pDelete(&id->m[i]);
2892    id->m[0]=pOne();
2893  }
2894  else
2895  {
2896    idDelMultiples(id);
2897  }
2898  idSkipZeroes(id);
2899}
2900
2901/*2
2902*returns TRUE if id1 is a submodule of id2
2903*/
2904BOOLEAN idIsSubModule(ideal id1,ideal id2)
2905{
2906  int i;
2907  poly p;
2908
2909  if (idIs0(id1)) return TRUE;
2910  for (i=0;i<IDELEMS(id1);i++)
2911  {
2912    if (id1->m[i] != NULL)
2913    {
2914      p = kNF(id2,currQuotient,id1->m[i]);
2915      if (p != NULL)
2916      {
2917        pDelete(&p);
2918        return FALSE;
2919      }
2920    }
2921  }
2922  return TRUE;
2923}
2924
2925/*2
2926* returns the ideals of initial terms
2927*/
2928ideal idHead(ideal h)
2929{
2930  ideal m = idInit(IDELEMS(h),h->rank);
2931  int i;
2932
2933  for (i=IDELEMS(h)-1;i>=0; i--)
2934  {
2935    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
2936  }
2937  return m;
2938}
2939
2940ideal idHomogen(ideal h, int varnum)
2941{
2942  ideal m = idInit(IDELEMS(h),h->rank);
2943  int i;
2944
2945  for (i=IDELEMS(h)-1;i>=0; i--)
2946  {
2947    m->m[i]=pHomogen(h->m[i],varnum);
2948  }
2949  return m;
2950}
2951
2952/*------------------type conversions----------------*/
2953ideal idVec2Ideal(poly vec)
2954{
2955   ideal result=idInit(1,1);
2956   omFree((ADDRESS)result->m);
2957   result->m=NULL; // remove later
2958   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2959   return result;
2960}
2961
2962#define NEW_STUFF
2963#ifndef NEW_STUFF
2964// converts mat to module, destroys mat
2965ideal idMatrix2Module(matrix mat)
2966{
2967  int mc=MATCOLS(mat);
2968  int mr=MATROWS(mat);
2969  ideal result = idInit(si_max(mc,1),si_max(mr,1));
2970  int i,j;
2971  poly h;
2972
2973  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
2974  {
2975    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
2976    {
2977      h = MATELEM(mat,i,j+1);
2978      if (h!=NULL)
2979      {
2980        MATELEM(mat,i,j+1)=NULL;
2981        pSetCompP(h,i);
2982        result->m[j] = pAdd(result->m[j],h);
2983      }
2984    }
2985  }
2986  // obachman: need to clean this up
2987  idDelete((ideal*) &mat);
2988  return result;
2989}
2990#else
2991
2992#include "sbuckets.h"
2993
2994// converts mat to module, destroys mat
2995ideal idMatrix2Module(matrix mat)
2996{
2997  int mc=MATCOLS(mat);
2998  int mr=MATROWS(mat);
2999  ideal result = idInit(si_max(mc,1),si_max(mr,1));
3000  int i,j, l;
3001  poly h;
3002  poly p;
3003  sBucket_pt bucket = sBucketCreate(currRing);
3004
3005  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
3006  {
3007    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
3008    {
3009      h = MATELEM(mat,i,j+1);
3010      if (h!=NULL)
3011      {
3012        l=pLength(h);
3013        MATELEM(mat,i,j+1)=NULL;
3014        p_SetCompP(h,i, currRing);
3015        sBucket_Merge_p(bucket, h, l);
3016      }
3017    }
3018    sBucketClearMerge(bucket, &(result->m[j]), &l);
3019  }
3020  sBucketDestroy(&bucket);
3021
3022  // obachman: need to clean this up
3023  idDelete((ideal*) &mat);
3024  return result;
3025}
3026#endif
3027
3028/*2
3029* converts a module into a matrix, destroyes the input
3030*/
3031matrix idModule2Matrix(ideal mod)
3032{
3033  matrix result = mpNew(mod->rank,IDELEMS(mod));
3034  int i,cp;
3035  poly p,h;
3036
3037  for(i=0;i<IDELEMS(mod);i++)
3038  {
3039    p=pReverse(mod->m[i]);
3040    mod->m[i]=NULL;
3041    while (p!=NULL)
3042    {
3043      h=p;
3044      pIter(p);
3045      pNext(h)=NULL;
3046//      cp = si_max(1,pGetComp(h));     // if used for ideals too
3047      cp = pGetComp(h);
3048      pSetComp(h,0);
3049      pSetmComp(h);
3050#ifdef TEST
3051      if (cp>mod->rank)
3052      {
3053        Print("## inv. rank %ld -> %d\n",mod->rank,cp);
3054        int k,l,o=mod->rank;
3055        mod->rank=cp;
3056        matrix d=mpNew(mod->rank,IDELEMS(mod));
3057        for (l=1; l<=o; l++)
3058        {
3059          for (k=1; k<=IDELEMS(mod); k++)
3060          {
3061            MATELEM(d,l,k)=MATELEM(result,l,k);
3062            MATELEM(result,l,k)=NULL;
3063          }
3064        }
3065        idDelete((ideal *)&result);
3066        result=d;
3067      }
3068#endif
3069      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
3070    }
3071  }
3072  // obachman 10/99: added the following line, otherwise memory leack!
3073  idDelete(&mod);
3074  return result;
3075}
3076
3077matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
3078{
3079  matrix result = mpNew(rows,cols);
3080  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
3081  poly p,h;
3082
3083  if (r>rows) r = rows;
3084  if (c>cols) c = cols;
3085  for(i=0;i<c;i++)
3086  {
3087    p=pReverse(mod->m[i]);
3088    mod->m[i]=NULL;
3089    while (p!=NULL)
3090    {
3091      h=p;
3092      pIter(p);
3093      pNext(h)=NULL;
3094      cp = pGetComp(h);
3095      if (cp<=r)
3096      {
3097        pSetComp(h,0);
3098        pSetmComp(h);
3099        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
3100      }
3101      else
3102        pDelete(&h);
3103    }
3104  }
3105  idDelete(&mod);
3106  return result;
3107}
3108
3109/*2
3110* substitute the n-th variable by the monomial e in id
3111* destroy id
3112*/
3113ideal  idSubst(ideal id, int n, poly e)
3114{
3115  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
3116  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
3117
3118  res->rank = id->rank;
3119  for(k--;k>=0;k--)
3120  {
3121    res->m[k]=pSubst(id->m[k],n,e);
3122    id->m[k]=NULL;
3123  }
3124  idDelete(&id);
3125  return res;
3126}
3127
3128BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
3129{
3130  if (w!=NULL) *w=NULL;
3131  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
3132  if (idIs0(m))
3133  {
3134    if (w!=NULL) (*w)=new intvec(m->rank);
3135    return TRUE;
3136  }
3137
3138  long cmax=1,order=0,ord,* diff,diffmin=32000;
3139  int *iscom;
3140  int i,j;
3141  poly p=NULL;
3142  pFDegProc d;
3143  if (pLexOrder && (currRing->order[0]==ringorder_lp))
3144     d=pTotaldegree;
3145  else 
3146     d=pFDeg;
3147  int length=IDELEMS(m);
3148  polyset P=m->m;
3149  polyset F=(polyset)omAlloc(length*sizeof(poly));
3150  for (i=length-1;i>=0;i--)
3151  {
3152    p=F[i]=P[i];
3153    cmax=si_max(cmax,(long)pMaxComp(p));
3154  }
3155  cmax++;
3156  diff = (long *)omAlloc0(cmax*sizeof(long));
3157  if (w!=NULL) *w=new intvec(cmax-1);
3158  iscom = (int *)omAlloc0(cmax*sizeof(int));
3159  i=0;
3160  while (i<=length)
3161  {
3162    if (i<length)
3163    {
3164      p=F[i];
3165      while ((p!=NULL) && (iscom[pGetComp(p)]==0)) pIter(p);
3166    }
3167    if ((p==NULL) && (i<length))
3168    {
3169      i++;
3170    }
3171    else
3172    {
3173      if (p==NULL) /* && (i==length) */
3174      {
3175        i=0;
3176        while ((i<length) && (F[i]==NULL)) i++;
3177        if (i>=length) break;
3178        p = F[i];
3179      }
3180      //if (pLexOrder && (currRing->order[0]==ringorder_lp))
3181      //  order=pTotaldegree(p);
3182      //else
3183      //  order = p->order;
3184      //  order = pFDeg(p,currRing);
3185      order = d(p,currRing) +diff[pGetComp(p)];
3186      //order += diff[pGetComp(p)];
3187      p = F[i];
3188//Print("Actual p=F[%d]: ",i);pWrite(p);
3189      F[i] = NULL;
3190      i=0;
3191    }
3192    while (p!=NULL)
3193    {
3194      if (pLexOrder && (currRing->order[0]==ringorder_lp))
3195        ord=pTotaldegree(p);
3196      else
3197      //  ord = p->order;
3198        ord = pFDeg(p,currRing);
3199      if (iscom[pGetComp(p)]==0)
3200      {
3201        diff[pGetComp(p)] = order-ord;
3202        iscom[pGetComp(p)] = 1;
3203/*
3204*PrintS("new diff: ");
3205*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
3206*PrintLn();
3207*PrintS("new iscom: ");
3208*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
3209*PrintLn();
3210*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
3211*/
3212      }
3213      else
3214      {
3215/*
3216*PrintS("new diff: ");
3217*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
3218*PrintLn();
3219*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
3220*/
3221        if (order != (ord+diff[pGetComp(p)]))
3222        {
3223          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
3224          omFreeSize((ADDRESS) diff,cmax*sizeof(long));
3225          omFreeSize((ADDRESS) F,length*sizeof(poly));
3226          delete *w;*w=NULL;
3227          return FALSE;
3228        }
3229      }
3230      pIter(p);
3231    }
3232  }
3233  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
3234  omFreeSize((ADDRESS) F,length*sizeof(poly));
3235  for (i=1;i<cmax;i++) (**w)[i-1]=(int)(diff[i]);
3236  for (i=1;i<cmax;i++)
3237  {
3238    if (diff[i]<diffmin) diffmin=diff[i];
3239  }
3240  if (w!=NULL)
3241  {
3242    for (i=1;i<cmax;i++)
3243    {
3244      (**w)[i-1]=(int)(diff[i]-diffmin);
3245    }
3246  }
3247  omFreeSize((ADDRESS) diff,cmax*sizeof(long));
3248  return TRUE;
3249}
3250
3251BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
3252{
3253  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
3254  if (idIs0(m)) return TRUE;
3255
3256  int cmax=-1;
3257  int i;
3258  poly p=NULL;
3259  int length=IDELEMS(m);
3260  polyset P=m->m;
3261  for (i=length-1;i>=0;i--)
3262  {
3263    p=P[i];
3264    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
3265  }
3266  if (w != NULL)
3267  if (w->length()+1 < cmax)
3268  {
3269    // Print("length: %d - %d \n", w->length(),cmax);
3270    return FALSE;
3271  }
3272
3273  if(w!=NULL)
3274    pSetModDeg(w);
3275
3276  for (i=length-1;i>=0;i--)
3277  {
3278    p=P[i];
3279    poly q=p;
3280    if (p!=NULL)
3281    {
3282      int d=pFDeg(p,currRing);
3283      loop
3284      {
3285        pIter(p);
3286        if (p==NULL) break;
3287        if (d!=pFDeg(p,currRing))
3288        {
3289          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
3290          if(w!=NULL)
3291            pSetModDeg(NULL);
3292          return FALSE;
3293        }
3294      }
3295    }
3296  }
3297
3298  if(w!=NULL)
3299    pSetModDeg(NULL);
3300
3301  return TRUE;
3302}
3303
3304ideal idJet(ideal i,int d)
3305{
3306  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
3307  r->nrows = i-> nrows;
3308  r->ncols = i-> ncols;
3309  //r->rank = i-> rank;
3310  int k;
3311  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
3312  {
3313    r->m[k]=ppJet(i->m[k],d);
3314  }
3315  return r;
3316}
3317
3318ideal idJetW(ideal i,int d, intvec * iv)
3319{
3320  ideal r=idInit(IDELEMS(i),i->rank);
3321  if (ecartWeights!=NULL)
3322  {
3323    WerrorS("cannot compute weighted jets now");
3324  }
3325  else
3326  {
3327    short *w=iv2array(iv);
3328    int k;
3329    for(k=0; k<IDELEMS(i); k++)
3330    {
3331      r->m[k]=ppJetW(i->m[k],d,w);
3332    }
3333    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
3334  }
3335  return r;
3336}
3337
3338int idMinDegW(ideal M,intvec *w)
3339{
3340  int d=-1;
3341  for(int i=0;i<IDELEMS(M);i++)
3342  {
3343    int d0=pMinDeg(M->m[i],w);
3344    if(-1<d0&&(d0<d||d==-1))
3345      d=d0;
3346  }
3347  return d;
3348}
3349
3350ideal idSeries(int n,ideal M,matrix U,intvec *w)
3351{
3352  for(int i=IDELEMS(M)-1;i>=0;i--)
3353  {
3354    if(U==NULL)
3355      M->m[i]=pSeries(n,M->m[i],NULL,w);
3356    else
3357    {
3358      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
3359      MATELEM(U,i+1,i+1)=NULL;
3360    }
3361  }
3362  if(U!=NULL)
3363    idDelete((ideal*)&U);
3364  return M;
3365}
3366
3367matrix idDiff(matrix i, int k)
3368{
3369  int e=MATCOLS(i)*MATROWS(i);
3370  matrix r=mpNew(MATROWS(i),MATCOLS(i));
3371  r->rank=i->rank;
3372  int j;
3373  for(j=0; j<e; j++)
3374  {
3375    r->m[j]=pDiff(i->m[j],k);
3376  }
3377  return r;
3378}
3379
3380matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
3381{
3382  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
3383  int i,j;
3384  for(i=0; i<IDELEMS(I); i++)
3385  {
3386    for(j=0; j<IDELEMS(J); j++)
3387    {
3388      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
3389    }
3390  }
3391  return r;
3392}
3393
3394/*3
3395*handles for some ideal operations the ring/syzcomp managment
3396*returns all syzygies (componentwise-)shifted by -syzcomp
3397*or -syzcomp-1 (in case of ideals as input)
3398static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
3399{
3400  ring orig_ring=currRing;
3401  ring syz_ring=rCurrRingAssure_SyzComp();
3402  rSetSyzComp(length);
3403
3404  ideal s_temp;
3405  if (orig_ring!=syz_ring)
3406    s_temp=idrMoveR_NoSort(arg,orig_ring);
3407  else
3408    s_temp=arg;
3409
3410  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
3411  if (w!=NULL) delete w;
3412
3413  if (syz_ring!=orig_ring)
3414  {
3415    idDelete(&s_temp);
3416    rChangeCurrRing(orig_ring);
3417  }
3418
3419  idDelete(&temp);
3420  ideal temp1=idRingCopy(s_temp1,syz_ring);
3421
3422  if (syz_ring!=orig_ring)
3423  {
3424    rChangeCurrRing(syz_ring);
3425    idDelete(&s_temp1);
3426    rChangeCurrRing(orig_ring);
3427    rKill(syz_ring);
3428  }
3429
3430  for (i=0;i<IDELEMS(temp1);i++)
3431  {
3432    if ((temp1->m[i]!=NULL)
3433    && (pGetComp(temp1->m[i])<=length))
3434    {
3435      pDelete(&(temp1->m[i]));
3436    }
3437    else
3438    {
3439      pShift(&(temp1->m[i]),-length);
3440    }
3441  }
3442  temp1->rank = rk;
3443  idSkipZeroes(temp1);
3444
3445  return temp1;
3446}
3447*/
3448/*2
3449* represents (h1+h2)/h2=h1/(h1 intersect h2)
3450*/
3451//ideal idModulo (ideal h2,ideal h1)
3452ideal idModulo (ideal h2,ideal h1, tHomog hom, intvec ** w)
3453{
3454  intvec *wtmp=NULL;
3455
3456  int i,j,k,rk,flength=0,slength,length;
3457  poly p,q;
3458
3459  if (idIs0(h2))
3460    return idFreeModule(si_max(1,h2->ncols));
3461  if (!idIs0(h1))
3462    flength = idRankFreeModule(h1);
3463  slength = idRankFreeModule(h2);
3464  length  = si_max(flength,slength);
3465  if (length==0)
3466  {
3467    length = 1;
3468  }
3469  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
3470  if ((w!=NULL)&&((*w)!=NULL))
3471  {
3472    //Print("input weights:");(*w)->show(1);PrintLn();
3473    int d;
3474    int k;
3475    wtmp=new intvec(length+IDELEMS(h2));
3476    for (i=0;i<length;i++)
3477      ((*wtmp)[i])=(**w)[i];
3478    for (i=0;i<IDELEMS(h2);i++)
3479    {
3480      poly p=h2->m[i];
3481      if (p!=NULL)
3482      {
3483        d = pDeg(p);
3484        k= pGetComp(p);
3485        if (slength>0) k--;
3486        d +=((**w)[k]);
3487        ((*wtmp)[i+length]) = d;
3488      }
3489    }
3490    //Print("weights:");wtmp->show(1);PrintLn();
3491  }
3492  for (i=0;i<IDELEMS(h2);i++)
3493  {
3494    temp->m[i] = pCopy(h2->m[i]);
3495    q = pOne();
3496    pSetComp(q,i+1+length);
3497    pSetmComp(q);
3498    if(temp->m[i]!=NULL)
3499    {
3500      if (slength==0) pShift(&(temp->m[i]),1);
3501      p = temp->m[i];
3502      while (pNext(p)!=NULL) pIter(p);
3503      pNext(p) = q;
3504    }
3505    else
3506      temp->m[i]=q;
3507  }
3508  rk = k = IDELEMS(h2);
3509  if (!idIs0(h1))
3510  {
3511    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
3512    IDELEMS(temp) += IDELEMS(h1);
3513    for (i=0;i<IDELEMS(h1);i++)
3514    {
3515      if (h1->m[i]!=NULL)
3516      {
3517        temp->m[k] = pCopy(h1->m[i]);
3518        if (flength==0) pShift(&(temp->m[k]),1);
3519        k++;
3520      }
3521    }
3522  }
3523
3524  ring orig_ring=currRing;
3525  ring syz_ring=rCurrRingAssure_SyzComp();
3526  rSetSyzComp(length);
3527  ideal s_temp;
3528
3529  if (syz_ring != orig_ring)
3530  {
3531    s_temp = idrMoveR_NoSort(temp, orig_ring);
3532  }
3533  else
3534  {
3535    s_temp = temp;
3536  }
3537
3538  idTest(s_temp);
3539  ideal s_temp1 = kStd(s_temp,currQuotient,hom,&wtmp,NULL,length);
3540
3541  //if (wtmp!=NULL)  Print("output weights:");wtmp->show(1);PrintLn();
3542  if ((w!=NULL) && (*w !=NULL) && (wtmp!=NULL))
3543  {
3544    delete *w;
3545    *w=new intvec(IDELEMS(h2));
3546    for (i=0;i<IDELEMS(h2);i++)
3547      ((**w)[i])=(*wtmp)[i+length];
3548  }
3549  if (wtmp!=NULL) delete wtmp;
3550
3551  for (i=0;i<IDELEMS(s_temp1);i++)
3552  {
3553    if ((s_temp1->m[i]!=NULL)
3554    && (pGetComp(s_temp1->m[i])<=length))
3555    {
3556      pDelete(&(s_temp1->m[i]));
3557    }
3558    else
3559    {
3560      pShift(&(s_temp1->m[i]),-length);
3561    }
3562  }
3563  s_temp1->rank = rk;
3564  idSkipZeroes(s_temp1);
3565
3566  if (syz_ring!=orig_ring)
3567  {
3568    rChangeCurrRing(orig_ring);
3569    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
3570    rKill(syz_ring);
3571    // Hmm ... here seems to be a memory leak
3572    // However, simply deleting it causes memory trouble
3573    // idDelete(&s_temp);
3574  }
3575  else
3576  {
3577    idDelete(&temp);
3578  }
3579  idTest(s_temp1);
3580  return s_temp1;
3581}
3582
3583int idElem(const ideal F)
3584{
3585  int i=0,j=IDELEMS(F)-1;
3586
3587  while(j>=0)
3588  {
3589    if ((F->m)[j]!=NULL) i++;
3590    j--;
3591  }
3592  return i;
3593}
3594
3595/*
3596*computes module-weights for liftings of homogeneous modules
3597*/
3598intvec * idMWLift(ideal mod,intvec * weights)
3599{
3600  if (idIs0(mod)) return new intvec(2);
3601  int i=IDELEMS(mod);
3602  while ((i>0) && (mod->m[i-1]==NULL)) i--;
3603  intvec *result = new intvec(i+1);
3604  while (i>0)
3605  {
3606    (*result)[i]=pFDeg(mod->m[i],currRing)+(*weights)[pGetComp(mod->m[i])];
3607  }
3608  return result;
3609}
3610
3611/*2
3612*sorts the kbase for idCoef* in a special way (lexicographically
3613*with x_max,...,x_1)
3614*/
3615ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
3616{
3617  int i;
3618  ideal result;
3619
3620  if (idIs0(kBase)) return NULL;
3621  result = idInit(IDELEMS(kBase),kBase->rank);
3622  *convert = idSort(kBase,FALSE);
3623  for (i=0;i<(*convert)->length();i++)
3624  {
3625    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
3626  }
3627  return result;
3628}
3629
3630/*2
3631*returns the index of a given monom in the list of the special kbase
3632*/
3633int idIndexOfKBase(poly monom, ideal kbase)
3634{
3635  int j=IDELEMS(kbase);
3636
3637  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
3638  if (j==0) return -1;
3639  int i=pVariables;
3640  while (i>0)
3641  {
3642    loop
3643    {
3644      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
3645      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
3646      j--;
3647      if (j==0) return -1;
3648    }
3649    if (i==1)
3650    {
3651      while(j>0)
3652      {
3653        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
3654        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
3655        j--;
3656      }
3657    }
3658    i--;
3659  }
3660  return -1;
3661}
3662
3663/*2
3664*decomposes the monom in a part of coefficients described by the
3665*complement of how and a monom in variables occuring in how, the
3666*index of which in kbase is returned as integer pos (-1 if it don't
3667*exists)
3668*/
3669poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3670{
3671  int i;
3672  poly coeff=pOne(), base=pOne();
3673
3674  for (i=1;i<=pVariables;i++)
3675  {
3676    if (pGetExp(how,i)>0)
3677    {
3678      pSetExp(base,i,pGetExp(monom,i));
3679    }
3680    else
3681    {
3682      pSetExp(coeff,i,pGetExp(monom,i));
3683    }
3684  }
3685  pSetComp(base,pGetComp(monom));
3686  pSetm(base);
3687  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3688  pSetm(coeff);
3689  *pos = idIndexOfKBase(base,kbase);
3690  if (*pos<0)
3691    pDelete(&coeff);
3692  pDelete(&base);
3693  return coeff;
3694}
3695
3696/*2
3697*returns a matrix A of coefficients with kbase*A=arg
3698*if all monomials in variables of how occur in kbase
3699*the other are deleted
3700*/
3701matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3702{
3703  matrix result;
3704  ideal tempKbase;
3705  poly p,q;
3706  intvec * convert;
3707  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3708#if 0
3709  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3710  if (idIs0(arg))
3711    return mpNew(i,1);
3712  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3713  result = mpNew(i,j);
3714#else
3715  result = mpNew(i, j);
3716  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3717#endif
3718
3719  tempKbase = idCreateSpecialKbase(kbase,&convert);
3720  for (k=0;k<j;k++)
3721  {
3722    p = arg->m[k];
3723    while (p!=NULL)
3724    {
3725      q = idDecompose(p,how,tempKbase,&pos);
3726      if (pos>=0)
3727      {
3728        MATELEM(result,(*convert)[pos],k+1) =
3729            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3730      }
3731      else
3732        pDelete(&q);
3733      pIter(p);
3734    }
3735  }
3736  idDelete(&tempKbase);
3737  return result;
3738}
3739
3740/*3
3741* searches for units in the components of the module arg and
3742* returns the first one
3743*/
3744static int idReadOutUnits(ideal arg,int* comp)
3745{
3746  if (idIs0(arg)) return -1;
3747  int i=0,j, generator=-1;
3748  int rk_arg=arg->rank; //idRankFreeModule(arg);
3749  int * componentIsUsed =(int *)omAlloc((rk_arg+1)*sizeof(int));
3750  poly p,q;
3751
3752  while ((generator<0) && (i<IDELEMS(arg)))
3753  {
3754    memset(componentIsUsed,0,(rk_arg+1)*sizeof(int));
3755    p = arg->m[i];
3756    while (p!=NULL)
3757    {
3758      j = pGetComp(p);
3759      if (componentIsUsed[j]==0)
3760      {
3761        if (pLmIsConstantComp(p))
3762        {
3763          generator = i;
3764          componentIsUsed[j] = 1;
3765        }
3766        else
3767        {
3768          componentIsUsed[j] = -1;
3769        }
3770      }
3771      else if (componentIsUsed[j]>0)
3772      {
3773        (componentIsUsed[j])++;
3774      }
3775      pIter(p);
3776    }
3777    i++;
3778  }
3779  i = 0;
3780  *comp = -1;
3781  for (j=0;j<=rk_arg;j++)
3782  {
3783    if (componentIsUsed[j]>0)
3784    {
3785      if ((*comp==-1) || (componentIsUsed[j]<i))
3786      {
3787        *comp = j;
3788        i= componentIsUsed[j];
3789      }
3790    }
3791  }
3792  omFree(componentIsUsed);
3793  return generator;
3794}
3795
3796#if 0
3797static void idDeleteComp(ideal arg,int red_comp)
3798{
3799  int i,j;
3800  poly p;
3801
3802  for (i=IDELEMS(arg)-1;i>=0;i--)
3803  {
3804    p = arg->m[i];
3805    while (p!=NULL)
3806    {
3807      j = pGetComp(p);
3808      if (j>red_comp)
3809      {
3810        pSetComp(p,j-1);
3811        pSetm(p);
3812      }
3813      pIter(p);
3814    }
3815  }
3816  (arg->rank)--;
3817}
3818#endif
3819
3820static void idDeleteComps(ideal arg,int* red_comp,int del)
3821// red_comp is an array [0..args->rank]
3822{
3823  int i,j;
3824  poly p;
3825
3826  for (i=IDELEMS(arg)-1;i>=0;i--)
3827  {
3828    p = arg->m[i];
3829    while (p!=NULL)
3830    {
3831      j = pGetComp(p);
3832      if (red_comp[j]!=j)
3833      {
3834        pSetComp(p,red_comp[j]);
3835        pSetmComp(p);
3836      }
3837      pIter(p);
3838    }
3839  }
3840  (arg->rank) -= del;
3841}
3842
3843/*2
3844* returns the presentation of an isomorphic, minimally
3845* embedded  module (arg represents the quotient!)
3846*/
3847ideal idMinEmbedding(ideal arg,BOOLEAN inPlace, intvec **w)
3848{
3849  if (idIs0(arg)) return idInit(1,arg->rank);
3850  int i,next_gen,next_comp;
3851  ideal res=arg;
3852
3853  if (!inPlace) res = idCopy(arg);
3854  res->rank=si_max(res->rank,idRankFreeModule(res));
3855  int *red_comp=(int*)omAlloc((res->rank+1)*sizeof(int));
3856  for (i=res->rank;i>=0;i--) red_comp[i]=i;
3857
3858  int del=0;
3859  loop
3860  {
3861    next_gen = idReadOutUnits(res,&next_comp);
3862    if (next_gen<0) break;
3863    del++;
3864    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
3865    for(i=next_comp+1;i<=arg->rank;i++) red_comp[i]--;
3866    if ((w !=NULL)&&(*w!=NULL))
3867    {
3868      for(i=next_comp;i<(*w)->length();i++) (**w)[i-1]=(**w)[i];
3869    }
3870  }
3871
3872  idDeleteComps(res,red_comp,del);
3873  idSkipZeroes(res);
3874  omFree(red_comp);
3875
3876  if ((w !=NULL)&&(*w!=NULL) &&(del>0))
3877  {
3878    intvec *wtmp=new intvec((*w)->length()-del);
3879    for(i=0;i<res->rank;i++) (*wtmp)[i]=(**w)[i];
3880    delete *w;
3881    *w=wtmp;
3882  }
3883  return res;
3884}
3885
3886/*2
3887* transpose a module
3888*/
3889ideal idTransp(ideal a)
3890{
3891  int r = a->rank, c = IDELEMS(a);
3892  ideal b =  idInit(r,c);
3893
3894  for (int i=c; i>0; i--)
3895  {
3896    poly p=a->m[i-1];
3897    while(p!=NULL)
3898    {
3899      poly h=pHead(p);
3900      int co=pGetComp(h)-1;
3901      pSetComp(h,i);
3902      pSetmComp(h);
3903      b->m[co]=pAdd(b->m[co],h);
3904      pIter(p);
3905    }
3906  }
3907  return b;
3908}
3909
3910intvec * idQHomWeight(ideal id)
3911{
3912  poly head, tail;
3913  int k;
3914  int in=IDELEMS(id)-1, ready=0, all=0,
3915      coldim=pVariables, rowmax=2*coldim;
3916  if (in<0) return NULL;
3917  intvec *imat=new intvec(rowmax+1,coldim,0);
3918
3919  do
3920  {
3921    head = id->m[in--];
3922    if (head!=NULL)
3923    {
3924      tail = pNext(head);
3925      while (tail!=NULL)
3926      {
3927        all++;
3928        for (k=1;k<=coldim;k++)
3929          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
3930        if (all==rowmax)
3931        {
3932          ivTriangIntern(imat, ready, all);
3933          if (ready==coldim)
3934          {
3935            delete imat;
3936            return NULL;
3937          }
3938        }
3939        pIter(tail);
3940      }
3941    }
3942  } while (in>=0);
3943  if (all>ready)
3944  {
3945    ivTriangIntern(imat, ready, all);
3946    if (ready==coldim)
3947    {
3948      delete imat;
3949      return NULL;
3950    }
3951  }
3952  intvec *result = ivSolveKern(imat, ready);
3953  delete imat;
3954  return result;
3955}
3956
3957BOOLEAN idIsZeroDim(ideal I)
3958{
3959  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(pVariables*sizeof(BOOLEAN));
3960  int i,n;
3961  poly po;
3962  BOOLEAN res=TRUE;
3963  for(i=IDELEMS(I)-1;i>=0;i--)
3964  {
3965    po=I->m[i];
3966    if ((po!=NULL) &&((n=pIsPurePower(po))!=0)) UsedAxis[n-1]=TRUE;
3967  }
3968  for(i=pVariables-1;i>=0;i--)
3969  {
3970    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
3971  }
3972  omFreeSize(UsedAxis,pVariables*sizeof(BOOLEAN));
3973  return res;
3974}
3975
3976void idNormalize(ideal I)
3977{
3978  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
3979  int i;
3980  poly p;
3981  for(i=IDELEMS(I)-1;i>=0;i--)
3982  {
3983    p=I->m[i] ;
3984    while(p!=NULL)
3985    {
3986      nNormalize(pGetCoeff(p));
3987      pIter(p);
3988    }
3989  }
3990}
3991
3992#include "clapsing.h"
3993
3994poly id_GCD(poly f, poly g, const ring r)
3995{
3996  ring save_r=currRing;
3997  rChangeCurrRing(r);
3998  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
3999  intvec *w = NULL;
4000  ideal S=idSyzygies(I,testHomog,&w);
4001  if (w!=NULL) delete w;
4002  poly gg=pTakeOutComp(&(S->m[0]),2);
4003  idDelete(&S);
4004  poly gcd_p=singclap_pdivide(f,gg);
4005  pDelete(&gg);
4006  rChangeCurrRing(save_r);
4007  return gcd_p;
4008}
4009
4010/*2
4011* xx,q: arrays of length 0..rl-1
4012* xx[i]: SB mod q[i]
4013* assume: char=0
4014* assume: q[i]!=0
4015* destroys xx
4016*/
4017ideal idChineseRemainder(ideal *xx, number *q, int rl)
4018{
4019  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
4020  ideal result=idInit(cnt,xx[0]->rank);
4021  result->nrows=xx[0]->nrows; // for lifting matrices
4022  result->ncols=xx[0]->ncols; // for lifting matrices
4023  int i,j;
4024  poly r,h,hh,res_p;
4025  number *x=(number *)omAlloc(rl*sizeof(number));
4026  for(i=cnt-1;i>=0;i--)
4027  {
4028    res_p=NULL;
4029    loop
4030    {
4031      r=NULL;
4032      for(j=rl-1;j>=0;j--)
4033      {
4034        h=xx[j]->m[i];
4035        if ((h!=NULL)
4036        &&((r==NULL)||(pLmCmp(r,h)==-1)))
4037          r=h;
4038      }
4039      if (r==NULL) break;
4040      h=pHead(r);
4041      for(j=rl-1;j>=0;j--)
4042      {
4043        hh=xx[j]->m[i];
4044        if ((hh!=NULL) && (pLmCmp(r,hh)==0))
4045        {
4046          x[j]=pGetCoeff(hh);
4047          hh=pLmFreeAndNext(hh);
4048          xx[j]->m[i]=hh;
4049        }
4050        else
4051          x[j]=nlInit(0, currRing);
4052      }
4053      number n=nlChineseRemainder(x,q,rl);
4054      for(j=rl-1;j>=0;j--)
4055      {
4056        x[j]=NULL; // nlInit(0...) takes no memory
4057      }
4058      pSetCoeff(h,n);
4059      //Print("new mon:");pWrite(h);
4060      res_p=pAdd(res_p,h);
4061    }
4062    result->m[i]=res_p;
4063  }
4064  omFree(x);
4065  for(i=rl-1;i>=0;i--) idDelete(&(xx[i]));
4066  omFree(xx);
4067  return result;
4068}
4069/* currently unsed:
4070ideal idChineseRemainder(ideal *xx, intvec *iv)
4071{
4072  int rl=iv->length();
4073  number *q=(number *)omAlloc(rl*sizeof(number));
4074  int i;
4075  for(i=0; i<rl; i++)
4076  {
4077    q[i]=nInit((*iv)[i]);
4078  }
4079  return idChineseRemainder(xx,q,rl);
4080}
4081*/
4082/*
4083 * lift ideal with coeffs over Z (mod N) to Q via Farey
4084 */
4085ideal idFarey(ideal x, number N)
4086{
4087  int cnt=IDELEMS(x)*x->nrows;
4088  ideal result=idInit(cnt,x->rank);
4089  result->nrows=x->nrows; // for lifting matrices
4090  result->ncols=x->ncols; // for lifting matrices
4091
4092  int i;
4093  for(i=cnt-1;i>=0;i--)
4094  {
4095    poly h=pCopy(x->m[i]);
4096    result->m[i]=h;
4097    while(h!=NULL)
4098    {
4099      number c=pGetCoeff(h);
4100      pSetCoeff0(h,nlFarey(c,N));
4101      nDelete(&c);
4102      pIter(h);
4103    }
4104    while((result->m[i]!=NULL)&&(nIsZero(pGetCoeff(result->m[i]))))
4105    {
4106      pLmDelete(&(result->m[i]));
4107    }
4108    h=result->m[i];
4109    while((h!=NULL) && (pNext(h)!=NULL))
4110    {
4111      if(nIsZero(pGetCoeff(pNext(h))))
4112      {
4113        pLmDelete(&pNext(h));
4114      }
4115      else pIter(h);
4116    }
4117  }
4118  return result;
4119}
4120
4121/*2
4122* transpose a module
4123* NOTE: just a version of "ideal idTransp(ideal)" which works within specified ring.
4124*/
4125ideal id_Transp(ideal a, const ring rRing)
4126{
4127  int r = a->rank, c = IDELEMS(a);
4128  ideal b =  idInit(r,c);
4129
4130  for (int i=c; i>0; i--)
4131  {
4132    poly p=a->m[i-1];
4133    while(p!=NULL)
4134    {
4135      poly h=p_Head(p, rRing);
4136      int co=p_GetComp(h, rRing)-1;
4137      p_SetComp(h, i, rRing);
4138      p_Setm(h, rRing);
4139      b->m[co] = p_Add_q(b->m[co], h, rRing);
4140      pIter(p);
4141    }
4142  }
4143  return b;
4144}
4145
4146
4147
4148/*2
4149* The following is needed to compute the image of certain map used in
4150* the computation of cohomologies via BGG
4151* let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
4152* assuming that nrows(M) <= m*n; the procedure computes:
4153* transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
4154* where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
4155* that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
4156
4157  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
4158*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
4159*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
4160+ =>
4161  f_i =
4162
4163   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
4164   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
4165                             ...
4166   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
4167
4168   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
4169*/
4170ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing)
4171{
4172// #ifdef DEBU
4173//  WarnS("tensorModuleMult!!!!");
4174
4175  assume(m > 0);
4176  assume(M != NULL);
4177
4178  const int n = rRing->N;
4179
4180  assume(M->rank <= m * n);
4181
4182  const int k = IDELEMS(M);
4183
4184  ideal idTemp =  idInit(k,m); // = {f_1, ..., f_k }
4185
4186  for( int i = 0; i < k; i++ ) // for every w \in M
4187  {
4188    poly pTempSum = NULL;
4189
4190    poly w = M->m[i];
4191
4192    while(w != NULL) // for each term of w...
4193    {
4194      poly h = p_Head(w, rRing);
4195
4196      const int  gen = p_GetComp(h, rRing); // 1 ...
4197
4198      assume(gen > 0);
4199      assume(gen <= n*m);
4200
4201      // TODO: write a formula with %, / instead of while!
4202      /*
4203      int c = gen;
4204      int v = 1;
4205      while(c > m)
4206      {
4207        c -= m;
4208        v++;
4209      }
4210      */
4211
4212      int cc = gen % m;
4213      if( cc == 0) cc = m;
4214      int vv = 1 + (gen - cc) / m;
4215
4216//      assume( cc == c );
4217//      assume( vv == v );
4218
4219      //  1<= c <= m
4220      assume( cc > 0 );
4221      assume( cc <= m );
4222
4223      assume( vv > 0 );
4224      assume( vv <= n );
4225
4226      assume( (cc + (vv-1)*m) == gen );
4227
4228      p_IncrExp(h, vv, rRing); // h *= var(j) && //      p_AddExp(h, vv, 1, rRing);
4229      p_SetComp(h, cc, rRing);
4230
4231      p_Setm(h, rRing);         // addjust degree after the previous steps!
4232
4233      pTempSum = p_Add_q(pTempSum, h, rRing); // it is slow since h will be usually put to the back of pTempSum!!!
4234
4235      pIter(w);
4236    }
4237
4238    idTemp->m[i] = pTempSum;
4239  }
4240
4241  // simplify idTemp???
4242
4243  ideal idResult = id_Transp(idTemp, rRing);
4244
4245  id_Delete(&idTemp, rRing);
4246
4247  return(idResult);
4248}
Note: See TracBrowser for help on using the repository browser.