source: git/Singular/ideals.cc @ c616d1

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