source: git/kernel/ideals.cc @ 098f98f

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