source: git/kernel/ideals.cc @ 07969d

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