source: git/kernel/ideals.cc @ 03993b

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