source: git/Singular/ideals.cc @ 663519a

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