source: git/Singular/ideals.cc @ b199d5

spielwiese
Last change on this file since b199d5 was b199d5, checked in by Mathias Schulze <mschulze@…>, 22 years ago
*mschulze: (T,R,U)=division(M,N) => M*U=N*T+R git-svn-id: file:///usr/local/Singular/svn/trunk@5959 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 70.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: ideals.cc,v 1.128 2002-03-07 16:00:58 mschulze 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] = 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 division of P by Q with remainder up to weighted degree n
1889*P, Q, and w are not changed
1890*/
1891lists idLiftW(ideal P, ideal Q, int n, short *w)
1892{
1893  int N=0;
1894  int i;
1895  for(i=IDELEMS(Q)-1;i>=0;i--)
1896    N=max(N,pDegW(Q->m[i],w));
1897  N+=n;
1898
1899  matrix T=mpNew(IDELEMS(Q),IDELEMS(P));
1900  ideal R=idInit(IDELEMS(P),P->rank);
1901
1902  for(i=IDELEMS(P)-1;i>=0;i--)
1903  {
1904    poly p=ppJetW(P->m[i],N,w);
1905
1906    int j=IDELEMS(Q)-1;
1907    while(p!=NULL)
1908    {
1909      if(pDivisibleBy(Q->m[j],p))
1910      {
1911        poly p0=pDivideM(pHead(p),pHead(Q->m[j]));
1912        p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
1913        pNormalize(p);
1914        if(pDegW(p0,w)>n)
1915          pDelete(&p0);
1916        else
1917          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
1918        j=IDELEMS(Q)-1;
1919      }
1920      else
1921      {
1922        if(j==0)
1923        {
1924          poly p0=p;
1925          pIter(p);
1926          pNext(p0)=NULL;
1927          if(pDegW(p0,w)>n)
1928            pDelete(&p0);
1929          else
1930            R->m[i]=pAdd(R->m[i],p0);
1931          j=IDELEMS(Q)-1;
1932        }
1933        else
1934          j--;
1935      }
1936    }
1937  }
1938
1939  lists L=(lists)omAllocBin(slists_bin);
1940  L->Init(2);
1941  L->m[0].rtyp=MATRIX_CMD;
1942  L->m[0].data=(void *)T;
1943  L->m[1].rtyp=MODUL_CMD;
1944  L->m[1].data=(void *)R;
1945
1946  return L;
1947}
1948
1949/*2
1950*computes the quotient of h1,h2 : interanl routine for idQuot
1951*BEWARE: the returned ideals may contain incorrected orderd polys !
1952*
1953*/
1954static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
1955                               BOOLEAN *addOnlyOne, int *kkmax)
1956{
1957  ideal temph1;
1958  poly     p,q = NULL;
1959  int i,l,ll,k,kkk,kmax;
1960  int j = 0;
1961  int k1 = idRankFreeModule(h1);
1962  int k2 = idRankFreeModule(h2);
1963  tHomog   hom=isNotHomog;
1964
1965  k=max(k1,k2);
1966  if (k==0)
1967    k = 1;
1968  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
1969
1970  intvec * weights;
1971  hom = (tHomog)idHomModule(h1,currQuotient,&weights);
1972  if (addOnlyOne && (!h1IsStb))
1973    temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
1974  else
1975    temph1 = idCopy(h1);
1976  if (weights!=NULL) delete weights;
1977  idTest(temph1);
1978/*--- making a single vector from h2 ---------------------*/
1979  for (i=0; i<IDELEMS(h2); i++)
1980  {
1981    if (h2->m[i] != NULL)
1982    {
1983      p = pCopy(h2->m[i]);
1984      if (k2 == 0)
1985        pShift(&p,j*k+1);
1986      else
1987        pShift(&p,j*k);
1988      q = pAdd(q,p);
1989      j++;
1990    }
1991  }
1992  *kkmax = kmax = j*k+1;
1993/*--- adding a monomial for the result (syzygy) ----------*/
1994  p = q;
1995  while (pNext(p)!=NULL) pIter(p);
1996  pNext(p) = pOne();
1997  pIter(p);
1998  pSetComp(p,kmax);
1999  pSetmComp(p);
2000/*--- constructing the big matrix ------------------------*/
2001  ideal h4 = idInit(16,kmax+k-1);
2002  h4->m[0] = q;
2003  if (k2 == 0)
2004  {
2005    if (k > IDELEMS(h4))
2006    {
2007      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
2008      IDELEMS(h4) = k;
2009    }
2010    for (i=1; i<k; i++)
2011    {
2012      p = pCopy_noCheck(h4->m[i-1]);
2013      pShift(&p,1);
2014      h4->m[i] = p;
2015    }
2016  }
2017
2018  kkk = IDELEMS(h4);
2019  i = IDELEMS(temph1);
2020  while ((i>0) && (temph1->m[i-1]==NULL)) i--;
2021  for (l=0; l<i; l++)
2022  {
2023    if(temph1->m[l]!=NULL)
2024    {
2025      for (ll=0; ll<j; ll++)
2026      {
2027        p = pCopy(temph1->m[l]);
2028        if (k1 == 0)
2029          pShift(&p,ll*k+1);
2030        else
2031          pShift(&p,ll*k);
2032        if (kkk >= IDELEMS(h4))
2033        {
2034          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
2035          IDELEMS(h4) += 16;
2036        }
2037        h4->m[kkk] = p;
2038        kkk++;
2039      }
2040    }
2041  }
2042/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
2043  if (*addOnlyOne)
2044  {
2045    p = h4->m[0];
2046    for (i=0;i<IDELEMS(h4)-1;i++)
2047    {
2048      h4->m[i] = h4->m[i+1];
2049    }
2050    h4->m[IDELEMS(h4)-1] = p;
2051    idSkipZeroes(h4);
2052    test |= Sy_bit(OPT_SB_1);
2053  }
2054  idDelete(&temph1);
2055  return h4;
2056}
2057/*2
2058*computes the quotient of h1,h2
2059*/
2060ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
2061{
2062  // first check for special case h1:(0)
2063  if (idIs0(h2))
2064  {
2065    ideal res;
2066    if (resultIsIdeal)
2067    {
2068      res = idInit(1,1);
2069      res->m[0] = pOne();
2070    }
2071    else
2072      res = idFreeModule(h1->rank);
2073    return res;
2074  }
2075  BITSET old_test=test;
2076  poly     p,q = NULL;
2077  int i,l,ll,k,kkk,kmax;
2078  BOOLEAN  addOnlyOne=TRUE;
2079  tHomog   hom=isNotHomog;
2080  intvec * weights1;
2081
2082  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
2083
2084  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
2085
2086  ring orig_ring=currRing;
2087  ring syz_ring=rCurrRingAssure_SyzComp();
2088  rSetSyzComp(kmax-1);
2089  if (orig_ring!=syz_ring)
2090  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
2091    s_h4 = idrMoveR(s_h4,orig_ring);
2092  idTest(s_h4);
2093  ideal s_h3;
2094  if (addOnlyOne)
2095  {
2096    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1,IDELEMS(s_h4)-1);
2097  }
2098  else
2099  {
2100    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
2101  }
2102  idTest(s_h3);
2103  if (weights1!=NULL) delete weights1;
2104  idDelete(&s_h4);
2105
2106
2107  for (i=0;i<IDELEMS(s_h3);i++)
2108  {
2109    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
2110    {
2111      if (resultIsIdeal)
2112        pShift(&s_h3->m[i],-kmax);
2113      else
2114        pShift(&s_h3->m[i],-kmax+1);
2115    }
2116    else
2117      pDelete(&s_h3->m[i]);
2118  }
2119  if (resultIsIdeal)
2120    s_h3->rank = 1;
2121  else
2122    s_h3->rank = h1->rank;
2123  if(syz_ring!=orig_ring)
2124  {
2125//    pDelete(&q);
2126    rChangeCurrRing(orig_ring);
2127    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
2128    rKill(syz_ring);
2129  }
2130  idSkipZeroes(s_h3);
2131  test = old_test;
2132  idTest(s_h3);
2133  return s_h3;
2134}
2135
2136/*2
2137*computes recursively all monomials of a certain degree
2138*in every step the actvar-th entry in the exponential
2139*vector is incremented and the other variables are
2140*computed by recursive calls of makemonoms
2141*if the last variable is reached, the difference to the
2142*degree is computed directly
2143*vars is the number variables
2144*actvar is the actual variable to handle
2145*deg is the degree of the monomials to compute
2146*monomdeg is the actual degree of the monomial in consideration
2147*/
2148static void makemonoms(int vars,int actvar,int deg,int monomdeg)
2149{
2150  poly p;
2151  int i=0;
2152
2153  if ((idpowerpoint == 0) && (actvar ==1))
2154  {
2155    idpower[idpowerpoint] = pOne();
2156    monomdeg = 0;
2157  }
2158  while (i<=deg)
2159  {
2160    if (deg == monomdeg)
2161    {
2162      pSetm(idpower[idpowerpoint]);
2163      idpowerpoint++;
2164      return;
2165    }
2166    if (actvar == vars)
2167    {
2168      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
2169      pSetm(idpower[idpowerpoint]);
2170      pTest(idpower[idpowerpoint]);
2171      idpowerpoint++;
2172      return;
2173    }
2174    else
2175    {
2176      p = pCopy(idpower[idpowerpoint]);
2177      makemonoms(vars,actvar+1,deg,monomdeg);
2178      idpower[idpowerpoint] = p;
2179    }
2180    monomdeg++;
2181    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
2182    pSetm(idpower[idpowerpoint]);
2183    pTest(idpower[idpowerpoint]);
2184    i++;
2185  }
2186}
2187
2188/*2
2189*returns the deg-th power of the maximal ideal of 0
2190*/
2191ideal idMaxIdeal(int deg)
2192{
2193  if (deg < 0)
2194  {
2195    WarnS("maxideal: power must be non-negative");
2196  }
2197  if (deg < 1)
2198  {
2199    ideal I=idInit(1,1);
2200    I->m[0]=pOne();
2201    return I;
2202  }
2203  if (deg == 1)
2204  {
2205    return idMaxIdeal();
2206  }
2207
2208  int vars = currRing->N;
2209  int i = binom(vars+deg-1,deg);
2210  ideal id=idInit(i,1);
2211  idpower = id->m;
2212  idpowerpoint = 0;
2213  makemonoms(vars,1,deg,0);
2214  idpower = NULL;
2215  idpowerpoint = 0;
2216  return id;
2217}
2218
2219/*2
2220*computes recursively all generators of a certain degree
2221*of the ideal "givenideal"
2222*elms is the number elements in the given ideal
2223*actelm is the actual element to handle
2224*deg is the degree of the power to compute
2225*gendeg is the actual degree of the generator in consideration
2226*/
2227static void makepotence(int elms,int actelm,int deg,int gendeg)
2228{
2229  poly p;
2230  int i=0;
2231
2232  if ((idpowerpoint == 0) && (actelm ==1))
2233  {
2234    idpower[idpowerpoint] = pOne();
2235    gendeg = 0;
2236  }
2237  while (i<=deg)
2238  {
2239    if (deg == gendeg)
2240    {
2241      idpowerpoint++;
2242      return;
2243    }
2244    if (actelm == elms)
2245    {
2246      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
2247      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
2248      idpowerpoint++;
2249      return;
2250    }
2251    else
2252    {
2253      p = pCopy(idpower[idpowerpoint]);
2254      makepotence(elms,actelm+1,deg,gendeg);
2255      idpower[idpowerpoint] = p;
2256    }
2257    gendeg++;
2258    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
2259    i++;
2260  }
2261}
2262
2263/*2
2264*returns the deg-th power of the ideal gid
2265*/
2266//ideal idPower(ideal gid,int deg)
2267//{
2268//  int i;
2269//  ideal id;
2270//
2271//  if (deg < 1) deg = 1;
2272//  i = binom(IDELEMS(gid)+deg-1,deg);
2273//  id=idInit(i,1);
2274//  idpower = id->m;
2275//  givenideal = gid->m;
2276//  idpowerpoint = 0;
2277//  makepotence(IDELEMS(gid),1,deg,0);
2278//  idpower = NULL;
2279//  givenideal = NULL;
2280//  idpowerpoint = 0;
2281//  return id;
2282//}
2283static void idNextPotence(ideal given, ideal result,
2284  int begin, int end, int deg, int restdeg, poly ap)
2285{
2286  poly p;
2287  int i;
2288
2289  p = pPower(pCopy(given->m[begin]),restdeg);
2290  i = result->nrows;
2291  result->m[i] = pMult(pCopy(ap),p);
2292//PrintS(".");
2293  (result->nrows)++;
2294  if (result->nrows >= IDELEMS(result))
2295  {
2296    pEnlargeSet(&(result->m),IDELEMS(result),16);
2297    IDELEMS(result) += 16;
2298  }
2299  if (begin == end) return;
2300  for (i=restdeg-1;i>0;i--)
2301  {
2302    p = pPower(pCopy(given->m[begin]),i);
2303    p = pMult(pCopy(ap),p);
2304    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
2305    pDelete(&p);
2306  }
2307  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
2308}
2309
2310ideal idPower(ideal given,int exp)
2311{
2312  ideal result,temp;
2313  poly p1;
2314  int i;
2315
2316  if (idIs0(given)) return idInit(1,1);
2317  temp = idCopy(given);
2318  idSkipZeroes(temp);
2319  i = binom(IDELEMS(temp)+exp-1,exp);
2320  result = idInit(i,1);
2321  result->nrows = 0;
2322//Print("ideal contains %d elements\n",i);
2323  p1=pOne();
2324  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
2325  pDelete(&p1);
2326  idDelete(&temp);
2327  result->nrows = 1;
2328  idSkipZeroes(result);
2329  idDelEquals(result);
2330  return result;
2331}
2332
2333/*2
2334* eliminate delVar (product of vars) in h1
2335*/
2336ideal idElimination (ideal h1,poly delVar,intvec *hilb)
2337{
2338  int    i,j=0,k,l;
2339  ideal  h,hh, h3;
2340  int    *ord,*block0,*block1;
2341  int    ordersize=2;
2342  int    **wv;
2343  tHomog hom;
2344  intvec * w;
2345  sip_sring tmpR;
2346  ring origR = currRing;
2347
2348  if (delVar==NULL)
2349  {
2350    return idCopy(h1);
2351  }
2352  if (currQuotient!=NULL)
2353  {
2354    WerrorS("cannot eliminate in a qring");
2355    return idCopy(h1);
2356  }
2357  if (idIs0(h1)) return idInit(1,h1->rank);
2358  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
2359  h3=idInit(16,h1->rank);
2360  for (k=0;; k++)
2361  {
2362    if (currRing->order[k]!=0) ordersize++;
2363    else break;
2364  }
2365  ord=(int*)omAlloc0(ordersize*sizeof(int));
2366  block0=(int*)omAlloc(ordersize*sizeof(int));
2367  block1=(int*)omAlloc(ordersize*sizeof(int));
2368  for (k=0;; k++)
2369  {
2370    if (currRing->order[k]!=0)
2371    {
2372      block0[k+1] = currRing->block0[k];
2373      block1[k+1] = currRing->block1[k];
2374      ord[k+1] = currRing->order[k];
2375    }
2376    else
2377      break;
2378  }
2379  block0[0] = 1;
2380  block1[0] = pVariables;
2381  wv=(int**) omAlloc0(ordersize*sizeof(int**));
2382  memcpy4(wv+1,currRing->wvhdl,(ordersize-1)*sizeof(int**));
2383  wv[0]=(int*)omAlloc((pVariables+1)*sizeof(int));
2384  memset(wv[0],0,(pVariables+1)*sizeof(int));
2385  for (j=0;j<pVariables;j++)
2386    if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2387  // use this special ordering: like ringorder_a, except that pFDeg, pWeights
2388  // ignore it
2389  ord[0] = ringorder_aa;
2390
2391  // fill in tmp ring to get back the data later on
2392  tmpR  = *origR;
2393  tmpR.order = ord;
2394  tmpR.block0 = block0;
2395  tmpR.block1 = block1;
2396  tmpR.wvhdl = wv;
2397  rComplete(&tmpR, 1);
2398
2399  // change into the new ring
2400  //pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
2401  rChangeCurrRing(&tmpR);
2402  h = idInit(IDELEMS(h1),h1->rank);
2403  // fetch data from the old ring
2404  for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
2405  // compute kStd
2406  hh = kStd(h,NULL,hom,&w,hilb);
2407  idDelete(&h);
2408
2409  // go back to the original ring
2410  rChangeCurrRing(origR);
2411  i = IDELEMS(hh)-1;
2412  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2413  j = -1;
2414  // fetch data from temp ring
2415  for (k=0; k<=i; k++)
2416  {
2417    l=pVariables;
2418    while ((l>0) && (p_GetExp( hh->m[k],l,&tmpR)*pGetExp(delVar,l)==0)) l--;
2419    if (l==0)
2420    {
2421      j++;
2422      if (j >= IDELEMS(h3))
2423      {
2424        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2425        IDELEMS(h3) += 16;
2426      }
2427      h3->m[j] = prCopyR( hh->m[k], &tmpR);
2428    }
2429  }
2430  id_Delete(&hh, &tmpR);
2431  idSkipZeroes(h3);
2432  omFree((ADDRESS)wv[0]);
2433  omFreeSize((ADDRESS)wv,ordersize*sizeof(int**));
2434  omFreeSize((ADDRESS)ord,ordersize*sizeof(int));
2435  omFreeSize((ADDRESS)block0,ordersize*sizeof(int));
2436  omFreeSize((ADDRESS)block1,ordersize*sizeof(int));
2437  rUnComplete(&tmpR);
2438  if (w!=NULL)
2439    delete w;
2440  return h3;
2441}
2442
2443#ifdef WITH_OLD_MINOR
2444/*2
2445* compute all ar-minors of the matrix a
2446*/
2447ideal idMinors(matrix a, int ar, ideal R)
2448{
2449  int     i,j,k,size;
2450  int *rowchoise,*colchoise;
2451  BOOLEAN rowch,colch;
2452  ideal result;
2453  matrix tmp;
2454  poly p,q;
2455
2456  i = binom(a->rows(),ar);
2457  j = binom(a->cols(),ar);
2458
2459  rowchoise=(int *)omAlloc(ar*sizeof(int));
2460  colchoise=(int *)omAlloc(ar*sizeof(int));
2461  if ((i>512) || (j>512) || (i*j >512)) size=512;
2462  else size=i*j;
2463  result=idInit(size,1);
2464  tmp=mpNew(ar,ar);
2465  k = 0; /* the index in result*/
2466  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2467  while (!rowch)
2468  {
2469    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2470    while (!colch)
2471    {
2472      for (i=1; i<=ar; i++)
2473      {
2474        for (j=1; j<=ar; j++)
2475        {
2476          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2477        }
2478      }
2479      p = mpDetBareiss(tmp);
2480      if (p!=NULL)
2481      {
2482        if (R!=NULL)
2483        {
2484          q = p;
2485          p = kNF(R,currQuotient,q);
2486          pDelete(&q);
2487        }
2488        if (p!=NULL)
2489        {
2490          if (k>=size)
2491          {
2492            pEnlargeSet(&result->m,size,32);
2493            size += 32;
2494          }
2495          result->m[k] = p;
2496          k++;
2497        }
2498      }
2499      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2500    }
2501    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2502  }
2503  /*delete the matrix tmp*/
2504  for (i=1; i<=ar; i++)
2505  {
2506    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2507  }
2508  idDelete((ideal*)&tmp);
2509  if (k==0)
2510  {
2511    k=1;
2512    result->m[0]=NULL;
2513  }
2514  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2515  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2516  pEnlargeSet(&result->m,size,k-size);
2517  IDELEMS(result) = k;
2518  return (result);
2519}
2520#else
2521/*2
2522* compute all ar-minors of the matrix a
2523* the caller of mpRecMin
2524* the elements of the result are not in R (if R!=NULL)
2525*/
2526ideal idMinors(matrix a, int ar, ideal R)
2527{
2528  int elems=0;
2529  int r=a->nrows,c=a->ncols;
2530  int i;
2531  matrix b;
2532  ideal result,h;
2533  ring origR;
2534  sip_sring tmpR;
2535  Exponent_t bound;
2536
2537  if((ar<=0) || (ar>r) || (ar>c))
2538  {
2539    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
2540    return NULL;
2541  }
2542  h = idMatrix2Module(mpCopy(a));
2543  bound = smExpBound(h,c,r,ar);
2544  idDelete(&h);
2545  smRingChange(&origR,tmpR,bound);
2546  b = mpNew(r,c);
2547  for (i=r*c-1;i>=0;i--)
2548  {
2549    if (a->m[i])
2550      b->m[i] = prCopyR(a->m[i],origR);
2551  }
2552  if (R) R = idrCopyR(R,origR);
2553  result=idInit(32,1);
2554  if(ar>1) mpRecMin(ar-1,result,elems,b,r,c,NULL,R);
2555  else mpMinorToResult(result,elems,b,r,c,R);
2556  idDelete((ideal *)&b);
2557  if (R) idDelete(&R);
2558  idSkipZeroes(result);
2559  rChangeCurrRing(origR);
2560  result = idrMoveR(result,&tmpR);
2561  smRingClean(origR,tmpR);
2562  idTest(result);
2563  return result;
2564}
2565#endif
2566
2567/*2
2568*skips all zeroes and double elements, searches also for units
2569*/
2570ideal idCompactify(ideal id)
2571{
2572  int i,j;
2573  BOOLEAN b=FALSE;
2574
2575  i = IDELEMS(id)-1;
2576  while ((! b) && (i>=0))
2577  {
2578    b=pIsUnit(id->m[i]);
2579    i--;
2580  }
2581  if (b)
2582  {
2583    ideal result=idInit(1,id->rank);
2584    result->m[0]=pOne();
2585    return result;
2586  }
2587  else
2588  {
2589    ideal result=idCopy(id);
2590    //if (IDELEMS(result) < 1)
2591    {
2592      for (i=1;i<IDELEMS(result);i++)
2593      {
2594        if (result->m[i]!=NULL)
2595        {
2596          for (j=0;j<i;j++)
2597          {
2598            if ((result->m[j]!=NULL)
2599            && (pComparePolys(result->m[i],result->m[j])))
2600            {
2601              pDelete(&(result->m[j]));
2602            }
2603          }
2604        }
2605      }
2606    }
2607//    else
2608//    {
2609//      intvec *v=idSort(result,TRUE);
2610//      for(i=0;i<IDELEMS(result);i++)
2611//        (*v)[i]--;
2612//      for (i=0;i<IDELEMS(result)-1;i++)
2613//      {
2614//        if (((*v)[i]>=0)
2615//        && (result->m[(*v)[i]]!=NULL))
2616//        {
2617//          j=i+1;
2618//          while ((j<IDELEMS(result))
2619//          && ((*v)[j]>=0)
2620//          && (result->m[(*v)[j]]!=NULL)
2621//          && (pComparePolys(result->m[(*v)[i]],result->m[(*v)[j]])))
2622//          {
2623//            pDelete(&(result->m[(*v)[j]]));
2624//            j++;
2625//          }
2626//        }
2627//      }
2628//      delete v;
2629//    }
2630    idSkipZeroes(result);
2631    return result;
2632  }
2633}
2634
2635/*2
2636*returns TRUE if id1 is a submodule of id2
2637*/
2638BOOLEAN idIsSubModule(ideal id1,ideal id2)
2639{
2640  int i;
2641  poly p;
2642
2643  if (idIs0(id1)) return TRUE;
2644  for (i=0;i<IDELEMS(id1);i++)
2645  {
2646    if (id1->m[i] != NULL)
2647    {
2648      p = kNF(id2,currQuotient,id1->m[i]);
2649      if (p != NULL)
2650      {
2651        pDelete(&p);
2652        return FALSE;
2653      }
2654    }
2655  }
2656  return TRUE;
2657}
2658
2659/*2
2660* returns the ideals of initial terms
2661*/
2662ideal idHead(ideal h)
2663{
2664  ideal m = idInit(IDELEMS(h),h->rank);
2665  int i;
2666
2667  for (i=IDELEMS(h)-1;i>=0; i--)
2668  {
2669    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
2670  }
2671  return m;
2672}
2673
2674ideal idHomogen(ideal h, int varnum)
2675{
2676  ideal m = idInit(IDELEMS(h),h->rank);
2677  int i;
2678
2679  for (i=IDELEMS(h)-1;i>=0; i--)
2680  {
2681    m->m[i]=pHomogen(h->m[i],varnum);
2682  }
2683  return m;
2684}
2685
2686/*------------------type conversions----------------*/
2687ideal idVec2Ideal(poly vec)
2688{
2689   ideal result=idInit(1,1);
2690   omFree((ADDRESS)result->m);
2691   result->m=NULL; // remove later
2692   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2693   return result;
2694}
2695
2696// #define NEW_STUFF
2697#ifndef NEW_STUFF
2698// converts mat to module, destroys mat
2699ideal idMatrix2Module(matrix mat)
2700{
2701  int mc=MATCOLS(mat);
2702  int mr=MATROWS(mat);
2703  ideal result = idInit(max(mc,1),max(mr,1));
2704  int i,j;
2705  poly h;
2706
2707  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
2708  {
2709    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
2710    {
2711      h = MATELEM(mat,i,j+1);
2712      if (h!=NULL)
2713      {
2714        MATELEM(mat,i,j+1)=NULL;
2715        pSetCompP(h,i);
2716        result->m[j] = pAdd(result->m[j],h);
2717      }
2718    }
2719  }
2720  // obachman: need to clean this up
2721  idDelete((ideal*) &mat);
2722  return result;
2723}
2724#else
2725
2726#include "sbuckets.h"
2727
2728// converts mat to module, destroys mat
2729ideal idMatrix2Module(matrix mat)
2730{
2731  int mc=MATCOLS(mat);
2732  int mr=MATROWS(mat);
2733  ideal result = idInit(max(mc,1),max(mr,1));
2734  int i,j, l;
2735  poly h;
2736  poly p;
2737  sBucket_pt bucket = sBucketInit(currRing);
2738
2739  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
2740  {
2741    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
2742    {
2743      h = MATELEM(mat,i,j+1);
2744      if (h!=NULL)
2745      {
2746        MATELEM(mat,i,j+1)=NULL;
2747        p_SetCompP(h,i, currRing, &l);
2748        sBucket_Merge_p(bucket, h, l);
2749      }
2750    }
2751    sBucketClearMerge(bucket, &(result->m[j]), &l);
2752  }
2753
2754  // obachman: need to clean this up
2755  idDelete((ideal*) &mat);
2756  return result;
2757}
2758#endif
2759
2760/*2
2761* converts a module into a matrix, destroyes the input
2762*/
2763matrix idModule2Matrix(ideal mod)
2764{
2765  matrix result = mpNew(mod->rank,IDELEMS(mod));
2766  int i,cp;
2767  poly p,h;
2768
2769  for(i=0;i<IDELEMS(mod);i++)
2770  {
2771    p=mod->m[i];
2772    mod->m[i]=NULL;
2773    while (p!=NULL)
2774    {
2775      h=p;
2776      pIter(p);
2777      pNext(h)=NULL;
2778//      cp = max(1,pGetComp(h));     // if used for ideals too
2779      cp = pGetComp(h);
2780      pSetComp(h,0);
2781      pSetmComp(h);
2782#ifdef TEST
2783      if (cp>mod->rank)
2784      {
2785        Print("## inv. rank %d -> %d\n",mod->rank,cp);
2786        int k,l,o=mod->rank;
2787        mod->rank=cp;
2788        matrix d=mpNew(mod->rank,IDELEMS(mod));
2789        for (l=1; l<=o; l++)
2790        {
2791          for (k=1; k<=IDELEMS(mod); k++)
2792          {
2793            MATELEM(d,l,k)=MATELEM(result,l,k);
2794            MATELEM(result,l,k)=NULL;
2795          }
2796        }
2797        idDelete((ideal *)&result);
2798        result=d;
2799      }
2800#endif
2801      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2802    }
2803  }
2804  // obachman 10/99: added the following line, otherwise memory leack!
2805  idDelete(&mod);
2806  return result;
2807}
2808
2809matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
2810{
2811  matrix result = mpNew(rows,cols);
2812  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
2813  poly p,h;
2814
2815  if (r>rows) r = rows;
2816  if (c>cols) c = cols;
2817  for(i=0;i<c;i++)
2818  {
2819    p=mod->m[i];
2820    mod->m[i]=NULL;
2821    while (p!=NULL)
2822    {
2823      h=p;
2824      pIter(p);
2825      pNext(h)=NULL;
2826      cp = pGetComp(h);
2827      if (cp<=r)
2828      {
2829        pSetComp(h,0);
2830        pSetmComp(h);
2831        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2832      }
2833      else
2834        pDelete(&h);
2835    }
2836  }
2837  idDelete(&mod);
2838  return result;
2839}
2840
2841/*2
2842* substitute the n-th variable by the monomial e in id
2843* destroy id
2844*/
2845ideal  idSubst(ideal id, int n, poly e)
2846{
2847  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
2848  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
2849
2850  res->rank = id->rank;
2851  for(k--;k>=0;k--)
2852  {
2853    res->m[k]=pSubst(id->m[k],n,e);
2854    id->m[k]=NULL;
2855  }
2856  idDelete(&id);
2857  return res;
2858}
2859
2860BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
2861{
2862  if (w!=NULL) *w=NULL;
2863  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
2864  if (idIs0(m)) return TRUE;
2865
2866  int i,j,cmax=2,order=0,ord,* diff,* iscom,diffmin=32000;
2867  poly p=NULL;
2868  int length=IDELEMS(m);
2869  polyset P=m->m;
2870  polyset F=(polyset)omAlloc(length*sizeof(poly));
2871  for (i=length-1;i>=0;i--)
2872  {
2873    p=F[i]=P[i];
2874    cmax=max(cmax,pMaxComp(p)+1);
2875  }
2876  diff = (int *)omAlloc0(cmax*sizeof(int));
2877  if (w!=NULL) *w=new intvec(cmax-1);
2878  iscom = (int *)omAlloc0(cmax*sizeof(int));
2879  i=0;
2880  while (i<=length)
2881  {
2882    if (i<length)
2883    {
2884      p=F[i];
2885      while ((p!=NULL) && (!iscom[pGetComp(p)])) pIter(p);
2886    }
2887    if ((p==NULL) && (i<length))
2888    {
2889      i++;
2890    }
2891    else
2892    {
2893      if (p==NULL)
2894      {
2895        i=0;
2896        while ((i<length) && (F[i]==NULL)) i++;
2897        if (i>=length) break;
2898        p = F[i];
2899      }
2900      if (pLexOrder)
2901        order=pTotaldegree(p);
2902      else
2903      //  order = p->order;
2904        order = pFDeg(p);
2905      order += diff[pGetComp(p)];
2906      p = F[i];
2907//Print("Actual p=F[%d]: ",i);pWrite(p);
2908      F[i] = NULL;
2909      i=0;
2910    }
2911    while (p!=NULL)
2912    {
2913      //if (pLexOrder)
2914      //  ord=pTotaldegree(p);
2915      //else
2916      //  ord = p->order;
2917      ord = pFDeg(p);
2918      if (!iscom[pGetComp(p)])
2919      {
2920        diff[pGetComp(p)] = order-ord;
2921        iscom[pGetComp(p)] = 1;
2922/*
2923*PrintS("new diff: ");
2924*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2925*PrintLn();
2926*PrintS("new iscom: ");
2927*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
2928*PrintLn();
2929*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
2930*/
2931      }
2932      else
2933      {
2934/*
2935*PrintS("new diff: ");
2936*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2937*PrintLn();
2938*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
2939*/
2940        if (order != ord+diff[pGetComp(p)])
2941        {
2942          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
2943          omFreeSize((ADDRESS) diff,cmax*sizeof(int));
2944          omFreeSize((ADDRESS) F,length*sizeof(poly));
2945          delete *w;*w=NULL;
2946          return FALSE;
2947        }
2948      }
2949      pIter(p);
2950    }
2951  }
2952  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
2953  omFreeSize((ADDRESS) F,length*sizeof(poly));
2954  for (i=1;i<cmax;i++) (**w)[i-1]=diff[i];
2955  for (i=1;i<cmax;i++)
2956  {
2957    if (diff[i]<diffmin) diffmin=diff[i];
2958  }
2959  if (w!=NULL)
2960  {
2961    for (i=1;i<cmax;i++)
2962    {
2963      (**w)[i-1]=diff[i]-diffmin;
2964    }
2965  }
2966  omFreeSize((ADDRESS) diff,cmax*sizeof(int));
2967  return TRUE;
2968}
2969
2970ideal idJet(ideal i,int d)
2971{
2972  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
2973  r->nrows = i-> nrows;
2974  r->ncols = i-> ncols;
2975  //r->rank = i-> rank;
2976  int k;
2977  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
2978  {
2979    r->m[k]=ppJet(i->m[k],d);
2980  }
2981  return r;
2982}
2983
2984ideal idJetW(ideal i,int d, intvec * iv)
2985{
2986  ideal r=idInit(IDELEMS(i),i->rank);
2987  if (ecartWeights!=NULL)
2988  {
2989    WerrorS("cannot compute weighted jets now");
2990  }
2991  else
2992  {
2993    short *w=iv2array(iv);
2994    int k;
2995    for(k=0; k<IDELEMS(i); k++)
2996    {
2997      r->m[k]=ppJetW(i->m[k],d,w);
2998    }
2999    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
3000  }
3001  return r;
3002}
3003
3004int idMinDeg(ideal M,intvec *w)
3005{
3006  int d=-1;
3007  for(int i=0;i<IDELEMS(M);i++)
3008  {
3009    int d0=pMinDeg(M->m[i],w);
3010    if(-1<d0&&(d0<d||d==-1))
3011      d=d0;
3012  }
3013  return d;
3014}
3015
3016ideal idSeries(int n,ideal M,matrix U=NULL,intvec *w=NULL)
3017{
3018  for(int i=IDELEMS(M)-1;i>=0;i--)
3019  {
3020    if(U==NULL)
3021      M->m[i]=pSeries(n,M->m[i],NULL,w);
3022    else
3023    {
3024      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
3025      MATELEM(U,i+1,i+1)=NULL;
3026    }
3027  }
3028  if(U!=NULL)
3029    idDelete((ideal*)&U);
3030  return M;
3031}
3032
3033matrix idDiff(matrix i, int k)
3034{
3035  int e=MATCOLS(i)*MATROWS(i);
3036  matrix r=mpNew(MATROWS(i),MATCOLS(i));
3037  int j;
3038  for(j=0; j<e; j++)
3039  {
3040    r->m[j]=pDiff(i->m[j],k);
3041  }
3042  return r;
3043}
3044
3045matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
3046{
3047  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
3048  int i,j;
3049  for(i=0; i<IDELEMS(I); i++)
3050  {
3051    for(j=0; j<IDELEMS(J); j++)
3052    {
3053      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
3054    }
3055  }
3056  return r;
3057}
3058
3059/*3
3060*handles for some ideal operations the ring/syzcomp managment
3061*returns all syzygies (componentwise-)shifted by -syzcomp
3062*or -syzcomp-1 (in case of ideals as input)
3063static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
3064{
3065  ring orig_ring=currRing;
3066  ring syz_ring=rCurrRingAssure_SyzComp();
3067  rSetSyzComp(length);
3068
3069  ideal s_temp;
3070  if (orig_ring!=syz_ring)
3071    s_temp=idrMoveR_NoSort(arg,orig_ring);
3072  else
3073    s_temp=arg;
3074
3075  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
3076  if (w!=NULL) delete w;
3077
3078  if (syz_ring!=orig_ring)
3079  {
3080    idDelete(&s_temp);
3081    rChangeCurrRing(orig_ring);
3082  }
3083
3084  idDelete(&temp);
3085  ideal temp1=idRingCopy(s_temp1,syz_ring);
3086
3087  if (syz_ring!=orig_ring)
3088  {
3089    rChangeCurrRing(syz_ring);
3090    idDelete(&s_temp1);
3091    rChangeCurrRing(orig_ring);
3092    rKill(syz_ring);
3093  }
3094
3095  for (i=0;i<IDELEMS(temp1);i++)
3096  {
3097    if ((temp1->m[i]!=NULL)
3098    && (pGetComp(temp1->m[i])<=length))
3099    {
3100      pDelete(&(temp1->m[i]));
3101    }
3102    else
3103    {
3104      pShift(&(temp1->m[i]),-length);
3105    }
3106  }
3107  temp1->rank = rk;
3108  idSkipZeroes(temp1);
3109
3110  return temp1;
3111}
3112*/
3113/*2
3114* represents (h1+h2)/h2=h1/(h1 intersect h2)
3115*/
3116ideal idModulo (ideal h2,ideal h1)
3117{
3118  int i,j,k,rk,flength=0,slength,length;
3119  intvec * w;
3120  poly p,q;
3121
3122  if (idIs0(h2))
3123    return idFreeModule(max(1,h2->ncols));
3124  if (!idIs0(h1))
3125    flength = idRankFreeModule(h1);
3126  slength = idRankFreeModule(h2);
3127  length  = max(flength,slength);
3128  if (length==0)
3129  {
3130    length = 1;
3131  }
3132  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
3133  for (i=0;i<IDELEMS(h2);i++)
3134  {
3135    temp->m[i] = pCopy(h2->m[i]);
3136    q = pOne();
3137    pSetComp(q,i+1+length);
3138    pSetmComp(q);
3139    if(temp->m[i]!=NULL)
3140    {
3141      if (slength==0) pShift(&(temp->m[i]),1);
3142      p = temp->m[i];
3143      while (pNext(p)!=NULL) pIter(p);
3144      pNext(p) = q;
3145    }
3146    else
3147      temp->m[i]=q;
3148  }
3149  rk = k = IDELEMS(h2);
3150  if (!idIs0(h1))
3151  {
3152    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
3153    IDELEMS(temp) += IDELEMS(h1);
3154    for (i=0;i<IDELEMS(h1);i++)
3155    {
3156      if (h1->m[i]!=NULL)
3157      {
3158        temp->m[k] = pCopy(h1->m[i]);
3159        if (flength==0) pShift(&(temp->m[k]),1);
3160        k++;
3161      }
3162    }
3163  }
3164
3165  ring orig_ring=currRing;
3166  ring syz_ring=rCurrRingAssure_SyzComp();
3167  rSetSyzComp(length);
3168  ideal s_temp;
3169
3170  if (syz_ring != orig_ring)
3171  {
3172    s_temp = idrMoveR_NoSort(temp, orig_ring);
3173  }
3174  else
3175  {
3176    s_temp = temp;
3177  }
3178
3179  idTest(s_temp);
3180  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
3181  if (w!=NULL) delete w;
3182
3183  for (i=0;i<IDELEMS(s_temp1);i++)
3184  {
3185    if ((s_temp1->m[i]!=NULL)
3186    && (pGetComp(s_temp1->m[i])<=length))
3187    {
3188      pDelete(&(s_temp1->m[i]));
3189    }
3190    else
3191    {
3192      pShift(&(s_temp1->m[i]),-length);
3193    }
3194  }
3195  s_temp1->rank = rk;
3196  idSkipZeroes(s_temp1);
3197
3198  if (syz_ring!=orig_ring)
3199  {
3200    rChangeCurrRing(orig_ring);
3201    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
3202    rKill(syz_ring);
3203    // Hmm ... here seems to be a memory leak
3204    // However, simply deleting it causes memory trouble
3205    // idDelete(&s_temp);
3206  }
3207  else
3208  {
3209    idDelete(&temp);
3210  }
3211  idTest(s_temp1);
3212  return s_temp1;
3213}
3214
3215int idElem(ideal F)
3216{
3217  int i=0,j=0;
3218
3219  while(j<IDELEMS(F))
3220  {
3221   if ((F->m)[j]!=NULL) i++;
3222   j++;
3223  }
3224  return i;
3225}
3226
3227/*
3228*computes module-weights for liftings of homogeneous modules
3229*/
3230intvec * idMWLift(ideal mod,intvec * weights)
3231{
3232  if (idIs0(mod)) return new intvec(2);
3233  int i=IDELEMS(mod);
3234  while ((i>0) && (mod->m[i-1]==NULL)) i--;
3235  intvec *result = new intvec(i+1);
3236  while (i>0)
3237  {
3238    (*result)[i]=pFDeg(mod->m[i])+(*weights)[pGetComp(mod->m[i])];
3239  }
3240  return result;
3241}
3242
3243/*2
3244*sorts the kbase for idCoef* in a special way (lexicographically
3245*with x_max,...,x_1)
3246*/
3247ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
3248{
3249  int i;
3250  ideal result;
3251
3252  if (idIs0(kBase)) return NULL;
3253  result = idInit(IDELEMS(kBase),kBase->rank);
3254  *convert = idSort(kBase,FALSE);
3255  for (i=0;i<(*convert)->length();i++)
3256  {
3257    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
3258  }
3259  return result;
3260}
3261
3262/*2
3263*returns the index of a given monom in the list of the special kbase
3264*/
3265int idIndexOfKBase(poly monom, ideal kbase)
3266{
3267  int j=IDELEMS(kbase);
3268
3269  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
3270  if (j==0) return -1;
3271  int i=pVariables;
3272  while (i>0)
3273  {
3274    loop
3275    {
3276      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
3277      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
3278      j--;
3279      if (j==0) return -1;
3280    }
3281    if (i==1)
3282    {
3283      while(j>0)
3284      {
3285        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
3286        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
3287        j--;
3288      }
3289    }
3290    i--;
3291  }
3292  return -1;
3293}
3294
3295/*2
3296*decomposes the monom in a part of coefficients described by the
3297*complement of how and a monom in variables occuring in how, the
3298*index of which in kbase is returned as integer pos (-1 if it don't
3299*exists)
3300*/
3301poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3302{
3303  int i;
3304  poly coeff=pOne(), base=pOne();
3305
3306  for (i=1;i<=pVariables;i++)
3307  {
3308    if (pGetExp(how,i)>0)
3309    {
3310      pSetExp(base,i,pGetExp(monom,i));
3311    }
3312    else
3313    {
3314      pSetExp(coeff,i,pGetExp(monom,i));
3315    }
3316  }
3317  pSetComp(base,pGetComp(monom));
3318  pSetm(base);
3319  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3320  pSetm(coeff);
3321  *pos = idIndexOfKBase(base,kbase);
3322  if (*pos<0)
3323    pDelete(&coeff);
3324  pDelete(&base);
3325  return coeff;
3326}
3327
3328/*2
3329*returns a matrix A of coefficients with kbase*A=arg
3330*if all monomials in variables of how occur in kbase
3331*the other are deleted
3332*/
3333matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3334{
3335  matrix result;
3336  ideal tempKbase;
3337  poly p,q;
3338  intvec * convert;
3339  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3340#if 0
3341  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3342  if (idIs0(arg))
3343    return mpNew(i,1);
3344  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3345  result = mpNew(i,j);
3346#else
3347  result = mpNew(i, j);
3348  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3349#endif
3350
3351  tempKbase = idCreateSpecialKbase(kbase,&convert);
3352  for (k=0;k<j;k++)
3353  {
3354    p = arg->m[k];
3355    while (p!=NULL)
3356    {
3357      q = idDecompose(p,how,tempKbase,&pos);
3358      if (pos>=0)
3359      {
3360        MATELEM(result,(*convert)[pos],k+1) =
3361            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3362      }
3363      else
3364        pDelete(&q);
3365      pIter(p);
3366    }
3367  }
3368  idDelete(&tempKbase);
3369  return result;
3370}
3371
3372/*3
3373* searches for units in the components of the module arg and
3374* returns the first one
3375*/
3376static int idReadOutUnits(ideal arg,int* comp)
3377{
3378  if (idIs0(arg)) return -1;
3379  int i=0,j,rk_arg=idRankFreeModule(arg),generator=-1;
3380  intvec * componentIsUsed =new intvec(rk_arg+1);
3381  poly p,q;
3382
3383  while ((i<IDELEMS(arg)) && (generator<0))
3384  {
3385    for (j=rk_arg;j>=0;j--)
3386      (*componentIsUsed)[j]=0;
3387    p = arg->m[i];
3388    while (p!=NULL)
3389    {
3390      j = pGetComp(p);
3391      if ((*componentIsUsed)[j]==0)
3392      {
3393        if (pLmIsConstantComp(p))
3394        {
3395          generator = i;
3396          (*componentIsUsed)[j] = 1;
3397        }
3398        else
3399        {
3400          (*componentIsUsed)[j] = -1;
3401        }
3402      }
3403      else if ((*componentIsUsed)[j]>0)
3404      {
3405        ((*componentIsUsed)[j])++;
3406      }
3407      pIter(p);
3408    }
3409    i++;
3410  }
3411  i = 0;
3412  *comp = -1;
3413  for (j=0;j<=rk_arg;j++)
3414  {
3415    if ((*componentIsUsed)[j]>0)
3416    {
3417      if ((*comp==-1) || ((*componentIsUsed)[j]<i))
3418      {
3419        *comp = j;
3420        i= (*componentIsUsed)[j];
3421      }
3422    }
3423  }
3424  return generator;
3425}
3426
3427static void idDeleteComp(ideal arg,int red_comp)
3428{
3429  int i,j;
3430  poly p;
3431
3432  for (i=IDELEMS(arg)-1;i>=0;i--)
3433  {
3434    p = arg->m[i];
3435    while (p!=NULL)
3436    {
3437      j = pGetComp(p);
3438      if (j>red_comp)
3439      {
3440        pSetComp(p,j-1);
3441        pSetm(p);
3442      }
3443      pIter(p);
3444    }
3445  }
3446  (arg->rank)--;
3447}
3448
3449/*2
3450* returns the presentation of an isomorphic, minimally
3451* embedded  module (arg represents the quotient!)
3452*/
3453ideal idMinEmbedding(ideal arg,BOOLEAN inPlace)
3454{
3455  if (idIs0(arg)) return idInit(1,arg->rank);
3456  int next_gen,next_comp;
3457  ideal res=arg;
3458
3459  if (!inPlace) res = idCopy(arg);
3460  loop
3461  {
3462    next_gen = idReadOutUnits(res,&next_comp);
3463    if (next_gen<0) break;
3464    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
3465    idDeleteComp(res,next_comp);
3466  }
3467  idSkipZeroes(res);
3468  return res;
3469}
3470
3471/*2
3472* transpose a module
3473*/
3474ideal idTransp(ideal a)
3475{
3476  int r = a->rank, c = IDELEMS(a);
3477  ideal b =  idInit(r,c);
3478
3479  for (int i=c; i>0; i--)
3480  {
3481    poly p=a->m[i-1];
3482    while(p!=NULL)
3483    {
3484      poly h=pHead(p);
3485      int co=pGetComp(h)-1;
3486      pSetComp(h,i);
3487      pSetmComp(h);
3488      b->m[co]=pAdd(b->m[co],h);
3489      pIter(p);
3490    }
3491  }
3492  return b;
3493}
3494
3495intvec * idQHomWeight(ideal id)
3496{
3497  poly head, tail;
3498  int k;
3499  int in=IDELEMS(id)-1, ready=0, all=0,
3500      coldim=pVariables, rowmax=2*coldim;
3501  if (in<0) return NULL;
3502  intvec *imat=new intvec(rowmax+1,coldim,0);
3503
3504  do
3505  {
3506    head = id->m[in--];
3507    if (head!=NULL)
3508    {
3509      tail = pNext(head);
3510      while (tail!=NULL)
3511      {
3512        all++;
3513        for (k=1;k<=coldim;k++)
3514          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
3515        if (all==rowmax)
3516        {
3517          ivTriangIntern(imat, ready, all);
3518          if (ready==coldim)
3519          {
3520            delete imat;
3521            return NULL;
3522          }
3523        }
3524        pIter(tail);
3525      }
3526    }
3527  } while (in>=0);
3528  if (all>ready)
3529  {
3530    ivTriangIntern(imat, ready, all);
3531    if (ready==coldim)
3532    {
3533      delete imat;
3534      return NULL;
3535    }
3536  }
3537  intvec *result = ivSolveKern(imat, ready);
3538  delete imat;
3539  return result;
3540}
3541
3542BOOLEAN idIsZeroDim(ideal I)
3543{
3544  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(pVariables*sizeof(BOOLEAN));
3545  int i,n;
3546  poly po;
3547  BOOLEAN res=TRUE;
3548  for(i=IDELEMS(I)-1;i>=0;i--)
3549  {
3550    po=I->m[i];
3551    if ((po!=NULL) &&((n=pIsPurePower(po))!=0)) UsedAxis[n-1]=TRUE;
3552  }
3553  for(i=pVariables-1;i>=0;i--)
3554  {
3555    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
3556  }
3557  omFreeSize(UsedAxis,pVariables*sizeof(BOOLEAN));
3558  return res;
3559}
3560
3561void idNormalize(ideal I)
3562{
3563  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
3564  int i;
3565  poly p;
3566  for(i=IDELEMS(I)-1;i>=0;i--)
3567  {
3568    p=I->m[i] ;
3569    while(p!=NULL)
3570    {
3571      nNormalize(pGetCoeff(p));
3572      pIter(p);
3573    }
3574  }
3575}
Note: See TracBrowser for help on using the repository browser.