source: git/kernel/ideals.cc @ 715f30

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