source: git/kernel/ideals.cc @ 10ca89

fieker-DuValspielwiese
Last change on this file since 10ca89 was c3005ea, checked in by Hans Schoenemann <hannes@…>, 13 years ago
code cleanup: pDehomgen, idDehomgen git-svn-id: file:///usr/local/Singular/svn/trunk@13700 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 86.5 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* verschiebt die Indizees der Modulerzeugenden um i
945*/
946void pShift (poly * p,int i)
947{
948  poly qp1 = *p,qp2 = *p;/*working pointers*/
949  int     j = pMaxComp(*p),k = pMinComp(*p);
950
951  if (j+i < 0) return ;
952  while (qp1 != NULL)
953  {
954    if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
955    {
956      pAddComp(qp1,i);
957      pSetmComp(qp1);
958      qp2 = qp1;
959      pIter(qp1);
960    }
961    else
962    {
963      if (qp2 == *p)
964      {
965        pIter(*p);
966        pLmDelete(&qp2);
967        qp2 = *p;
968        qp1 = *p;
969      }
970      else
971      {
972        qp2->next = qp1->next;
973        if (qp1!=NULL) pLmDelete(&qp1);
974        qp1 = qp2->next;
975      }
976    }
977  }
978}
979
980/*2
981*initialized a field with r numbers between beg and end for the
982*procedure idNextChoise
983*/
984void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
985{
986  /*returns the first choise of r numbers between beg and end*/
987  int i;
988  for (i=0; i<r; i++)
989  {
990    choise[i] = 0;
991  }
992  if (r <= end-beg+1)
993    for (i=0; i<r; i++)
994    {
995      choise[i] = beg+i;
996    }
997  if (r > end-beg+1)
998    *endch = TRUE;
999  else
1000    *endch = FALSE;
1001}
1002
1003/*2
1004*returns the next choise of r numbers between beg and end
1005*/
1006void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
1007{
1008  int i = r-1,j;
1009  while ((i >= 0) && (choise[i] == end))
1010  {
1011    i--;
1012    end--;
1013  }
1014  if (i == -1)
1015    *endch = TRUE;
1016  else
1017  {
1018    choise[i]++;
1019    for (j=i+1; j<r; j++)
1020    {
1021      choise[j] = choise[i]+j-i;
1022    }
1023    *endch = FALSE;
1024  }
1025}
1026
1027/*2
1028*takes the field choise of d numbers between beg and end, cancels the t-th
1029*entree and searches for the ordinal number of that d-1 dimensional field
1030* w.r.t. the algorithm of construction
1031*/
1032int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
1033{
1034  int * localchoise,i,result=0;
1035  BOOLEAN b=FALSE;
1036
1037  if (d<=1) return 1;
1038  localchoise=(int*)omAlloc((d-1)*sizeof(int));
1039  idInitChoise(d-1,begin,end,&b,localchoise);
1040  while (!b)
1041  {
1042    result++;
1043    i = 0;
1044    while ((i<t) && (localchoise[i]==choise[i])) i++;
1045    if (i>=t)
1046    {
1047      i = t+1;
1048      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
1049      if (i>=d)
1050      {
1051        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
1052        return result;
1053      }
1054    }
1055    idGetNextChoise(d-1,end,&b,localchoise);
1056  }
1057  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
1058  return 0;
1059}
1060
1061/*2
1062*computes the binomial coefficient
1063*/
1064int binom (int n,int r)
1065{
1066  int i,result;
1067
1068  if (r==0) return 1;
1069  if (n-r<r) return binom(n,n-r);
1070  result = n-r+1;
1071  for (i=2;i<=r;i++)
1072  {
1073    result *= n-r+i;
1074    if (result<0)
1075    {
1076      WarnS("overflow in binomials");
1077      return 0;
1078    }
1079    result /= i;
1080  }
1081  return result;
1082}
1083
1084/*2
1085*the free module of rank i
1086*/
1087ideal idFreeModule (int i)
1088{
1089  int j;
1090  ideal h;
1091
1092  h=idInit(i,i);
1093  for (j=0; j<i; j++)
1094  {
1095    h->m[j] = pOne();
1096    pSetComp(h->m[j],j+1);
1097    pSetmComp(h->m[j]);
1098  }
1099  return h;
1100}
1101
1102/*2
1103* h3 := h1 intersect h2
1104*/
1105ideal idSect (ideal h1,ideal h2)
1106{
1107  int i,j,k,length;
1108  int flength = idRankFreeModule(h1);
1109  int slength = idRankFreeModule(h2);
1110  int rank=si_min(flength,slength);
1111  if ((idIs0(h1)) || (idIs0(h2)))  return idInit(1,rank);
1112
1113  ideal first,second,temp,temp1,result;
1114  poly p,q;
1115
1116  if (IDELEMS(h1)<IDELEMS(h2))
1117  {
1118    first = h1;
1119    second = h2;
1120  }
1121  else
1122  {
1123    first = h2;
1124    second = h1;
1125    int t=flength; flength=slength; slength=t;
1126  }
1127  length  = si_max(flength,slength);
1128  if (length==0)
1129  {
1130    length = 1;
1131  }
1132  j = IDELEMS(first);
1133
1134  ring orig_ring=currRing;
1135  ring syz_ring=rCurrRingAssure_SyzComp();
1136  rSetSyzComp(length);
1137
1138  while ((j>0) && (first->m[j-1]==NULL)) j--;
1139  temp = idInit(j /*IDELEMS(first)*/+IDELEMS(second),length+j);
1140  k = 0;
1141  for (i=0;i<j;i++)
1142  {
1143    if (first->m[i]!=NULL)
1144    {
1145      if (syz_ring==orig_ring)
1146        temp->m[k] = pCopy(first->m[i]);
1147      else
1148        temp->m[k] = prCopyR(first->m[i], orig_ring);
1149      q = pOne();
1150      pSetComp(q,i+1+length);
1151      pSetmComp(q);
1152      if (flength==0) pShift(&(temp->m[k]),1);
1153      p = temp->m[k];
1154      while (pNext(p)!=NULL) pIter(p);
1155      pNext(p) = q;
1156      k++;
1157    }
1158  }
1159  for (i=0;i<IDELEMS(second);i++)
1160  {
1161    if (second->m[i]!=NULL)
1162    {
1163      if (syz_ring==orig_ring)
1164        temp->m[k] = pCopy(second->m[i]);
1165      else
1166        temp->m[k] = prCopyR(second->m[i], orig_ring);
1167      if (slength==0) pShift(&(temp->m[k]),1);
1168      k++;
1169    }
1170  }
1171  intvec *w=NULL;
1172  temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
1173  if (w!=NULL) delete w;
1174  idDelete(&temp);
1175
1176  if(syz_ring!=orig_ring)
1177    rChangeCurrRing(orig_ring);
1178
1179  result = idInit(IDELEMS(temp1),rank);
1180  j = 0;
1181  for (i=0;i<IDELEMS(temp1);i++)
1182  {
1183    if ((temp1->m[i]!=NULL)
1184    && (p_GetComp(temp1->m[i],syz_ring)>length))
1185    {
1186      if(syz_ring==orig_ring)
1187      {
1188        p = temp1->m[i];
1189      }
1190      else
1191      {
1192        p = prMoveR(temp1->m[i], syz_ring);
1193      }
1194      temp1->m[i]=NULL;
1195      while (p!=NULL)
1196      {
1197        q = pNext(p);
1198        pNext(p) = NULL;
1199        k = pGetComp(p)-1-length;
1200        pSetComp(p,0);
1201        pSetmComp(p);
1202        /* Warning! multiply only from the left! it's very important for Plural */
1203        result->m[j] = pAdd(result->m[j],pMult(p,pCopy(first->m[k])));
1204        p = q;
1205      }
1206      j++;
1207    }
1208  }
1209  if(syz_ring!=orig_ring)
1210  {
1211    rChangeCurrRing(syz_ring);
1212    idDelete(&temp1);
1213    rChangeCurrRing(orig_ring);
1214    rKill(syz_ring);
1215  }
1216  else
1217  {
1218    idDelete(&temp1);
1219  }
1220
1221  idSkipZeroes(result);
1222  if (TEST_OPT_RETURN_SB)
1223  {
1224     w=NULL;
1225     temp1=kStd(result,currQuotient,testHomog,&w);
1226     if (w!=NULL) delete w;
1227     idDelete(&result);
1228     idSkipZeroes(temp1);
1229     return temp1;
1230  }
1231  else //temp1=kInterRed(result,currQuotient);
1232    return result;
1233}
1234
1235/*2
1236* ideal/module intersection for a list of objects
1237* given as 'resolvente'
1238*/
1239ideal idMultSect(resolvente arg, int length)
1240{
1241  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
1242  ideal bigmat,tempstd,result;
1243  poly p;
1244  int isIdeal=0;
1245  intvec * w=NULL;
1246
1247  /* find 0-ideals and max rank -----------------------------------*/
1248  for (i=0;i<length;i++)
1249  {
1250    if (!idIs0(arg[i]))
1251    {
1252      realrki=idRankFreeModule(arg[i]);
1253      k++;
1254      j += IDELEMS(arg[i]);
1255      if (realrki>maxrk) maxrk = realrki;
1256    }
1257    else
1258    {
1259      if (arg[i]!=NULL)
1260      {
1261        return idInit(1,arg[i]->rank);
1262      }
1263    }
1264  }
1265  if (maxrk == 0)
1266  {
1267    isIdeal = 1;
1268    maxrk = 1;
1269  }
1270  /* init -----------------------------------------------------------*/
1271  j += maxrk;
1272  syzComp = k*maxrk;
1273
1274  ring orig_ring=currRing;
1275  ring syz_ring=rCurrRingAssure_SyzComp();
1276  rSetSyzComp(syzComp);
1277
1278  bigmat = idInit(j,(k+1)*maxrk);
1279  /* create unit matrices ------------------------------------------*/
1280  for (i=0;i<maxrk;i++)
1281  {
1282    for (j=0;j<=k;j++)
1283    {
1284      p = pOne();
1285      pSetComp(p,i+1+j*maxrk);
1286      pSetmComp(p);
1287      bigmat->m[i] = pAdd(bigmat->m[i],p);
1288    }
1289  }
1290  /* enter given ideals ------------------------------------------*/
1291  i = maxrk;
1292  k = 0;
1293  for (j=0;j<length;j++)
1294  {
1295    if (arg[j]!=NULL)
1296    {
1297      for (l=0;l<IDELEMS(arg[j]);l++)
1298      {
1299        if (arg[j]->m[l]!=NULL)
1300        {
1301          if (syz_ring==orig_ring)
1302            bigmat->m[i] = pCopy(arg[j]->m[l]);
1303          else
1304            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring);
1305          pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
1306          i++;
1307        }
1308      }
1309      k++;
1310    }
1311  }
1312  /* std computation --------------------------------------------*/
1313  tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
1314  if (w!=NULL) delete w;
1315  idDelete(&bigmat);
1316
1317  if(syz_ring!=orig_ring)
1318    rChangeCurrRing(orig_ring);
1319
1320  /* interprete result ----------------------------------------*/
1321  result = idInit(IDELEMS(tempstd),maxrk);
1322  k = 0;
1323  for (j=0;j<IDELEMS(tempstd);j++)
1324  {
1325    if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
1326    {
1327      if (syz_ring==orig_ring)
1328        p = pCopy(tempstd->m[j]);
1329      else
1330        p = prCopyR(tempstd->m[j], syz_ring);
1331      pShift(&p,-syzComp-isIdeal);
1332      result->m[k] = p;
1333      k++;
1334    }
1335  }
1336  /* clean up ----------------------------------------------------*/
1337  if(syz_ring!=orig_ring)
1338    rChangeCurrRing(syz_ring);
1339  idDelete(&tempstd);
1340  if(syz_ring!=orig_ring)
1341  {
1342    rChangeCurrRing(orig_ring);
1343    rKill(syz_ring);
1344  }
1345  idSkipZeroes(result);
1346  return result;
1347}
1348
1349/*2
1350*computes syzygies of h1,
1351*if quot != NULL it computes in the quotient ring modulo "quot"
1352*works always in a ring with ringorder_s
1353*/
1354static ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w)
1355{
1356  ideal   h2, h3;
1357  int     i;
1358  int     j,jj=0,k;
1359  poly    p,q;
1360
1361  if (idIs0(h1)) return NULL;
1362  k = idRankFreeModule(h1);
1363  h2=idCopy(h1);
1364  i = IDELEMS(h2)-1;
1365  if (k == 0)
1366  {
1367    for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
1368    k = 1;
1369  }
1370  if (syzcomp<k)
1371  {
1372    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
1373    syzcomp = k;
1374    rSetSyzComp(k);
1375  }
1376  h2->rank = syzcomp+i+1;
1377
1378  //if (hom==testHomog)
1379  //{
1380  //  if(idHomIdeal(h1,currQuotient))
1381  //  {
1382  //    hom=TRUE;
1383  //  }
1384  //}
1385
1386#if MYTEST
1387#ifdef RDEBUG
1388  Print("Prepare::h2: ");
1389  idPrint(h2);
1390
1391  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
1392
1393#endif
1394#endif
1395
1396  for (j=0; j<=i; j++)
1397  {
1398    p = h2->m[j];
1399    q = pOne();
1400    pSetComp(q,syzcomp+1+j);
1401    pSetmComp(q);
1402    if (p!=NULL)
1403    {
1404      while (pNext(p)) pIter(p);
1405      p->next = q;
1406    }
1407    else
1408      h2->m[j]=q;
1409  }
1410
1411#ifdef PDEBUG
1412  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
1413
1414#if MYTEST
1415#ifdef RDEBUG
1416  Print("Prepare::Input: ");
1417  idPrint(h2);
1418
1419  Print("Prepare::currQuotient: ");
1420  idPrint(currQuotient);
1421#endif
1422#endif
1423
1424#endif
1425
1426  idTest(h2);
1427
1428  h3 = kStd(h2,currQuotient,hom,w,NULL,syzcomp);
1429
1430#if MYTEST
1431#ifdef RDEBUG
1432  Print("Prepare::Output: ");
1433  idPrint(h3);
1434  for(j=0;j<IDELEMS(h2);j++) pTest(h3->m[j]);
1435#endif
1436#endif
1437
1438
1439  idDelete(&h2);
1440  return h3;
1441}
1442
1443/*2
1444* compute the syzygies of h1 in R/quot,
1445* weights of components are in w
1446* if setRegularity, return the regularity in deg
1447* do not change h1,  w
1448*/
1449ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
1450                  BOOLEAN setRegularity, int *deg)
1451{
1452  ideal s_h1;
1453  poly  p;
1454  int   j, k, length=0,reg;
1455  BOOLEAN isMonomial=TRUE;
1456  int ii, idElemens_h1;
1457
1458  assume(h1 != NULL);
1459
1460  idElemens_h1=IDELEMS(h1);
1461#ifdef PDEBUG
1462  for(ii=0;ii<idElemens_h1 /*IDELEMS(h1)*/;ii++) pTest(h1->m[ii]);
1463#endif
1464  if (idIs0(h1))
1465  {
1466    ideal result=idFreeModule(idElemens_h1/*IDELEMS(h1)*/);
1467    int curr_syz_limit=rGetCurrSyzLimit();
1468    if (curr_syz_limit>0)
1469    for (ii=0;ii<idElemens_h1/*IDELEMS(h1)*/;ii++)
1470    {
1471      if (h1->m[ii]!=NULL)
1472        pShift(&h1->m[ii],curr_syz_limit);
1473    }
1474    return result;
1475  }
1476  int slength=(int)idRankFreeModule(h1);
1477  k=si_max(1,slength /*idRankFreeModule(h1)*/);
1478
1479  assume(currRing != NULL);
1480  ring orig_ring=currRing;
1481  ring syz_ring=rCurrRingAssure_SyzComp();
1482
1483  if (setSyzComp)
1484    rSetSyzComp(k);
1485
1486  if (orig_ring != syz_ring)
1487  {
1488    s_h1=idrCopyR_NoSort(h1,orig_ring);
1489  }
1490  else
1491  {
1492    s_h1 = h1;
1493  }
1494
1495  idTest(s_h1);
1496
1497  ideal s_h3=idPrepare(s_h1,h,k,w); // main (syz) GB computation
1498
1499  if (s_h3==NULL)
1500  {
1501    return idFreeModule( idElemens_h1 /*IDELEMS(h1)*/);
1502  }
1503
1504  if (orig_ring != syz_ring)
1505  {
1506    idDelete(&s_h1);
1507    for (j=0; j<IDELEMS(s_h3); j++)
1508    {
1509      if (s_h3->m[j] != NULL)
1510      {
1511        if (p_MinComp(s_h3->m[j],syz_ring) > k)
1512          pShift(&s_h3->m[j], -k);
1513        else
1514          pDelete(&s_h3->m[j]);
1515      }
1516    }
1517    idSkipZeroes(s_h3);
1518    s_h3->rank -= k;
1519    rChangeCurrRing(orig_ring);
1520    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
1521    rKill(syz_ring);
1522    idTest(s_h3);
1523    return s_h3;
1524  }
1525
1526  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
1527
1528  for (j=IDELEMS(s_h3)-1; j>=0; j--)
1529  {
1530    if (s_h3->m[j] != NULL)
1531    {
1532      if (p_MinComp(s_h3->m[j],syz_ring) <= k)
1533      {
1534        e->m[j] = s_h3->m[j];
1535        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
1536        pDelete(&pNext(s_h3->m[j]));
1537        s_h3->m[j] = NULL;
1538      }
1539    }
1540  }
1541
1542  idSkipZeroes(s_h3);
1543  idSkipZeroes(e);
1544
1545  if ((deg != NULL)
1546  && (!isMonomial)
1547  && (!TEST_OPT_NOTREGULARITY)
1548  && (setRegularity)
1549  && (h==isHomog)
1550  && (!rIsPluralRing(currRing))
1551  )
1552  {
1553    ring dp_C_ring = rCurrRingAssure_dp_C();
1554    if (dp_C_ring != syz_ring)
1555      e = idrMoveR_NoSort(e, syz_ring);
1556    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
1557    intvec * dummy = syBetti(res,length,&reg, *w);
1558    *deg = reg+2;
1559    delete dummy;
1560    for (j=0;j<length;j++)
1561    {
1562      if (res[j]!=NULL) idDelete(&(res[j]));
1563    }
1564    omFreeSize((ADDRESS)res,length*sizeof(ideal));
1565    idDelete(&e);
1566    if (dp_C_ring != syz_ring)
1567    {
1568      rChangeCurrRing(syz_ring);
1569      rKill(dp_C_ring);
1570    }
1571  }
1572  else
1573  {
1574    idDelete(&e);
1575  }
1576  idTest(s_h3);
1577  if (currQuotient != NULL)
1578  {
1579    ideal ts_h3=kStd(s_h3,currQuotient,h,w);
1580    idDelete(&s_h3);
1581    s_h3 = ts_h3;
1582  }
1583  return s_h3;
1584}
1585
1586/*2
1587*/
1588ideal idXXX (ideal  h1, int k)
1589{
1590  ideal s_h1;
1591  int j;
1592  intvec *w=NULL;
1593
1594  assume(currRing != NULL);
1595  ring orig_ring=currRing;
1596  ring syz_ring=rCurrRingAssure_SyzComp();
1597
1598  rSetSyzComp(k);
1599
1600  if (orig_ring != syz_ring)
1601  {
1602    s_h1=idrCopyR_NoSort(h1,orig_ring);
1603  }
1604  else
1605  {
1606    s_h1 = h1;
1607  }
1608
1609  ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
1610
1611  if (s_h3==NULL)
1612  {
1613    return idFreeModule(IDELEMS(h1));
1614  }
1615
1616  if (orig_ring != syz_ring)
1617  {
1618    idDelete(&s_h1);
1619    idSkipZeroes(s_h3);
1620    rChangeCurrRing(orig_ring);
1621    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
1622    rKill(syz_ring);
1623    idTest(s_h3);
1624    return s_h3;
1625  }
1626
1627  idSkipZeroes(s_h3);
1628  idTest(s_h3);
1629  return s_h3;
1630}
1631
1632/*
1633*computes a standard basis for h1 and stores the transformation matrix
1634* in ma
1635*/
1636ideal idLiftStd (ideal  h1, matrix* ma, tHomog hi, ideal * syz)
1637{
1638  int   i, j, k, t, inputIsIdeal=idRankFreeModule(h1);
1639  poly  p=NULL, q, qq;
1640  intvec *w=NULL;
1641
1642  idDelete((ideal*)ma);
1643  BOOLEAN lift3=FALSE;
1644  if (syz!=NULL) { lift3=TRUE; idDelete(syz); }
1645  if (idIs0(h1))
1646  {
1647    *ma=mpNew(1,0);
1648    if (lift3)
1649    {
1650      *syz=idFreeModule(IDELEMS(h1));
1651      int curr_syz_limit=rGetCurrSyzLimit();
1652      if (curr_syz_limit>0)
1653      for (int ii=0;ii<IDELEMS(h1);ii++)
1654      {
1655        if (h1->m[ii]!=NULL)
1656          pShift(&h1->m[ii],curr_syz_limit);
1657      }
1658    }
1659    return idInit(1,h1->rank);
1660  }
1661
1662  BITSET save_verbose=verbose;
1663
1664  k=si_max(1,(int)idRankFreeModule(h1));
1665
1666  if ((k==1) && (!lift3)) verbose |=Sy_bit(V_IDLIFT);
1667
1668  ring orig_ring = currRing;
1669  ring syz_ring = rCurrRingAssure_SyzComp();
1670  rSetSyzComp(k);
1671
1672  ideal s_h1=h1;
1673
1674  if (orig_ring != syz_ring)
1675    s_h1 = idrCopyR_NoSort(h1,orig_ring);
1676  else
1677    s_h1 = h1;
1678
1679  ideal s_h3=idPrepare(s_h1,hi,k,&w); // main (syz) GB computation
1680
1681  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
1682
1683  if (lift3) (*syz)=idInit(IDELEMS(s_h3),IDELEMS(h1));
1684
1685  if (w!=NULL) delete w;
1686  i = 0;
1687
1688  // now sort the result, SB : leave in s_h3
1689  //                      T:  put in s_h2
1690  //                      syz: put in *syz
1691  for (j=0; j<IDELEMS(s_h3); j++)
1692  {
1693    if (s_h3->m[j] != NULL)
1694    {
1695      //if (p_MinComp(s_h3->m[j],syz_ring) <= k)
1696      if (pGetComp(s_h3->m[j]) <= k) // syz_ring == currRing
1697      {
1698        i++;
1699        q = s_h3->m[j];
1700        while (pNext(q) != NULL)
1701        {
1702          if (pGetComp(pNext(q)) > k)
1703          {
1704            s_h2->m[j] = pNext(q);
1705            pNext(q) = NULL;
1706          }
1707          else
1708          {
1709            pIter(q);
1710          }
1711        }
1712        if (!inputIsIdeal) pShift(&(s_h3->m[j]), -1);
1713      }
1714      else
1715      {
1716        // we a syzygy here:
1717        if (lift3)
1718        {
1719          pShift(&s_h3->m[j], -k);
1720          (*syz)->m[j]=s_h3->m[j];
1721          s_h3->m[j]=NULL;
1722        }
1723        else
1724          pDelete(&(s_h3->m[j]));
1725      }
1726    }
1727  }
1728  idSkipZeroes(s_h3);
1729  //extern char * iiStringMatrix(matrix im, int dim,char ch);
1730  //PrintS("SB: ----------------------------------------\n");
1731  //PrintS(iiStringMatrix((matrix)s_h3,k,'\n'));
1732  //PrintLn();
1733  //PrintS("T: ----------------------------------------\n");
1734  //PrintS(iiStringMatrix((matrix)s_h2,h1->rank,'\n'));
1735  //PrintLn();
1736
1737  if (lift3) idSkipZeroes(*syz);
1738
1739  j = IDELEMS(s_h1);
1740
1741
1742  if (syz_ring!=orig_ring)
1743  {
1744    idDelete(&s_h1);
1745    rChangeCurrRing(orig_ring);
1746  }
1747
1748  *ma = mpNew(j,i);
1749
1750  i = 1;
1751  for (j=0; j<IDELEMS(s_h2); j++)
1752  {
1753    if (s_h2->m[j] != NULL)
1754    {
1755      q = prMoveR( s_h2->m[j], syz_ring);
1756      s_h2->m[j] = NULL;
1757
1758      while (q != NULL)
1759      {
1760        p = q;
1761        pIter(q);
1762        pNext(p) = NULL;
1763        t=pGetComp(p);
1764        pSetComp(p,0);
1765        pSetmComp(p);
1766        MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
1767      }
1768      i++;
1769    }
1770  }
1771  idDelete(&s_h2);
1772
1773  for (i=0; i<IDELEMS(s_h3); i++)
1774  {
1775    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring);
1776  }
1777  if (lift3)
1778  {
1779    for (i=0; i<IDELEMS(*syz); i++)
1780    {
1781      (*syz)->m[i] = prMoveR_NoSort((*syz)->m[i], syz_ring);
1782    }
1783  }
1784
1785  if (syz_ring!=orig_ring) rKill(syz_ring);
1786  verbose = save_verbose;
1787  return s_h3;
1788}
1789
1790static void idPrepareStd(ideal s_temp, int k)
1791{
1792  int j,rk=idRankFreeModule(s_temp);
1793  poly p,q;
1794
1795  if (rk == 0)
1796  {
1797    for (j=0; j<IDELEMS(s_temp); j++)
1798    {
1799      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
1800    }
1801    k = si_max(k,1);
1802  }
1803  for (j=0; j<IDELEMS(s_temp); j++)
1804  {
1805    if (s_temp->m[j]!=NULL)
1806    {
1807      p = s_temp->m[j];
1808      q = pOne();
1809      //pGetCoeff(q)=nNeg(pGetCoeff(q));   //set q to -1
1810      pSetComp(q,k+1+j);
1811      pSetmComp(q);
1812      while (pNext(p)) pIter(p);
1813      pNext(p) = q;
1814    }
1815  }
1816}
1817
1818/*2
1819*computes a representation of the generators of submod with respect to those
1820* of mod
1821*/
1822
1823ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
1824             BOOLEAN isSB, BOOLEAN divide, matrix *unit)
1825{
1826  int lsmod =idRankFreeModule(submod), i, j, k;
1827  int comps_to_add=0;
1828  poly p;
1829
1830  if (idIs0(submod))
1831  {
1832    if (unit!=NULL)
1833    {
1834      *unit=mpNew(1,1);
1835      MATELEM(*unit,1,1)=pOne();
1836    }
1837    if (rest!=NULL)
1838    {
1839      *rest=idInit(1,mod->rank);
1840    }
1841    return idInit(1,mod->rank);
1842  }
1843  if (idIs0(mod)) /* and not idIs0(submod) */
1844  {
1845    WerrorS("2nd module does not lie in the first");
1846    #if 0
1847    if (unit!=NULL)
1848    {
1849      i=IDELEMS(submod);
1850      *unit=mpNew(i,i);
1851      for (j=i;j>0;j--)
1852      {
1853        MATELEM(*unit,j,j)=pOne();
1854      }
1855    }
1856    if (rest!=NULL)
1857    {
1858      *rest=idCopy(submod);
1859    }
1860    return idInit(1,mod->rank);
1861    #endif
1862    return idInit(IDELEMS(submod),submod->rank);
1863  }
1864  if (unit!=NULL)
1865  {
1866    comps_to_add = IDELEMS(submod);
1867    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
1868      comps_to_add--;
1869  }
1870  k=si_max(idRankFreeModule(mod),idRankFreeModule(submod));
1871  if  ((k!=0) && (lsmod==0)) lsmod=1;
1872  k=si_max(k,(int)mod->rank);
1873  if (k<submod->rank) { WarnS("rk(submod) > rk(mod) ?");k=submod->rank; }
1874
1875  ring orig_ring=currRing;
1876  ring syz_ring=rCurrRingAssure_SyzComp();
1877  rSetSyzComp(k);
1878
1879  ideal s_mod, s_temp;
1880  if (orig_ring != syz_ring)
1881  {
1882    s_mod = idrCopyR_NoSort(mod,orig_ring);
1883    s_temp = idrCopyR_NoSort(submod,orig_ring);
1884  }
1885  else
1886  {
1887    s_mod = mod;
1888    s_temp = idCopy(submod);
1889  }
1890  ideal s_h3;
1891  if (isSB)
1892  {
1893    s_h3 = idCopy(s_mod);
1894    idPrepareStd(s_h3, k+comps_to_add);
1895  }
1896  else
1897  {
1898    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
1899  }
1900  if (!goodShape)
1901  {
1902    for (j=0;j<IDELEMS(s_h3);j++)
1903    {
1904      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
1905        pDelete(&(s_h3->m[j]));
1906    }
1907  }
1908  idSkipZeroes(s_h3);
1909  if (lsmod==0)
1910  {
1911    for (j=IDELEMS(s_temp);j>0;j--)
1912    {
1913      if (s_temp->m[j-1]!=NULL)
1914        pShift(&(s_temp->m[j-1]),1);
1915    }
1916  }
1917  if (unit!=NULL)
1918  {
1919    for(j = 0;j<comps_to_add;j++)
1920    {
1921      p = s_temp->m[j];
1922      if (p!=NULL)
1923      {
1924        while (pNext(p)!=NULL) pIter(p);
1925        pNext(p) = pOne();
1926        pIter(p);
1927        pSetComp(p,1+j+k);
1928        pSetmComp(p);
1929        p = pNeg(p);
1930      }
1931    }
1932  }
1933  ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
1934  s_result->rank = s_h3->rank;
1935  ideal s_rest = idInit(IDELEMS(s_result),k);
1936  idDelete(&s_h3);
1937  idDelete(&s_temp);
1938
1939  for (j=0;j<IDELEMS(s_result);j++)
1940  {
1941    if (s_result->m[j]!=NULL)
1942    {
1943      if (pGetComp(s_result->m[j])<=k)
1944      {
1945        if (!divide)
1946        {
1947          if (isSB)
1948          {
1949            WarnS("first module not a standardbasis\n"
1950              "// ** or second not a proper submodule");
1951          }
1952          else
1953            WerrorS("2nd module does not lie in the first");
1954          idDelete(&s_result);
1955          idDelete(&s_rest);
1956          s_result=idInit(IDELEMS(submod),submod->rank);
1957          break;
1958        }
1959        else
1960        {
1961          p = s_rest->m[j] = s_result->m[j];
1962          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1963          s_result->m[j] = pNext(p);
1964          pNext(p) = NULL;
1965        }
1966      }
1967      pShift(&(s_result->m[j]),-k);
1968      pNeg(s_result->m[j]);
1969    }
1970  }
1971  if ((lsmod==0) && (!idIs0(s_rest)))
1972  {
1973    for (j=IDELEMS(s_rest);j>0;j--)
1974    {
1975      if (s_rest->m[j-1]!=NULL)
1976      {
1977        pShift(&(s_rest->m[j-1]),-1);
1978        s_rest->m[j-1] = s_rest->m[j-1];
1979      }
1980    }
1981  }
1982  if(syz_ring!=orig_ring)
1983  {
1984    idDelete(&s_mod);
1985    rChangeCurrRing(orig_ring);
1986    s_result = idrMoveR_NoSort(s_result, syz_ring);
1987    s_rest = idrMoveR_NoSort(s_rest, syz_ring);
1988    rKill(syz_ring);
1989  }
1990  if (rest!=NULL)
1991    *rest = s_rest;
1992  else
1993    idDelete(&s_rest);
1994//idPrint(s_result);
1995  if (unit!=NULL)
1996  {
1997    *unit=mpNew(comps_to_add,comps_to_add);
1998    int i;
1999    for(i=0;i<IDELEMS(s_result);i++)
2000    {
2001      poly p=s_result->m[i];
2002      poly q=NULL;
2003      while(p!=NULL)
2004      {
2005        if(pGetComp(p)<=comps_to_add)
2006        {
2007          pSetComp(p,0);
2008          if (q!=NULL)
2009          {
2010            pNext(q)=pNext(p);
2011          }
2012          else
2013          {
2014            pIter(s_result->m[i]);
2015          }
2016          pNext(p)=NULL;
2017          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
2018          if(q!=NULL)   p=pNext(q);
2019          else          p=s_result->m[i];
2020        }
2021        else
2022        {
2023          q=p;
2024          pIter(p);
2025        }
2026      }
2027      pShift(&s_result->m[i],-comps_to_add);
2028    }
2029  }
2030  return s_result;
2031}
2032
2033/*2
2034*computes division of P by Q with remainder up to (w-weighted) degree n
2035*P, Q, and w are not changed
2036*/
2037void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
2038{
2039  long N=0;
2040  int i;
2041  for(i=IDELEMS(Q)-1;i>=0;i--)
2042    if(w==NULL)
2043      N=si_max(N,pDeg(Q->m[i]));
2044    else
2045      N=si_max(N,pDegW(Q->m[i],w));
2046  N+=n;
2047
2048  T=mpNew(IDELEMS(Q),IDELEMS(P));
2049  R=idInit(IDELEMS(P),P->rank);
2050
2051  for(i=IDELEMS(P)-1;i>=0;i--)
2052  {
2053    poly p;
2054    if(w==NULL)
2055      p=ppJet(P->m[i],N);
2056    else
2057      p=ppJetW(P->m[i],N,w);
2058
2059    int j=IDELEMS(Q)-1;
2060    while(p!=NULL)
2061    {
2062      if(pDivisibleBy(Q->m[j],p))
2063      {
2064        poly p0=pDivideM(pHead(p),pHead(Q->m[j]));
2065        if(w==NULL)
2066          p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
2067        else
2068          p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
2069        pNormalize(p);
2070        if((w==NULL)&&(pDeg(p0)>n)||(w!=NULL)&&(pDegW(p0,w)>n))
2071          pDelete(&p0);
2072        else
2073          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
2074        j=IDELEMS(Q)-1;
2075      }
2076      else
2077      {
2078        if(j==0)
2079        {
2080          poly p0=p;
2081          pIter(p);
2082          pNext(p0)=NULL;
2083          if(((w==NULL)&&(pDeg(p0)>n))
2084          ||((w!=NULL)&&(pDegW(p0,w)>n)))
2085            pDelete(&p0);
2086          else
2087            R->m[i]=pAdd(R->m[i],p0);
2088          j=IDELEMS(Q)-1;
2089        }
2090        else
2091          j--;
2092      }
2093    }
2094  }
2095}
2096
2097/*2
2098*computes the quotient of h1,h2 : internal routine for idQuot
2099*BEWARE: the returned ideals may contain incorrectly ordered polys !
2100*
2101*/
2102static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
2103                               BOOLEAN *addOnlyOne, int *kkmax)
2104{
2105  ideal temph1;
2106  poly     p,q = NULL;
2107  int i,l,ll,k,kkk,kmax;
2108  int j = 0;
2109  int k1 = idRankFreeModule(h1);
2110  int k2 = idRankFreeModule(h2);
2111  tHomog   hom=isNotHomog;
2112
2113  k=si_max(k1,k2);
2114  if (k==0)
2115    k = 1;
2116  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
2117
2118  intvec * weights;
2119  hom = (tHomog)idHomModule(h1,currQuotient,&weights);
2120  if (/**addOnlyOne &&*/ (!h1IsStb))
2121    temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
2122  else
2123    temph1 = idCopy(h1);
2124  if (weights!=NULL) delete weights;
2125  idTest(temph1);
2126/*--- making a single vector from h2 ---------------------*/
2127  for (i=0; i<IDELEMS(h2); i++)
2128  {
2129    if (h2->m[i] != NULL)
2130    {
2131      p = pCopy(h2->m[i]);
2132      if (k2 == 0)
2133        pShift(&p,j*k+1);
2134      else
2135        pShift(&p,j*k);
2136      q = pAdd(q,p);
2137      j++;
2138    }
2139  }
2140  *kkmax = kmax = j*k+1;
2141/*--- adding a monomial for the result (syzygy) ----------*/
2142  p = q;
2143  while (pNext(p)!=NULL) pIter(p);
2144  pNext(p) = pOne();
2145  pIter(p);
2146  pSetComp(p,kmax);
2147  pSetmComp(p);
2148/*--- constructing the big matrix ------------------------*/
2149  ideal h4 = idInit(16,kmax+k-1);
2150  h4->m[0] = q;
2151  if (k2 == 0)
2152  {
2153    if (k > IDELEMS(h4))
2154    {
2155      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
2156      IDELEMS(h4) = k;
2157    }
2158    for (i=1; i<k; i++)
2159    {
2160      if (h4->m[i-1]!=NULL)
2161      {
2162        p = pCopy_noCheck(h4->m[i-1]);
2163        pShift(&p,1);
2164        h4->m[i] = p;
2165      }
2166    }
2167  }
2168  idSkipZeroes(h4);
2169  kkk = IDELEMS(h4);
2170  i = IDELEMS(temph1);
2171  for (l=0; l<i; l++)
2172  {
2173    if(temph1->m[l]!=NULL)
2174    {
2175      for (ll=0; ll<j; ll++)
2176      {
2177        p = pCopy(temph1->m[l]);
2178        if (k1 == 0)
2179          pShift(&p,ll*k+1);
2180        else
2181          pShift(&p,ll*k);
2182        if (kkk >= IDELEMS(h4))
2183        {
2184          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
2185          IDELEMS(h4) += 16;
2186        }
2187        h4->m[kkk] = p;
2188        kkk++;
2189      }
2190    }
2191  }
2192/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
2193  if (*addOnlyOne)
2194  {
2195    idSkipZeroes(h4);
2196    p = h4->m[0];
2197    for (i=0;i<IDELEMS(h4)-1;i++)
2198    {
2199      h4->m[i] = h4->m[i+1];
2200    }
2201    h4->m[IDELEMS(h4)-1] = p;
2202    test |= Sy_bit(OPT_SB_1);
2203  }
2204  idDelete(&temph1);
2205  return h4;
2206}
2207/*2
2208*computes the quotient of h1,h2
2209*/
2210ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
2211{
2212  // first check for special case h1:(0)
2213  if (idIs0(h2))
2214  {
2215    ideal res;
2216    if (resultIsIdeal)
2217    {
2218      res = idInit(1,1);
2219      res->m[0] = pOne();
2220    }
2221    else
2222      res = idFreeModule(h1->rank);
2223    return res;
2224  }
2225  BITSET old_test=test;
2226  int i,l,ll,k,kkk,kmax;
2227  BOOLEAN  addOnlyOne=TRUE;
2228  tHomog   hom=isNotHomog;
2229  intvec * weights1;
2230
2231  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
2232
2233  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
2234
2235  ring orig_ring=currRing;
2236  ring syz_ring=rCurrRingAssure_SyzComp();
2237  rSetSyzComp(kmax-1);
2238  if (orig_ring!=syz_ring)
2239  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
2240    s_h4 = idrMoveR(s_h4,orig_ring);
2241  idTest(s_h4);
2242  #if 0
2243  void ipPrint_MA0(matrix m, const char *name);
2244  matrix m=idModule2Matrix(idCopy(s_h4));
2245  PrintS("start:\n");
2246  ipPrint_MA0(m,"Q");
2247  idDelete((ideal *)&m);
2248  PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
2249  #endif
2250  ideal s_h3;
2251  if (addOnlyOne)
2252  {
2253    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
2254  }
2255  else
2256  {
2257    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
2258  }
2259  test = old_test;
2260  #if 0
2261  // only together with the above debug stuff
2262  idSkipZeroes(s_h3);
2263  m=idModule2Matrix(idCopy(s_h3));
2264  Print("result, kmax=%d:\n",kmax);
2265  ipPrint_MA0(m,"S");
2266  idDelete((ideal *)&m);
2267  #endif
2268  idTest(s_h3);
2269  if (weights1!=NULL) delete weights1;
2270  idDelete(&s_h4);
2271
2272  for (i=0;i<IDELEMS(s_h3);i++)
2273  {
2274    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
2275    {
2276      if (resultIsIdeal)
2277        pShift(&s_h3->m[i],-kmax);
2278      else
2279        pShift(&s_h3->m[i],-kmax+1);
2280    }
2281    else
2282      pDelete(&s_h3->m[i]);
2283  }
2284  if (resultIsIdeal)
2285    s_h3->rank = 1;
2286  else
2287    s_h3->rank = h1->rank;
2288  if(syz_ring!=orig_ring)
2289  {
2290    rChangeCurrRing(orig_ring);
2291    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
2292    rKill(syz_ring);
2293  }
2294  idSkipZeroes(s_h3);
2295  idTest(s_h3);
2296  return s_h3;
2297}
2298
2299/*2
2300*computes recursively all monomials of a certain degree
2301*in every step the actvar-th entry in the exponential
2302*vector is incremented and the other variables are
2303*computed by recursive calls of makemonoms
2304*if the last variable is reached, the difference to the
2305*degree is computed directly
2306*vars is the number variables
2307*actvar is the actual variable to handle
2308*deg is the degree of the monomials to compute
2309*monomdeg is the actual degree of the monomial in consideration
2310*/
2311static void makemonoms(int vars,int actvar,int deg,int monomdeg)
2312{
2313  poly p;
2314  int i=0;
2315
2316  if ((idpowerpoint == 0) && (actvar ==1))
2317  {
2318    idpower[idpowerpoint] = pOne();
2319    monomdeg = 0;
2320  }
2321  while (i<=deg)
2322  {
2323    if (deg == monomdeg)
2324    {
2325      pSetm(idpower[idpowerpoint]);
2326      idpowerpoint++;
2327      return;
2328    }
2329    if (actvar == vars)
2330    {
2331      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
2332      pSetm(idpower[idpowerpoint]);
2333      pTest(idpower[idpowerpoint]);
2334      idpowerpoint++;
2335      return;
2336    }
2337    else
2338    {
2339      p = pCopy(idpower[idpowerpoint]);
2340      makemonoms(vars,actvar+1,deg,monomdeg);
2341      idpower[idpowerpoint] = p;
2342    }
2343    monomdeg++;
2344    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
2345    pSetm(idpower[idpowerpoint]);
2346    pTest(idpower[idpowerpoint]);
2347    i++;
2348  }
2349}
2350
2351/*2
2352*returns the deg-th power of the maximal ideal of 0
2353*/
2354ideal idMaxIdeal(int deg)
2355{
2356  if (deg < 0)
2357  {
2358    WarnS("maxideal: power must be non-negative");
2359  }
2360  if (deg < 1)
2361  {
2362    ideal I=idInit(1,1);
2363    I->m[0]=pOne();
2364    return I;
2365  }
2366  if (deg == 1)
2367  {
2368    return idMaxIdeal();
2369  }
2370
2371  int vars = currRing->N;
2372  int i = binom(vars+deg-1,deg);
2373  if (i<=0) return idInit(1,1);
2374  ideal id=idInit(i,1);
2375  idpower = id->m;
2376  idpowerpoint = 0;
2377  makemonoms(vars,1,deg,0);
2378  idpower = NULL;
2379  idpowerpoint = 0;
2380  return id;
2381}
2382
2383/*2
2384*computes recursively all generators of a certain degree
2385*of the ideal "givenideal"
2386*elms is the number elements in the given ideal
2387*actelm is the actual element to handle
2388*deg is the degree of the power to compute
2389*gendeg is the actual degree of the generator in consideration
2390*/
2391static void makepotence(int elms,int actelm,int deg,int gendeg)
2392{
2393  poly p;
2394  int i=0;
2395
2396  if ((idpowerpoint == 0) && (actelm ==1))
2397  {
2398    idpower[idpowerpoint] = pOne();
2399    gendeg = 0;
2400  }
2401  while (i<=deg)
2402  {
2403    if (deg == gendeg)
2404    {
2405      idpowerpoint++;
2406      return;
2407    }
2408    if (actelm == elms)
2409    {
2410      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
2411      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
2412      idpowerpoint++;
2413      return;
2414    }
2415    else
2416    {
2417      p = pCopy(idpower[idpowerpoint]);
2418      makepotence(elms,actelm+1,deg,gendeg);
2419      idpower[idpowerpoint] = p;
2420    }
2421    gendeg++;
2422    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
2423    i++;
2424  }
2425}
2426
2427/*2
2428*returns the deg-th power of the ideal gid
2429*/
2430//ideal idPower(ideal gid,int deg)
2431//{
2432//  int i;
2433//  ideal id;
2434//
2435//  if (deg < 1) deg = 1;
2436//  i = binom(IDELEMS(gid)+deg-1,deg);
2437//  id=idInit(i,1);
2438//  idpower = id->m;
2439//  givenideal = gid->m;
2440//  idpowerpoint = 0;
2441//  makepotence(IDELEMS(gid),1,deg,0);
2442//  idpower = NULL;
2443//  givenideal = NULL;
2444//  idpowerpoint = 0;
2445//  return id;
2446//}
2447static void idNextPotence(ideal given, ideal result,
2448  int begin, int end, int deg, int restdeg, poly ap)
2449{
2450  poly p;
2451  int i;
2452
2453  p = pPower(pCopy(given->m[begin]),restdeg);
2454  i = result->nrows;
2455  result->m[i] = pMult(pCopy(ap),p);
2456//PrintS(".");
2457  (result->nrows)++;
2458  if (result->nrows >= IDELEMS(result))
2459  {
2460    pEnlargeSet(&(result->m),IDELEMS(result),16);
2461    IDELEMS(result) += 16;
2462  }
2463  if (begin == end) return;
2464  for (i=restdeg-1;i>0;i--)
2465  {
2466    p = pPower(pCopy(given->m[begin]),i);
2467    p = pMult(pCopy(ap),p);
2468    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
2469    pDelete(&p);
2470  }
2471  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
2472}
2473
2474ideal idPower(ideal given,int exp)
2475{
2476  ideal result,temp;
2477  poly p1;
2478  int i;
2479
2480  if (idIs0(given)) return idInit(1,1);
2481  temp = idCopy(given);
2482  idSkipZeroes(temp);
2483  i = binom(IDELEMS(temp)+exp-1,exp);
2484  result = idInit(i,1);
2485  result->nrows = 0;
2486//Print("ideal contains %d elements\n",i);
2487  p1=pOne();
2488  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
2489  pDelete(&p1);
2490  idDelete(&temp);
2491  result->nrows = 1;
2492  idDelEquals(result);
2493  idSkipZeroes(result);
2494  return result;
2495}
2496
2497/*2
2498* eliminate delVar (product of vars) in h1
2499*/
2500ideal idElimination (ideal h1,poly delVar,intvec *hilb)
2501{
2502  int    i,j=0,k,l;
2503  ideal  h,hh, h3;
2504  int    *ord,*block0,*block1;
2505  int    ordersize=2;
2506  int    **wv;
2507  tHomog hom;
2508  intvec * w;
2509  ring tmpR;
2510  ring origR = currRing;
2511
2512  if (delVar==NULL)
2513  {
2514    return idCopy(h1);
2515  }
2516  if ((currQuotient!=NULL) && rIsPluralRing(origR))
2517  {
2518    WerrorS("cannot eliminate in a qring");
2519    return idCopy(h1);
2520  }
2521  if (idIs0(h1)) return idInit(1,h1->rank);
2522#ifdef HAVE_PLURAL
2523  if (rIsPluralRing(origR))
2524    /* in the NC case, we have to check the admissibility of */
2525    /* the subalgebra to be intersected with */
2526  {
2527    if ((ncRingType(origR) != nc_skew) && (ncRingType(origR) != nc_exterior)) /* in (quasi)-commutative algebras every subalgebra is admissible */
2528    {
2529      if (nc_CheckSubalgebra(delVar,origR))
2530      {
2531        WerrorS("no elimination is possible: subalgebra is not admissible");
2532        return idCopy(h1);
2533      }
2534    }
2535  }
2536#endif
2537  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
2538  h3=idInit(16,h1->rank);
2539  for (k=0;; k++)
2540  {
2541    if (origR->order[k]!=0) ordersize++;
2542    else break;
2543  }
2544  ord=(int*)omAlloc0(ordersize*sizeof(int));
2545  block0=(int*)omAlloc0(ordersize*sizeof(int));
2546  block1=(int*)omAlloc0(ordersize*sizeof(int));
2547  wv=(int**) omAlloc0(ordersize*sizeof(int**));
2548#if 0
2549  if (rIsPluralRing(origR)) // we have too keep the odering: it may be needed
2550                            // for G-algebra
2551  {
2552    for (k=0;k<ordersize-1; k++)
2553    {
2554      block0[k+1] = origR->block0[k];
2555      block1[k+1] = origR->block1[k];
2556      ord[k+1] = origR->order[k];
2557      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
2558    }
2559  }
2560  else
2561  {
2562    block0[1] = 1;
2563    block1[1] = pVariables;
2564    if (origR->OrdSgn==1) ord[1] = ringorder_wp;
2565    else                  ord[1] = ringorder_ws;
2566    wv[1]=(int*)omAlloc0(pVariables*sizeof(int));
2567    double wNsqr = (double)2.0 / (double)pVariables;
2568    wFunctional = wFunctionalBuch;
2569    int  *x= (int * )omAlloc(2 * (pVariables + 1) * sizeof(int));
2570    int sl=IDELEMS(h1) - 1;
2571    wCall(h1->m, sl, x, wNsqr);
2572    for (sl = pVariables; sl!=0; sl--)
2573      wv[1][sl-1] = x[sl + pVariables + 1];
2574    omFreeSize((ADDRESS)x, 2 * (pVariables + 1) * sizeof(int));
2575
2576    ord[2]=ringorder_C;
2577    ord[3]=0;
2578  }
2579#else
2580  for (k=0;k<ordersize-1; k++)
2581  {
2582    block0[k+1] = origR->block0[k];
2583    block1[k+1] = origR->block1[k];
2584    ord[k+1] = origR->order[k];
2585    if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
2586  }
2587#endif
2588  block0[0] = 1;
2589  block1[0] = rVar(origR);
2590  wv[0]=(int*)omAlloc((rVar(origR) + 1)*sizeof(int));
2591  memset(wv[0],0,(rVar(origR) + 1)*sizeof(int));
2592  for (j=0;j<rVar(origR);j++)
2593    if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2594  // use this special ordering: like ringorder_a, except that pFDeg, pWeights
2595  // ignore it
2596  ord[0] = ringorder_aa;
2597  // fill in tmp ring to get back the data later on
2598  tmpR  = rCopy0(origR,FALSE,FALSE); // qring==NULL
2599  //rUnComplete(tmpR);
2600  tmpR->p_Procs=NULL;
2601  tmpR->order = ord;
2602  tmpR->block0 = block0;
2603  tmpR->block1 = block1;
2604  tmpR->wvhdl = wv;
2605  rComplete(tmpR, 1);
2606
2607#ifdef HAVE_PLURAL
2608  /* update nc structure on tmpR */
2609  if (rIsPluralRing(origR))
2610  {
2611    if ( nc_rComplete(origR, tmpR, false) ) // no quotient ideal!
2612    {
2613      Werror("no elimination is possible: ordering condition is violated");
2614      // cleanup
2615      rDelete(tmpR);
2616      if (w!=NULL)
2617        delete w;
2618      return idCopy(h1);
2619    }
2620  }
2621#endif
2622  // change into the new ring
2623  //pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
2624  rChangeCurrRing(tmpR);
2625
2626  //h = idInit(IDELEMS(h1),h1->rank);
2627  // fetch data from the old ring
2628  //for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
2629  h=idrCopyR(h1,origR,currRing);
2630  if (origR->qideal!=NULL)
2631  {
2632    WarnS("eliminate in q-ring: experimental");
2633    ideal q=idrCopyR(origR->qideal,origR,currRing);
2634    ideal s=idSimpleAdd(h,q);
2635    idDelete(&h);
2636    idDelete(&q);
2637    h=s;
2638  }
2639  // compute kStd
2640#if 1
2641  //rWrite(tmpR);PrintLn();
2642  BITSET save=test;
2643  //test |=1;
2644  //Print("h: %d gen, rk=%d\n",IDELEMS(h),h->rank);
2645  //extern char * showOption();
2646  //Print("%s\n",showOption());
2647  hh = kStd(h,NULL,hom,&w,hilb);
2648  test=save;
2649  idDelete(&h);
2650#else
2651  extern ideal kGroebner(ideal F, ideal Q);
2652  hh=kGroebner(h,NULL);
2653#endif
2654  // go back to the original ring
2655  rChangeCurrRing(origR);
2656  i = IDELEMS(hh)-1;
2657  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2658  j = -1;
2659  // fetch data from temp ring
2660  for (k=0; k<=i; k++)
2661  {
2662    l=pVariables;
2663    while ((l>0) && (p_GetExp( hh->m[k],l,tmpR)*pGetExp(delVar,l)==0)) l--;
2664    if (l==0)
2665    {
2666      j++;
2667      if (j >= IDELEMS(h3))
2668      {
2669        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2670        IDELEMS(h3) += 16;
2671      }
2672      h3->m[j] = prMoveR( hh->m[k], tmpR);
2673      hh->m[k] = NULL;
2674    }
2675  }
2676  id_Delete(&hh, tmpR);
2677  idSkipZeroes(h3);
2678  rDelete(tmpR);
2679  if (w!=NULL)
2680    delete w;
2681  return h3;
2682}
2683
2684/*2
2685* compute the which-th ar-minor of the matrix a
2686*/
2687poly idMinor(matrix a, int ar, unsigned long which, ideal R)
2688{
2689  int     i,j,k,size;
2690  unsigned long curr;
2691  int *rowchoise,*colchoise;
2692  BOOLEAN rowch,colch;
2693  ideal result;
2694  matrix tmp;
2695  poly p,q;
2696
2697  i = binom(a->rows(),ar);
2698  j = binom(a->cols(),ar);
2699
2700  rowchoise=(int *)omAlloc(ar*sizeof(int));
2701  colchoise=(int *)omAlloc(ar*sizeof(int));
2702  if ((i>512) || (j>512) || (i*j >512)) size=512;
2703  else size=i*j;
2704  result=idInit(size,1);
2705  tmp=mpNew(ar,ar);
2706  k = 0; /* the index in result*/
2707  curr = 0; /* index of current minor */
2708  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2709  while (!rowch)
2710  {
2711    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2712    while (!colch)
2713    {
2714      if (curr == which)
2715      {
2716        for (i=1; i<=ar; i++)
2717        {
2718          for (j=1; j<=ar; j++)
2719          {
2720            MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2721          }
2722        }
2723        p = mpDetBareiss(tmp);
2724        if (p!=NULL)
2725        {
2726          if (R!=NULL)
2727          {
2728            q = p;
2729            p = kNF(R,currQuotient,q);
2730            pDelete(&q);
2731          }
2732          /*delete the matrix tmp*/
2733          for (i=1; i<=ar; i++)
2734          {
2735            for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2736          }
2737          idDelete((ideal*)&tmp);
2738          omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2739          omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2740          return (p);
2741        }
2742      }
2743      curr++;
2744      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2745    }
2746    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2747  }
2748  return (poly) 1;
2749}
2750
2751#ifdef WITH_OLD_MINOR
2752/*2
2753* compute all ar-minors of the matrix a
2754*/
2755ideal idMinors(matrix a, int ar, ideal R)
2756{
2757  int     i,j,k,size;
2758  int *rowchoise,*colchoise;
2759  BOOLEAN rowch,colch;
2760  ideal result;
2761  matrix tmp;
2762  poly p,q;
2763
2764  i = binom(a->rows(),ar);
2765  j = binom(a->cols(),ar);
2766
2767  rowchoise=(int *)omAlloc(ar*sizeof(int));
2768  colchoise=(int *)omAlloc(ar*sizeof(int));
2769  if ((i>512) || (j>512) || (i*j >512)) size=512;
2770  else size=i*j;
2771  result=idInit(size,1);
2772  tmp=mpNew(ar,ar);
2773  k = 0; /* the index in result*/
2774  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2775  while (!rowch)
2776  {
2777    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2778    while (!colch)
2779    {
2780      for (i=1; i<=ar; i++)
2781      {
2782        for (j=1; j<=ar; j++)
2783        {
2784          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2785        }
2786      }
2787      p = mpDetBareiss(tmp);
2788      if (p!=NULL)
2789      {
2790        if (R!=NULL)
2791        {
2792          q = p;
2793          p = kNF(R,currQuotient,q);
2794          pDelete(&q);
2795        }
2796        if (p!=NULL)
2797        {
2798          if (k>=size)
2799          {
2800            pEnlargeSet(&result->m,size,32);
2801            size += 32;
2802          }
2803          result->m[k] = p;
2804          k++;
2805        }
2806      }
2807      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2808    }
2809    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2810  }
2811  /*delete the matrix tmp*/
2812  for (i=1; i<=ar; i++)
2813  {
2814    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2815  }
2816  idDelete((ideal*)&tmp);
2817  if (k==0)
2818  {
2819    k=1;
2820    result->m[0]=NULL;
2821  }
2822  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2823  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2824  pEnlargeSet(&result->m,size,k-size);
2825  IDELEMS(result) = k;
2826  return (result);
2827}
2828#else
2829/*2
2830* compute all ar-minors of the matrix a
2831* the caller of mpRecMin
2832* the elements of the result are not in R (if R!=NULL)
2833*/
2834ideal idMinors(matrix a, int ar, ideal R)
2835{
2836  int elems=0;
2837  int r=a->nrows,c=a->ncols;
2838  int i;
2839  matrix b;
2840  ideal result,h;
2841  ring origR;
2842  ring tmpR;
2843  long bound;
2844
2845  if((ar<=0) || (ar>r) || (ar>c))
2846  {
2847    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
2848    return NULL;
2849  }
2850  h = idMatrix2Module(mpCopy(a));
2851  bound = smExpBound(h,c,r,ar);
2852  idDelete(&h);
2853  tmpR=smRingChange(&origR,bound);
2854  b = mpNew(r,c);
2855  for (i=r*c-1;i>=0;i--)
2856  {
2857    if (a->m[i])
2858      b->m[i] = prCopyR(a->m[i],origR);
2859  }
2860  if (R!=NULL)
2861  {
2862    R = idrCopyR(R,origR);
2863    //if (ar>1) // otherwise done in mpMinorToResult
2864    //{
2865    //  matrix bb=(matrix)kNF(R,currQuotient,(ideal)b);
2866    //  bb->rank=b->rank; bb->nrows=b->nrows; bb->ncols=b->ncols;
2867    //  idDelete((ideal*)&b); b=bb;
2868    //}
2869  }
2870  result=idInit(32,1);
2871  if(ar>1) mpRecMin(ar-1,result,elems,b,r,c,NULL,R);
2872  else mpMinorToResult(result,elems,b,r,c,R);
2873  idDelete((ideal *)&b);
2874  if (R!=NULL) idDelete(&R);
2875  idSkipZeroes(result);
2876  rChangeCurrRing(origR);
2877  result = idrMoveR(result,tmpR);
2878  smKillModifiedRing(tmpR);
2879  idTest(result);
2880  return result;
2881}
2882#endif
2883
2884/*2
2885*skips all zeroes and double elements, searches also for units
2886*/
2887void idCompactify(ideal id)
2888{
2889  int i,j;
2890  BOOLEAN b=FALSE;
2891
2892  i = IDELEMS(id)-1;
2893  while ((! b) && (i>=0))
2894  {
2895    b=pIsUnit(id->m[i]);
2896    i--;
2897  }
2898  if (b)
2899  {
2900    for(i=IDELEMS(id)-1;i>=0;i--) pDelete(&id->m[i]);
2901    id->m[0]=pOne();
2902  }
2903  else
2904  {
2905    idDelMultiples(id);
2906  }
2907  idSkipZeroes(id);
2908}
2909
2910/*2
2911*returns TRUE if id1 is a submodule of id2
2912*/
2913BOOLEAN idIsSubModule(ideal id1,ideal id2)
2914{
2915  int i;
2916  poly p;
2917
2918  if (idIs0(id1)) return TRUE;
2919  for (i=0;i<IDELEMS(id1);i++)
2920  {
2921    if (id1->m[i] != NULL)
2922    {
2923      p = kNF(id2,currQuotient,id1->m[i]);
2924      if (p != NULL)
2925      {
2926        pDelete(&p);
2927        return FALSE;
2928      }
2929    }
2930  }
2931  return TRUE;
2932}
2933
2934/*2
2935* returns the ideals of initial terms
2936*/
2937ideal idHead(ideal h)
2938{
2939  ideal m = idInit(IDELEMS(h),h->rank);
2940  int i;
2941
2942  for (i=IDELEMS(h)-1;i>=0; i--)
2943  {
2944    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
2945  }
2946  return m;
2947}
2948
2949ideal idHomogen(ideal h, int varnum)
2950{
2951  ideal m = idInit(IDELEMS(h),h->rank);
2952  int i;
2953
2954  for (i=IDELEMS(h)-1;i>=0; i--)
2955  {
2956    m->m[i]=pHomogen(h->m[i],varnum);
2957  }
2958  return m;
2959}
2960
2961/*------------------type conversions----------------*/
2962ideal idVec2Ideal(poly vec)
2963{
2964   ideal result=idInit(1,1);
2965   omFree((ADDRESS)result->m);
2966   result->m=NULL; // remove later
2967   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2968   return result;
2969}
2970
2971#define NEW_STUFF
2972#ifndef NEW_STUFF
2973// converts mat to module, destroys mat
2974ideal idMatrix2Module(matrix mat)
2975{
2976  int mc=MATCOLS(mat);
2977  int mr=MATROWS(mat);
2978  ideal result = idInit(si_max(mc,1),si_max(mr,1));
2979  int i,j;
2980  poly h;
2981
2982  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
2983  {
2984    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
2985    {
2986      h = MATELEM(mat,i,j+1);
2987      if (h!=NULL)
2988      {
2989        MATELEM(mat,i,j+1)=NULL;
2990        pSetCompP(h,i);
2991        result->m[j] = pAdd(result->m[j],h);
2992      }
2993    }
2994  }
2995  // obachman: need to clean this up
2996  idDelete((ideal*) &mat);
2997  return result;
2998}
2999#else
3000
3001#include <kernel/sbuckets.h>
3002
3003// converts mat to module, destroys mat
3004ideal idMatrix2Module(matrix mat)
3005{
3006  int mc=MATCOLS(mat);
3007  int mr=MATROWS(mat);
3008  ideal result = idInit(si_max(mc,1),si_max(mr,1));
3009  int i,j, l;
3010  poly h;
3011  poly p;
3012  sBucket_pt bucket = sBucketCreate(currRing);
3013
3014  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
3015  {
3016    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
3017    {
3018      h = MATELEM(mat,i,j+1);
3019      if (h!=NULL)
3020      {
3021        l=pLength(h);
3022        MATELEM(mat,i,j+1)=NULL;
3023        p_SetCompP(h,i, currRing);
3024        sBucket_Merge_p(bucket, h, l);
3025      }
3026    }
3027    sBucketClearMerge(bucket, &(result->m[j]), &l);
3028  }
3029  sBucketDestroy(&bucket);
3030
3031  // obachman: need to clean this up
3032  idDelete((ideal*) &mat);
3033  return result;
3034}
3035#endif
3036
3037/*2
3038* converts a module into a matrix, destroyes the input
3039*/
3040matrix idModule2Matrix(ideal mod)
3041{
3042  matrix result = mpNew(mod->rank,IDELEMS(mod));
3043  int i,cp;
3044  poly p,h;
3045
3046  for(i=0;i<IDELEMS(mod);i++)
3047  {
3048    p=pReverse(mod->m[i]);
3049    mod->m[i]=NULL;
3050    while (p!=NULL)
3051    {
3052      h=p;
3053      pIter(p);
3054      pNext(h)=NULL;
3055//      cp = si_max(1,pGetComp(h));     // if used for ideals too
3056      cp = pGetComp(h);
3057      pSetComp(h,0);
3058      pSetmComp(h);
3059#ifdef TEST
3060      if (cp>mod->rank)
3061      {
3062        Print("## inv. rank %ld -> %d\n",mod->rank,cp);
3063        int k,l,o=mod->rank;
3064        mod->rank=cp;
3065        matrix d=mpNew(mod->rank,IDELEMS(mod));
3066        for (l=1; l<=o; l++)
3067        {
3068          for (k=1; k<=IDELEMS(mod); k++)
3069          {
3070            MATELEM(d,l,k)=MATELEM(result,l,k);
3071            MATELEM(result,l,k)=NULL;
3072          }
3073        }
3074        idDelete((ideal *)&result);
3075        result=d;
3076      }
3077#endif
3078      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
3079    }
3080  }
3081  // obachman 10/99: added the following line, otherwise memory leack!
3082  idDelete(&mod);
3083  return result;
3084}
3085
3086matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
3087{
3088  matrix result = mpNew(rows,cols);
3089  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
3090  poly p,h;
3091
3092  if (r>rows) r = rows;
3093  if (c>cols) c = cols;
3094  for(i=0;i<c;i++)
3095  {
3096    p=pReverse(mod->m[i]);
3097    mod->m[i]=NULL;
3098    while (p!=NULL)
3099    {
3100      h=p;
3101      pIter(p);
3102      pNext(h)=NULL;
3103      cp = pGetComp(h);
3104      if (cp<=r)
3105      {
3106        pSetComp(h,0);
3107        pSetmComp(h);
3108        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
3109      }
3110      else
3111        pDelete(&h);
3112    }
3113  }
3114  idDelete(&mod);
3115  return result;
3116}
3117
3118/*2
3119* substitute the n-th variable by the monomial e in id
3120* destroy id
3121*/
3122ideal  idSubst(ideal id, int n, poly e)
3123{
3124  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
3125  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
3126
3127  res->rank = id->rank;
3128  for(k--;k>=0;k--)
3129  {
3130    res->m[k]=pSubst(id->m[k],n,e);
3131    id->m[k]=NULL;
3132  }
3133  idDelete(&id);
3134  return res;
3135}
3136
3137BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
3138{
3139  if (w!=NULL) *w=NULL;
3140  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
3141  if (idIs0(m))
3142  {
3143    if (w!=NULL) (*w)=new intvec(m->rank);
3144    return TRUE;
3145  }
3146
3147  long cmax=1,order=0,ord,* diff,diffmin=32000;
3148  int *iscom;
3149  int i,j;
3150  poly p=NULL;
3151  pFDegProc d;
3152  if (pLexOrder && (currRing->order[0]==ringorder_lp))
3153     d=p_Totaldegree;
3154  else
3155     d=pFDeg;
3156  int length=IDELEMS(m);
3157  polyset P=m->m;
3158  polyset F=(polyset)omAlloc(length*sizeof(poly));
3159  for (i=length-1;i>=0;i--)
3160  {
3161    p=F[i]=P[i];
3162    cmax=si_max(cmax,(long)pMaxComp(p));
3163  }
3164  cmax++;
3165  diff = (long *)omAlloc0(cmax*sizeof(long));
3166  if (w!=NULL) *w=new intvec(cmax-1);
3167  iscom = (int *)omAlloc0(cmax*sizeof(int));
3168  i=0;
3169  while (i<=length)
3170  {
3171    if (i<length)
3172    {
3173      p=F[i];
3174      while ((p!=NULL) && (iscom[pGetComp(p)]==0)) pIter(p);
3175    }
3176    if ((p==NULL) && (i<length))
3177    {
3178      i++;
3179    }
3180    else
3181    {
3182      if (p==NULL) /* && (i==length) */
3183      {
3184        i=0;
3185        while ((i<length) && (F[i]==NULL)) i++;
3186        if (i>=length) break;
3187        p = F[i];
3188      }
3189      //if (pLexOrder && (currRing->order[0]==ringorder_lp))
3190      //  order=pTotaldegree(p);
3191      //else
3192      //  order = p->order;
3193      //  order = pFDeg(p,currRing);
3194      order = d(p,currRing) +diff[pGetComp(p)];
3195      //order += diff[pGetComp(p)];
3196      p = F[i];
3197//Print("Actual p=F[%d]: ",i);pWrite(p);
3198      F[i] = NULL;
3199      i=0;
3200    }
3201    while (p!=NULL)
3202    {
3203      if (pLexOrder && (currRing->order[0]==ringorder_lp))
3204        ord=pTotaldegree(p);
3205      else
3206      //  ord = p->order;
3207        ord = pFDeg(p,currRing);
3208      if (iscom[pGetComp(p)]==0)
3209      {
3210        diff[pGetComp(p)] = order-ord;
3211        iscom[pGetComp(p)] = 1;
3212/*
3213*PrintS("new diff: ");
3214*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
3215*PrintLn();
3216*PrintS("new iscom: ");
3217*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
3218*PrintLn();
3219*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
3220*/
3221      }
3222      else
3223      {
3224/*
3225*PrintS("new diff: ");
3226*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
3227*PrintLn();
3228*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
3229*/
3230        if (order != (ord+diff[pGetComp(p)]))
3231        {
3232          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
3233          omFreeSize((ADDRESS) diff,cmax*sizeof(long));
3234          omFreeSize((ADDRESS) F,length*sizeof(poly));
3235          delete *w;*w=NULL;
3236          return FALSE;
3237        }
3238      }
3239      pIter(p);
3240    }
3241  }
3242  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
3243  omFreeSize((ADDRESS) F,length*sizeof(poly));
3244  for (i=1;i<cmax;i++) (**w)[i-1]=(int)(diff[i]);
3245  for (i=1;i<cmax;i++)
3246  {
3247    if (diff[i]<diffmin) diffmin=diff[i];
3248  }
3249  if (w!=NULL)
3250  {
3251    for (i=1;i<cmax;i++)
3252    {
3253      (**w)[i-1]=(int)(diff[i]-diffmin);
3254    }
3255  }
3256  omFreeSize((ADDRESS) diff,cmax*sizeof(long));
3257  return TRUE;
3258}
3259
3260BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
3261{
3262  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
3263  if (idIs0(m)) return TRUE;
3264
3265  int cmax=-1;
3266  int i;
3267  poly p=NULL;
3268  int length=IDELEMS(m);
3269  polyset P=m->m;
3270  for (i=length-1;i>=0;i--)
3271  {
3272    p=P[i];
3273    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
3274  }
3275  if (w != NULL)
3276  if (w->length()+1 < cmax)
3277  {
3278    // Print("length: %d - %d \n", w->length(),cmax);
3279    return FALSE;
3280  }
3281
3282  if(w!=NULL)
3283    pSetModDeg(w);
3284
3285  for (i=length-1;i>=0;i--)
3286  {
3287    p=P[i];
3288    poly q=p;
3289    if (p!=NULL)
3290    {
3291      int d=pFDeg(p,currRing);
3292      loop
3293      {
3294        pIter(p);
3295        if (p==NULL) break;
3296        if (d!=pFDeg(p,currRing))
3297        {
3298          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
3299          if(w!=NULL)
3300            pSetModDeg(NULL);
3301          return FALSE;
3302        }
3303      }
3304    }
3305  }
3306
3307  if(w!=NULL)
3308    pSetModDeg(NULL);
3309
3310  return TRUE;
3311}
3312
3313ideal idJet(ideal i,int d)
3314{
3315  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
3316  r->nrows = i-> nrows;
3317  r->ncols = i-> ncols;
3318  //r->rank = i-> rank;
3319  int k;
3320  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
3321  {
3322    r->m[k]=ppJet(i->m[k],d);
3323  }
3324  return r;
3325}
3326
3327ideal idJetW(ideal i,int d, intvec * iv)
3328{
3329  ideal r=idInit(IDELEMS(i),i->rank);
3330  if (ecartWeights!=NULL)
3331  {
3332    WerrorS("cannot compute weighted jets now");
3333  }
3334  else
3335  {
3336    short *w=iv2array(iv);
3337    int k;
3338    for(k=0; k<IDELEMS(i); k++)
3339    {
3340      r->m[k]=ppJetW(i->m[k],d,w);
3341    }
3342    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
3343  }
3344  return r;
3345}
3346
3347int idMinDegW(ideal M,intvec *w)
3348{
3349  int d=-1;
3350  for(int i=0;i<IDELEMS(M);i++)
3351  {
3352    int d0=pMinDeg(M->m[i],w);
3353    if(-1<d0&&(d0<d||d==-1))
3354      d=d0;
3355  }
3356  return d;
3357}
3358
3359ideal idSeries(int n,ideal M,matrix U,intvec *w)
3360{
3361  for(int i=IDELEMS(M)-1;i>=0;i--)
3362  {
3363    if(U==NULL)
3364      M->m[i]=pSeries(n,M->m[i],NULL,w);
3365    else
3366    {
3367      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
3368      MATELEM(U,i+1,i+1)=NULL;
3369    }
3370  }
3371  if(U!=NULL)
3372    idDelete((ideal*)&U);
3373  return M;
3374}
3375
3376matrix idDiff(matrix i, int k)
3377{
3378  int e=MATCOLS(i)*MATROWS(i);
3379  matrix r=mpNew(MATROWS(i),MATCOLS(i));
3380  r->rank=i->rank;
3381  int j;
3382  for(j=0; j<e; j++)
3383  {
3384    r->m[j]=pDiff(i->m[j],k);
3385  }
3386  return r;
3387}
3388
3389matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
3390{
3391  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
3392  int i,j;
3393  for(i=0; i<IDELEMS(I); i++)
3394  {
3395    for(j=0; j<IDELEMS(J); j++)
3396    {
3397      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
3398    }
3399  }
3400  return r;
3401}
3402
3403/*3
3404*handles for some ideal operations the ring/syzcomp managment
3405*returns all syzygies (componentwise-)shifted by -syzcomp
3406*or -syzcomp-1 (in case of ideals as input)
3407static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
3408{
3409  ring orig_ring=currRing;
3410  ring syz_ring=rCurrRingAssure_SyzComp();
3411  rSetSyzComp(length);
3412
3413  ideal s_temp;
3414  if (orig_ring!=syz_ring)
3415    s_temp=idrMoveR_NoSort(arg,orig_ring);
3416  else
3417    s_temp=arg;
3418
3419  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
3420  if (w!=NULL) delete w;
3421
3422  if (syz_ring!=orig_ring)
3423  {
3424    idDelete(&s_temp);
3425    rChangeCurrRing(orig_ring);
3426  }
3427
3428  idDelete(&temp);
3429  ideal temp1=idRingCopy(s_temp1,syz_ring);
3430
3431  if (syz_ring!=orig_ring)
3432  {
3433    rChangeCurrRing(syz_ring);
3434    idDelete(&s_temp1);
3435    rChangeCurrRing(orig_ring);
3436    rKill(syz_ring);
3437  }
3438
3439  for (i=0;i<IDELEMS(temp1);i++)
3440  {
3441    if ((temp1->m[i]!=NULL)
3442    && (pGetComp(temp1->m[i])<=length))
3443    {
3444      pDelete(&(temp1->m[i]));
3445    }
3446    else
3447    {
3448      pShift(&(temp1->m[i]),-length);
3449    }
3450  }
3451  temp1->rank = rk;
3452  idSkipZeroes(temp1);
3453
3454  return temp1;
3455}
3456*/
3457/*2
3458* represents (h1+h2)/h2=h1/(h1 intersect h2)
3459*/
3460//ideal idModulo (ideal h2,ideal h1)
3461ideal idModulo (ideal h2,ideal h1, tHomog hom, intvec ** w)
3462{
3463  intvec *wtmp=NULL;
3464
3465  int i,j,k,rk,flength=0,slength,length;
3466  poly p,q;
3467
3468  if (idIs0(h2))
3469    return idFreeModule(si_max(1,h2->ncols));
3470  if (!idIs0(h1))
3471    flength = idRankFreeModule(h1);
3472  slength = idRankFreeModule(h2);
3473  length  = si_max(flength,slength);
3474  if (length==0)
3475  {
3476    length = 1;
3477  }
3478  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
3479  if ((w!=NULL)&&((*w)!=NULL))
3480  {
3481    //Print("input weights:");(*w)->show(1);PrintLn();
3482    int d;
3483    int k;
3484    wtmp=new intvec(length+IDELEMS(h2));
3485    for (i=0;i<length;i++)
3486      ((*wtmp)[i])=(**w)[i];
3487    for (i=0;i<IDELEMS(h2);i++)
3488    {
3489      poly p=h2->m[i];
3490      if (p!=NULL)
3491      {
3492        d = pDeg(p);
3493        k= pGetComp(p);
3494        if (slength>0) k--;
3495        d +=((**w)[k]);
3496        ((*wtmp)[i+length]) = d;
3497      }
3498    }
3499    //Print("weights:");wtmp->show(1);PrintLn();
3500  }
3501  for (i=0;i<IDELEMS(h2);i++)
3502  {
3503    temp->m[i] = pCopy(h2->m[i]);
3504    q = pOne();
3505    pSetComp(q,i+1+length);
3506    pSetmComp(q);
3507    if(temp->m[i]!=NULL)
3508    {
3509      if (slength==0) pShift(&(temp->m[i]),1);
3510      p = temp->m[i];
3511      while (pNext(p)!=NULL) pIter(p);
3512      pNext(p) = q;
3513    }
3514    else
3515      temp->m[i]=q;
3516  }
3517  rk = k = IDELEMS(h2);
3518  if (!idIs0(h1))
3519  {
3520    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
3521    IDELEMS(temp) += IDELEMS(h1);
3522    for (i=0;i<IDELEMS(h1);i++)
3523    {
3524      if (h1->m[i]!=NULL)
3525      {
3526        temp->m[k] = pCopy(h1->m[i]);
3527        if (flength==0) pShift(&(temp->m[k]),1);
3528        k++;
3529      }
3530    }
3531  }
3532
3533  ring orig_ring=currRing;
3534  ring syz_ring=rCurrRingAssure_SyzComp();
3535  rSetSyzComp(length);
3536  ideal s_temp;
3537
3538  if (syz_ring != orig_ring)
3539  {
3540    s_temp = idrMoveR_NoSort(temp, orig_ring);
3541  }
3542  else
3543  {
3544    s_temp = temp;
3545  }
3546
3547  idTest(s_temp);
3548  ideal s_temp1 = kStd(s_temp,currQuotient,hom,&wtmp,NULL,length);
3549
3550  //if (wtmp!=NULL)  Print("output weights:");wtmp->show(1);PrintLn();
3551  if ((w!=NULL) && (*w !=NULL) && (wtmp!=NULL))
3552  {
3553    delete *w;
3554    *w=new intvec(IDELEMS(h2));
3555    for (i=0;i<IDELEMS(h2);i++)
3556      ((**w)[i])=(*wtmp)[i+length];
3557  }
3558  if (wtmp!=NULL) delete wtmp;
3559
3560  for (i=0;i<IDELEMS(s_temp1);i++)
3561  {
3562    if ((s_temp1->m[i]!=NULL)
3563    && (pGetComp(s_temp1->m[i])<=length))
3564    {
3565      pDelete(&(s_temp1->m[i]));
3566    }
3567    else
3568    {
3569      pShift(&(s_temp1->m[i]),-length);
3570    }
3571  }
3572  s_temp1->rank = rk;
3573  idSkipZeroes(s_temp1);
3574
3575  if (syz_ring!=orig_ring)
3576  {
3577    rChangeCurrRing(orig_ring);
3578    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
3579    rKill(syz_ring);
3580    // Hmm ... here seems to be a memory leak
3581    // However, simply deleting it causes memory trouble
3582    // idDelete(&s_temp);
3583  }
3584  else
3585  {
3586    idDelete(&temp);
3587  }
3588  idTest(s_temp1);
3589  return s_temp1;
3590}
3591
3592int idElem(const ideal F)
3593{
3594  int i=0,j=IDELEMS(F)-1;
3595
3596  while(j>=0)
3597  {
3598    if ((F->m)[j]!=NULL) i++;
3599    j--;
3600  }
3601  return i;
3602}
3603
3604/*
3605*computes module-weights for liftings of homogeneous modules
3606*/
3607intvec * idMWLift(ideal mod,intvec * weights)
3608{
3609  if (idIs0(mod)) return new intvec(2);
3610  int i=IDELEMS(mod);
3611  while ((i>0) && (mod->m[i-1]==NULL)) i--;
3612  intvec *result = new intvec(i+1);
3613  while (i>0)
3614  {
3615    (*result)[i]=pFDeg(mod->m[i],currRing)+(*weights)[pGetComp(mod->m[i])];
3616  }
3617  return result;
3618}
3619
3620/*2
3621*sorts the kbase for idCoef* in a special way (lexicographically
3622*with x_max,...,x_1)
3623*/
3624ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
3625{
3626  int i;
3627  ideal result;
3628
3629  if (idIs0(kBase)) return NULL;
3630  result = idInit(IDELEMS(kBase),kBase->rank);
3631  *convert = idSort(kBase,FALSE);
3632  for (i=0;i<(*convert)->length();i++)
3633  {
3634    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
3635  }
3636  return result;
3637}
3638
3639/*2
3640*returns the index of a given monom in the list of the special kbase
3641*/
3642int idIndexOfKBase(poly monom, ideal kbase)
3643{
3644  int j=IDELEMS(kbase);
3645
3646  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
3647  if (j==0) return -1;
3648  int i=pVariables;
3649  while (i>0)
3650  {
3651    loop
3652    {
3653      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
3654      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
3655      j--;
3656      if (j==0) return -1;
3657    }
3658    if (i==1)
3659    {
3660      while(j>0)
3661      {
3662        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
3663        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
3664        j--;
3665      }
3666    }
3667    i--;
3668  }
3669  return -1;
3670}
3671
3672/*2
3673*decomposes the monom in a part of coefficients described by the
3674*complement of how and a monom in variables occuring in how, the
3675*index of which in kbase is returned as integer pos (-1 if it don't
3676*exists)
3677*/
3678poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3679{
3680  int i;
3681  poly coeff=pOne(), base=pOne();
3682
3683  for (i=1;i<=pVariables;i++)
3684  {
3685    if (pGetExp(how,i)>0)
3686    {
3687      pSetExp(base,i,pGetExp(monom,i));
3688    }
3689    else
3690    {
3691      pSetExp(coeff,i,pGetExp(monom,i));
3692    }
3693  }
3694  pSetComp(base,pGetComp(monom));
3695  pSetm(base);
3696  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3697  pSetm(coeff);
3698  *pos = idIndexOfKBase(base,kbase);
3699  if (*pos<0)
3700    pDelete(&coeff);
3701  pDelete(&base);
3702  return coeff;
3703}
3704
3705/*2
3706*returns a matrix A of coefficients with kbase*A=arg
3707*if all monomials in variables of how occur in kbase
3708*the other are deleted
3709*/
3710matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3711{
3712  matrix result;
3713  ideal tempKbase;
3714  poly p,q;
3715  intvec * convert;
3716  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3717#if 0
3718  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3719  if (idIs0(arg))
3720    return mpNew(i,1);
3721  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3722  result = mpNew(i,j);
3723#else
3724  result = mpNew(i, j);
3725  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3726#endif
3727
3728  tempKbase = idCreateSpecialKbase(kbase,&convert);
3729  for (k=0;k<j;k++)
3730  {
3731    p = arg->m[k];
3732    while (p!=NULL)
3733    {
3734      q = idDecompose(p,how,tempKbase,&pos);
3735      if (pos>=0)
3736      {
3737        MATELEM(result,(*convert)[pos],k+1) =
3738            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3739      }
3740      else
3741        pDelete(&q);
3742      pIter(p);
3743    }
3744  }
3745  idDelete(&tempKbase);
3746  return result;
3747}
3748
3749/*3
3750* searches for units in the components of the module arg and
3751* returns the first one
3752*/
3753static int idReadOutUnits(ideal arg,int* comp)
3754{
3755  if (idIs0(arg)) return -1;
3756  int i=0,j, generator=-1;
3757  int rk_arg=arg->rank; //idRankFreeModule(arg);
3758  int * componentIsUsed =(int *)omAlloc((rk_arg+1)*sizeof(int));
3759  poly p,q;
3760
3761  while ((generator<0) && (i<IDELEMS(arg)))
3762  {
3763    memset(componentIsUsed,0,(rk_arg+1)*sizeof(int));
3764    p = arg->m[i];
3765    while (p!=NULL)
3766    {
3767      j = pGetComp(p);
3768      if (componentIsUsed[j]==0)
3769      {
3770        if (pLmIsConstantComp(p))
3771        {
3772          generator = i;
3773          componentIsUsed[j] = 1;
3774        }
3775        else
3776        {
3777          componentIsUsed[j] = -1;
3778        }
3779      }
3780      else if (componentIsUsed[j]>0)
3781      {
3782        (componentIsUsed[j])++;
3783      }
3784      pIter(p);
3785    }
3786    i++;
3787  }
3788  i = 0;
3789  *comp = -1;
3790  for (j=0;j<=rk_arg;j++)
3791  {
3792    if (componentIsUsed[j]>0)
3793    {
3794      if ((*comp==-1) || (componentIsUsed[j]<i))
3795      {
3796        *comp = j;
3797        i= componentIsUsed[j];
3798      }
3799    }
3800  }
3801  omFree(componentIsUsed);
3802  return generator;
3803}
3804
3805#if 0
3806static void idDeleteComp(ideal arg,int red_comp)
3807{
3808  int i,j;
3809  poly p;
3810
3811  for (i=IDELEMS(arg)-1;i>=0;i--)
3812  {
3813    p = arg->m[i];
3814    while (p!=NULL)
3815    {
3816      j = pGetComp(p);
3817      if (j>red_comp)
3818      {
3819        pSetComp(p,j-1);
3820        pSetm(p);
3821      }
3822      pIter(p);
3823    }
3824  }
3825  (arg->rank)--;
3826}
3827#endif
3828
3829static void idDeleteComps(ideal arg,int* red_comp,int del)
3830// red_comp is an array [0..args->rank]
3831{
3832  int i,j;
3833  poly p;
3834
3835  for (i=IDELEMS(arg)-1;i>=0;i--)
3836  {
3837    p = arg->m[i];
3838    while (p!=NULL)
3839    {
3840      j = pGetComp(p);
3841      if (red_comp[j]!=j)
3842      {
3843        pSetComp(p,red_comp[j]);
3844        pSetmComp(p);
3845      }
3846      pIter(p);
3847    }
3848  }
3849  (arg->rank) -= del;
3850}
3851
3852/*2
3853* returns the presentation of an isomorphic, minimally
3854* embedded  module (arg represents the quotient!)
3855*/
3856ideal idMinEmbedding(ideal arg,BOOLEAN inPlace, intvec **w)
3857{
3858  if (idIs0(arg)) return idInit(1,arg->rank);
3859  int i,next_gen,next_comp;
3860  ideal res=arg;
3861
3862  if (!inPlace) res = idCopy(arg);
3863  res->rank=si_max(res->rank,idRankFreeModule(res));
3864  int *red_comp=(int*)omAlloc((res->rank+1)*sizeof(int));
3865  for (i=res->rank;i>=0;i--) red_comp[i]=i;
3866
3867  int del=0;
3868  loop
3869  {
3870    next_gen = idReadOutUnits(res,&next_comp);
3871    if (next_gen<0) break;
3872    del++;
3873    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
3874    for(i=next_comp+1;i<=arg->rank;i++) red_comp[i]--;
3875    if ((w !=NULL)&&(*w!=NULL))
3876    {
3877      for(i=next_comp;i<(*w)->length();i++) (**w)[i-1]=(**w)[i];
3878    }
3879  }
3880
3881  idDeleteComps(res,red_comp,del);
3882  idSkipZeroes(res);
3883  omFree(red_comp);
3884
3885  if ((w !=NULL)&&(*w!=NULL) &&(del>0))
3886  {
3887    intvec *wtmp=new intvec((*w)->length()-del);
3888    for(i=0;i<res->rank;i++) (*wtmp)[i]=(**w)[i];
3889    delete *w;
3890    *w=wtmp;
3891  }
3892  return res;
3893}
3894
3895/*2
3896* transpose a module
3897*/
3898ideal idTransp(ideal a)
3899{
3900  int r = a->rank, c = IDELEMS(a);
3901  ideal b =  idInit(r,c);
3902
3903  for (int i=c; i>0; i--)
3904  {
3905    poly p=a->m[i-1];
3906    while(p!=NULL)
3907    {
3908      poly h=pHead(p);
3909      int co=pGetComp(h)-1;
3910      pSetComp(h,i);
3911      pSetmComp(h);
3912      b->m[co]=pAdd(b->m[co],h);
3913      pIter(p);
3914    }
3915  }
3916  return b;
3917}
3918
3919intvec * idQHomWeight(ideal id)
3920{
3921  poly head, tail;
3922  int k;
3923  int in=IDELEMS(id)-1, ready=0, all=0,
3924      coldim=pVariables, rowmax=2*coldim;
3925  if (in<0) return NULL;
3926  intvec *imat=new intvec(rowmax+1,coldim,0);
3927
3928  do
3929  {
3930    head = id->m[in--];
3931    if (head!=NULL)
3932    {
3933      tail = pNext(head);
3934      while (tail!=NULL)
3935      {
3936        all++;
3937        for (k=1;k<=coldim;k++)
3938          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
3939        if (all==rowmax)
3940        {
3941          ivTriangIntern(imat, ready, all);
3942          if (ready==coldim)
3943          {
3944            delete imat;
3945            return NULL;
3946          }
3947        }
3948        pIter(tail);
3949      }
3950    }
3951  } while (in>=0);
3952  if (all>ready)
3953  {
3954    ivTriangIntern(imat, ready, all);
3955    if (ready==coldim)
3956    {
3957      delete imat;
3958      return NULL;
3959    }
3960  }
3961  intvec *result = ivSolveKern(imat, ready);
3962  delete imat;
3963  return result;
3964}
3965
3966BOOLEAN idIsZeroDim(ideal I)
3967{
3968  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(pVariables*sizeof(BOOLEAN));
3969  int i,n;
3970  poly po;
3971  BOOLEAN res=TRUE;
3972  for(i=IDELEMS(I)-1;i>=0;i--)
3973  {
3974    po=I->m[i];
3975    if ((po!=NULL) &&((n=pIsPurePower(po))!=0)) UsedAxis[n-1]=TRUE;
3976  }
3977  for(i=pVariables-1;i>=0;i--)
3978  {
3979    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
3980  }
3981  omFreeSize(UsedAxis,pVariables*sizeof(BOOLEAN));
3982  return res;
3983}
3984
3985void idNormalize(ideal I)
3986{
3987  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
3988  int i;
3989  poly p;
3990  for(i=IDELEMS(I)-1;i>=0;i--)
3991  {
3992    p=I->m[i] ;
3993    while(p!=NULL)
3994    {
3995      nNormalize(pGetCoeff(p));
3996      pIter(p);
3997    }
3998  }
3999}
4000
4001#include <kernel/clapsing.h>
4002
4003#ifdef HAVE_FACTORY
4004poly id_GCD(poly f, poly g, const ring r)
4005{
4006  ring save_r=currRing;
4007  rChangeCurrRing(r);
4008  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
4009  intvec *w = NULL;
4010  ideal S=idSyzygies(I,testHomog,&w);
4011  if (w!=NULL) delete w;
4012  poly gg=pTakeOutComp(&(S->m[0]),2);
4013  idDelete(&S);
4014  poly gcd_p=singclap_pdivide(f,gg);
4015  pDelete(&gg);
4016  rChangeCurrRing(save_r);
4017  return gcd_p;
4018}
4019#endif
4020
4021/*2
4022* xx,q: arrays of length 0..rl-1
4023* xx[i]: SB mod q[i]
4024* assume: char=0
4025* assume: q[i]!=0
4026* destroys xx
4027*/
4028#ifdef HAVE_FACTORY
4029ideal idChineseRemainder(ideal *xx, number *q, int rl)
4030{
4031  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
4032  ideal result=idInit(cnt,xx[0]->rank);
4033  result->nrows=xx[0]->nrows; // for lifting matrices
4034  result->ncols=xx[0]->ncols; // for lifting matrices
4035  int i,j;
4036  poly r,h,hh,res_p;
4037  number *x=(number *)omAlloc(rl*sizeof(number));
4038  for(i=cnt-1;i>=0;i--)
4039  {
4040    res_p=NULL;
4041    loop
4042    {
4043      r=NULL;
4044      for(j=rl-1;j>=0;j--)
4045      {
4046        h=xx[j]->m[i];
4047        if ((h!=NULL)
4048        &&((r==NULL)||(pLmCmp(r,h)==-1)))
4049          r=h;
4050      }
4051      if (r==NULL) break;
4052      h=pHead(r);
4053      for(j=rl-1;j>=0;j--)
4054      {
4055        hh=xx[j]->m[i];
4056        if ((hh!=NULL) && (pLmCmp(r,hh)==0))
4057        {
4058          x[j]=pGetCoeff(hh);
4059          hh=pLmFreeAndNext(hh);
4060          xx[j]->m[i]=hh;
4061        }
4062        else
4063          x[j]=nlInit(0, currRing);
4064      }
4065      number n=nlChineseRemainder(x,q,rl);
4066      for(j=rl-1;j>=0;j--)
4067      {
4068        x[j]=NULL; // nlInit(0...) takes no memory
4069      }
4070      if (nlIsZero(n)) pDelete(&h);
4071      else
4072      {
4073        pSetCoeff(h,n);
4074        //Print("new mon:");pWrite(h);
4075        res_p=pAdd(res_p,h);
4076      }
4077    }
4078    result->m[i]=res_p;
4079  }
4080  omFree(x);
4081  for(i=rl-1;i>=0;i--) idDelete(&(xx[i]));
4082  omFree(xx);
4083  return result;
4084}
4085#endif
4086/* currently unsed:
4087ideal idChineseRemainder(ideal *xx, intvec *iv)
4088{
4089  int rl=iv->length();
4090  number *q=(number *)omAlloc(rl*sizeof(number));
4091  int i;
4092  for(i=0; i<rl; i++)
4093  {
4094    q[i]=nInit((*iv)[i]);
4095  }
4096  return idChineseRemainder(xx,q,rl);
4097}
4098*/
4099/*
4100 * lift ideal with coeffs over Z (mod N) to Q via Farey
4101 */
4102ideal idFarey(ideal x, number N)
4103{
4104  int cnt=IDELEMS(x)*x->nrows;
4105  ideal result=idInit(cnt,x->rank);
4106  result->nrows=x->nrows; // for lifting matrices
4107  result->ncols=x->ncols; // for lifting matrices
4108
4109  int i;
4110  for(i=cnt-1;i>=0;i--)
4111  {
4112    poly h=pCopy(x->m[i]);
4113    result->m[i]=h;
4114    while(h!=NULL)
4115    {
4116      number c=pGetCoeff(h);
4117      pSetCoeff0(h,nlFarey(c,N));
4118      nDelete(&c);
4119      pIter(h);
4120    }
4121    while((result->m[i]!=NULL)&&(nIsZero(pGetCoeff(result->m[i]))))
4122    {
4123      pLmDelete(&(result->m[i]));
4124    }
4125    h=result->m[i];
4126    while((h!=NULL) && (pNext(h)!=NULL))
4127    {
4128      if(nIsZero(pGetCoeff(pNext(h))))
4129      {
4130        pLmDelete(&pNext(h));
4131      }
4132      else pIter(h);
4133    }
4134  }
4135  return result;
4136}
4137
4138/*2
4139* transpose a module
4140* NOTE: just a version of "ideal idTransp(ideal)" which works within specified ring.
4141*/
4142ideal id_Transp(ideal a, const ring rRing)
4143{
4144  int r = a->rank, c = IDELEMS(a);
4145  ideal b =  idInit(r,c);
4146
4147  for (int i=c; i>0; i--)
4148  {
4149    poly p=a->m[i-1];
4150    while(p!=NULL)
4151    {
4152      poly h=p_Head(p, rRing);
4153      int co=p_GetComp(h, rRing)-1;
4154      p_SetComp(h, i, rRing);
4155      p_Setm(h, rRing);
4156      b->m[co] = p_Add_q(b->m[co], h, rRing);
4157      pIter(p);
4158    }
4159  }
4160  return b;
4161}
4162
4163
4164
4165/*2
4166* The following is needed to compute the image of certain map used in
4167* the computation of cohomologies via BGG
4168* let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
4169* assuming that nrows(M) <= m*n; the procedure computes:
4170* transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
4171* where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
4172* that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
4173
4174  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
4175*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
4176*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
4177+ =>
4178  f_i =
4179
4180   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
4181   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
4182                             ...
4183   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
4184
4185   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
4186*/
4187ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing)
4188{
4189// #ifdef DEBU
4190//  WarnS("tensorModuleMult!!!!");
4191
4192  assume(m > 0);
4193  assume(M != NULL);
4194
4195  const int n = rRing->N;
4196
4197  assume(M->rank <= m * n);
4198
4199  const int k = IDELEMS(M);
4200
4201  ideal idTemp =  idInit(k,m); // = {f_1, ..., f_k }
4202
4203  for( int i = 0; i < k; i++ ) // for every w \in M
4204  {
4205    poly pTempSum = NULL;
4206
4207    poly w = M->m[i];
4208
4209    while(w != NULL) // for each term of w...
4210    {
4211      poly h = p_Head(w, rRing);
4212
4213      const int  gen = p_GetComp(h, rRing); // 1 ...
4214
4215      assume(gen > 0);
4216      assume(gen <= n*m);
4217
4218      // TODO: write a formula with %, / instead of while!
4219      /*
4220      int c = gen;
4221      int v = 1;
4222      while(c > m)
4223      {
4224        c -= m;
4225        v++;
4226      }
4227      */
4228
4229      int cc = gen % m;
4230      if( cc == 0) cc = m;
4231      int vv = 1 + (gen - cc) / m;
4232
4233//      assume( cc == c );
4234//      assume( vv == v );
4235
4236      //  1<= c <= m
4237      assume( cc > 0 );
4238      assume( cc <= m );
4239
4240      assume( vv > 0 );
4241      assume( vv <= n );
4242
4243      assume( (cc + (vv-1)*m) == gen );
4244
4245      p_IncrExp(h, vv, rRing); // h *= var(j) && //      p_AddExp(h, vv, 1, rRing);
4246      p_SetComp(h, cc, rRing);
4247
4248      p_Setm(h, rRing);         // addjust degree after the previous steps!
4249
4250      pTempSum = p_Add_q(pTempSum, h, rRing); // it is slow since h will be usually put to the back of pTempSum!!!
4251
4252      pIter(w);
4253    }
4254
4255    idTemp->m[i] = pTempSum;
4256  }
4257
4258  // simplify idTemp???
4259
4260  ideal idResult = id_Transp(idTemp, rRing);
4261
4262  id_Delete(&idTemp, rRing);
4263
4264  return(idResult);
4265}
Note: See TracBrowser for help on using the repository browser.