source: git/Singular/ideals.cc @ 5ca9807

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