source: git/kernel/ideals.cc @ e070895

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