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

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