source: git/kernel/ideals.cc @ e9c3b2

spielwiese
Last change on this file since e9c3b2 was e9c3b2, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
ADD: intvec: new view() method ADD: some debug for NF strategy object ADD: idSize From: Oleksandr Motsak <motsak@mathematik.uni-kl.de> git-svn-id: file:///usr/local/Singular/svn/trunk@13978 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 89.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT - all basic methods to manipulate ideals
7*/
8
9/* includes */
10#include <kernel/mod2.h>
11
12#ifndef NDEBUG
13# define MYTEST 0
14#else /* ifndef NDEBUG */
15# define MYTEST 0
16#endif /* ifndef NDEBUG */
17
18#include <kernel/options.h>
19#include <omalloc/omalloc.h>
20#include <kernel/febase.h>
21#include <kernel/numbers.h>
22#include <kernel/longrat.h>
23#include <kernel/polys.h>
24#include <kernel/ring.h>
25#include <kernel/kstd1.h>
26#include <kernel/matpol.h>
27#include <kernel/weight.h>
28#include <kernel/intvec.h>
29#include <kernel/syz.h>
30#include <kernel/sparsmat.h>
31#include <kernel/ideals.h>
32#include <kernel/prCopy.h>
33#include <kernel/gring.h>
34
35
36omBin sip_sideal_bin = omGetSpecBin(sizeof(sip_sideal));
37
38/* #define WITH_OLD_MINOR */
39#define pCopy_noCheck(p) pCopy(p)
40
41static poly * idpower;
42/*collects the monomials in makemonoms, must be allocated befor*/
43static int idpowerpoint;
44/*index of the actual monomial in idpower*/
45static poly * givenideal;
46/*the ideal from which a power is computed*/
47
48/*0 implementation*/
49
50/*2
51* initialise an ideal
52*/
53#ifdef PDEBUG
54ideal idDBInit(int idsize, int rank, const char *f, int l)
55#else
56ideal idInit(int idsize, int rank)
57#endif
58{
59  /*- initialise an ideal -*/
60  ideal hh = (ideal )omAllocBin(sip_sideal_bin);
61  hh->nrows = 1;
62  hh->rank = rank;
63  IDELEMS(hh) = idsize;
64  if (idsize>0)
65  {
66    hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
67  }
68  else
69    hh->m=NULL;
70  return hh;
71}
72
73#ifdef PDEBUG
74// this is only for outputting an ideal within the debugger
75void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
76{
77  assume( debugPrint >= 0 );
78
79  if( id == NULL )
80    PrintS("(NULL)");
81  else
82  {
83    Print("Module of rank %ld,real rank %ld and %d generators.\n",
84          id->rank,idRankFreeModule(id, lmRing, tailRing),IDELEMS(id));
85
86    int j = (id->ncols*id->nrows) - 1;
87    while ((j > 0) && (id->m[j]==NULL)) j--;
88    for (int i = 0; i <= j; i++)
89    {
90      Print("generator %d: ",i); p_DebugPrint(id->m[i], lmRing, tailRing, debugPrint);
91    }
92  }
93}
94#endif
95
96/* index of generator with leading term in ground ring (if any);
97   otherwise -1 */
98int idPosConstant(ideal id)
99{
100  int k;
101  for (k = IDELEMS(id)-1; k>=0; k--)
102  {
103    if (p_LmIsConstantComp(id->m[k], currRing) == TRUE)
104      return k;
105  }
106  return -1;
107}
108
109/*2
110* initialise the maximal ideal (at 0)
111*/
112ideal idMaxIdeal (void)
113{
114  int l;
115  ideal hh=NULL;
116
117  hh=idInit(pVariables,1);
118  for (l=0; l<pVariables; l++)
119  {
120    hh->m[l] = pOne();
121    pSetExp(hh->m[l],l+1,1);
122    pSetm(hh->m[l]);
123  }
124  return hh;
125}
126
127/*2
128* deletes an ideal/matrix
129*/
130void id_Delete (ideal * h, ring r)
131{
132  int j,elems;
133  if (*h == NULL)
134    return;
135  elems=j=(*h)->nrows*(*h)->ncols;
136  if (j>0)
137  {
138    do
139    {
140      p_Delete(&((*h)->m[--j]), r);
141    }
142    while (j>0);
143    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
144  }
145  omFreeBin((ADDRESS)*h, sip_sideal_bin);
146  *h=NULL;
147}
148
149
150/*2
151* Shallowdeletes an ideal/matrix
152*/
153void id_ShallowDelete (ideal *h, ring r)
154{
155  int j,elems;
156  if (*h == NULL)
157    return;
158  elems=j=(*h)->nrows*(*h)->ncols;
159  if (j>0)
160  {
161    do
162    {
163      p_ShallowDelete(&((*h)->m[--j]), r);
164    }
165    while (j>0);
166    omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
167  }
168  omFreeBin((ADDRESS)*h, sip_sideal_bin);
169  *h=NULL;
170}
171
172/*2
173*gives an ideal the minimal possible size
174*/
175void idSkipZeroes (ideal ide)
176{
177  int k;
178  int j = -1;
179  BOOLEAN change=FALSE;
180  for (k=0; k<IDELEMS(ide); k++)
181  {
182    if (ide->m[k] != NULL)
183    {
184      j++;
185      if (change)
186      {
187        ide->m[j] = ide->m[k];
188      }
189    }
190    else
191    {
192      change=TRUE;
193    }
194  }
195  if (change)
196  {
197    if (j == -1)
198      j = 0;
199    else
200    {
201      for (k=j+1; k<IDELEMS(ide); k++)
202        ide->m[k] = NULL;
203    }
204    pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
205    IDELEMS(ide) = j+1;
206  }
207}
208
209/*2
210* copies the first k (>= 1) entries of the given ideal
211* and returns these as a new ideal
212* (Note that the copied polynomials may be zero.)
213*/
214ideal idCopyFirstK (const ideal ide, const int k)
215{
216  ideal newI = idInit(k, 0);
217  for (int i = 0; i < k; i++)
218    newI->m[i] = pCopy(ide->m[i]);
219  return newI;
220}
221
222/*2
223* ideal id = (id[i])
224* result is leadcoeff(id[i]) = 1
225*/
226void idNorm(ideal id)
227{
228  for (int i=IDELEMS(id)-1; i>=0; i--)
229  {
230    if (id->m[i] != NULL)
231    {
232      pNorm(id->m[i]);
233    }
234  }
235}
236
237/*2
238* ideal id = (id[i]), c any unit
239* if id[i] = c*id[j] then id[j] is deleted for j > i
240*/
241void idDelMultiples(ideal id)
242{
243  int i, j;
244  int k = IDELEMS(id)-1;
245  for (i=k; i>=0; i--)
246  {
247    if (id->m[i]!=NULL)
248    {
249      for (j=k; j>i; j--)
250      {
251        if (id->m[j]!=NULL)
252        {
253#ifdef HAVE_RINGS
254          if (rField_is_Ring(currRing))
255          {
256            /* if id[j] = c*id[i] then delete id[j].
257               In the below cases of a ground field, we
258               check whether id[i] = c*id[j] and, if so,
259               delete id[j] for historical reasons (so
260               that previous output does not change) */
261            if (pComparePolys(id->m[j], id->m[i])) pDelete(&id->m[j]);
262          }
263          else
264          {
265            if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
266          }
267#else
268          if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
269#endif         
270        }
271      }
272    }
273  }
274}
275
276/*2
277* ideal id = (id[i])
278* if id[i] = id[j] then id[j] is deleted for j > i
279*/
280void idDelEquals(ideal id)
281{
282  int i, j;
283  int k = IDELEMS(id)-1;
284  for (i=k; i>=0; i--)
285  {
286    if (id->m[i]!=NULL)
287    {
288      for (j=k; j>i; j--)
289      {
290        if ((id->m[j]!=NULL)
291        && (pEqualPolys(id->m[i], id->m[j])))
292        {
293          pDelete(&id->m[j]);
294        }
295      }
296    }
297  }
298}
299
300//
301// Delete id[j], if Lm(j) == Lm(i) and j > i
302//
303void idDelLmEquals(ideal id)
304{
305  int i, j;
306  int k = IDELEMS(id)-1;
307  for (i=k; i>=0; i--)
308  {
309    if (id->m[i] != NULL)
310    {
311      for (j=k; j>i; j--)
312      {
313        if ((id->m[j] != NULL)
314        && pLmEqual(id->m[i], id->m[j]))
315        {
316          pDelete(&id->m[j]);
317        }
318      }
319    }
320  }
321}
322
323void idDelDiv(ideal id)
324{
325  int i, j;
326  int k = IDELEMS(id)-1;
327  for (i=k; i>=0; i--)
328  {
329    if (id->m[i] != NULL)
330    {
331      for (j=k; j>i; j--)
332      {
333        if (id->m[j]!=NULL)
334        {
335          if(pDivisibleBy(id->m[i], id->m[j]))
336          {
337            pDelete(&id->m[j]);
338          }
339          else if(pDivisibleBy(id->m[j], id->m[i]))
340          {
341            pDelete(&id->m[i]);
342            break;
343          }
344        }
345      }
346    }
347  }
348}
349
350/*2
351*test if the ideal has only constant polynomials
352*/
353BOOLEAN idIsConstant(ideal id)
354{
355  int k;
356  for (k = IDELEMS(id)-1; k>=0; k--)
357  {
358    if (pIsConstantPoly(id->m[k]) == FALSE)
359      return FALSE;
360  }
361  return TRUE;
362}
363
364/*2
365* copy an ideal
366*/
367#ifdef PDEBUG
368ideal idDBCopy(ideal h1,const char *f,int l)
369{
370  int i;
371  ideal h2;
372
373  idDBTest(h1,PDEBUG,f,l);
374//#ifdef TEST
375  if (h1 == NULL)
376  {
377    h2=idDBInit(1,1,f,l);
378  }
379  else
380//#endif
381  {
382    h2=idDBInit(IDELEMS(h1),h1->rank,f,l);
383    for (i=IDELEMS(h1)-1; i>=0; i--)
384      h2->m[i] = pCopy(h1->m[i]);
385  }
386  return h2;
387}
388#endif
389
390ideal id_Copy (ideal h1, const ring r)
391{
392  int i;
393  ideal h2;
394
395//#ifdef TEST
396  if (h1 == NULL)
397  {
398    h2=idInit(1,1);
399  }
400  else
401//#endif
402  {
403    h2=idInit(IDELEMS(h1),h1->rank);
404    for (i=IDELEMS(h1)-1; i>=0; i--)
405      h2->m[i] = p_Copy(h1->m[i],r);
406  }
407  return h2;
408}
409
410#ifdef PDEBUG
411void idDBTest(ideal h1, int level, const char *f,const int l)
412{
413  int i;
414
415  if (h1 != NULL)
416  {
417    // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
418    omCheckAddrSize(h1,sizeof(*h1));
419    omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
420    /* to be able to test matrices: */
421    for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
422      _p_Test(h1->m[i], currRing, level);
423    int new_rk=idRankFreeModule(h1);
424    if(new_rk > h1->rank)
425    {
426      dReportError("wrong rank %d (should be %d) in %s:%d\n",
427                   h1->rank, new_rk, f,l);
428      omPrintAddrInfo(stderr, h1, " for ideal");
429      h1->rank=new_rk;
430    }
431  }
432}
433#endif
434
435/*3
436* for idSort: compare a and b revlex inclusive module comp.
437*/
438static int pComp_RevLex(poly a, poly b,BOOLEAN nolex)
439{
440  if (b==NULL) return 1;
441  if (a==NULL) return -1;
442
443  if (nolex) 
444  {
445    int r=pLmCmp(a,b);
446    if (r!=0) return r;
447    number h=nSub(pGetCoeff(a),pGetCoeff(b));
448    r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
449    nDelete(&h);
450    return r;
451  }
452  int l=pVariables;
453  while ((l>0) && (pGetExp(a,l)==pGetExp(b,l))) l--;
454  if (l==0)
455  {
456    if (pGetComp(a)==pGetComp(b))
457    {
458      number h=nSub(pGetCoeff(a),pGetCoeff(b));
459      int r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
460      nDelete(&h);
461      return r;
462    }
463    if (pGetComp(a)>pGetComp(b)) return 1;
464  }
465  else if (pGetExp(a,l)>pGetExp(b,l))
466    return 1;
467  return -1;
468}
469
470/*2
471*sorts the ideal w.r.t. the actual ringordering
472*uses lex-ordering when nolex = FALSE
473*/
474intvec *idSort(ideal id,BOOLEAN nolex)
475{
476  poly p,q;
477  intvec * result = new intvec(IDELEMS(id));
478  int i, j, actpos=0, newpos, l;
479  int diff, olddiff, lastcomp, newcomp;
480  BOOLEAN notFound;
481
482  for (i=0;i<IDELEMS(id);i++)
483  {
484    if (id->m[i]!=NULL)
485    {
486      notFound = TRUE;
487      newpos = actpos / 2;
488      diff = (actpos+1) / 2;
489      diff = (diff+1) / 2;
490      lastcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
491      if (lastcomp<0)
492      {
493        newpos -= diff;
494      }
495      else if (lastcomp>0)
496      {
497        newpos += diff;
498      }
499      else
500      {
501        notFound = FALSE;
502      }
503      //while ((newpos>=0) && (newpos<actpos) && (notFound))
504      while (notFound && (newpos>=0) && (newpos<actpos))
505      {
506        newcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
507        olddiff = diff;
508        if (diff>1)
509        {
510          diff = (diff+1) / 2;
511          if ((newcomp==1)
512          && (actpos-newpos>1)
513          && (diff>1)
514          && (newpos+diff>=actpos))
515          {
516            diff = actpos-newpos-1;
517          }
518          else if ((newcomp==-1)
519          && (diff>1)
520          && (newpos<diff))
521          {
522            diff = newpos;
523          }
524        }
525        if (newcomp<0)
526        {
527          if ((olddiff==1) && (lastcomp>0))
528            notFound = FALSE;
529          else
530            newpos -= diff;
531        }
532        else if (newcomp>0)
533        {
534          if ((olddiff==1) && (lastcomp<0))
535          {
536            notFound = FALSE;
537            newpos++;
538          }
539          else
540          {
541            newpos += diff;
542          }
543        }
544        else
545        {
546          notFound = FALSE;
547        }
548        lastcomp = newcomp;
549        if (diff==0) notFound=FALSE; /*hs*/
550      }
551      if (newpos<0) newpos = 0;
552      if (newpos>actpos) newpos = actpos;
553      while ((newpos<actpos) && (pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex)==0))
554        newpos++;
555      for (j=actpos;j>newpos;j--)
556      {
557        (*result)[j] = (*result)[j-1];
558      }
559      (*result)[newpos] = i;
560      actpos++;
561    }
562  }
563  for (j=0;j<actpos;j++) (*result)[j]++;
564  return result;
565}
566
567/*2
568* concat the lists h1 and h2 without zeros
569*/
570ideal idSimpleAdd (ideal h1,ideal h2)
571{
572  int i,j,r,l;
573  ideal result;
574
575  if (h1==NULL) return idCopy(h2);
576  if (h2==NULL) return idCopy(h1);
577  j = IDELEMS(h1)-1;
578  while ((j >= 0) && (h1->m[j] == NULL)) j--;
579  i = IDELEMS(h2)-1;
580  while ((i >= 0) && (h2->m[i] == NULL)) i--;
581  r = si_max(h1->rank,h2->rank);
582  if (i+j==(-2))
583    return idInit(1,r);
584  else
585    result=idInit(i+j+2,r);
586  for (l=j; l>=0; l--)
587  {
588    result->m[l] = pCopy(h1->m[l]);
589  }
590  r = i+j+1;
591  for (l=i; l>=0; l--, r--)
592  {
593    result->m[r] = pCopy(h2->m[l]);
594  }
595  return result;
596}
597
598/*2
599* insert h2 into h1 (if h2 is not the zero polynomial)
600* return TRUE iff h2 was indeed inserted
601*/
602BOOLEAN idInsertPoly (ideal h1, poly h2)
603{
604  if (h2==NULL) return FALSE;
605  int j = IDELEMS(h1)-1;
606  while ((j >= 0) && (h1->m[j] == NULL)) j--;
607  j++;
608  if (j==IDELEMS(h1))
609  {
610    pEnlargeSet(&(h1->m),IDELEMS(h1),16);
611    IDELEMS(h1)+=16;
612  }
613  h1->m[j]=h2;
614  return TRUE;
615}
616
617/*2
618* insert h2 into h1 depending on the two boolean parameters:
619* - if zeroOk is true, then h2 will also be inserted when it is zero
620* - if duplicateOk is true, then h2 will also be inserted when it is
621*   already present in h1
622* return TRUE iff h2 was indeed inserted
623*/
624BOOLEAN idInsertPolyWithTests (ideal h1, const int validEntries,
625  const poly h2, const bool zeroOk, const bool duplicateOk)
626{
627  if ((!zeroOk) && (h2 == NULL)) return FALSE;
628  if (!duplicateOk)
629  {
630    bool h2FoundInH1 = false;
631    int i = 0;
632    while ((i < validEntries) && (!h2FoundInH1))
633    {
634      h2FoundInH1 = pEqualPolys(h1->m[i], h2);
635      i++;
636    }
637    if (h2FoundInH1) return FALSE;
638  }
639  if (validEntries == IDELEMS(h1))
640  {
641    pEnlargeSet(&(h1->m), IDELEMS(h1), 16);
642    IDELEMS(h1) += 16;
643  }
644  h1->m[validEntries] = h2;
645  return TRUE;
646}
647
648/*2
649* h1 + h2
650*/
651ideal idAdd (ideal h1,ideal h2)
652{
653  ideal result = idSimpleAdd(h1,h2);
654  idCompactify(result);
655  return result;
656}
657
658/*2
659* h1 * h2
660*/
661ideal  idMult (ideal h1,ideal  h2)
662{
663  int i,j,k;
664  ideal  hh;
665
666  j = IDELEMS(h1);
667  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
668  i = IDELEMS(h2);
669  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
670  j = j * i;
671  if (j == 0)
672    hh = idInit(1,1);
673  else
674    hh=idInit(j,1);
675  if (h1->rank<h2->rank)
676    hh->rank = h2->rank;
677  else
678    hh->rank = h1->rank;
679  if (j==0) return hh;
680  k = 0;
681  for (i=0; i<IDELEMS(h1); i++)
682  {
683    if (h1->m[i] != NULL)
684    {
685      for (j=0; j<IDELEMS(h2); j++)
686      {
687        if (h2->m[j] != NULL)
688        {
689          hh->m[k] = ppMult_qq(h1->m[i],h2->m[j]);
690          k++;
691        }
692      }
693    }
694  }
695  {
696    idCompactify(hh);
697    return hh;
698  }
699}
700
701/*2
702*returns true if h is the zero ideal
703*/
704BOOLEAN idIs0 (ideal h)
705{
706  int i;
707
708  if (h == NULL) return TRUE;
709  i = IDELEMS(h)-1;
710  while ((i >= 0) && (h->m[i] == NULL))
711  {
712    i--;
713  }
714  if (i < 0)
715    return TRUE;
716  else
717    return FALSE;
718}
719
720/*2
721* return the maximal component number found in any polynomial in s
722*/
723long idRankFreeModule (ideal s, ring lmRing, ring tailRing)
724{
725  if (s!=NULL)
726  {
727    int  j=0;
728
729    if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
730    {
731      int  l=IDELEMS(s);
732      poly *p=s->m;
733      int  k;
734      for (; l != 0; l--)
735      {
736        if (*p!=NULL)
737        {
738          pp_Test(*p, lmRing, tailRing);
739          k = p_MaxComp(*p, lmRing, tailRing);
740          if (k>j) j = k;
741        }
742        p++;
743      }
744    }
745    return j;
746  }
747  return -1;
748}
749
750BOOLEAN idIsModule(ideal id, ring r)
751{
752  if (id != NULL && rRing_has_Comp(r))
753  {
754    int j, l = IDELEMS(id);
755    for (j=0; j<l; j++)
756    {
757      if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0) return TRUE;
758    }
759  }
760  return FALSE;
761}
762
763
764/*2
765*returns true if id is homogenous with respect to the aktual weights
766*/
767BOOLEAN idHomIdeal (ideal id, ideal Q)
768{
769  int i;
770  BOOLEAN     b;
771  if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
772  i = 0;
773  b = TRUE;
774  while ((i < IDELEMS(id)) && b)
775  {
776    b = pIsHomogeneous(id->m[i]);
777    i++;
778  }
779  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
780  {
781    i=0;
782    while ((i < IDELEMS(Q)) && b)
783    {
784      b = pIsHomogeneous(Q->m[i]);
785      i++;
786    }
787  }
788  return b;
789}
790
791/*2
792*returns a minimized set of generators of h1
793*/
794ideal idMinBase (ideal h1)
795{
796  ideal h2, h3,h4,e;
797  int j,k;
798  int i,l,ll;
799  intvec * wth;
800  BOOLEAN homog;
801
802  homog = idHomModule(h1,currQuotient,&wth);
803  if (rHasGlobalOrdering_currRing())
804  {
805    if(!homog)
806    {
807      WarnS("minbase applies only to the local or homogeneous case");
808      e=idCopy(h1);
809      return e;
810    }
811    else
812    {
813      ideal re=kMin_std(h1,currQuotient,(tHomog)homog,&wth,h2,NULL,0,3);
814      idDelete(&re);
815      return h2;
816    }
817  }
818  e=idInit(1,h1->rank);
819  if (idIs0(h1))
820  {
821    return e;
822  }
823  pEnlargeSet(&(e->m),IDELEMS(e),15);
824  IDELEMS(e) = 16;
825  h2 = kStd(h1,currQuotient,isNotHomog,NULL);
826  h3 = idMaxIdeal();
827  h4=idMult(h2,h3);
828  idDelete(&h3);
829  h3=kStd(h4,currQuotient,isNotHomog,NULL);
830  k = IDELEMS(h3);
831  while ((k > 0) && (h3->m[k-1] == NULL)) k--;
832  j = -1;
833  l = IDELEMS(h2);
834  while ((l > 0) && (h2->m[l-1] == NULL)) l--;
835  for (i=l-1; i>=0; i--)
836  {
837    if (h2->m[i] != NULL)
838    {
839      ll = 0;
840      while ((ll < k) && ((h3->m[ll] == NULL)
841      || !pDivisibleBy(h3->m[ll],h2->m[i])))
842        ll++;
843      if (ll >= k)
844      {
845        j++;
846        if (j > IDELEMS(e)-1)
847        {
848          pEnlargeSet(&(e->m),IDELEMS(e),16);
849          IDELEMS(e) += 16;
850        }
851        e->m[j] = pCopy(h2->m[i]);
852      }
853    }
854  }
855  idDelete(&h2);
856  idDelete(&h3);
857  idDelete(&h4);
858  if (currQuotient!=NULL)
859  {
860    h3=idInit(1,e->rank);
861    h2=kNF(h3,currQuotient,e);
862    idDelete(&h3);
863    idDelete(&e);
864    e=h2;
865  }
866  idSkipZeroes(e);
867  return e;
868}
869
870/*2
871*the minimal index of used variables - 1
872*/
873int pLowVar (poly p)
874{
875  int k,l,lex;
876
877  if (p == NULL) return -1;
878
879  k = 32000;/*a very large dummy value*/
880  while (p != NULL)
881  {
882    l = 1;
883    lex = pGetExp(p,l);
884    while ((l < pVariables) && (lex == 0))
885    {
886      l++;
887      lex = pGetExp(p,l);
888    }
889    l--;
890    if (l < k) k = l;
891    pIter(p);
892  }
893  return k;
894}
895
896/*3
897*multiplies p with t (!cas) or  (t-1)
898*the index of t is:1, so we have to shift all variables
899*p is NOT in the actual ring, it has no t
900*/
901static poly pMultWithT (poly p,BOOLEAN cas)
902{
903  /*qp is the working pointer in p*/
904  /*result is the result, qresult is the working pointer*/
905  /*pp is p in the actual ring(shifted), qpp the working pointer*/
906  poly result,qp,pp;
907  poly qresult=NULL;
908  poly qpp=NULL;
909  int  i,j,lex;
910  number n;
911
912  pp = NULL;
913  result = NULL;
914  qp = p;
915  while (qp != NULL)
916  {
917    i = 0;
918    if (result == NULL)
919    {/*first monomial*/
920      result = pInit();
921      qresult = result;
922    }
923    else
924    {
925      qresult->next = pInit();
926      pIter(qresult);
927    }
928    for (j=pVariables-1; j>0; j--)
929    {
930      lex = pGetExp(qp,j);
931      pSetExp(qresult,j+1,lex);/*copy all variables*/
932    }
933    lex = pGetComp(qp);
934    pSetComp(qresult,lex);
935    n=nCopy(pGetCoeff(qp));
936    pSetCoeff0(qresult,n);
937    qresult->next = NULL;
938    pSetm(qresult);
939    /*qresult is now qp brought into the actual ring*/
940    if (cas)
941    { /*case: mult with t-1*/
942      pSetExp(qresult,1,0);
943      pSetm(qresult);
944      if (pp == NULL)
945      { /*first monomial*/
946        pp = pCopy(qresult);
947        qpp = pp;
948      }
949      else
950      {
951        qpp->next = pCopy(qresult);
952        pIter(qpp);
953      }
954      pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
955      /*now qpp contains -1*qp*/
956    }
957    pSetExp(qresult,1,1);/*this is mult. by t*/
958    pSetm(qresult);
959    pIter(qp);
960  }
961  /*
962  *now p is processed:
963  *result contains t*p
964  * if cas: pp contains -1*p (in the new ring)
965  */
966  if (cas)  qresult->next = pp;
967  /*  else      qresult->next = NULL;*/
968  return result;
969}
970
971/*2
972* verschiebt die Indizees der Modulerzeugenden um i
973*/
974void pShift (poly * p,int i)
975{
976  poly qp1 = *p,qp2 = *p;/*working pointers*/
977  int     j = pMaxComp(*p),k = pMinComp(*p);
978
979  if (j+i < 0) return ;
980  while (qp1 != NULL)
981  {
982    if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
983    {
984      pAddComp(qp1,i);
985      pSetmComp(qp1);
986      qp2 = qp1;
987      pIter(qp1);
988    }
989    else
990    {
991      if (qp2 == *p)
992      {
993        pIter(*p);
994        pLmDelete(&qp2);
995        qp2 = *p;
996        qp1 = *p;
997      }
998      else
999      {
1000        qp2->next = qp1->next;
1001        if (qp1!=NULL) pLmDelete(&qp1);
1002        qp1 = qp2->next;
1003      }
1004    }
1005  }
1006}
1007
1008/*2
1009*initialized a field with r numbers between beg and end for the
1010*procedure idNextChoise
1011*/
1012void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
1013{
1014  /*returns the first choise of r numbers between beg and end*/
1015  int i;
1016  for (i=0; i<r; i++)
1017  {
1018    choise[i] = 0;
1019  }
1020  if (r <= end-beg+1)
1021    for (i=0; i<r; i++)
1022    {
1023      choise[i] = beg+i;
1024    }
1025  if (r > end-beg+1)
1026    *endch = TRUE;
1027  else
1028    *endch = FALSE;
1029}
1030
1031/*2
1032*returns the next choise of r numbers between beg and end
1033*/
1034void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
1035{
1036  int i = r-1,j;
1037  while ((i >= 0) && (choise[i] == end))
1038  {
1039    i--;
1040    end--;
1041  }
1042  if (i == -1)
1043    *endch = TRUE;
1044  else
1045  {
1046    choise[i]++;
1047    for (j=i+1; j<r; j++)
1048    {
1049      choise[j] = choise[i]+j-i;
1050    }
1051    *endch = FALSE;
1052  }
1053}
1054
1055/*2
1056*takes the field choise of d numbers between beg and end, cancels the t-th
1057*entree and searches for the ordinal number of that d-1 dimensional field
1058* w.r.t. the algorithm of construction
1059*/
1060int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
1061{
1062  int * localchoise,i,result=0;
1063  BOOLEAN b=FALSE;
1064
1065  if (d<=1) return 1;
1066  localchoise=(int*)omAlloc((d-1)*sizeof(int));
1067  idInitChoise(d-1,begin,end,&b,localchoise);
1068  while (!b)
1069  {
1070    result++;
1071    i = 0;
1072    while ((i<t) && (localchoise[i]==choise[i])) i++;
1073    if (i>=t)
1074    {
1075      i = t+1;
1076      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
1077      if (i>=d)
1078      {
1079        omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
1080        return result;
1081      }
1082    }
1083    idGetNextChoise(d-1,end,&b,localchoise);
1084  }
1085  omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
1086  return 0;
1087}
1088
1089/*2
1090*computes the binomial coefficient
1091*/
1092int binom (int n,int r)
1093{
1094  int i,result;
1095
1096  if (r==0) return 1;
1097  if (n-r<r) return binom(n,n-r);
1098  result = n-r+1;
1099  for (i=2;i<=r;i++)
1100  {
1101    result *= n-r+i;
1102    if (result<0)
1103    {
1104      WarnS("overflow in binomials");
1105      return 0;
1106    }
1107    result /= i;
1108  }
1109  return result;
1110}
1111
1112/*2
1113*the free module of rank i
1114*/
1115ideal idFreeModule (int i)
1116{
1117  int j;
1118  ideal h;
1119
1120  h=idInit(i,i);
1121  for (j=0; j<i; j++)
1122  {
1123    h->m[j] = pOne();
1124    pSetComp(h->m[j],j+1);
1125    pSetmComp(h->m[j]);
1126  }
1127  return h;
1128}
1129
1130/*2
1131* h3 := h1 intersect h2
1132*/
1133ideal idSect (ideal h1,ideal h2)
1134{
1135  int i,j,k,length;
1136  int flength = idRankFreeModule(h1);
1137  int slength = idRankFreeModule(h2);
1138  int rank=si_min(flength,slength);
1139  if ((idIs0(h1)) || (idIs0(h2)))  return idInit(1,rank);
1140
1141  ideal first,second,temp,temp1,result;
1142  poly p,q;
1143
1144  if (IDELEMS(h1)<IDELEMS(h2))
1145  {
1146    first = h1;
1147    second = h2;
1148  }
1149  else
1150  {
1151    first = h2;
1152    second = h1;
1153    int t=flength; flength=slength; slength=t;
1154  }
1155  length  = si_max(flength,slength);
1156  if (length==0)
1157  {
1158    length = 1;
1159  }
1160  j = IDELEMS(first);
1161
1162  ring orig_ring=currRing;
1163  ring syz_ring=rCurrRingAssure_SyzComp();
1164  rSetSyzComp(length);
1165
1166  while ((j>0) && (first->m[j-1]==NULL)) j--;
1167  temp = idInit(j /*IDELEMS(first)*/+IDELEMS(second),length+j);
1168  k = 0;
1169  for (i=0;i<j;i++)
1170  {
1171    if (first->m[i]!=NULL)
1172    {
1173      if (syz_ring==orig_ring)
1174        temp->m[k] = pCopy(first->m[i]);
1175      else
1176        temp->m[k] = prCopyR(first->m[i], orig_ring);
1177      q = pOne();
1178      pSetComp(q,i+1+length);
1179      pSetmComp(q);
1180      if (flength==0) pShift(&(temp->m[k]),1);
1181      p = temp->m[k];
1182      while (pNext(p)!=NULL) pIter(p);
1183      pNext(p) = q;
1184      k++;
1185    }
1186  }
1187  for (i=0;i<IDELEMS(second);i++)
1188  {
1189    if (second->m[i]!=NULL)
1190    {
1191      if (syz_ring==orig_ring)
1192        temp->m[k] = pCopy(second->m[i]);
1193      else
1194        temp->m[k] = prCopyR(second->m[i], orig_ring);
1195      if (slength==0) pShift(&(temp->m[k]),1);
1196      k++;
1197    }
1198  }
1199  intvec *w=NULL;
1200  temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
1201  if (w!=NULL) delete w;
1202  idDelete(&temp);
1203
1204  if(syz_ring!=orig_ring)
1205    rChangeCurrRing(orig_ring);
1206
1207  result = idInit(IDELEMS(temp1),rank);
1208  j = 0;
1209  for (i=0;i<IDELEMS(temp1);i++)
1210  {
1211    if ((temp1->m[i]!=NULL)
1212    && (p_GetComp(temp1->m[i],syz_ring)>length))
1213    {
1214      if(syz_ring==orig_ring)
1215      {
1216        p = temp1->m[i];
1217      }
1218      else
1219      {
1220        p = prMoveR(temp1->m[i], syz_ring);
1221      }
1222      temp1->m[i]=NULL;
1223      while (p!=NULL)
1224      {
1225        q = pNext(p);
1226        pNext(p) = NULL;
1227        k = pGetComp(p)-1-length;
1228        pSetComp(p,0);
1229        pSetmComp(p);
1230        /* Warning! multiply only from the left! it's very important for Plural */
1231        result->m[j] = pAdd(result->m[j],pMult(p,pCopy(first->m[k])));
1232        p = q;
1233      }
1234      j++;
1235    }
1236  }
1237  if(syz_ring!=orig_ring)
1238  {
1239    rChangeCurrRing(syz_ring);
1240    idDelete(&temp1);
1241    rChangeCurrRing(orig_ring);
1242    rKill(syz_ring);
1243  }
1244  else
1245  {
1246    idDelete(&temp1);
1247  }
1248
1249  idSkipZeroes(result);
1250  if (TEST_OPT_RETURN_SB)
1251  {
1252     w=NULL;
1253     temp1=kStd(result,currQuotient,testHomog,&w);
1254     if (w!=NULL) delete w;
1255     idDelete(&result);
1256     idSkipZeroes(temp1);
1257     return temp1;
1258  }
1259  else //temp1=kInterRed(result,currQuotient);
1260    return result;
1261}
1262
1263/*2
1264* ideal/module intersection for a list of objects
1265* given as 'resolvente'
1266*/
1267ideal idMultSect(resolvente arg, int length)
1268{
1269  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
1270  ideal bigmat,tempstd,result;
1271  poly p;
1272  int isIdeal=0;
1273  intvec * w=NULL;
1274
1275  /* find 0-ideals and max rank -----------------------------------*/
1276  for (i=0;i<length;i++)
1277  {
1278    if (!idIs0(arg[i]))
1279    {
1280      realrki=idRankFreeModule(arg[i]);
1281      k++;
1282      j += IDELEMS(arg[i]);
1283      if (realrki>maxrk) maxrk = realrki;
1284    }
1285    else
1286    {
1287      if (arg[i]!=NULL)
1288      {
1289        return idInit(1,arg[i]->rank);
1290      }
1291    }
1292  }
1293  if (maxrk == 0)
1294  {
1295    isIdeal = 1;
1296    maxrk = 1;
1297  }
1298  /* init -----------------------------------------------------------*/
1299  j += maxrk;
1300  syzComp = k*maxrk;
1301
1302  ring orig_ring=currRing;
1303  ring syz_ring=rCurrRingAssure_SyzComp();
1304  rSetSyzComp(syzComp);
1305
1306  bigmat = idInit(j,(k+1)*maxrk);
1307  /* create unit matrices ------------------------------------------*/
1308  for (i=0;i<maxrk;i++)
1309  {
1310    for (j=0;j<=k;j++)
1311    {
1312      p = pOne();
1313      pSetComp(p,i+1+j*maxrk);
1314      pSetmComp(p);
1315      bigmat->m[i] = pAdd(bigmat->m[i],p);
1316    }
1317  }
1318  /* enter given ideals ------------------------------------------*/
1319  i = maxrk;
1320  k = 0;
1321  for (j=0;j<length;j++)
1322  {
1323    if (arg[j]!=NULL)
1324    {
1325      for (l=0;l<IDELEMS(arg[j]);l++)
1326      {
1327        if (arg[j]->m[l]!=NULL)
1328        {
1329          if (syz_ring==orig_ring)
1330            bigmat->m[i] = pCopy(arg[j]->m[l]);
1331          else
1332            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring);
1333          pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
1334          i++;
1335        }
1336      }
1337      k++;
1338    }
1339  }
1340  /* std computation --------------------------------------------*/
1341  tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
1342  if (w!=NULL) delete w;
1343  idDelete(&bigmat);
1344
1345  if(syz_ring!=orig_ring)
1346    rChangeCurrRing(orig_ring);
1347
1348  /* interprete result ----------------------------------------*/
1349  result = idInit(IDELEMS(tempstd),maxrk);
1350  k = 0;
1351  for (j=0;j<IDELEMS(tempstd);j++)
1352  {
1353    if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
1354    {
1355      if (syz_ring==orig_ring)
1356        p = pCopy(tempstd->m[j]);
1357      else
1358        p = prCopyR(tempstd->m[j], syz_ring);
1359      pShift(&p,-syzComp-isIdeal);
1360      result->m[k] = p;
1361      k++;
1362    }
1363  }
1364  /* clean up ----------------------------------------------------*/
1365  if(syz_ring!=orig_ring)
1366    rChangeCurrRing(syz_ring);
1367  idDelete(&tempstd);
1368  if(syz_ring!=orig_ring)
1369  {
1370    rChangeCurrRing(orig_ring);
1371    rKill(syz_ring);
1372  }
1373  idSkipZeroes(result);
1374  return result;
1375}
1376
1377/*2
1378*computes syzygies of h1,
1379*if quot != NULL it computes in the quotient ring modulo "quot"
1380*works always in a ring with ringorder_s
1381*/
1382static ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w)
1383{
1384  ideal   h2, h3;
1385  int     i;
1386  int     j,jj=0,k;
1387  poly    p,q;
1388
1389  if (idIs0(h1)) return NULL;
1390  k = idRankFreeModule(h1);
1391  h2=idCopy(h1);
1392  i = IDELEMS(h2)-1;
1393  if (k == 0)
1394  {
1395    for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
1396    k = 1;
1397  }
1398  if (syzcomp<k)
1399  {
1400    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
1401    syzcomp = k;
1402    rSetSyzComp(k);
1403  }
1404  h2->rank = syzcomp+i+1;
1405
1406  //if (hom==testHomog)
1407  //{
1408  //  if(idHomIdeal(h1,currQuotient))
1409  //  {
1410  //    hom=TRUE;
1411  //  }
1412  //}
1413
1414#if MYTEST
1415#ifdef RDEBUG
1416  Print("Prepare::h2: ");
1417  idPrint(h2);
1418
1419  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
1420
1421#endif
1422#endif
1423
1424  for (j=0; j<=i; j++)
1425  {
1426    p = h2->m[j];
1427    q = pOne();
1428    pSetComp(q,syzcomp+1+j);
1429    pSetmComp(q);
1430    if (p!=NULL)
1431    {
1432      while (pNext(p)) pIter(p);
1433      p->next = q;
1434    }
1435    else
1436      h2->m[j]=q;
1437  }
1438
1439#ifdef PDEBUG
1440  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
1441
1442#if MYTEST
1443#ifdef RDEBUG
1444  Print("Prepare::Input: ");
1445  idPrint(h2);
1446
1447  Print("Prepare::currQuotient: ");
1448  idPrint(currQuotient);
1449#endif
1450#endif
1451
1452#endif
1453
1454  idTest(h2);
1455
1456  h3 = kStd(h2,currQuotient,hom,w,NULL,syzcomp);
1457
1458#if MYTEST
1459#ifdef RDEBUG
1460  Print("Prepare::Output: ");
1461  idPrint(h3);
1462  for(j=0;j<IDELEMS(h2);j++) pTest(h3->m[j]);
1463#endif
1464#endif
1465
1466
1467  idDelete(&h2);
1468  return h3;
1469}
1470
1471/*2
1472* compute the syzygies of h1 in R/quot,
1473* weights of components are in w
1474* if setRegularity, return the regularity in deg
1475* do not change h1,  w
1476*/
1477ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
1478                  BOOLEAN setRegularity, int *deg)
1479{
1480  ideal s_h1;
1481  poly  p;
1482  int   j, k, length=0,reg;
1483  BOOLEAN isMonomial=TRUE;
1484  int ii, idElemens_h1;
1485
1486  assume(h1 != NULL);
1487
1488  idElemens_h1=IDELEMS(h1);
1489#ifdef PDEBUG
1490  for(ii=0;ii<idElemens_h1 /*IDELEMS(h1)*/;ii++) pTest(h1->m[ii]);
1491#endif
1492  if (idIs0(h1))
1493  {
1494    ideal result=idFreeModule(idElemens_h1/*IDELEMS(h1)*/);
1495    int curr_syz_limit=rGetCurrSyzLimit();
1496    if (curr_syz_limit>0)
1497    for (ii=0;ii<idElemens_h1/*IDELEMS(h1)*/;ii++)
1498    {
1499      if (h1->m[ii]!=NULL)
1500        pShift(&h1->m[ii],curr_syz_limit);
1501    }
1502    return result;
1503  }
1504  int slength=(int)idRankFreeModule(h1);
1505  k=si_max(1,slength /*idRankFreeModule(h1)*/);
1506
1507  assume(currRing != NULL);
1508  ring orig_ring=currRing;
1509  ring syz_ring=rCurrRingAssure_SyzComp();
1510
1511  if (setSyzComp)
1512    rSetSyzComp(k);
1513
1514  if (orig_ring != syz_ring)
1515  {
1516    s_h1=idrCopyR_NoSort(h1,orig_ring);
1517  }
1518  else
1519  {
1520    s_h1 = h1;
1521  }
1522
1523  idTest(s_h1);
1524
1525  ideal s_h3=idPrepare(s_h1,h,k,w); // main (syz) GB computation
1526
1527  if (s_h3==NULL)
1528  {
1529    return idFreeModule( idElemens_h1 /*IDELEMS(h1)*/);
1530  }
1531
1532  if (orig_ring != syz_ring)
1533  {
1534    idDelete(&s_h1);
1535    for (j=0; j<IDELEMS(s_h3); j++)
1536    {
1537      if (s_h3->m[j] != NULL)
1538      {
1539        if (p_MinComp(s_h3->m[j],syz_ring) > k)
1540          pShift(&s_h3->m[j], -k);
1541        else
1542          pDelete(&s_h3->m[j]);
1543      }
1544    }
1545    idSkipZeroes(s_h3);
1546    s_h3->rank -= k;
1547    rChangeCurrRing(orig_ring);
1548    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
1549    rKill(syz_ring);
1550    #ifdef HAVE_PLURAL
1551    if (rIsPluralRing(currRing))
1552    {
1553      idDelMultiples(s_h3);
1554      idSkipZeroes(s_h3);
1555    }
1556    #endif
1557    idTest(s_h3);
1558    return s_h3;
1559  }
1560
1561  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
1562
1563  for (j=IDELEMS(s_h3)-1; j>=0; j--)
1564  {
1565    if (s_h3->m[j] != NULL)
1566    {
1567      if (p_MinComp(s_h3->m[j],syz_ring) <= k)
1568      {
1569        e->m[j] = s_h3->m[j];
1570        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
1571        pDelete(&pNext(s_h3->m[j]));
1572        s_h3->m[j] = NULL;
1573      }
1574    }
1575  }
1576
1577  idSkipZeroes(s_h3);
1578  idSkipZeroes(e);
1579
1580  if ((deg != NULL)
1581  && (!isMonomial)
1582  && (!TEST_OPT_NOTREGULARITY)
1583  && (setRegularity)
1584  && (h==isHomog)
1585  && (!rIsPluralRing(currRing))
1586  )
1587  {
1588    ring dp_C_ring = rCurrRingAssure_dp_C();
1589    if (dp_C_ring != syz_ring)
1590      e = idrMoveR_NoSort(e, syz_ring);
1591    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
1592    intvec * dummy = syBetti(res,length,&reg, *w);
1593    *deg = reg+2;
1594    delete dummy;
1595    for (j=0;j<length;j++)
1596    {
1597      if (res[j]!=NULL) idDelete(&(res[j]));
1598    }
1599    omFreeSize((ADDRESS)res,length*sizeof(ideal));
1600    idDelete(&e);
1601    if (dp_C_ring != syz_ring)
1602    {
1603      rChangeCurrRing(syz_ring);
1604      rKill(dp_C_ring);
1605    }
1606  }
1607  else
1608  {
1609    idDelete(&e);
1610  }
1611  idTest(s_h3);
1612  if (currQuotient != NULL)
1613  {
1614    ideal ts_h3=kStd(s_h3,currQuotient,h,w);
1615    idDelete(&s_h3);
1616    s_h3 = ts_h3;
1617  }
1618  return s_h3;
1619}
1620
1621/*2
1622*/
1623ideal idXXX (ideal  h1, int k)
1624{
1625  ideal s_h1;
1626  int j;
1627  intvec *w=NULL;
1628
1629  assume(currRing != NULL);
1630  ring orig_ring=currRing;
1631  ring syz_ring=rCurrRingAssure_SyzComp();
1632
1633  rSetSyzComp(k);
1634
1635  if (orig_ring != syz_ring)
1636  {
1637    s_h1=idrCopyR_NoSort(h1,orig_ring);
1638  }
1639  else
1640  {
1641    s_h1 = h1;
1642  }
1643
1644  ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
1645
1646  if (s_h3==NULL)
1647  {
1648    return idFreeModule(IDELEMS(h1));
1649  }
1650
1651  if (orig_ring != syz_ring)
1652  {
1653    idDelete(&s_h1);
1654    idSkipZeroes(s_h3);
1655    rChangeCurrRing(orig_ring);
1656    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
1657    rKill(syz_ring);
1658    idTest(s_h3);
1659    return s_h3;
1660  }
1661
1662  idSkipZeroes(s_h3);
1663  idTest(s_h3);
1664  return s_h3;
1665}
1666
1667/*
1668*computes a standard basis for h1 and stores the transformation matrix
1669* in ma
1670*/
1671ideal idLiftStd (ideal  h1, matrix* ma, tHomog hi, ideal * syz)
1672{
1673  int   i, j, k, t, inputIsIdeal=idRankFreeModule(h1);
1674  poly  p=NULL, q, qq;
1675  intvec *w=NULL;
1676
1677  idDelete((ideal*)ma);
1678  BOOLEAN lift3=FALSE;
1679  if (syz!=NULL) { lift3=TRUE; idDelete(syz); }
1680  if (idIs0(h1))
1681  {
1682    *ma=mpNew(1,0);
1683    if (lift3)
1684    {
1685      *syz=idFreeModule(IDELEMS(h1));
1686      int curr_syz_limit=rGetCurrSyzLimit();
1687      if (curr_syz_limit>0)
1688      for (int ii=0;ii<IDELEMS(h1);ii++)
1689      {
1690        if (h1->m[ii]!=NULL)
1691          pShift(&h1->m[ii],curr_syz_limit);
1692      }
1693    }
1694    return idInit(1,h1->rank);
1695  }
1696
1697  BITSET save_verbose=verbose;
1698
1699  k=si_max(1,(int)idRankFreeModule(h1));
1700
1701  if ((k==1) && (!lift3)) verbose |=Sy_bit(V_IDLIFT);
1702
1703  ring orig_ring = currRing;
1704  ring syz_ring = rCurrRingAssure_SyzComp();
1705  rSetSyzComp(k);
1706
1707  ideal s_h1=h1;
1708
1709  if (orig_ring != syz_ring)
1710    s_h1 = idrCopyR_NoSort(h1,orig_ring);
1711  else
1712    s_h1 = h1;
1713
1714  ideal s_h3=idPrepare(s_h1,hi,k,&w); // main (syz) GB computation
1715
1716  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
1717
1718  if (lift3) (*syz)=idInit(IDELEMS(s_h3),IDELEMS(h1));
1719
1720  if (w!=NULL) delete w;
1721  i = 0;
1722
1723  // now sort the result, SB : leave in s_h3
1724  //                      T:  put in s_h2
1725  //                      syz: put in *syz
1726  for (j=0; j<IDELEMS(s_h3); j++)
1727  {
1728    if (s_h3->m[j] != NULL)
1729    {
1730      //if (p_MinComp(s_h3->m[j],syz_ring) <= k)
1731      if (pGetComp(s_h3->m[j]) <= k) // syz_ring == currRing
1732      {
1733        i++;
1734        q = s_h3->m[j];
1735        while (pNext(q) != NULL)
1736        {
1737          if (pGetComp(pNext(q)) > k)
1738          {
1739            s_h2->m[j] = pNext(q);
1740            pNext(q) = NULL;
1741          }
1742          else
1743          {
1744            pIter(q);
1745          }
1746        }
1747        if (!inputIsIdeal) pShift(&(s_h3->m[j]), -1);
1748      }
1749      else
1750      {
1751        // we a syzygy here:
1752        if (lift3)
1753        {
1754          pShift(&s_h3->m[j], -k);
1755          (*syz)->m[j]=s_h3->m[j];
1756          s_h3->m[j]=NULL;
1757        }
1758        else
1759          pDelete(&(s_h3->m[j]));
1760      }
1761    }
1762  }
1763  idSkipZeroes(s_h3);
1764  //extern char * iiStringMatrix(matrix im, int dim,char ch);
1765  //PrintS("SB: ----------------------------------------\n");
1766  //PrintS(iiStringMatrix((matrix)s_h3,k,'\n'));
1767  //PrintLn();
1768  //PrintS("T: ----------------------------------------\n");
1769  //PrintS(iiStringMatrix((matrix)s_h2,h1->rank,'\n'));
1770  //PrintLn();
1771
1772  if (lift3) idSkipZeroes(*syz);
1773
1774  j = IDELEMS(s_h1);
1775
1776
1777  if (syz_ring!=orig_ring)
1778  {
1779    idDelete(&s_h1);
1780    rChangeCurrRing(orig_ring);
1781  }
1782
1783  *ma = mpNew(j,i);
1784
1785  i = 1;
1786  for (j=0; j<IDELEMS(s_h2); j++)
1787  {
1788    if (s_h2->m[j] != NULL)
1789    {
1790      q = prMoveR( s_h2->m[j], syz_ring);
1791      s_h2->m[j] = NULL;
1792
1793      while (q != NULL)
1794      {
1795        p = q;
1796        pIter(q);
1797        pNext(p) = NULL;
1798        t=pGetComp(p);
1799        pSetComp(p,0);
1800        pSetmComp(p);
1801        MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
1802      }
1803      i++;
1804    }
1805  }
1806  idDelete(&s_h2);
1807
1808  for (i=0; i<IDELEMS(s_h3); i++)
1809  {
1810    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring);
1811  }
1812  if (lift3)
1813  {
1814    for (i=0; i<IDELEMS(*syz); i++)
1815    {
1816      (*syz)->m[i] = prMoveR_NoSort((*syz)->m[i], syz_ring);
1817    }
1818  }
1819
1820  if (syz_ring!=orig_ring) rKill(syz_ring);
1821  verbose = save_verbose;
1822  return s_h3;
1823}
1824
1825static void idPrepareStd(ideal s_temp, int k)
1826{
1827  int j,rk=idRankFreeModule(s_temp);
1828  poly p,q;
1829
1830  if (rk == 0)
1831  {
1832    for (j=0; j<IDELEMS(s_temp); j++)
1833    {
1834      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
1835    }
1836    k = si_max(k,1);
1837  }
1838  for (j=0; j<IDELEMS(s_temp); j++)
1839  {
1840    if (s_temp->m[j]!=NULL)
1841    {
1842      p = s_temp->m[j];
1843      q = pOne();
1844      //pGetCoeff(q)=nNeg(pGetCoeff(q));   //set q to -1
1845      pSetComp(q,k+1+j);
1846      pSetmComp(q);
1847      while (pNext(p)) pIter(p);
1848      pNext(p) = q;
1849    }
1850  }
1851}
1852
1853/*2
1854*computes a representation of the generators of submod with respect to those
1855* of mod
1856*/
1857
1858ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
1859             BOOLEAN isSB, BOOLEAN divide, matrix *unit)
1860{
1861  int lsmod =idRankFreeModule(submod), i, j, k;
1862  int comps_to_add=0;
1863  poly p;
1864
1865  if (idIs0(submod))
1866  {
1867    if (unit!=NULL)
1868    {
1869      *unit=mpNew(1,1);
1870      MATELEM(*unit,1,1)=pOne();
1871    }
1872    if (rest!=NULL)
1873    {
1874      *rest=idInit(1,mod->rank);
1875    }
1876    return idInit(1,mod->rank);
1877  }
1878  if (idIs0(mod)) /* and not idIs0(submod) */
1879  {
1880    WerrorS("2nd module does not lie in the first");
1881    #if 0
1882    if (unit!=NULL)
1883    {
1884      i=IDELEMS(submod);
1885      *unit=mpNew(i,i);
1886      for (j=i;j>0;j--)
1887      {
1888        MATELEM(*unit,j,j)=pOne();
1889      }
1890    }
1891    if (rest!=NULL)
1892    {
1893      *rest=idCopy(submod);
1894    }
1895    return idInit(1,mod->rank);
1896    #endif
1897    return idInit(IDELEMS(submod),submod->rank);
1898  }
1899  if (unit!=NULL)
1900  {
1901    comps_to_add = IDELEMS(submod);
1902    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
1903      comps_to_add--;
1904  }
1905  k=si_max(idRankFreeModule(mod),idRankFreeModule(submod));
1906  if  ((k!=0) && (lsmod==0)) lsmod=1;
1907  k=si_max(k,(int)mod->rank);
1908  if (k<submod->rank) { WarnS("rk(submod) > rk(mod) ?");k=submod->rank; }
1909
1910  ring orig_ring=currRing;
1911  ring syz_ring=rCurrRingAssure_SyzComp();
1912  rSetSyzComp(k);
1913
1914  ideal s_mod, s_temp;
1915  if (orig_ring != syz_ring)
1916  {
1917    s_mod = idrCopyR_NoSort(mod,orig_ring);
1918    s_temp = idrCopyR_NoSort(submod,orig_ring);
1919  }
1920  else
1921  {
1922    s_mod = mod;
1923    s_temp = idCopy(submod);
1924  }
1925  ideal s_h3;
1926  if (isSB)
1927  {
1928    s_h3 = idCopy(s_mod);
1929    idPrepareStd(s_h3, k+comps_to_add);
1930  }
1931  else
1932  {
1933    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
1934  }
1935  if (!goodShape)
1936  {
1937    for (j=0;j<IDELEMS(s_h3);j++)
1938    {
1939      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
1940        pDelete(&(s_h3->m[j]));
1941    }
1942  }
1943  idSkipZeroes(s_h3);
1944  if (lsmod==0)
1945  {
1946    for (j=IDELEMS(s_temp);j>0;j--)
1947    {
1948      if (s_temp->m[j-1]!=NULL)
1949        pShift(&(s_temp->m[j-1]),1);
1950    }
1951  }
1952  if (unit!=NULL)
1953  {
1954    for(j = 0;j<comps_to_add;j++)
1955    {
1956      p = s_temp->m[j];
1957      if (p!=NULL)
1958      {
1959        while (pNext(p)!=NULL) pIter(p);
1960        pNext(p) = pOne();
1961        pIter(p);
1962        pSetComp(p,1+j+k);
1963        pSetmComp(p);
1964        p = pNeg(p);
1965      }
1966    }
1967  }
1968  ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
1969  s_result->rank = s_h3->rank;
1970  ideal s_rest = idInit(IDELEMS(s_result),k);
1971  idDelete(&s_h3);
1972  idDelete(&s_temp);
1973
1974  for (j=0;j<IDELEMS(s_result);j++)
1975  {
1976    if (s_result->m[j]!=NULL)
1977    {
1978      if (pGetComp(s_result->m[j])<=k)
1979      {
1980        if (!divide)
1981        {
1982          if (isSB)
1983          {
1984            WarnS("first module not a standardbasis\n"
1985              "// ** or second not a proper submodule");
1986          }
1987          else
1988            WerrorS("2nd module does not lie in the first");
1989          idDelete(&s_result);
1990          idDelete(&s_rest);
1991          s_result=idInit(IDELEMS(submod),submod->rank);
1992          break;
1993        }
1994        else
1995        {
1996          p = s_rest->m[j] = s_result->m[j];
1997          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1998          s_result->m[j] = pNext(p);
1999          pNext(p) = NULL;
2000        }
2001      }
2002      pShift(&(s_result->m[j]),-k);
2003      pNeg(s_result->m[j]);
2004    }
2005  }
2006  if ((lsmod==0) && (!idIs0(s_rest)))
2007  {
2008    for (j=IDELEMS(s_rest);j>0;j--)
2009    {
2010      if (s_rest->m[j-1]!=NULL)
2011      {
2012        pShift(&(s_rest->m[j-1]),-1);
2013        s_rest->m[j-1] = s_rest->m[j-1];
2014      }
2015    }
2016  }
2017  if(syz_ring!=orig_ring)
2018  {
2019    idDelete(&s_mod);
2020    rChangeCurrRing(orig_ring);
2021    s_result = idrMoveR_NoSort(s_result, syz_ring);
2022    s_rest = idrMoveR_NoSort(s_rest, syz_ring);
2023    rKill(syz_ring);
2024  }
2025  if (rest!=NULL)
2026    *rest = s_rest;
2027  else
2028    idDelete(&s_rest);
2029//idPrint(s_result);
2030  if (unit!=NULL)
2031  {
2032    *unit=mpNew(comps_to_add,comps_to_add);
2033    int i;
2034    for(i=0;i<IDELEMS(s_result);i++)
2035    {
2036      poly p=s_result->m[i];
2037      poly q=NULL;
2038      while(p!=NULL)
2039      {
2040        if(pGetComp(p)<=comps_to_add)
2041        {
2042          pSetComp(p,0);
2043          if (q!=NULL)
2044          {
2045            pNext(q)=pNext(p);
2046          }
2047          else
2048          {
2049            pIter(s_result->m[i]);
2050          }
2051          pNext(p)=NULL;
2052          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
2053          if(q!=NULL)   p=pNext(q);
2054          else          p=s_result->m[i];
2055        }
2056        else
2057        {
2058          q=p;
2059          pIter(p);
2060        }
2061      }
2062      pShift(&s_result->m[i],-comps_to_add);
2063    }
2064  }
2065  return s_result;
2066}
2067
2068/*2
2069*computes division of P by Q with remainder up to (w-weighted) degree n
2070*P, Q, and w are not changed
2071*/
2072void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
2073{
2074  long N=0;
2075  int i;
2076  for(i=IDELEMS(Q)-1;i>=0;i--)
2077    if(w==NULL)
2078      N=si_max(N,pDeg(Q->m[i]));
2079    else
2080      N=si_max(N,pDegW(Q->m[i],w));
2081  N+=n;
2082
2083  T=mpNew(IDELEMS(Q),IDELEMS(P));
2084  R=idInit(IDELEMS(P),P->rank);
2085
2086  for(i=IDELEMS(P)-1;i>=0;i--)
2087  {
2088    poly p;
2089    if(w==NULL)
2090      p=ppJet(P->m[i],N);
2091    else
2092      p=ppJetW(P->m[i],N,w);
2093
2094    int j=IDELEMS(Q)-1;
2095    while(p!=NULL)
2096    {
2097      if(pDivisibleBy(Q->m[j],p))
2098      {
2099        poly p0=pDivideM(pHead(p),pHead(Q->m[j]));
2100        if(w==NULL)
2101          p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
2102        else
2103          p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
2104        pNormalize(p);
2105        if((w==NULL)&&(pDeg(p0)>n)||(w!=NULL)&&(pDegW(p0,w)>n))
2106          pDelete(&p0);
2107        else
2108          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
2109        j=IDELEMS(Q)-1;
2110      }
2111      else
2112      {
2113        if(j==0)
2114        {
2115          poly p0=p;
2116          pIter(p);
2117          pNext(p0)=NULL;
2118          if(((w==NULL)&&(pDeg(p0)>n))
2119          ||((w!=NULL)&&(pDegW(p0,w)>n)))
2120            pDelete(&p0);
2121          else
2122            R->m[i]=pAdd(R->m[i],p0);
2123          j=IDELEMS(Q)-1;
2124        }
2125        else
2126          j--;
2127      }
2128    }
2129  }
2130}
2131
2132/*2
2133*computes the quotient of h1,h2 : internal routine for idQuot
2134*BEWARE: the returned ideals may contain incorrectly ordered polys !
2135*
2136*/
2137static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb,
2138                               BOOLEAN *addOnlyOne, int *kkmax)
2139{
2140  ideal temph1;
2141  poly     p,q = NULL;
2142  int i,l,ll,k,kkk,kmax;
2143  int j = 0;
2144  int k1 = idRankFreeModule(h1);
2145  int k2 = idRankFreeModule(h2);
2146  tHomog   hom=isNotHomog;
2147
2148  k=si_max(k1,k2);
2149  if (k==0)
2150    k = 1;
2151  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
2152
2153  intvec * weights;
2154  hom = (tHomog)idHomModule(h1,currQuotient,&weights);
2155  if (/**addOnlyOne &&*/ (!h1IsStb))
2156    temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
2157  else
2158    temph1 = idCopy(h1);
2159  if (weights!=NULL) delete weights;
2160  idTest(temph1);
2161/*--- making a single vector from h2 ---------------------*/
2162  for (i=0; i<IDELEMS(h2); i++)
2163  {
2164    if (h2->m[i] != NULL)
2165    {
2166      p = pCopy(h2->m[i]);
2167      if (k2 == 0)
2168        pShift(&p,j*k+1);
2169      else
2170        pShift(&p,j*k);
2171      q = pAdd(q,p);
2172      j++;
2173    }
2174  }
2175  *kkmax = kmax = j*k+1;
2176/*--- adding a monomial for the result (syzygy) ----------*/
2177  p = q;
2178  while (pNext(p)!=NULL) pIter(p);
2179  pNext(p) = pOne();
2180  pIter(p);
2181  pSetComp(p,kmax);
2182  pSetmComp(p);
2183/*--- constructing the big matrix ------------------------*/
2184  ideal h4 = idInit(16,kmax+k-1);
2185  h4->m[0] = q;
2186  if (k2 == 0)
2187  {
2188    if (k > IDELEMS(h4))
2189    {
2190      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
2191      IDELEMS(h4) = k;
2192    }
2193    for (i=1; i<k; i++)
2194    {
2195      if (h4->m[i-1]!=NULL)
2196      {
2197        p = pCopy_noCheck(h4->m[i-1]);
2198        pShift(&p,1);
2199        h4->m[i] = p;
2200      }
2201    }
2202  }
2203  idSkipZeroes(h4);
2204  kkk = IDELEMS(h4);
2205  i = IDELEMS(temph1);
2206  for (l=0; l<i; l++)
2207  {
2208    if(temph1->m[l]!=NULL)
2209    {
2210      for (ll=0; ll<j; ll++)
2211      {
2212        p = pCopy(temph1->m[l]);
2213        if (k1 == 0)
2214          pShift(&p,ll*k+1);
2215        else
2216          pShift(&p,ll*k);
2217        if (kkk >= IDELEMS(h4))
2218        {
2219          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
2220          IDELEMS(h4) += 16;
2221        }
2222        h4->m[kkk] = p;
2223        kkk++;
2224      }
2225    }
2226  }
2227/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
2228  if (*addOnlyOne)
2229  {
2230    idSkipZeroes(h4);
2231    p = h4->m[0];
2232    for (i=0;i<IDELEMS(h4)-1;i++)
2233    {
2234      h4->m[i] = h4->m[i+1];
2235    }
2236    h4->m[IDELEMS(h4)-1] = p;
2237    test |= Sy_bit(OPT_SB_1);
2238  }
2239  idDelete(&temph1);
2240  return h4;
2241}
2242/*2
2243*computes the quotient of h1,h2
2244*/
2245ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
2246{
2247  // first check for special case h1:(0)
2248  if (idIs0(h2))
2249  {
2250    ideal res;
2251    if (resultIsIdeal)
2252    {
2253      res = idInit(1,1);
2254      res->m[0] = pOne();
2255    }
2256    else
2257      res = idFreeModule(h1->rank);
2258    return res;
2259  }
2260  BITSET old_test=test;
2261  int i,l,ll,k,kkk,kmax;
2262  BOOLEAN  addOnlyOne=TRUE;
2263  tHomog   hom=isNotHomog;
2264  intvec * weights1;
2265
2266  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
2267
2268  hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
2269
2270  ring orig_ring=currRing;
2271  ring syz_ring=rCurrRingAssure_SyzComp();
2272  rSetSyzComp(kmax-1);
2273  if (orig_ring!=syz_ring)
2274  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
2275    s_h4 = idrMoveR(s_h4,orig_ring);
2276  idTest(s_h4);
2277  #if 0
2278  void ipPrint_MA0(matrix m, const char *name);
2279  matrix m=idModule2Matrix(idCopy(s_h4));
2280  PrintS("start:\n");
2281  ipPrint_MA0(m,"Q");
2282  idDelete((ideal *)&m);
2283  PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
2284  #endif
2285  ideal s_h3;
2286  if (addOnlyOne)
2287  {
2288    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
2289  }
2290  else
2291  {
2292    s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
2293  }
2294  test = old_test;
2295  #if 0
2296  // only together with the above debug stuff
2297  idSkipZeroes(s_h3);
2298  m=idModule2Matrix(idCopy(s_h3));
2299  Print("result, kmax=%d:\n",kmax);
2300  ipPrint_MA0(m,"S");
2301  idDelete((ideal *)&m);
2302  #endif
2303  idTest(s_h3);
2304  if (weights1!=NULL) delete weights1;
2305  idDelete(&s_h4);
2306
2307  for (i=0;i<IDELEMS(s_h3);i++)
2308  {
2309    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
2310    {
2311      if (resultIsIdeal)
2312        pShift(&s_h3->m[i],-kmax);
2313      else
2314        pShift(&s_h3->m[i],-kmax+1);
2315    }
2316    else
2317      pDelete(&s_h3->m[i]);
2318  }
2319  if (resultIsIdeal)
2320    s_h3->rank = 1;
2321  else
2322    s_h3->rank = h1->rank;
2323  if(syz_ring!=orig_ring)
2324  {
2325    rChangeCurrRing(orig_ring);
2326    s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
2327    rKill(syz_ring);
2328  }
2329  idSkipZeroes(s_h3);
2330  idTest(s_h3);
2331  return s_h3;
2332}
2333
2334/*2
2335*computes recursively all monomials of a certain degree
2336*in every step the actvar-th entry in the exponential
2337*vector is incremented and the other variables are
2338*computed by recursive calls of makemonoms
2339*if the last variable is reached, the difference to the
2340*degree is computed directly
2341*vars is the number variables
2342*actvar is the actual variable to handle
2343*deg is the degree of the monomials to compute
2344*monomdeg is the actual degree of the monomial in consideration
2345*/
2346static void makemonoms(int vars,int actvar,int deg,int monomdeg)
2347{
2348  poly p;
2349  int i=0;
2350
2351  if ((idpowerpoint == 0) && (actvar ==1))
2352  {
2353    idpower[idpowerpoint] = pOne();
2354    monomdeg = 0;
2355  }
2356  while (i<=deg)
2357  {
2358    if (deg == monomdeg)
2359    {
2360      pSetm(idpower[idpowerpoint]);
2361      idpowerpoint++;
2362      return;
2363    }
2364    if (actvar == vars)
2365    {
2366      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
2367      pSetm(idpower[idpowerpoint]);
2368      pTest(idpower[idpowerpoint]);
2369      idpowerpoint++;
2370      return;
2371    }
2372    else
2373    {
2374      p = pCopy(idpower[idpowerpoint]);
2375      makemonoms(vars,actvar+1,deg,monomdeg);
2376      idpower[idpowerpoint] = p;
2377    }
2378    monomdeg++;
2379    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
2380    pSetm(idpower[idpowerpoint]);
2381    pTest(idpower[idpowerpoint]);
2382    i++;
2383  }
2384}
2385
2386/*2
2387*returns the deg-th power of the maximal ideal of 0
2388*/
2389ideal idMaxIdeal(int deg)
2390{
2391  if (deg < 0)
2392  {
2393    WarnS("maxideal: power must be non-negative");
2394  }
2395  if (deg < 1)
2396  {
2397    ideal I=idInit(1,1);
2398    I->m[0]=pOne();
2399    return I;
2400  }
2401  if (deg == 1)
2402  {
2403    return idMaxIdeal();
2404  }
2405
2406  int vars = currRing->N;
2407  int i = binom(vars+deg-1,deg);
2408  if (i<=0) return idInit(1,1);
2409  ideal id=idInit(i,1);
2410  idpower = id->m;
2411  idpowerpoint = 0;
2412  makemonoms(vars,1,deg,0);
2413  idpower = NULL;
2414  idpowerpoint = 0;
2415  return id;
2416}
2417
2418/*2
2419*computes recursively all generators of a certain degree
2420*of the ideal "givenideal"
2421*elms is the number elements in the given ideal
2422*actelm is the actual element to handle
2423*deg is the degree of the power to compute
2424*gendeg is the actual degree of the generator in consideration
2425*/
2426static void makepotence(int elms,int actelm,int deg,int gendeg)
2427{
2428  poly p;
2429  int i=0;
2430
2431  if ((idpowerpoint == 0) && (actelm ==1))
2432  {
2433    idpower[idpowerpoint] = pOne();
2434    gendeg = 0;
2435  }
2436  while (i<=deg)
2437  {
2438    if (deg == gendeg)
2439    {
2440      idpowerpoint++;
2441      return;
2442    }
2443    if (actelm == elms)
2444    {
2445      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
2446      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
2447      idpowerpoint++;
2448      return;
2449    }
2450    else
2451    {
2452      p = pCopy(idpower[idpowerpoint]);
2453      makepotence(elms,actelm+1,deg,gendeg);
2454      idpower[idpowerpoint] = p;
2455    }
2456    gendeg++;
2457    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
2458    i++;
2459  }
2460}
2461
2462/*2
2463*returns the deg-th power of the ideal gid
2464*/
2465//ideal idPower(ideal gid,int deg)
2466//{
2467//  int i;
2468//  ideal id;
2469//
2470//  if (deg < 1) deg = 1;
2471//  i = binom(IDELEMS(gid)+deg-1,deg);
2472//  id=idInit(i,1);
2473//  idpower = id->m;
2474//  givenideal = gid->m;
2475//  idpowerpoint = 0;
2476//  makepotence(IDELEMS(gid),1,deg,0);
2477//  idpower = NULL;
2478//  givenideal = NULL;
2479//  idpowerpoint = 0;
2480//  return id;
2481//}
2482static void idNextPotence(ideal given, ideal result,
2483  int begin, int end, int deg, int restdeg, poly ap)
2484{
2485  poly p;
2486  int i;
2487
2488  p = pPower(pCopy(given->m[begin]),restdeg);
2489  i = result->nrows;
2490  result->m[i] = pMult(pCopy(ap),p);
2491//PrintS(".");
2492  (result->nrows)++;
2493  if (result->nrows >= IDELEMS(result))
2494  {
2495    pEnlargeSet(&(result->m),IDELEMS(result),16);
2496    IDELEMS(result) += 16;
2497  }
2498  if (begin == end) return;
2499  for (i=restdeg-1;i>0;i--)
2500  {
2501    p = pPower(pCopy(given->m[begin]),i);
2502    p = pMult(pCopy(ap),p);
2503    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
2504    pDelete(&p);
2505  }
2506  idNextPotence(given, result, begin+1, end, deg, restdeg, ap);
2507}
2508
2509ideal idPower(ideal given,int exp)
2510{
2511  ideal result,temp;
2512  poly p1;
2513  int i;
2514
2515  if (idIs0(given)) return idInit(1,1);
2516  temp = idCopy(given);
2517  idSkipZeroes(temp);
2518  i = binom(IDELEMS(temp)+exp-1,exp);
2519  result = idInit(i,1);
2520  result->nrows = 0;
2521//Print("ideal contains %d elements\n",i);
2522  p1=pOne();
2523  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
2524  pDelete(&p1);
2525  idDelete(&temp);
2526  result->nrows = 1;
2527  idDelEquals(result);
2528  idSkipZeroes(result);
2529  return result;
2530}
2531
2532/*2
2533* eliminate delVar (product of vars) in h1
2534*/
2535ideal idElimination (ideal h1,poly delVar,intvec *hilb)
2536{
2537  int    i,j=0,k,l;
2538  ideal  h,hh, h3;
2539  int    *ord,*block0,*block1;
2540  int    ordersize=2;
2541  int    **wv;
2542  tHomog hom;
2543  intvec * w;
2544  ring tmpR;
2545  ring origR = currRing;
2546
2547  if (delVar==NULL)
2548  {
2549    return idCopy(h1);
2550  }
2551  if ((currQuotient!=NULL) && rIsPluralRing(origR))
2552  {
2553    WerrorS("cannot eliminate in a qring");
2554    return idCopy(h1);
2555  }
2556  if (idIs0(h1)) return idInit(1,h1->rank);
2557#ifdef HAVE_PLURAL
2558  if (rIsPluralRing(origR))
2559    /* in the NC case, we have to check the admissibility of */
2560    /* the subalgebra to be intersected with */
2561  {
2562    if ((ncRingType(origR) != nc_skew) && (ncRingType(origR) != nc_exterior)) /* in (quasi)-commutative algebras every subalgebra is admissible */
2563    {
2564      if (nc_CheckSubalgebra(delVar,origR))
2565      {
2566        WerrorS("no elimination is possible: subalgebra is not admissible");
2567        return idCopy(h1);
2568      }
2569    }
2570  }
2571#endif
2572  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
2573  h3=idInit(16,h1->rank);
2574  for (k=0;; k++)
2575  {
2576    if (origR->order[k]!=0) ordersize++;
2577    else break;
2578  }
2579#if 0
2580  if (rIsPluralRing(origR)) // we have too keep the odering: it may be needed
2581                            // for G-algebra
2582  {
2583    for (k=0;k<ordersize-1; k++)
2584    {
2585      block0[k+1] = origR->block0[k];
2586      block1[k+1] = origR->block1[k];
2587      ord[k+1] = origR->order[k];
2588      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
2589    }
2590  }
2591  else
2592  {
2593    block0[1] = 1;
2594    block1[1] = pVariables;
2595    if (origR->OrdSgn==1) ord[1] = ringorder_wp;
2596    else                  ord[1] = ringorder_ws;
2597    wv[1]=(int*)omAlloc0(pVariables*sizeof(int));
2598    double wNsqr = (double)2.0 / (double)pVariables;
2599    wFunctional = wFunctionalBuch;
2600    int  *x= (int * )omAlloc(2 * (pVariables + 1) * sizeof(int));
2601    int sl=IDELEMS(h1) - 1;
2602    wCall(h1->m, sl, x, wNsqr);
2603    for (sl = pVariables; sl!=0; sl--)
2604      wv[1][sl-1] = x[sl + pVariables + 1];
2605    omFreeSize((ADDRESS)x, 2 * (pVariables + 1) * sizeof(int));
2606
2607    ord[2]=ringorder_C;
2608    ord[3]=0;
2609  }
2610#else
2611#endif
2612  if ((hom==TRUE) && (origR->OrdSgn==1) && (!rIsPluralRing(origR)))
2613  {
2614    #if 1
2615    // we change to an ordering:
2616    // aa(1,1,1,...,0,0,0),wp(...),C
2617    // this seems to be better than version 2 below,
2618    // according to Tst/../elimiate_[3568].tat (- 17 %)
2619    ord=(int*)omAlloc0(4*sizeof(int));
2620    block0=(int*)omAlloc0(4*sizeof(int));
2621    block1=(int*)omAlloc0(4*sizeof(int));
2622    wv=(int**) omAlloc0(4*sizeof(int**));
2623    block0[0] = block0[1] = 1;
2624    block1[0] = block1[1] = rVar(origR);
2625    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
2626    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
2627    // ignore it
2628    ord[0] = ringorder_aa;
2629    for (j=0;j<rVar(origR);j++)
2630      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2631    BOOLEAN wp=FALSE;
2632    for (j=0;j<rVar(origR);j++)
2633      if (pWeight(j+1,origR)!=1) { wp=TRUE;break; }
2634    if (wp)
2635    {
2636      wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
2637      for (j=0;j<rVar(origR);j++)
2638        wv[1][j]=pWeight(j+1,origR);
2639      ord[1] = ringorder_wp;
2640    }
2641    else
2642      ord[1] = ringorder_dp;
2643    #else
2644    // we change to an ordering:
2645    // a(w1,...wn),wp(1,...0.....),C
2646    ord=(int*)omAlloc0(4*sizeof(int));
2647    block0=(int*)omAlloc0(4*sizeof(int));
2648    block1=(int*)omAlloc0(4*sizeof(int));
2649    wv=(int**) omAlloc0(4*sizeof(int**));
2650    block0[0] = block0[1] = 1;
2651    block1[0] = block1[1] = rVar(origR);
2652    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
2653    wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
2654    ord[0] = ringorder_a;
2655    for (j=0;j<rVar(origR);j++)
2656      wv[0][j]=pWeight(j+1,origR);
2657    ord[1] = ringorder_wp;
2658    for (j=0;j<rVar(origR);j++)
2659      if (pGetExp(delVar,j+1)!=0) wv[1][j]=1;
2660    #endif
2661    ord[2] = ringorder_C;
2662    ord[3] = 0;
2663  }
2664  else
2665  {
2666    // we change to an ordering:
2667    // aa(....),orig_ordering
2668    ord=(int*)omAlloc0(ordersize*sizeof(int));
2669    block0=(int*)omAlloc0(ordersize*sizeof(int));
2670    block1=(int*)omAlloc0(ordersize*sizeof(int));
2671    wv=(int**) omAlloc0(ordersize*sizeof(int**));
2672    for (k=0;k<ordersize-1; k++)
2673    {
2674      block0[k+1] = origR->block0[k];
2675      block1[k+1] = origR->block1[k];
2676      ord[k+1] = origR->order[k];
2677      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
2678    }
2679    block0[0] = 1;
2680    block1[0] = rVar(origR);
2681    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
2682    for (j=0;j<rVar(origR);j++)
2683      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2684    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
2685    // ignore it
2686    ord[0] = ringorder_aa;
2687  }
2688  // fill in tmp ring to get back the data later on
2689  tmpR  = rCopy0(origR,FALSE,FALSE); // qring==NULL
2690  //rUnComplete(tmpR);
2691  tmpR->p_Procs=NULL;
2692  tmpR->order = ord;
2693  tmpR->block0 = block0;
2694  tmpR->block1 = block1;
2695  tmpR->wvhdl = wv;
2696  rComplete(tmpR, 1);
2697
2698#ifdef HAVE_PLURAL
2699  /* update nc structure on tmpR */
2700  if (rIsPluralRing(origR))
2701  {
2702    if ( nc_rComplete(origR, tmpR, false) ) // no quotient ideal!
2703    {
2704      Werror("no elimination is possible: ordering condition is violated");
2705      // cleanup
2706      rDelete(tmpR);
2707      if (w!=NULL)
2708        delete w;
2709      return idCopy(h1);
2710    }
2711  }
2712#endif
2713  // change into the new ring
2714  //pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
2715  rChangeCurrRing(tmpR);
2716
2717  //h = idInit(IDELEMS(h1),h1->rank);
2718  // fetch data from the old ring
2719  //for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
2720  h=idrCopyR(h1,origR,currRing);
2721  if (origR->qideal!=NULL)
2722  {
2723    WarnS("eliminate in q-ring: experimental");
2724    ideal q=idrCopyR(origR->qideal,origR,currRing);
2725    ideal s=idSimpleAdd(h,q);
2726    idDelete(&h);
2727    idDelete(&q);
2728    h=s;
2729  }
2730  // compute kStd
2731#if 1
2732  //rWrite(tmpR);PrintLn();
2733  BITSET save=test;
2734  //test |=1;
2735  //Print("h: %d gen, rk=%d\n",IDELEMS(h),h->rank);
2736  //extern char * showOption();
2737  //Print("%s\n",showOption());
2738  hh = kStd(h,NULL,hom,&w,hilb);
2739  test=save;
2740  idDelete(&h);
2741#else
2742  extern ideal kGroebner(ideal F, ideal Q);
2743  hh=kGroebner(h,NULL);
2744#endif
2745  // go back to the original ring
2746  rChangeCurrRing(origR);
2747  i = IDELEMS(hh)-1;
2748  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2749  j = -1;
2750  // fetch data from temp ring
2751  for (k=0; k<=i; k++)
2752  {
2753    l=pVariables;
2754    while ((l>0) && (p_GetExp( hh->m[k],l,tmpR)*pGetExp(delVar,l)==0)) l--;
2755    if (l==0)
2756    {
2757      j++;
2758      if (j >= IDELEMS(h3))
2759      {
2760        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2761        IDELEMS(h3) += 16;
2762      }
2763      h3->m[j] = prMoveR( hh->m[k], tmpR);
2764      hh->m[k] = NULL;
2765    }
2766  }
2767  id_Delete(&hh, tmpR);
2768  idSkipZeroes(h3);
2769  rDelete(tmpR);
2770  if (w!=NULL)
2771    delete w;
2772  return h3;
2773}
2774
2775/*2
2776* compute the which-th ar-minor of the matrix a
2777*/
2778poly idMinor(matrix a, int ar, unsigned long which, ideal R)
2779{
2780  int     i,j,k,size;
2781  unsigned long curr;
2782  int *rowchoise,*colchoise;
2783  BOOLEAN rowch,colch;
2784  ideal result;
2785  matrix tmp;
2786  poly p,q;
2787
2788  i = binom(a->rows(),ar);
2789  j = binom(a->cols(),ar);
2790
2791  rowchoise=(int *)omAlloc(ar*sizeof(int));
2792  colchoise=(int *)omAlloc(ar*sizeof(int));
2793  if ((i>512) || (j>512) || (i*j >512)) size=512;
2794  else size=i*j;
2795  result=idInit(size,1);
2796  tmp=mpNew(ar,ar);
2797  k = 0; /* the index in result*/
2798  curr = 0; /* index of current minor */
2799  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2800  while (!rowch)
2801  {
2802    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2803    while (!colch)
2804    {
2805      if (curr == which)
2806      {
2807        for (i=1; i<=ar; i++)
2808        {
2809          for (j=1; j<=ar; j++)
2810          {
2811            MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2812          }
2813        }
2814        p = mpDetBareiss(tmp);
2815        if (p!=NULL)
2816        {
2817          if (R!=NULL)
2818          {
2819            q = p;
2820            p = kNF(R,currQuotient,q);
2821            pDelete(&q);
2822          }
2823          /*delete the matrix tmp*/
2824          for (i=1; i<=ar; i++)
2825          {
2826            for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2827          }
2828          idDelete((ideal*)&tmp);
2829          omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2830          omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2831          return (p);
2832        }
2833      }
2834      curr++;
2835      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2836    }
2837    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2838  }
2839  return (poly) 1;
2840}
2841
2842#ifdef WITH_OLD_MINOR
2843/*2
2844* compute all ar-minors of the matrix a
2845*/
2846ideal idMinors(matrix a, int ar, ideal R)
2847{
2848  int     i,j,k,size;
2849  int *rowchoise,*colchoise;
2850  BOOLEAN rowch,colch;
2851  ideal result;
2852  matrix tmp;
2853  poly p,q;
2854
2855  i = binom(a->rows(),ar);
2856  j = binom(a->cols(),ar);
2857
2858  rowchoise=(int *)omAlloc(ar*sizeof(int));
2859  colchoise=(int *)omAlloc(ar*sizeof(int));
2860  if ((i>512) || (j>512) || (i*j >512)) size=512;
2861  else size=i*j;
2862  result=idInit(size,1);
2863  tmp=mpNew(ar,ar);
2864  k = 0; /* the index in result*/
2865  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2866  while (!rowch)
2867  {
2868    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2869    while (!colch)
2870    {
2871      for (i=1; i<=ar; i++)
2872      {
2873        for (j=1; j<=ar; j++)
2874        {
2875          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2876        }
2877      }
2878      p = mpDetBareiss(tmp);
2879      if (p!=NULL)
2880      {
2881        if (R!=NULL)
2882        {
2883          q = p;
2884          p = kNF(R,currQuotient,q);
2885          pDelete(&q);
2886        }
2887        if (p!=NULL)
2888        {
2889          if (k>=size)
2890          {
2891            pEnlargeSet(&result->m,size,32);
2892            size += 32;
2893          }
2894          result->m[k] = p;
2895          k++;
2896        }
2897      }
2898      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2899    }
2900    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2901  }
2902  /*delete the matrix tmp*/
2903  for (i=1; i<=ar; i++)
2904  {
2905    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2906  }
2907  idDelete((ideal*)&tmp);
2908  if (k==0)
2909  {
2910    k=1;
2911    result->m[0]=NULL;
2912  }
2913  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
2914  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
2915  pEnlargeSet(&result->m,size,k-size);
2916  IDELEMS(result) = k;
2917  return (result);
2918}
2919#else
2920/*2
2921* compute all ar-minors of the matrix a
2922* the caller of mpRecMin
2923* the elements of the result are not in R (if R!=NULL)
2924*/
2925ideal idMinors(matrix a, int ar, ideal R)
2926{
2927  int elems=0;
2928  int r=a->nrows,c=a->ncols;
2929  int i;
2930  matrix b;
2931  ideal result,h;
2932  ring origR;
2933  ring tmpR;
2934  long bound;
2935
2936  if((ar<=0) || (ar>r) || (ar>c))
2937  {
2938    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
2939    return NULL;
2940  }
2941  h = idMatrix2Module(mpCopy(a));
2942  bound = smExpBound(h,c,r,ar);
2943  idDelete(&h);
2944  tmpR=smRingChange(&origR,bound);
2945  b = mpNew(r,c);
2946  for (i=r*c-1;i>=0;i--)
2947  {
2948    if (a->m[i])
2949      b->m[i] = prCopyR(a->m[i],origR);
2950  }
2951  if (R!=NULL)
2952  {
2953    R = idrCopyR(R,origR);
2954    //if (ar>1) // otherwise done in mpMinorToResult
2955    //{
2956    //  matrix bb=(matrix)kNF(R,currQuotient,(ideal)b);
2957    //  bb->rank=b->rank; bb->nrows=b->nrows; bb->ncols=b->ncols;
2958    //  idDelete((ideal*)&b); b=bb;
2959    //}
2960  }
2961  result=idInit(32,1);
2962  if(ar>1) mpRecMin(ar-1,result,elems,b,r,c,NULL,R);
2963  else mpMinorToResult(result,elems,b,r,c,R);
2964  idDelete((ideal *)&b);
2965  if (R!=NULL) idDelete(&R);
2966  idSkipZeroes(result);
2967  rChangeCurrRing(origR);
2968  result = idrMoveR(result,tmpR);
2969  smKillModifiedRing(tmpR);
2970  idTest(result);
2971  return result;
2972}
2973#endif
2974
2975/*2
2976*skips all zeroes and double elements, searches also for units
2977*/
2978void idCompactify(ideal id)
2979{
2980  int i,j;
2981  BOOLEAN b=FALSE;
2982
2983  i = IDELEMS(id)-1;
2984  while ((! b) && (i>=0))
2985  {
2986    b=pIsUnit(id->m[i]);
2987    i--;
2988  }
2989  if (b)
2990  {
2991    for(i=IDELEMS(id)-1;i>=0;i--) pDelete(&id->m[i]);
2992    id->m[0]=pOne();
2993  }
2994  else
2995  {
2996    idDelMultiples(id);
2997  }
2998  idSkipZeroes(id);
2999}
3000
3001/*2
3002*returns TRUE if id1 is a submodule of id2
3003*/
3004BOOLEAN idIsSubModule(ideal id1,ideal id2)
3005{
3006  int i;
3007  poly p;
3008
3009  if (idIs0(id1)) return TRUE;
3010  for (i=0;i<IDELEMS(id1);i++)
3011  {
3012    if (id1->m[i] != NULL)
3013    {
3014      p = kNF(id2,currQuotient,id1->m[i]);
3015      if (p != NULL)
3016      {
3017        pDelete(&p);
3018        return FALSE;
3019      }
3020    }
3021  }
3022  return TRUE;
3023}
3024
3025/*2
3026* returns the ideals of initial terms
3027*/
3028ideal idHead(ideal h)
3029{
3030  ideal m = idInit(IDELEMS(h),h->rank);
3031  int i;
3032
3033  for (i=IDELEMS(h)-1;i>=0; i--)
3034  {
3035    if (h->m[i]!=NULL) m->m[i]=pHead(h->m[i]);
3036  }
3037  return m;
3038}
3039
3040ideal idHomogen(ideal h, int varnum)
3041{
3042  ideal m = idInit(IDELEMS(h),h->rank);
3043  int i;
3044
3045  for (i=IDELEMS(h)-1;i>=0; i--)
3046  {
3047    m->m[i]=pHomogen(h->m[i],varnum);
3048  }
3049  return m;
3050}
3051
3052/*------------------type conversions----------------*/
3053ideal idVec2Ideal(poly vec)
3054{
3055   ideal result=idInit(1,1);
3056   omFree((ADDRESS)result->m);
3057   result->m=NULL; // remove later
3058   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
3059   return result;
3060}
3061
3062#define NEW_STUFF
3063#ifndef NEW_STUFF
3064// converts mat to module, destroys mat
3065ideal idMatrix2Module(matrix mat)
3066{
3067  int mc=MATCOLS(mat);
3068  int mr=MATROWS(mat);
3069  ideal result = idInit(si_max(mc,1),si_max(mr,1));
3070  int i,j;
3071  poly h;
3072
3073  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
3074  {
3075    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
3076    {
3077      h = MATELEM(mat,i,j+1);
3078      if (h!=NULL)
3079      {
3080        MATELEM(mat,i,j+1)=NULL;
3081        pSetCompP(h,i);
3082        result->m[j] = pAdd(result->m[j],h);
3083      }
3084    }
3085  }
3086  // obachman: need to clean this up
3087  idDelete((ideal*) &mat);
3088  return result;
3089}
3090#else
3091
3092#include <kernel/sbuckets.h>
3093
3094// converts mat to module, destroys mat
3095ideal idMatrix2Module(matrix mat)
3096{
3097  int mc=MATCOLS(mat);
3098  int mr=MATROWS(mat);
3099  ideal result = idInit(si_max(mc,1),si_max(mr,1));
3100  int i,j, l;
3101  poly h;
3102  poly p;
3103  sBucket_pt bucket = sBucketCreate(currRing);
3104
3105  for(j=0;j<mc /*MATCOLS(mat)*/;j++) /* j is also index in result->m */
3106  {
3107    for (i=1;i<=mr /*MATROWS(mat)*/;i++)
3108    {
3109      h = MATELEM(mat,i,j+1);
3110      if (h!=NULL)
3111      {
3112        l=pLength(h);
3113        MATELEM(mat,i,j+1)=NULL;
3114        p_SetCompP(h,i, currRing);
3115        sBucket_Merge_p(bucket, h, l);
3116      }
3117    }
3118    sBucketClearMerge(bucket, &(result->m[j]), &l);
3119  }
3120  sBucketDestroy(&bucket);
3121
3122  // obachman: need to clean this up
3123  idDelete((ideal*) &mat);
3124  return result;
3125}
3126#endif
3127
3128/*2
3129* converts a module into a matrix, destroyes the input
3130*/
3131matrix idModule2Matrix(ideal mod)
3132{
3133  matrix result = mpNew(mod->rank,IDELEMS(mod));
3134  int i,cp;
3135  poly p,h;
3136
3137  for(i=0;i<IDELEMS(mod);i++)
3138  {
3139    p=pReverse(mod->m[i]);
3140    mod->m[i]=NULL;
3141    while (p!=NULL)
3142    {
3143      h=p;
3144      pIter(p);
3145      pNext(h)=NULL;
3146//      cp = si_max(1,pGetComp(h));     // if used for ideals too
3147      cp = pGetComp(h);
3148      pSetComp(h,0);
3149      pSetmComp(h);
3150#ifdef TEST
3151      if (cp>mod->rank)
3152      {
3153        Print("## inv. rank %ld -> %d\n",mod->rank,cp);
3154        int k,l,o=mod->rank;
3155        mod->rank=cp;
3156        matrix d=mpNew(mod->rank,IDELEMS(mod));
3157        for (l=1; l<=o; l++)
3158        {
3159          for (k=1; k<=IDELEMS(mod); k++)
3160          {
3161            MATELEM(d,l,k)=MATELEM(result,l,k);
3162            MATELEM(result,l,k)=NULL;
3163          }
3164        }
3165        idDelete((ideal *)&result);
3166        result=d;
3167      }
3168#endif
3169      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
3170    }
3171  }
3172  // obachman 10/99: added the following line, otherwise memory leack!
3173  idDelete(&mod);
3174  return result;
3175}
3176
3177matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
3178{
3179  matrix result = mpNew(rows,cols);
3180  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
3181  poly p,h;
3182
3183  if (r>rows) r = rows;
3184  if (c>cols) c = cols;
3185  for(i=0;i<c;i++)
3186  {
3187    p=pReverse(mod->m[i]);
3188    mod->m[i]=NULL;
3189    while (p!=NULL)
3190    {
3191      h=p;
3192      pIter(p);
3193      pNext(h)=NULL;
3194      cp = pGetComp(h);
3195      if (cp<=r)
3196      {
3197        pSetComp(h,0);
3198        pSetmComp(h);
3199        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
3200      }
3201      else
3202        pDelete(&h);
3203    }
3204  }
3205  idDelete(&mod);
3206  return result;
3207}
3208
3209/*2
3210* substitute the n-th variable by the monomial e in id
3211* destroy id
3212*/
3213ideal  idSubst(ideal id, int n, poly e)
3214{
3215  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
3216  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
3217
3218  res->rank = id->rank;
3219  for(k--;k>=0;k--)
3220  {
3221    res->m[k]=pSubst(id->m[k],n,e);
3222    id->m[k]=NULL;
3223  }
3224  idDelete(&id);
3225  return res;
3226}
3227
3228BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
3229{
3230  if (w!=NULL) *w=NULL;
3231  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
3232  if (idIs0(m))
3233  {
3234    if (w!=NULL) (*w)=new intvec(m->rank);
3235    return TRUE;
3236  }
3237
3238  long cmax=1,order=0,ord,* diff,diffmin=32000;
3239  int *iscom;
3240  int i,j;
3241  poly p=NULL;
3242  pFDegProc d;
3243  if (pLexOrder && (currRing->order[0]==ringorder_lp))
3244     d=p_Totaldegree;
3245  else
3246     d=pFDeg;
3247  int length=IDELEMS(m);
3248  polyset P=m->m;
3249  polyset F=(polyset)omAlloc(length*sizeof(poly));
3250  for (i=length-1;i>=0;i--)
3251  {
3252    p=F[i]=P[i];
3253    cmax=si_max(cmax,(long)pMaxComp(p));
3254  }
3255  cmax++;
3256  diff = (long *)omAlloc0(cmax*sizeof(long));
3257  if (w!=NULL) *w=new intvec(cmax-1);
3258  iscom = (int *)omAlloc0(cmax*sizeof(int));
3259  i=0;
3260  while (i<=length)
3261  {
3262    if (i<length)
3263    {
3264      p=F[i];
3265      while ((p!=NULL) && (iscom[pGetComp(p)]==0)) pIter(p);
3266    }
3267    if ((p==NULL) && (i<length))
3268    {
3269      i++;
3270    }
3271    else
3272    {
3273      if (p==NULL) /* && (i==length) */
3274      {
3275        i=0;
3276        while ((i<length) && (F[i]==NULL)) i++;
3277        if (i>=length) break;
3278        p = F[i];
3279      }
3280      //if (pLexOrder && (currRing->order[0]==ringorder_lp))
3281      //  order=pTotaldegree(p);
3282      //else
3283      //  order = p->order;
3284      //  order = pFDeg(p,currRing);
3285      order = d(p,currRing) +diff[pGetComp(p)];
3286      //order += diff[pGetComp(p)];
3287      p = F[i];
3288//Print("Actual p=F[%d]: ",i);pWrite(p);
3289      F[i] = NULL;
3290      i=0;
3291    }
3292    while (p!=NULL)
3293    {
3294      if (pLexOrder && (currRing->order[0]==ringorder_lp))
3295        ord=pTotaldegree(p);
3296      else
3297      //  ord = p->order;
3298        ord = pFDeg(p,currRing);
3299      if (iscom[pGetComp(p)]==0)
3300      {
3301        diff[pGetComp(p)] = order-ord;
3302        iscom[pGetComp(p)] = 1;
3303/*
3304*PrintS("new diff: ");
3305*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
3306*PrintLn();
3307*PrintS("new iscom: ");
3308*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
3309*PrintLn();
3310*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
3311*/
3312      }
3313      else
3314      {
3315/*
3316*PrintS("new diff: ");
3317*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
3318*PrintLn();
3319*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
3320*/
3321        if (order != (ord+diff[pGetComp(p)]))
3322        {
3323          omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
3324          omFreeSize((ADDRESS) diff,cmax*sizeof(long));
3325          omFreeSize((ADDRESS) F,length*sizeof(poly));
3326          delete *w;*w=NULL;
3327          return FALSE;
3328        }
3329      }
3330      pIter(p);
3331    }
3332  }
3333  omFreeSize((ADDRESS) iscom,cmax*sizeof(int));
3334  omFreeSize((ADDRESS) F,length*sizeof(poly));
3335  for (i=1;i<cmax;i++) (**w)[i-1]=(int)(diff[i]);
3336  for (i=1;i<cmax;i++)
3337  {
3338    if (diff[i]<diffmin) diffmin=diff[i];
3339  }
3340  if (w!=NULL)
3341  {
3342    for (i=1;i<cmax;i++)
3343    {
3344      (**w)[i-1]=(int)(diff[i]-diffmin);
3345    }
3346  }
3347  omFreeSize((ADDRESS) diff,cmax*sizeof(long));
3348  return TRUE;
3349}
3350
3351BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
3352{
3353  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
3354  if (idIs0(m)) return TRUE;
3355
3356  int cmax=-1;
3357  int i;
3358  poly p=NULL;
3359  int length=IDELEMS(m);
3360  polyset P=m->m;
3361  for (i=length-1;i>=0;i--)
3362  {
3363    p=P[i];
3364    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
3365  }
3366  if (w != NULL)
3367  if (w->length()+1 < cmax)
3368  {
3369    // Print("length: %d - %d \n", w->length(),cmax);
3370    return FALSE;
3371  }
3372
3373  if(w!=NULL)
3374    pSetModDeg(w);
3375
3376  for (i=length-1;i>=0;i--)
3377  {
3378    p=P[i];
3379    poly q=p;
3380    if (p!=NULL)
3381    {
3382      int d=pFDeg(p,currRing);
3383      loop
3384      {
3385        pIter(p);
3386        if (p==NULL) break;
3387        if (d!=pFDeg(p,currRing))
3388        {
3389          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
3390          if(w!=NULL)
3391            pSetModDeg(NULL);
3392          return FALSE;
3393        }
3394      }
3395    }
3396  }
3397
3398  if(w!=NULL)
3399    pSetModDeg(NULL);
3400
3401  return TRUE;
3402}
3403
3404ideal idJet(ideal i,int d)
3405{
3406  ideal r=idInit((i->nrows)*(i->ncols),i->rank);
3407  r->nrows = i-> nrows;
3408  r->ncols = i-> ncols;
3409  //r->rank = i-> rank;
3410  int k;
3411  for(k=(i->nrows)*(i->ncols)-1;k>=0; k--)
3412  {
3413    r->m[k]=ppJet(i->m[k],d);
3414  }
3415  return r;
3416}
3417
3418ideal idJetW(ideal i,int d, intvec * iv)
3419{
3420  ideal r=idInit(IDELEMS(i),i->rank);
3421  if (ecartWeights!=NULL)
3422  {
3423    WerrorS("cannot compute weighted jets now");
3424  }
3425  else
3426  {
3427    short *w=iv2array(iv);
3428    int k;
3429    for(k=0; k<IDELEMS(i); k++)
3430    {
3431      r->m[k]=ppJetW(i->m[k],d,w);
3432    }
3433    omFreeSize((ADDRESS)w,(pVariables+1)*sizeof(short));
3434  }
3435  return r;
3436}
3437
3438int idMinDegW(ideal M,intvec *w)
3439{
3440  int d=-1;
3441  for(int i=0;i<IDELEMS(M);i++)
3442  {
3443    int d0=pMinDeg(M->m[i],w);
3444    if(-1<d0&&(d0<d||d==-1))
3445      d=d0;
3446  }
3447  return d;
3448}
3449
3450ideal idSeries(int n,ideal M,matrix U,intvec *w)
3451{
3452  for(int i=IDELEMS(M)-1;i>=0;i--)
3453  {
3454    if(U==NULL)
3455      M->m[i]=pSeries(n,M->m[i],NULL,w);
3456    else
3457    {
3458      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
3459      MATELEM(U,i+1,i+1)=NULL;
3460    }
3461  }
3462  if(U!=NULL)
3463    idDelete((ideal*)&U);
3464  return M;
3465}
3466
3467matrix idDiff(matrix i, int k)
3468{
3469  int e=MATCOLS(i)*MATROWS(i);
3470  matrix r=mpNew(MATROWS(i),MATCOLS(i));
3471  r->rank=i->rank;
3472  int j;
3473  for(j=0; j<e; j++)
3474  {
3475    r->m[j]=pDiff(i->m[j],k);
3476  }
3477  return r;
3478}
3479
3480matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
3481{
3482  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
3483  int i,j;
3484  for(i=0; i<IDELEMS(I); i++)
3485  {
3486    for(j=0; j<IDELEMS(J); j++)
3487    {
3488      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
3489    }
3490  }
3491  return r;
3492}
3493
3494/*3
3495*handles for some ideal operations the ring/syzcomp managment
3496*returns all syzygies (componentwise-)shifted by -syzcomp
3497*or -syzcomp-1 (in case of ideals as input)
3498static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
3499{
3500  ring orig_ring=currRing;
3501  ring syz_ring=rCurrRingAssure_SyzComp();
3502  rSetSyzComp(length);
3503
3504  ideal s_temp;
3505  if (orig_ring!=syz_ring)
3506    s_temp=idrMoveR_NoSort(arg,orig_ring);
3507  else
3508    s_temp=arg;
3509
3510  ideal s_temp1 = kStd(s_temp,currQuotient,testHomog,&w,NULL,length);
3511  if (w!=NULL) delete w;
3512
3513  if (syz_ring!=orig_ring)
3514  {
3515    idDelete(&s_temp);
3516    rChangeCurrRing(orig_ring);
3517  }
3518
3519  idDelete(&temp);
3520  ideal temp1=idRingCopy(s_temp1,syz_ring);
3521
3522  if (syz_ring!=orig_ring)
3523  {
3524    rChangeCurrRing(syz_ring);
3525    idDelete(&s_temp1);
3526    rChangeCurrRing(orig_ring);
3527    rKill(syz_ring);
3528  }
3529
3530  for (i=0;i<IDELEMS(temp1);i++)
3531  {
3532    if ((temp1->m[i]!=NULL)
3533    && (pGetComp(temp1->m[i])<=length))
3534    {
3535      pDelete(&(temp1->m[i]));
3536    }
3537    else
3538    {
3539      pShift(&(temp1->m[i]),-length);
3540    }
3541  }
3542  temp1->rank = rk;
3543  idSkipZeroes(temp1);
3544
3545  return temp1;
3546}
3547*/
3548/*2
3549* represents (h1+h2)/h2=h1/(h1 intersect h2)
3550*/
3551//ideal idModulo (ideal h2,ideal h1)
3552ideal idModulo (ideal h2,ideal h1, tHomog hom, intvec ** w)
3553{
3554  intvec *wtmp=NULL;
3555
3556  int i,j,k,rk,flength=0,slength,length;
3557  poly p,q;
3558
3559  if (idIs0(h2))
3560    return idFreeModule(si_max(1,h2->ncols));
3561  if (!idIs0(h1))
3562    flength = idRankFreeModule(h1);
3563  slength = idRankFreeModule(h2);
3564  length  = si_max(flength,slength);
3565  if (length==0)
3566  {
3567    length = 1;
3568  }
3569  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
3570  if ((w!=NULL)&&((*w)!=NULL))
3571  {
3572    //Print("input weights:");(*w)->show(1);PrintLn();
3573    int d;
3574    int k;
3575    wtmp=new intvec(length+IDELEMS(h2));
3576    for (i=0;i<length;i++)
3577      ((*wtmp)[i])=(**w)[i];
3578    for (i=0;i<IDELEMS(h2);i++)
3579    {
3580      poly p=h2->m[i];
3581      if (p!=NULL)
3582      {
3583        d = pDeg(p);
3584        k= pGetComp(p);
3585        if (slength>0) k--;
3586        d +=((**w)[k]);
3587        ((*wtmp)[i+length]) = d;
3588      }
3589    }
3590    //Print("weights:");wtmp->show(1);PrintLn();
3591  }
3592  for (i=0;i<IDELEMS(h2);i++)
3593  {
3594    temp->m[i] = pCopy(h2->m[i]);
3595    q = pOne();
3596    pSetComp(q,i+1+length);
3597    pSetmComp(q);
3598    if(temp->m[i]!=NULL)
3599    {
3600      if (slength==0) pShift(&(temp->m[i]),1);
3601      p = temp->m[i];
3602      while (pNext(p)!=NULL) pIter(p);
3603      pNext(p) = q;
3604    }
3605    else
3606      temp->m[i]=q;
3607  }
3608  rk = k = IDELEMS(h2);
3609  if (!idIs0(h1))
3610  {
3611    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
3612    IDELEMS(temp) += IDELEMS(h1);
3613    for (i=0;i<IDELEMS(h1);i++)
3614    {
3615      if (h1->m[i]!=NULL)
3616      {
3617        temp->m[k] = pCopy(h1->m[i]);
3618        if (flength==0) pShift(&(temp->m[k]),1);
3619        k++;
3620      }
3621    }
3622  }
3623
3624  ring orig_ring=currRing;
3625  ring syz_ring=rCurrRingAssure_SyzComp();
3626  rSetSyzComp(length);
3627  ideal s_temp;
3628
3629  if (syz_ring != orig_ring)
3630  {
3631    s_temp = idrMoveR_NoSort(temp, orig_ring);
3632  }
3633  else
3634  {
3635    s_temp = temp;
3636  }
3637
3638  idTest(s_temp);
3639  ideal s_temp1 = kStd(s_temp,currQuotient,hom,&wtmp,NULL,length);
3640
3641  //if (wtmp!=NULL)  Print("output weights:");wtmp->show(1);PrintLn();
3642  if ((w!=NULL) && (*w !=NULL) && (wtmp!=NULL))
3643  {
3644    delete *w;
3645    *w=new intvec(IDELEMS(h2));
3646    for (i=0;i<IDELEMS(h2);i++)
3647      ((**w)[i])=(*wtmp)[i+length];
3648  }
3649  if (wtmp!=NULL) delete wtmp;
3650
3651  for (i=0;i<IDELEMS(s_temp1);i++)
3652  {
3653    if ((s_temp1->m[i]!=NULL)
3654    && (pGetComp(s_temp1->m[i])<=length))
3655    {
3656      pDelete(&(s_temp1->m[i]));
3657    }
3658    else
3659    {
3660      pShift(&(s_temp1->m[i]),-length);
3661    }
3662  }
3663  s_temp1->rank = rk;
3664  idSkipZeroes(s_temp1);
3665
3666  if (syz_ring!=orig_ring)
3667  {
3668    rChangeCurrRing(orig_ring);
3669    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring);
3670    rKill(syz_ring);
3671    // Hmm ... here seems to be a memory leak
3672    // However, simply deleting it causes memory trouble
3673    // idDelete(&s_temp);
3674  }
3675  else
3676  {
3677    idDelete(&temp);
3678  }
3679  idTest(s_temp1);
3680  return s_temp1;
3681}
3682
3683int idElem(const ideal F)
3684{
3685  int i=0,j=IDELEMS(F)-1;
3686
3687  while(j>=0)
3688  {
3689    if ((F->m)[j]!=NULL) i++;
3690    j--;
3691  }
3692  return i;
3693}
3694
3695/*
3696*computes module-weights for liftings of homogeneous modules
3697*/
3698intvec * idMWLift(ideal mod,intvec * weights)
3699{
3700  if (idIs0(mod)) return new intvec(2);
3701  int i=IDELEMS(mod);
3702  while ((i>0) && (mod->m[i-1]==NULL)) i--;
3703  intvec *result = new intvec(i+1);
3704  while (i>0)
3705  {
3706    (*result)[i]=pFDeg(mod->m[i],currRing)+(*weights)[pGetComp(mod->m[i])];
3707  }
3708  return result;
3709}
3710
3711/*2
3712*sorts the kbase for idCoef* in a special way (lexicographically
3713*with x_max,...,x_1)
3714*/
3715ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
3716{
3717  int i;
3718  ideal result;
3719
3720  if (idIs0(kBase)) return NULL;
3721  result = idInit(IDELEMS(kBase),kBase->rank);
3722  *convert = idSort(kBase,FALSE);
3723  for (i=0;i<(*convert)->length();i++)
3724  {
3725    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
3726  }
3727  return result;
3728}
3729
3730/*2
3731*returns the index of a given monom in the list of the special kbase
3732*/
3733int idIndexOfKBase(poly monom, ideal kbase)
3734{
3735  int j=IDELEMS(kbase);
3736
3737  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
3738  if (j==0) return -1;
3739  int i=pVariables;
3740  while (i>0)
3741  {
3742    loop
3743    {
3744      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
3745      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
3746      j--;
3747      if (j==0) return -1;
3748    }
3749    if (i==1)
3750    {
3751      while(j>0)
3752      {
3753        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
3754        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
3755        j--;
3756      }
3757    }
3758    i--;
3759  }
3760  return -1;
3761}
3762
3763/*2
3764*decomposes the monom in a part of coefficients described by the
3765*complement of how and a monom in variables occuring in how, the
3766*index of which in kbase is returned as integer pos (-1 if it don't
3767*exists)
3768*/
3769poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3770{
3771  int i;
3772  poly coeff=pOne(), base=pOne();
3773
3774  for (i=1;i<=pVariables;i++)
3775  {
3776    if (pGetExp(how,i)>0)
3777    {
3778      pSetExp(base,i,pGetExp(monom,i));
3779    }
3780    else
3781    {
3782      pSetExp(coeff,i,pGetExp(monom,i));
3783    }
3784  }
3785  pSetComp(base,pGetComp(monom));
3786  pSetm(base);
3787  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3788  pSetm(coeff);
3789  *pos = idIndexOfKBase(base,kbase);
3790  if (*pos<0)
3791    pDelete(&coeff);
3792  pDelete(&base);
3793  return coeff;
3794}
3795
3796/*2
3797*returns a matrix A of coefficients with kbase*A=arg
3798*if all monomials in variables of how occur in kbase
3799*the other are deleted
3800*/
3801matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3802{
3803  matrix result;
3804  ideal tempKbase;
3805  poly p,q;
3806  intvec * convert;
3807  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3808#if 0
3809  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3810  if (idIs0(arg))
3811    return mpNew(i,1);
3812  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3813  result = mpNew(i,j);
3814#else
3815  result = mpNew(i, j);
3816  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3817#endif
3818
3819  tempKbase = idCreateSpecialKbase(kbase,&convert);
3820  for (k=0;k<j;k++)
3821  {
3822    p = arg->m[k];
3823    while (p!=NULL)
3824    {
3825      q = idDecompose(p,how,tempKbase,&pos);
3826      if (pos>=0)
3827      {
3828        MATELEM(result,(*convert)[pos],k+1) =
3829            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3830      }
3831      else
3832        pDelete(&q);
3833      pIter(p);
3834    }
3835  }
3836  idDelete(&tempKbase);
3837  return result;
3838}
3839
3840/*3
3841* searches for units in the components of the module arg and
3842* returns the first one
3843*/
3844static int idReadOutUnits(ideal arg,int* comp)
3845{
3846  if (idIs0(arg)) return -1;
3847  int i=0,j, generator=-1;
3848  int rk_arg=arg->rank; //idRankFreeModule(arg);
3849  int * componentIsUsed =(int *)omAlloc((rk_arg+1)*sizeof(int));
3850  poly p,q;
3851
3852  while ((generator<0) && (i<IDELEMS(arg)))
3853  {
3854    memset(componentIsUsed,0,(rk_arg+1)*sizeof(int));
3855    p = arg->m[i];
3856    while (p!=NULL)
3857    {
3858      j = pGetComp(p);
3859      if (componentIsUsed[j]==0)
3860      {
3861        if (pLmIsConstantComp(p))
3862        {
3863          generator = i;
3864          componentIsUsed[j] = 1;
3865        }
3866        else
3867        {
3868          componentIsUsed[j] = -1;
3869        }
3870      }
3871      else if (componentIsUsed[j]>0)
3872      {
3873        (componentIsUsed[j])++;
3874      }
3875      pIter(p);
3876    }
3877    i++;
3878  }
3879  i = 0;
3880  *comp = -1;
3881  for (j=0;j<=rk_arg;j++)
3882  {
3883    if (componentIsUsed[j]>0)
3884    {
3885      if ((*comp==-1) || (componentIsUsed[j]<i))
3886      {
3887        *comp = j;
3888        i= componentIsUsed[j];
3889      }
3890    }
3891  }
3892  omFree(componentIsUsed);
3893  return generator;
3894}
3895
3896#if 0
3897static void idDeleteComp(ideal arg,int red_comp)
3898{
3899  int i,j;
3900  poly p;
3901
3902  for (i=IDELEMS(arg)-1;i>=0;i--)
3903  {
3904    p = arg->m[i];
3905    while (p!=NULL)
3906    {
3907      j = pGetComp(p);
3908      if (j>red_comp)
3909      {
3910        pSetComp(p,j-1);
3911        pSetm(p);
3912      }
3913      pIter(p);
3914    }
3915  }
3916  (arg->rank)--;
3917}
3918#endif
3919
3920static void idDeleteComps(ideal arg,int* red_comp,int del)
3921// red_comp is an array [0..args->rank]
3922{
3923  int i,j;
3924  poly p;
3925
3926  for (i=IDELEMS(arg)-1;i>=0;i--)
3927  {
3928    p = arg->m[i];
3929    while (p!=NULL)
3930    {
3931      j = pGetComp(p);
3932      if (red_comp[j]!=j)
3933      {
3934        pSetComp(p,red_comp[j]);
3935        pSetmComp(p);
3936      }
3937      pIter(p);
3938    }
3939  }
3940  (arg->rank) -= del;
3941}
3942
3943/*2
3944* returns the presentation of an isomorphic, minimally
3945* embedded  module (arg represents the quotient!)
3946*/
3947ideal idMinEmbedding(ideal arg,BOOLEAN inPlace, intvec **w)
3948{
3949  if (idIs0(arg)) return idInit(1,arg->rank);
3950  int i,next_gen,next_comp;
3951  ideal res=arg;
3952
3953  if (!inPlace) res = idCopy(arg);
3954  res->rank=si_max(res->rank,idRankFreeModule(res));
3955  int *red_comp=(int*)omAlloc((res->rank+1)*sizeof(int));
3956  for (i=res->rank;i>=0;i--) red_comp[i]=i;
3957
3958  int del=0;
3959  loop
3960  {
3961    next_gen = idReadOutUnits(res,&next_comp);
3962    if (next_gen<0) break;
3963    del++;
3964    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
3965    for(i=next_comp+1;i<=arg->rank;i++) red_comp[i]--;
3966    if ((w !=NULL)&&(*w!=NULL))
3967    {
3968      for(i=next_comp;i<(*w)->length();i++) (**w)[i-1]=(**w)[i];
3969    }
3970  }
3971
3972  idDeleteComps(res,red_comp,del);
3973  idSkipZeroes(res);
3974  omFree(red_comp);
3975
3976  if ((w !=NULL)&&(*w!=NULL) &&(del>0))
3977  {
3978    intvec *wtmp=new intvec((*w)->length()-del);
3979    for(i=0;i<res->rank;i++) (*wtmp)[i]=(**w)[i];
3980    delete *w;
3981    *w=wtmp;
3982  }
3983  return res;
3984}
3985
3986/*2
3987* transpose a module
3988*/
3989ideal idTransp(ideal a)
3990{
3991  int r = a->rank, c = IDELEMS(a);
3992  ideal b =  idInit(r,c);
3993
3994  for (int i=c; i>0; i--)
3995  {
3996    poly p=a->m[i-1];
3997    while(p!=NULL)
3998    {
3999      poly h=pHead(p);
4000      int co=pGetComp(h)-1;
4001      pSetComp(h,i);
4002      pSetmComp(h);
4003      b->m[co]=pAdd(b->m[co],h);
4004      pIter(p);
4005    }
4006  }
4007  return b;
4008}
4009
4010intvec * idQHomWeight(ideal id)
4011{
4012  poly head, tail;
4013  int k;
4014  int in=IDELEMS(id)-1, ready=0, all=0,
4015      coldim=pVariables, rowmax=2*coldim;
4016  if (in<0) return NULL;
4017  intvec *imat=new intvec(rowmax+1,coldim,0);
4018
4019  do
4020  {
4021    head = id->m[in--];
4022    if (head!=NULL)
4023    {
4024      tail = pNext(head);
4025      while (tail!=NULL)
4026      {
4027        all++;
4028        for (k=1;k<=coldim;k++)
4029          IMATELEM(*imat,all,k) = pGetExpDiff(head,tail,k);
4030        if (all==rowmax)
4031        {
4032          ivTriangIntern(imat, ready, all);
4033          if (ready==coldim)
4034          {
4035            delete imat;
4036            return NULL;
4037          }
4038        }
4039        pIter(tail);
4040      }
4041    }
4042  } while (in>=0);
4043  if (all>ready)
4044  {
4045    ivTriangIntern(imat, ready, all);
4046    if (ready==coldim)
4047    {
4048      delete imat;
4049      return NULL;
4050    }
4051  }
4052  intvec *result = ivSolveKern(imat, ready);
4053  delete imat;
4054  return result;
4055}
4056
4057BOOLEAN idIsZeroDim(ideal I)
4058{
4059  BOOLEAN *UsedAxis=(BOOLEAN *)omAlloc0(pVariables*sizeof(BOOLEAN));
4060  int i,n;
4061  poly po;
4062  BOOLEAN res=TRUE;
4063  for(i=IDELEMS(I)-1;i>=0;i--)
4064  {
4065    po=I->m[i];
4066    if ((po!=NULL) &&((n=pIsPurePower(po))!=0)) UsedAxis[n-1]=TRUE;
4067  }
4068  for(i=pVariables-1;i>=0;i--)
4069  {
4070    if(UsedAxis[i]==FALSE) {res=FALSE; break;} // not zero-dim.
4071  }
4072  omFreeSize(UsedAxis,pVariables*sizeof(BOOLEAN));
4073  return res;
4074}
4075
4076void idNormalize(ideal I)
4077{
4078  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
4079  int i;
4080  poly p;
4081  for(i=IDELEMS(I)-1;i>=0;i--)
4082  {
4083    p=I->m[i] ;
4084    while(p!=NULL)
4085    {
4086      nNormalize(pGetCoeff(p));
4087      pIter(p);
4088    }
4089  }
4090}
4091
4092#include <kernel/clapsing.h>
4093
4094#ifdef HAVE_FACTORY
4095poly id_GCD(poly f, poly g, const ring r)
4096{
4097  ring save_r=currRing;
4098  rChangeCurrRing(r);
4099  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
4100  intvec *w = NULL;
4101  ideal S=idSyzygies(I,testHomog,&w);
4102  if (w!=NULL) delete w;
4103  poly gg=pTakeOutComp(&(S->m[0]),2);
4104  idDelete(&S);
4105  poly gcd_p=singclap_pdivide(f,gg);
4106  pDelete(&gg);
4107  rChangeCurrRing(save_r);
4108  return gcd_p;
4109}
4110#endif
4111
4112/*2
4113* xx,q: arrays of length 0..rl-1
4114* xx[i]: SB mod q[i]
4115* assume: char=0
4116* assume: q[i]!=0
4117* destroys xx
4118*/
4119#ifdef HAVE_FACTORY
4120ideal idChineseRemainder(ideal *xx, number *q, int rl)
4121{
4122  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
4123  ideal result=idInit(cnt,xx[0]->rank);
4124  result->nrows=xx[0]->nrows; // for lifting matrices
4125  result->ncols=xx[0]->ncols; // for lifting matrices
4126  int i,j;
4127  poly r,h,hh,res_p;
4128  number *x=(number *)omAlloc(rl*sizeof(number));
4129  for(i=cnt-1;i>=0;i--)
4130  {
4131    res_p=NULL;
4132    loop
4133    {
4134      r=NULL;
4135      for(j=rl-1;j>=0;j--)
4136      {
4137        h=xx[j]->m[i];
4138        if ((h!=NULL)
4139        &&((r==NULL)||(pLmCmp(r,h)==-1)))
4140          r=h;
4141      }
4142      if (r==NULL) break;
4143      h=pHead(r);
4144      for(j=rl-1;j>=0;j--)
4145      {
4146        hh=xx[j]->m[i];
4147        if ((hh!=NULL) && (pLmCmp(r,hh)==0))
4148        {
4149          x[j]=pGetCoeff(hh);
4150          hh=pLmFreeAndNext(hh);
4151          xx[j]->m[i]=hh;
4152        }
4153        else
4154          x[j]=nlInit(0, currRing);
4155      }
4156      number n=nlChineseRemainder(x,q,rl);
4157      for(j=rl-1;j>=0;j--)
4158      {
4159        x[j]=NULL; // nlInit(0...) takes no memory
4160      }
4161      if (nlIsZero(n)) pDelete(&h);
4162      else
4163      {
4164        pSetCoeff(h,n);
4165        //Print("new mon:");pWrite(h);
4166        res_p=pAdd(res_p,h);
4167      }
4168    }
4169    result->m[i]=res_p;
4170  }
4171  omFree(x);
4172  for(i=rl-1;i>=0;i--) idDelete(&(xx[i]));
4173  omFree(xx);
4174  return result;
4175}
4176#endif
4177/* currently unsed:
4178ideal idChineseRemainder(ideal *xx, intvec *iv)
4179{
4180  int rl=iv->length();
4181  number *q=(number *)omAlloc(rl*sizeof(number));
4182  int i;
4183  for(i=0; i<rl; i++)
4184  {
4185    q[i]=nInit((*iv)[i]);
4186  }
4187  return idChineseRemainder(xx,q,rl);
4188}
4189*/
4190/*
4191 * lift ideal with coeffs over Z (mod N) to Q via Farey
4192 */
4193ideal idFarey(ideal x, number N)
4194{
4195  int cnt=IDELEMS(x)*x->nrows;
4196  ideal result=idInit(cnt,x->rank);
4197  result->nrows=x->nrows; // for lifting matrices
4198  result->ncols=x->ncols; // for lifting matrices
4199
4200  int i;
4201  for(i=cnt-1;i>=0;i--)
4202  {
4203    poly h=pCopy(x->m[i]);
4204    result->m[i]=h;
4205    while(h!=NULL)
4206    {
4207      number c=pGetCoeff(h);
4208      pSetCoeff0(h,nlFarey(c,N));
4209      nDelete(&c);
4210      pIter(h);
4211    }
4212    while((result->m[i]!=NULL)&&(nIsZero(pGetCoeff(result->m[i]))))
4213    {
4214      pLmDelete(&(result->m[i]));
4215    }
4216    h=result->m[i];
4217    while((h!=NULL) && (pNext(h)!=NULL))
4218    {
4219      if(nIsZero(pGetCoeff(pNext(h))))
4220      {
4221        pLmDelete(&pNext(h));
4222      }
4223      else pIter(h);
4224    }
4225  }
4226  return result;
4227}
4228
4229/*2
4230* transpose a module
4231* NOTE: just a version of "ideal idTransp(ideal)" which works within specified ring.
4232*/
4233ideal id_Transp(ideal a, const ring rRing)
4234{
4235  int r = a->rank, c = IDELEMS(a);
4236  ideal b =  idInit(r,c);
4237
4238  for (int i=c; i>0; i--)
4239  {
4240    poly p=a->m[i-1];
4241    while(p!=NULL)
4242    {
4243      poly h=p_Head(p, rRing);
4244      int co=p_GetComp(h, rRing)-1;
4245      p_SetComp(h, i, rRing);
4246      p_Setm(h, rRing);
4247      b->m[co] = p_Add_q(b->m[co], h, rRing);
4248      pIter(p);
4249    }
4250  }
4251  return b;
4252}
4253
4254
4255
4256/*2
4257* The following is needed to compute the image of certain map used in
4258* the computation of cohomologies via BGG
4259* let M = { w_1, ..., w_k }, k = size(M) == ncols(M), n = nvars(currRing).
4260* assuming that nrows(M) <= m*n; the procedure computes:
4261* transpose(M) * transpose( var(1) I_m | ... | var(n) I_m ) :== transpose(module{f_1, ... f_k}),
4262* where f_i = \sum_{j=1}^{m} (w_i, v_j) gen(j),  (w_i, v_j) is a `scalar` multiplication.
4263* that is, if w_i = (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m) then
4264
4265  (a^1_1, ... a^1_m) | (a^2_1, ..., a^2_m) | ... | (a^n_1, ..., a^n_m)
4266*  var_1  ... var_1  |  var_2  ...  var_2  | ... |  var_n  ...  var(n)
4267*  gen_1  ... gen_m  |  gen_1  ...  gen_m  | ... |  gen_1  ...  gen_m
4268+ =>
4269  f_i =
4270
4271   a^1_1 * var(1) * gen(1) + ... + a^1_m * var(1) * gen(m) +
4272   a^2_1 * var(2) * gen(1) + ... + a^2_m * var(2) * gen(m) +
4273                             ...
4274   a^n_1 * var(n) * gen(1) + ... + a^n_m * var(n) * gen(m);
4275
4276   NOTE: for every f_i we run only ONCE along w_i saving partial sums into a temporary array of polys of size m
4277*/
4278ideal id_TensorModuleMult(const int m, const ideal M, const ring rRing)
4279{
4280// #ifdef DEBU
4281//  WarnS("tensorModuleMult!!!!");
4282
4283  assume(m > 0);
4284  assume(M != NULL);
4285
4286  const int n = rRing->N;
4287
4288  assume(M->rank <= m * n);
4289
4290  const int k = IDELEMS(M);
4291
4292  ideal idTemp =  idInit(k,m); // = {f_1, ..., f_k }
4293
4294  for( int i = 0; i < k; i++ ) // for every w \in M
4295  {
4296    poly pTempSum = NULL;
4297
4298    poly w = M->m[i];
4299
4300    while(w != NULL) // for each term of w...
4301    {
4302      poly h = p_Head(w, rRing);
4303
4304      const int  gen = p_GetComp(h, rRing); // 1 ...
4305
4306      assume(gen > 0);
4307      assume(gen <= n*m);
4308
4309      // TODO: write a formula with %, / instead of while!
4310      /*
4311      int c = gen;
4312      int v = 1;
4313      while(c > m)
4314      {
4315        c -= m;
4316        v++;
4317      }
4318      */
4319
4320      int cc = gen % m;
4321      if( cc == 0) cc = m;
4322      int vv = 1 + (gen - cc) / m;
4323
4324//      assume( cc == c );
4325//      assume( vv == v );
4326
4327      //  1<= c <= m
4328      assume( cc > 0 );
4329      assume( cc <= m );
4330
4331      assume( vv > 0 );
4332      assume( vv <= n );
4333
4334      assume( (cc + (vv-1)*m) == gen );
4335
4336      p_IncrExp(h, vv, rRing); // h *= var(j) && //      p_AddExp(h, vv, 1, rRing);
4337      p_SetComp(h, cc, rRing);
4338
4339      p_Setm(h, rRing);         // addjust degree after the previous steps!
4340
4341      pTempSum = p_Add_q(pTempSum, h, rRing); // it is slow since h will be usually put to the back of pTempSum!!!
4342
4343      pIter(w);
4344    }
4345
4346    idTemp->m[i] = pTempSum;
4347  }
4348
4349  // simplify idTemp???
4350
4351  ideal idResult = id_Transp(idTemp, rRing);
4352
4353  id_Delete(&idTemp, rRing);
4354
4355  return(idResult);
4356}
Note: See TracBrowser for help on using the repository browser.