source: git/Singular/ideals.cc @ dd01bf0

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