source: git/Singular/ideals.cc @ 6f2edc

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