/kernel/ideals.cc
C++ | 4429 lines | 3593 code | 286 blank | 550 comment | 823 complexity | 8410beffb9efed74f3dd9a0fe5bb46dc MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0, Unlicense
Large files files are truncated, but you can click here to view the full file
- /****************************************
- * Computer Algebra System SINGULAR *
- ****************************************/
- /* $Id$ */
- /*
- * ABSTRACT - all basic methods to manipulate ideals
- */
- /* includes */
- #include <kernel/mod2.h>
- #ifndef NDEBUG
- # define MYTEST 0
- #else /* ifndef NDEBUG */
- # define MYTEST 1
- #endif /* ifndef NDEBUG */
- #include <kernel/options.h>
- #include <omalloc/omalloc.h>
- #include <kernel/febase.h>
- #include <kernel/numbers.h>
- #include <kernel/longrat.h>
- #include <kernel/polys.h>
- #include <kernel/ring.h>
- #include <kernel/kstd1.h>
- #include <kernel/matpol.h>
- #include <kernel/weight.h>
- #include <kernel/intvec.h>
- #include <kernel/syz.h>
- #include <kernel/sparsmat.h>
- #include <kernel/ideals.h>
- #include <kernel/prCopy.h>
- #include <kernel/gring.h>
- omBin sip_sideal_bin = omGetSpecBin(sizeof(sip_sideal));
- /* #define WITH_OLD_MINOR */
- #define pCopy_noCheck(p) pCopy(p)
- static poly * idpower;
- /*collects the monomials in makemonoms, must be allocated befor*/
- static int idpowerpoint;
- /*index of the actual monomial in idpower*/
- static poly * givenideal;
- /*the ideal from which a power is computed*/
- /*0 implementation*/
- /*2
- * initialise an ideal
- */
- ideal idInit(int idsize, int rank)
- {
- /*- initialise an ideal -*/
- ideal hh = (ideal )omAllocBin(sip_sideal_bin);
- hh->nrows = 1;
- hh->rank = rank;
- IDELEMS(hh) = idsize;
- if (idsize>0)
- {
- hh->m = (poly *)omAlloc0(idsize*sizeof(poly));
- }
- else
- hh->m=NULL;
- return hh;
- }
- #ifdef PDEBUG
- // this is only for outputting an ideal within the debugger
- void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
- {
- assume( debugPrint >= 0 );
- if( id == NULL )
- PrintS("(NULL)");
- else
- {
- Print("Module of rank %ld,real rank %ld and %d generators.\n",
- id->rank,idRankFreeModule(id, lmRing, tailRing),IDELEMS(id));
- int j = (id->ncols*id->nrows) - 1;
- while ((j > 0) && (id->m[j]==NULL)) j--;
- for (int i = 0; i <= j; i++)
- {
- Print("generator %d: ",i); p_DebugPrint(id->m[i], lmRing, tailRing, debugPrint);
- }
- }
- }
- #endif
- /* index of generator with leading term in ground ring (if any);
- otherwise -1 */
- int idPosConstant(ideal id)
- {
- int k;
- for (k = IDELEMS(id)-1; k>=0; k--)
- {
- if (p_LmIsConstantComp(id->m[k], currRing) == TRUE)
- return k;
- }
- return -1;
- }
- /*2
- * initialise the maximal ideal (at 0)
- */
- ideal idMaxIdeal (void)
- {
- int l;
- ideal hh=NULL;
- hh=idInit(pVariables,1);
- for (l=0; l<pVariables; l++)
- {
- hh->m[l] = pOne();
- pSetExp(hh->m[l],l+1,1);
- pSetm(hh->m[l]);
- }
- return hh;
- }
- /*2
- * deletes an ideal/matrix
- */
- void id_Delete (ideal * h, ring r)
- {
- int j,elems;
- if (*h == NULL)
- return;
- elems=j=(*h)->nrows*(*h)->ncols;
- if (j>0)
- {
- do
- {
- p_Delete(&((*h)->m[--j]), r);
- }
- while (j>0);
- omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
- }
- omFreeBin((ADDRESS)*h, sip_sideal_bin);
- *h=NULL;
- }
- /*2
- * Shallowdeletes an ideal/matrix
- */
- void id_ShallowDelete (ideal *h, ring r)
- {
- int j,elems;
- if (*h == NULL)
- return;
- elems=j=(*h)->nrows*(*h)->ncols;
- if (j>0)
- {
- do
- {
- p_ShallowDelete(&((*h)->m[--j]), r);
- }
- while (j>0);
- omFreeSize((ADDRESS)((*h)->m),sizeof(poly)*elems);
- }
- omFreeBin((ADDRESS)*h, sip_sideal_bin);
- *h=NULL;
- }
- /*2
- *gives an ideal the minimal possible size
- */
- void idSkipZeroes (ideal ide)
- {
- int k;
- int j = -1;
- BOOLEAN change=FALSE;
- for (k=0; k<IDELEMS(ide); k++)
- {
- if (ide->m[k] != NULL)
- {
- j++;
- if (change)
- {
- ide->m[j] = ide->m[k];
- }
- }
- else
- {
- change=TRUE;
- }
- }
- if (change)
- {
- if (j == -1)
- j = 0;
- else
- {
- for (k=j+1; k<IDELEMS(ide); k++)
- ide->m[k] = NULL;
- }
- pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
- IDELEMS(ide) = j+1;
- }
- }
- /*2
- * copies the first k (>= 1) entries of the given ideal
- * and returns these as a new ideal
- * (Note that the copied polynomials may be zero.)
- */
- ideal idCopyFirstK (const ideal ide, const int k)
- {
- ideal newI = idInit(k, 0);
- for (int i = 0; i < k; i++)
- newI->m[i] = pCopy(ide->m[i]);
- return newI;
- }
- /*2
- * ideal id = (id[i])
- * result is leadcoeff(id[i]) = 1
- */
- void idNorm(ideal id)
- {
- for (int i=IDELEMS(id)-1; i>=0; i--)
- {
- if (id->m[i] != NULL)
- {
- pNorm(id->m[i]);
- }
- }
- }
- /*2
- * ideal id = (id[i]), c any unit
- * if id[i] = c*id[j] then id[j] is deleted for j > i
- */
- void idDelMultiples(ideal id)
- {
- int i, j;
- int k = IDELEMS(id)-1;
- for (i=k; i>=0; i--)
- {
- if (id->m[i]!=NULL)
- {
- for (j=k; j>i; j--)
- {
- if (id->m[j]!=NULL)
- {
- #ifdef HAVE_RINGS
- if (rField_is_Ring(currRing))
- {
- /* if id[j] = c*id[i] then delete id[j].
- In the below cases of a ground field, we
- check whether id[i] = c*id[j] and, if so,
- delete id[j] for historical reasons (so
- that previous output does not change) */
- if (pComparePolys(id->m[j], id->m[i])) pDelete(&id->m[j]);
- }
- else
- {
- if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
- }
- #else
- if (pComparePolys(id->m[i], id->m[j])) pDelete(&id->m[j]);
- #endif
- }
- }
- }
- }
- }
- /*2
- * ideal id = (id[i])
- * if id[i] = id[j] then id[j] is deleted for j > i
- */
- void idDelEquals(ideal id)
- {
- int i, j;
- int k = IDELEMS(id)-1;
- for (i=k; i>=0; i--)
- {
- if (id->m[i]!=NULL)
- {
- for (j=k; j>i; j--)
- {
- if ((id->m[j]!=NULL)
- && (pEqualPolys(id->m[i], id->m[j])))
- {
- pDelete(&id->m[j]);
- }
- }
- }
- }
- }
- //
- // Delete id[j], if Lm(j) == Lm(i) and both LC(j), LC(i) are units and j > i
- //
- void idDelLmEquals(ideal id)
- {
- int i, j;
- int k = IDELEMS(id)-1;
- for (i=k; i>=0; i--)
- {
- if (id->m[i] != NULL)
- {
- for (j=k; j>i; j--)
- {
- if ((id->m[j] != NULL)
- && pLmEqual(id->m[i], id->m[j])
- #ifdef HAVE_RINGS
- && nIsUnit(pGetCoeff(id->m[i])) && nIsUnit(pGetCoeff(id->m[j]))
- #endif
- )
- {
- pDelete(&id->m[j]);
- }
- }
- }
- }
- }
- //
- // delete id[j], if LT(j) == coeff*mon*LT(i) and vice versa, i.e.,
- // delete id[i], if LT(i) == coeff*mon*LT(j)
- //
- void idDelDiv(ideal id)
- {
- int i, j;
- int k = IDELEMS(id)-1;
- for (i=k; i>=0; i--)
- {
- if (id->m[i] != NULL)
- {
- for (j=k; j>i; j--)
- {
- if (id->m[j]!=NULL)
- {
- #ifdef HAVE_RINGS
- if (rField_is_Ring(currRing))
- {
- if (pDivisibleByRingCase(id->m[i], id->m[j]))
- {
- pDelete(&id->m[j]);
- }
- else if (pDivisibleByRingCase(id->m[j], id->m[i]))
- {
- pDelete(&id->m[i]);
- break;
- }
- }
- else
- {
- #endif
- /* the case of a ground field: */
- if (pDivisibleBy(id->m[i], id->m[j]))
- {
- pDelete(&id->m[j]);
- }
- else if (pDivisibleBy(id->m[j], id->m[i]))
- {
- pDelete(&id->m[i]);
- break;
- }
- #ifdef HAVE_RINGS
- }
- #endif
- }
- }
- }
- }
- }
- /*2
- *test if the ideal has only constant polynomials
- */
- BOOLEAN idIsConstant(ideal id)
- {
- int k;
- for (k = IDELEMS(id)-1; k>=0; k--)
- {
- if (pIsConstantPoly(id->m[k]) == FALSE)
- return FALSE;
- }
- return TRUE;
- }
- /*2
- * copy an ideal
- */
- ideal id_Copy (ideal h1, const ring r)
- {
- int i;
- ideal h2;
- //#ifdef TEST
- if (h1 == NULL)
- {
- h2=idInit(1,1);
- }
- else
- //#endif
- {
- h2=idInit(IDELEMS(h1),h1->rank);
- for (i=IDELEMS(h1)-1; i>=0; i--)
- h2->m[i] = p_Copy(h1->m[i],r);
- }
- return h2;
- }
- #ifdef PDEBUG
- void idDBTest(ideal h1, int level, const char *f,const int l)
- {
- int i;
- if (h1 != NULL)
- {
- // assume(IDELEMS(h1) > 0); for ideal/module, does not apply to matrix
- omCheckAddrSize(h1,sizeof(*h1));
- omdebugAddrSize(h1->m,h1->ncols*h1->nrows*sizeof(poly));
- /* to be able to test matrices: */
- for (i=(h1->ncols*h1->nrows)-1; i>=0; i--)
- _p_Test(h1->m[i], currRing, level);
- int new_rk=idRankFreeModule(h1);
- if(new_rk > h1->rank)
- {
- dReportError("wrong rank %d (should be %d) in %s:%d\n",
- h1->rank, new_rk, f,l);
- omPrintAddrInfo(stderr, h1, " for ideal");
- h1->rank=new_rk;
- }
- }
- }
- #endif
- /*3
- * for idSort: compare a and b revlex inclusive module comp.
- */
- static int pComp_RevLex(poly a, poly b,BOOLEAN nolex)
- {
- if (b==NULL) return 1;
- if (a==NULL) return -1;
- if (nolex)
- {
- int r=pLmCmp(a,b);
- if (r!=0) return r;
- number h=nSub(pGetCoeff(a),pGetCoeff(b));
- r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
- nDelete(&h);
- return r;
- }
- int l=pVariables;
- while ((l>0) && (pGetExp(a,l)==pGetExp(b,l))) l--;
- if (l==0)
- {
- if (pGetComp(a)==pGetComp(b))
- {
- number h=nSub(pGetCoeff(a),pGetCoeff(b));
- int r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
- nDelete(&h);
- return r;
- }
- if (pGetComp(a)>pGetComp(b)) return 1;
- }
- else if (pGetExp(a,l)>pGetExp(b,l))
- return 1;
- return -1;
- }
- /*2
- *sorts the ideal w.r.t. the actual ringordering
- *uses lex-ordering when nolex = FALSE
- */
- intvec *idSort(ideal id,BOOLEAN nolex)
- {
- poly p,q;
- intvec * result = new intvec(IDELEMS(id));
- int i, j, actpos=0, newpos, l;
- int diff, olddiff, lastcomp, newcomp;
- BOOLEAN notFound;
- for (i=0;i<IDELEMS(id);i++)
- {
- if (id->m[i]!=NULL)
- {
- notFound = TRUE;
- newpos = actpos / 2;
- diff = (actpos+1) / 2;
- diff = (diff+1) / 2;
- lastcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
- if (lastcomp<0)
- {
- newpos -= diff;
- }
- else if (lastcomp>0)
- {
- newpos += diff;
- }
- else
- {
- notFound = FALSE;
- }
- //while ((newpos>=0) && (newpos<actpos) && (notFound))
- while (notFound && (newpos>=0) && (newpos<actpos))
- {
- newcomp = pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex);
- olddiff = diff;
- if (diff>1)
- {
- diff = (diff+1) / 2;
- if ((newcomp==1)
- && (actpos-newpos>1)
- && (diff>1)
- && (newpos+diff>=actpos))
- {
- diff = actpos-newpos-1;
- }
- else if ((newcomp==-1)
- && (diff>1)
- && (newpos<diff))
- {
- diff = newpos;
- }
- }
- if (newcomp<0)
- {
- if ((olddiff==1) && (lastcomp>0))
- notFound = FALSE;
- else
- newpos -= diff;
- }
- else if (newcomp>0)
- {
- if ((olddiff==1) && (lastcomp<0))
- {
- notFound = FALSE;
- newpos++;
- }
- else
- {
- newpos += diff;
- }
- }
- else
- {
- notFound = FALSE;
- }
- lastcomp = newcomp;
- if (diff==0) notFound=FALSE; /*hs*/
- }
- if (newpos<0) newpos = 0;
- if (newpos>actpos) newpos = actpos;
- while ((newpos<actpos) && (pComp_RevLex(id->m[i],id->m[(*result)[newpos]],nolex)==0))
- newpos++;
- for (j=actpos;j>newpos;j--)
- {
- (*result)[j] = (*result)[j-1];
- }
- (*result)[newpos] = i;
- actpos++;
- }
- }
- for (j=0;j<actpos;j++) (*result)[j]++;
- return result;
- }
- /*2
- * concat the lists h1 and h2 without zeros
- */
- ideal idSimpleAdd (ideal h1,ideal h2)
- {
- int i,j,r,l;
- ideal result;
- if (h1==NULL) return idCopy(h2);
- if (h2==NULL) return idCopy(h1);
- j = IDELEMS(h1)-1;
- while ((j >= 0) && (h1->m[j] == NULL)) j--;
- i = IDELEMS(h2)-1;
- while ((i >= 0) && (h2->m[i] == NULL)) i--;
- r = si_max(h1->rank,h2->rank);
- if (i+j==(-2))
- return idInit(1,r);
- else
- result=idInit(i+j+2,r);
- for (l=j; l>=0; l--)
- {
- result->m[l] = pCopy(h1->m[l]);
- }
- r = i+j+1;
- for (l=i; l>=0; l--, r--)
- {
- result->m[r] = pCopy(h2->m[l]);
- }
- return result;
- }
- /*2
- * insert h2 into h1 (if h2 is not the zero polynomial)
- * return TRUE iff h2 was indeed inserted
- */
- BOOLEAN idInsertPoly (ideal h1, poly h2)
- {
- if (h2==NULL) return FALSE;
- int j = IDELEMS(h1)-1;
- while ((j >= 0) && (h1->m[j] == NULL)) j--;
- j++;
- if (j==IDELEMS(h1))
- {
- pEnlargeSet(&(h1->m),IDELEMS(h1),16);
- IDELEMS(h1)+=16;
- }
- h1->m[j]=h2;
- return TRUE;
- }
- /*2
- * insert h2 into h1 depending on the two boolean parameters:
- * - if zeroOk is true, then h2 will also be inserted when it is zero
- * - if duplicateOk is true, then h2 will also be inserted when it is
- * already present in h1
- * return TRUE iff h2 was indeed inserted
- */
- BOOLEAN idInsertPolyWithTests (ideal h1, const int validEntries,
- const poly h2, const bool zeroOk, const bool duplicateOk)
- {
- if ((!zeroOk) && (h2 == NULL)) return FALSE;
- if (!duplicateOk)
- {
- bool h2FoundInH1 = false;
- int i = 0;
- while ((i < validEntries) && (!h2FoundInH1))
- {
- h2FoundInH1 = pEqualPolys(h1->m[i], h2);
- i++;
- }
- if (h2FoundInH1) return FALSE;
- }
- if (validEntries == IDELEMS(h1))
- {
- pEnlargeSet(&(h1->m), IDELEMS(h1), 16);
- IDELEMS(h1) += 16;
- }
- h1->m[validEntries] = h2;
- return TRUE;
- }
- /*2
- * h1 + h2
- */
- ideal idAdd (ideal h1,ideal h2)
- {
- ideal result = idSimpleAdd(h1,h2);
- idCompactify(result);
- return result;
- }
- /*2
- * h1 * h2
- */
- ideal idMult (ideal h1,ideal h2)
- {
- int i,j,k;
- ideal hh;
- j = IDELEMS(h1);
- while ((j > 0) && (h1->m[j-1] == NULL)) j--;
- i = IDELEMS(h2);
- while ((i > 0) && (h2->m[i-1] == NULL)) i--;
- j = j * i;
- if (j == 0)
- hh = idInit(1,1);
- else
- hh=idInit(j,1);
- if (h1->rank<h2->rank)
- hh->rank = h2->rank;
- else
- hh->rank = h1->rank;
- if (j==0) return hh;
- k = 0;
- for (i=0; i<IDELEMS(h1); i++)
- {
- if (h1->m[i] != NULL)
- {
- for (j=0; j<IDELEMS(h2); j++)
- {
- if (h2->m[j] != NULL)
- {
- hh->m[k] = ppMult_qq(h1->m[i],h2->m[j]);
- k++;
- }
- }
- }
- }
- {
- idCompactify(hh);
- return hh;
- }
- }
- /*2
- *returns true if h is the zero ideal
- */
- BOOLEAN idIs0 (ideal h)
- {
- int i;
- if (h == NULL) return TRUE;
- i = IDELEMS(h)-1;
- while ((i >= 0) && (h->m[i] == NULL))
- {
- i--;
- }
- if (i < 0)
- return TRUE;
- else
- return FALSE;
- }
- /*2
- * return the maximal component number found in any polynomial in s
- */
- long idRankFreeModule (ideal s, ring lmRing, ring tailRing)
- {
- if (s!=NULL)
- {
- int j=0;
- if (rRing_has_Comp(tailRing) && rRing_has_Comp(lmRing))
- {
- int l=IDELEMS(s);
- poly *p=s->m;
- int k;
- for (; l != 0; l--)
- {
- if (*p!=NULL)
- {
- pp_Test(*p, lmRing, tailRing);
- k = p_MaxComp(*p, lmRing, tailRing);
- if (k>j) j = k;
- }
- p++;
- }
- }
- return j;
- }
- return -1;
- }
- BOOLEAN idIsModule(ideal id, ring r)
- {
- if (id != NULL && rRing_has_Comp(r))
- {
- int j, l = IDELEMS(id);
- for (j=0; j<l; j++)
- {
- if (id->m[j] != NULL && p_GetComp(id->m[j], r) > 0) return TRUE;
- }
- }
- return FALSE;
- }
- /*2
- *returns true if id is homogenous with respect to the aktual weights
- */
- BOOLEAN idHomIdeal (ideal id, ideal Q)
- {
- int i;
- BOOLEAN b;
- if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
- i = 0;
- b = TRUE;
- while ((i < IDELEMS(id)) && b)
- {
- b = pIsHomogeneous(id->m[i]);
- i++;
- }
- if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
- {
- i=0;
- while ((i < IDELEMS(Q)) && b)
- {
- b = pIsHomogeneous(Q->m[i]);
- i++;
- }
- }
- return b;
- }
- /*2
- *returns a minimized set of generators of h1
- */
- ideal idMinBase (ideal h1)
- {
- ideal h2, h3,h4,e;
- int j,k;
- int i,l,ll;
- intvec * wth;
- BOOLEAN homog;
- homog = idHomModule(h1,currQuotient,&wth);
- if (rHasGlobalOrdering_currRing())
- {
- if(!homog)
- {
- WarnS("minbase applies only to the local or homogeneous case");
- e=idCopy(h1);
- return e;
- }
- else
- {
- ideal re=kMin_std(h1,currQuotient,(tHomog)homog,&wth,h2,NULL,0,3);
- idDelete(&re);
- return h2;
- }
- }
- e=idInit(1,h1->rank);
- if (idIs0(h1))
- {
- return e;
- }
- pEnlargeSet(&(e->m),IDELEMS(e),15);
- IDELEMS(e) = 16;
- h2 = kStd(h1,currQuotient,isNotHomog,NULL);
- h3 = idMaxIdeal();
- h4=idMult(h2,h3);
- idDelete(&h3);
- h3=kStd(h4,currQuotient,isNotHomog,NULL);
- k = IDELEMS(h3);
- while ((k > 0) && (h3->m[k-1] == NULL)) k--;
- j = -1;
- l = IDELEMS(h2);
- while ((l > 0) && (h2->m[l-1] == NULL)) l--;
- for (i=l-1; i>=0; i--)
- {
- if (h2->m[i] != NULL)
- {
- ll = 0;
- while ((ll < k) && ((h3->m[ll] == NULL)
- || !pDivisibleBy(h3->m[ll],h2->m[i])))
- ll++;
- if (ll >= k)
- {
- j++;
- if (j > IDELEMS(e)-1)
- {
- pEnlargeSet(&(e->m),IDELEMS(e),16);
- IDELEMS(e) += 16;
- }
- e->m[j] = pCopy(h2->m[i]);
- }
- }
- }
- idDelete(&h2);
- idDelete(&h3);
- idDelete(&h4);
- if (currQuotient!=NULL)
- {
- h3=idInit(1,e->rank);
- h2=kNF(h3,currQuotient,e);
- idDelete(&h3);
- idDelete(&e);
- e=h2;
- }
- idSkipZeroes(e);
- return e;
- }
- /*2
- *the minimal index of used variables - 1
- */
- int pLowVar (poly p)
- {
- int k,l,lex;
- if (p == NULL) return -1;
- k = 32000;/*a very large dummy value*/
- while (p != NULL)
- {
- l = 1;
- lex = pGetExp(p,l);
- while ((l < pVariables) && (lex == 0))
- {
- l++;
- lex = pGetExp(p,l);
- }
- l--;
- if (l < k) k = l;
- pIter(p);
- }
- return k;
- }
- /*3
- *multiplies p with t (!cas) or (t-1)
- *the index of t is:1, so we have to shift all variables
- *p is NOT in the actual ring, it has no t
- */
- static poly pMultWithT (poly p,BOOLEAN cas)
- {
- /*qp is the working pointer in p*/
- /*result is the result, qresult is the working pointer*/
- /*pp is p in the actual ring(shifted), qpp the working pointer*/
- poly result,qp,pp;
- poly qresult=NULL;
- poly qpp=NULL;
- int i,j,lex;
- number n;
- pp = NULL;
- result = NULL;
- qp = p;
- while (qp != NULL)
- {
- i = 0;
- if (result == NULL)
- {/*first monomial*/
- result = pInit();
- qresult = result;
- }
- else
- {
- qresult->next = pInit();
- pIter(qresult);
- }
- for (j=pVariables-1; j>0; j--)
- {
- lex = pGetExp(qp,j);
- pSetExp(qresult,j+1,lex);/*copy all variables*/
- }
- lex = pGetComp(qp);
- pSetComp(qresult,lex);
- n=nCopy(pGetCoeff(qp));
- pSetCoeff0(qresult,n);
- qresult->next = NULL;
- pSetm(qresult);
- /*qresult is now qp brought into the actual ring*/
- if (cas)
- { /*case: mult with t-1*/
- pSetExp(qresult,1,0);
- pSetm(qresult);
- if (pp == NULL)
- { /*first monomial*/
- pp = pCopy(qresult);
- qpp = pp;
- }
- else
- {
- qpp->next = pCopy(qresult);
- pIter(qpp);
- }
- pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
- /*now qpp contains -1*qp*/
- }
- pSetExp(qresult,1,1);/*this is mult. by t*/
- pSetm(qresult);
- pIter(qp);
- }
- /*
- *now p is processed:
- *result contains t*p
- * if cas: pp contains -1*p (in the new ring)
- */
- if (cas) qresult->next = pp;
- /* else qresult->next = NULL;*/
- return result;
- }
- /*2
- * verschiebt die Indizees der Modulerzeugenden um i
- */
- void pShift (poly * p,int i)
- {
- poly qp1 = *p,qp2 = *p;/*working pointers*/
- int j = pMaxComp(*p),k = pMinComp(*p);
- if (j+i < 0) return ;
- while (qp1 != NULL)
- {
- if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
- {
- pAddComp(qp1,i);
- pSetmComp(qp1);
- qp2 = qp1;
- pIter(qp1);
- }
- else
- {
- if (qp2 == *p)
- {
- pIter(*p);
- pLmDelete(&qp2);
- qp2 = *p;
- qp1 = *p;
- }
- else
- {
- qp2->next = qp1->next;
- if (qp1!=NULL) pLmDelete(&qp1);
- qp1 = qp2->next;
- }
- }
- }
- }
- /*2
- *initialized a field with r numbers between beg and end for the
- *procedure idNextChoise
- */
- void idInitChoise (int r,int beg,int end,BOOLEAN *endch,int * choise)
- {
- /*returns the first choise of r numbers between beg and end*/
- int i;
- for (i=0; i<r; i++)
- {
- choise[i] = 0;
- }
- if (r <= end-beg+1)
- for (i=0; i<r; i++)
- {
- choise[i] = beg+i;
- }
- if (r > end-beg+1)
- *endch = TRUE;
- else
- *endch = FALSE;
- }
- /*2
- *returns the next choise of r numbers between beg and end
- */
- void idGetNextChoise (int r,int end,BOOLEAN *endch,int * choise)
- {
- int i = r-1,j;
- while ((i >= 0) && (choise[i] == end))
- {
- i--;
- end--;
- }
- if (i == -1)
- *endch = TRUE;
- else
- {
- choise[i]++;
- for (j=i+1; j<r; j++)
- {
- choise[j] = choise[i]+j-i;
- }
- *endch = FALSE;
- }
- }
- /*2
- *takes the field choise of d numbers between beg and end, cancels the t-th
- *entree and searches for the ordinal number of that d-1 dimensional field
- * w.r.t. the algorithm of construction
- */
- int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
- {
- int * localchoise,i,result=0;
- BOOLEAN b=FALSE;
- if (d<=1) return 1;
- localchoise=(int*)omAlloc((d-1)*sizeof(int));
- idInitChoise(d-1,begin,end,&b,localchoise);
- while (!b)
- {
- result++;
- i = 0;
- while ((i<t) && (localchoise[i]==choise[i])) i++;
- if (i>=t)
- {
- i = t+1;
- while ((i<d) && (localchoise[i-1]==choise[i])) i++;
- if (i>=d)
- {
- omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
- return result;
- }
- }
- idGetNextChoise(d-1,end,&b,localchoise);
- }
- omFreeSize((ADDRESS)localchoise,(d-1)*sizeof(int));
- return 0;
- }
- /*2
- *computes the binomial coefficient
- */
- int binom (int n,int r)
- {
- int i,result;
- if (r==0) return 1;
- if (n-r<r) return binom(n,n-r);
- result = n-r+1;
- for (i=2;i<=r;i++)
- {
- result *= n-r+i;
- if (result<0)
- {
- WarnS("overflow in binomials");
- return 0;
- }
- result /= i;
- }
- return result;
- }
- /*2
- *the free module of rank i
- */
- ideal idFreeModule (int i)
- {
- int j;
- ideal h;
- h=idInit(i,i);
- for (j=0; j<i; j++)
- {
- h->m[j] = pOne();
- pSetComp(h->m[j],j+1);
- pSetmComp(h->m[j]);
- }
- return h;
- }
- ideal idSectWithElim (ideal h1,ideal h2)
- // does not destroy h1,h2
- {
- if (TEST_OPT_PROT) PrintS("intersect by elimination method\n");
- assume(!idIs0(h1));
- assume(!idIs0(h2));
- assume(IDELEMS(h1)<=IDELEMS(h2));
- assume(idRankFreeModule(h1)==0);
- assume(idRankFreeModule(h2)==0);
- // add a new variable:
- int j;
- ring origRing=currRing;
- ring r=rCopy0(origRing);
- r->N++;
- r->block0[0]=1;
- r->block1[0]= r->N;
- omFree(r->order);
- r->order=(int*)omAlloc0(3*sizeof(int*));
- r->order[0]=ringorder_dp;
- r->order[1]=ringorder_C;
- char **names=(char**)omAlloc0(rVar(r) * sizeof(char_ptr));
- for (j=0;j<r->N-1;j++) names[j]=r->names[j];
- names[r->N-1]=omStrDup("@");
- omFree(r->names);
- r->names=names;
- rComplete(r,TRUE);
- // fetch h1, h2
- ideal h;
- h1=idrCopyR(h1,origRing,r);
- h2=idrCopyR(h2,origRing,r);
- // switch to temp. ring r
- rChangeCurrRing(r);
- // create 1-t, t
- poly omt=pOne();
- pSetExp(omt,r->N,1);
- poly t=pCopy(omt);
- pSetm(omt);
- omt=pNeg(omt);
- omt=pAdd(omt,pOne());
- // compute (1-t)*h1
- h1=(ideal)mpMultP((matrix)h1,omt);
- // compute t*h2
- h2=(ideal)mpMultP((matrix)h2,pCopy(t));
- // (1-t)h1 + t*h2
- h=idInit(IDELEMS(h1)+IDELEMS(h2),1);
- int l;
- for (l=IDELEMS(h1)-1; l>=0; l--)
- {
- h->m[l] = h1->m[l]; h1->m[l]=NULL;
- }
- j=IDELEMS(h1);
- for (l=IDELEMS(h2)-1; l>=0; l--)
- {
- h->m[l+j] = h2->m[l]; h2->m[l]=NULL;
- }
- idDelete(&h1);
- idDelete(&h2);
- // eliminate t:
- ideal res=idElimination(h,t);
- // cleanup
- idDelete(&h);
- res=idrMoveR(res,r,origRing);
- rChangeCurrRing(origRing);
- rKill(r);
- return res;
- }
- /*2
- * h3 := h1 intersect h2
- */
- ideal idSect (ideal h1,ideal h2)
- {
- int i,j,k,length;
- int flength = idRankFreeModule(h1);
- int slength = idRankFreeModule(h2);
- int rank=si_min(flength,slength);
- if ((idIs0(h1)) || (idIs0(h2))) return idInit(1,rank);
- ideal first,second,temp,temp1,result;
- poly p,q;
- if (IDELEMS(h1)<IDELEMS(h2))
- {
- first = h1;
- second = h2;
- }
- else
- {
- first = h2;
- second = h1;
- int t=flength; flength=slength; slength=t;
- }
- length = si_max(flength,slength);
- if (length==0)
- {
- if ((currQuotient==NULL)
- && (currRing->OrdSgn==1)
- && (!rIsPluralRing(currRing))
- && ((TEST_V_INTERSECT_ELIM) || (!TEST_V_INTERSECT_SYZ)))
- return idSectWithElim(first,second);
- else length = 1;
- }
- if (TEST_OPT_PROT) PrintS("intersect by syzygy methods\n");
- j = IDELEMS(first);
- ring orig_ring=currRing;
- ring syz_ring=rCurrRingAssure_SyzComp();
- rSetSyzComp(length);
- while ((j>0) && (first->m[j-1]==NULL)) j--;
- temp = idInit(j /*IDELEMS(first)*/+IDELEMS(second),length+j);
- k = 0;
- for (i=0;i<j;i++)
- {
- if (first->m[i]!=NULL)
- {
- if (syz_ring==orig_ring)
- temp->m[k] = pCopy(first->m[i]);
- else
- temp->m[k] = prCopyR(first->m[i], orig_ring);
- q = pOne();
- pSetComp(q,i+1+length);
- pSetmComp(q);
- if (flength==0) pShift(&(temp->m[k]),1);
- p = temp->m[k];
- while (pNext(p)!=NULL) pIter(p);
- pNext(p) = q;
- k++;
- }
- }
- for (i=0;i<IDELEMS(second);i++)
- {
- if (second->m[i]!=NULL)
- {
- if (syz_ring==orig_ring)
- temp->m[k] = pCopy(second->m[i]);
- else
- temp->m[k] = prCopyR(second->m[i], orig_ring);
- if (slength==0) pShift(&(temp->m[k]),1);
- k++;
- }
- }
- intvec *w=NULL;
- temp1 = kStd(temp,currQuotient,testHomog,&w,NULL,length);
- if (w!=NULL) delete w;
- idDelete(&temp);
- if(syz_ring!=orig_ring)
- rChangeCurrRing(orig_ring);
- result = idInit(IDELEMS(temp1),rank);
- j = 0;
- for (i=0;i<IDELEMS(temp1);i++)
- {
- if ((temp1->m[i]!=NULL)
- && (p_GetComp(temp1->m[i],syz_ring)>length))
- {
- if(syz_ring==orig_ring)
- {
- p = temp1->m[i];
- }
- else
- {
- p = prMoveR(temp1->m[i], syz_ring);
- }
- temp1->m[i]=NULL;
- while (p!=NULL)
- {
- q = pNext(p);
- pNext(p) = NULL;
- k = pGetComp(p)-1-length;
- pSetComp(p,0);
- pSetmComp(p);
- /* Warning! multiply only from the left! it's very important for Plural */
- result->m[j] = pAdd(result->m[j],pMult(p,pCopy(first->m[k])));
- p = q;
- }
- j++;
- }
- }
- if(syz_ring!=orig_ring)
- {
- rChangeCurrRing(syz_ring);
- idDelete(&temp1);
- rChangeCurrRing(orig_ring);
- rKill(syz_ring);
- }
- else
- {
- idDelete(&temp1);
- }
- idSkipZeroes(result);
- if (TEST_OPT_RETURN_SB)
- {
- w=NULL;
- temp1=kStd(result,currQuotient,testHomog,&w);
- if (w!=NULL) delete w;
- idDelete(&result);
- idSkipZeroes(temp1);
- return temp1;
- }
- else //temp1=kInterRed(result,currQuotient);
- return result;
- }
- /*2
- * ideal/module intersection for a list of objects
- * given as 'resolvente'
- */
- ideal idMultSect(resolvente arg, int length)
- {
- int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
- ideal bigmat,tempstd,result;
- poly p;
- int isIdeal=0;
- intvec * w=NULL;
- /* find 0-ideals and max rank -----------------------------------*/
- for (i=0;i<length;i++)
- {
- if (!idIs0(arg[i]))
- {
- realrki=idRankFreeModule(arg[i]);
- k++;
- j += IDELEMS(arg[i]);
- if (realrki>maxrk) maxrk = realrki;
- }
- else
- {
- if (arg[i]!=NULL)
- {
- return idInit(1,arg[i]->rank);
- }
- }
- }
- if (maxrk == 0)
- {
- isIdeal = 1;
- maxrk = 1;
- }
- /* init -----------------------------------------------------------*/
- j += maxrk;
- syzComp = k*maxrk;
- ring orig_ring=currRing;
- ring syz_ring=rCurrRingAssure_SyzComp();
- rSetSyzComp(syzComp);
- bigmat = idInit(j,(k+1)*maxrk);
- /* create unit matrices ------------------------------------------*/
- for (i=0;i<maxrk;i++)
- {
- for (j=0;j<=k;j++)
- {
- p = pOne();
- pSetComp(p,i+1+j*maxrk);
- pSetmComp(p);
- bigmat->m[i] = pAdd(bigmat->m[i],p);
- }
- }
- /* enter given ideals ------------------------------------------*/
- i = maxrk;
- k = 0;
- for (j=0;j<length;j++)
- {
- if (arg[j]!=NULL)
- {
- for (l=0;l<IDELEMS(arg[j]);l++)
- {
- if (arg[j]->m[l]!=NULL)
- {
- if (syz_ring==orig_ring)
- bigmat->m[i] = pCopy(arg[j]->m[l]);
- else
- bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring);
- pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
- i++;
- }
- }
- k++;
- }
- }
- /* std computation --------------------------------------------*/
- tempstd = kStd(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
- if (w!=NULL) delete w;
- idDelete(&bigmat);
- if(syz_ring!=orig_ring)
- rChangeCurrRing(orig_ring);
- /* interprete result ----------------------------------------*/
- result = idInit(IDELEMS(tempstd),maxrk);
- k = 0;
- for (j=0;j<IDELEMS(tempstd);j++)
- {
- if ((tempstd->m[j]!=NULL) && (p_GetComp(tempstd->m[j],syz_ring)>syzComp))
- {
- if (syz_ring==orig_ring)
- p = pCopy(tempstd->m[j]);
- else
- p = prCopyR(tempstd->m[j], syz_ring);
- pShift(&p,-syzComp-isIdeal);
- result->m[k] = p;
- k++;
- }
- }
- /* clean up ----------------------------------------------------*/
- if(syz_ring!=orig_ring)
- rChangeCurrRing(syz_ring);
- idDelete(&tempstd);
- if(syz_ring!=orig_ring)
- {
- rChangeCurrRing(orig_ring);
- rKill(syz_ring);
- }
- idSkipZeroes(result);
- return result;
- }
- /*2
- *computes syzygies of h1,
- *if quot != NULL it computes in the quotient ring modulo "quot"
- *works always in a ring with ringorder_s
- */
- static ideal idPrepare (ideal h1, tHomog hom, int syzcomp, intvec **w)
- {
- ideal h2, h3;
- int i;
- int j,jj=0,k;
- poly p,q;
- if (idIs0(h1)) return NULL;
- k = idRankFreeModule(h1);
- h2=idCopy(h1);
- i = IDELEMS(h2)-1;
- if (k == 0)
- {
- for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
- k = 1;
- }
- if (syzcomp<k)
- {
- Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
- syzcomp = k;
- rSetSyzComp(k);
- }
- h2->rank = syzcomp+i+1;
- //if (hom==testHomog)
- //{
- // if(idHomIdeal(h1,currQuotient))
- // {
- // hom=TRUE;
- // }
- //}
- #if MYTEST
- #ifdef RDEBUG
- Print("Prepare::h2: ");
- idPrint(h2);
- for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
- #endif
- #endif
- for (j=0; j<=i; j++)
- {
- p = h2->m[j];
- q = pOne();
- pSetComp(q,syzcomp+1+j);
- pSetmComp(q);
- if (p!=NULL)
- {
- while (pNext(p)) pIter(p);
- p->next = q;
- }
- else
- h2->m[j]=q;
- }
- #ifdef PDEBUG
- for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
- #if MYTEST
- #ifdef RDEBUG
- Print("Prepare::Input: ");
- idPrint(h2);
- Print("Prepare::currQuotient: ");
- idPrint(currQuotient);
- #endif
- #endif
- #endif
- idTest(h2);
- h3 = kStd(h2,currQuotient,hom,w,NULL,syzcomp);
- #if MYTEST
- #ifdef RDEBUG
- Print("Prepare::Output: ");
- idPrint(h3);
- for(j=0;j<IDELEMS(h2);j++) pTest(h3->m[j]);
- #endif
- #endif
- idDelete(&h2);
- return h3;
- }
- /*2
- * compute the syzygies of h1 in R/quot,
- * weights of components are in w
- * if setRegularity, return the regularity in deg
- * do not change h1, w
- */
- ideal idSyzygies (ideal h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
- BOOLEAN setRegularity, int *deg)
- {
- ideal s_h1;
- poly p;
- int j, k, length=0,reg;
- BOOLEAN isMonomial=TRUE;
- int ii, idElemens_h1;
- assume(h1 != NULL);
- idElemens_h1=IDELEMS(h1);
- #ifdef PDEBUG
- for(ii=0;ii<idElemens_h1 /*IDELEMS(h1)*/;ii++) pTest(h1->m[ii]);
- #endif
- if (idIs0(h1))
- {
- ideal result=idFreeModule(idElemens_h1/*IDELEMS(h1)*/);
- int curr_syz_limit=rGetCurrSyzLimit();
- if (curr_syz_limit>0)
- for (ii=0;ii<idElemens_h1/*IDELEMS(h1)*/;ii++)
- {
- if (h1->m[ii]!=NULL)
- pShift(&h1->m[ii],curr_syz_limit);
- }
- return result;
- }
- int slength=(int)idRankFreeModule(h1);
- k=si_max(1,slength /*idRankFreeModule(h1)*/);
- assume(currRing != NULL);
- ring orig_ring=currRing;
- ring syz_ring=rCurrRingAssure_SyzComp();
- if (setSyzComp)
- rSetSyzComp(k);
- if (orig_ring != syz_ring)
- {
- s_h1=idrCopyR_NoSort(h1,orig_ring);
- }
- else
- {
- s_h1 = h1;
- }
- idTest(s_h1);
- ideal s_h3=idPrepare(s_h1,h,k,w); // main (syz) GB computation
- if (s_h3==NULL)
- {
- return idFreeModule( idElemens_h1 /*IDELEMS(h1)*/);
- }
- if (orig_ring != syz_ring)
- {
- idDelete(&s_h1);
- for (j=0; j<IDELEMS(s_h3); j++)
- {
- if (s_h3->m[j] != NULL)
- {
- if (p_MinComp(s_h3->m[j],syz_ring) > k)
- pShift(&s_h3->m[j], -k);
- else
- pDelete(&s_h3->m[j]);
- }
- }
- idSkipZeroes(s_h3);
- s_h3->rank -= k;
- rChangeCurrRing(orig_ring);
- s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
- rKill(syz_ring);
- #ifdef HAVE_PLURAL
- if (rIsPluralRing(currRing))
- {
- idDelMultiples(s_h3);
- idSkipZeroes(s_h3);
- }
- #endif
- idTest(s_h3);
- return s_h3;
- }
- ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
- for (j=IDELEMS(s_h3)-1; j>=0; j--)
- {
- if (s_h3->m[j] != NULL)
- {
- if (p_MinComp(s_h3->m[j],syz_ring) <= k)
- {
- e->m[j] = s_h3->m[j];
- isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
- pDelete(&pNext(s_h3->m[j]));
- s_h3->m[j] = NULL;
- }
- }
- }
- idSkipZeroes(s_h3);
- idSkipZeroes(e);
- if ((deg != NULL)
- && (!isMonomial)
- && (!TEST_OPT_NOTREGULARITY)
- && (setRegularity)
- && (h==isHomog)
- && (!rIsPluralRing(currRing))
- )
- {
- ring dp_C_ring = rCurrRingAssure_dp_C();
- if (dp_C_ring != syz_ring)
- e = idrMoveR_NoSort(e, syz_ring);
- resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
- intvec * dummy = syBetti(res,length,®, *w);
- *deg = reg+2;
- delete dummy;
- for (j=0;j<length;j++)
- {
- if (res[j]!=NULL) idDelete(&(res[j]));
- }
- omFreeSize((ADDRESS)res,length*sizeof(ideal));
- idDelete(&e);
- if (dp_C_ring != syz_ring)
- {
- rChangeCurrRing(syz_ring);
- rKill(dp_C_ring);
- }
- }
- else
- {
- idDelete(&e);
- }
- idTest(s_h3);
- if (currQuotient != NULL)
- {
- ideal ts_h3=kStd(s_h3,currQuotient,h,w);
- idDelete(&s_h3);
- s_h3 = ts_h3;
- }
- return s_h3;
- }
- /*2
- */
- ideal idXXX (ideal h1, int k)
- {
- ideal s_h1;
- int j;
- intvec *w=NULL;
- assume(currRing != NULL);
- ring orig_ring=currRing;
- ring syz_ring=rCurrRingAssure_SyzComp();
- rSetSyzComp(k);
- if (orig_ring != syz_ring)
- {
- s_h1=idrCopyR_NoSort(h1,orig_ring);
- }
- else
- {
- s_h1 = h1;
- }
- ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
- if (s_h3==NULL)
- {
- return idFreeModule(IDELEMS(h1));
- }
- if (orig_ring != syz_ring)
- {
- idDelete(&s_h1);
- idSkipZeroes(s_h3);
- rChangeCurrRing(orig_ring);
- s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
- rKill(syz_ring);
- idTest(s_h3);
- return s_h3;
- }
- idSkipZeroes(s_h3);
- idTest(s_h3);
- return s_h3;
- }
- /*
- *computes a standard basis for h1 and stores the transformation matrix
- * in ma
- */
- ideal idLiftStd (ideal h1, matrix* ma, tHomog hi, ideal * syz)
- {
- int i, j, k, t, inputIsIdeal=idRankFreeModule(h1);
- poly p=NULL, q, qq;
- intvec *w=NULL;
- idDelete((ideal*)ma);
- BOOLEAN lift3=FALSE;
- if (syz!=NULL) { lift3=TRUE; idDelete(syz); }
- if (idIs0(h1))
- {
- *ma=mpNew(1,0);
- if (lift3)
- {
- *syz=idFreeModule(IDELEMS(h1));
- int curr_syz_limit=rGetCurrSyzLimit();
- if (curr_syz_limit>0)
- for (int ii=0;ii<IDELEMS(h1);ii++)
- {
- if (h1->m[ii]!=NULL)
- pShift(&h1->m[ii],curr_syz_limit);
- }
- }
- return idInit(1,h1->rank);
- }
- BITSET save_verbose=verbose;
- k=si_max(1,(int)idRankFreeModule(h1));
- if ((k==1) && (!lift3)) verbose |=Sy_bit(V_IDLIFT);
- ring orig_ring = currRing;
- ring syz_ring = rCurrRingAssure_SyzComp();
- rSetSyzComp(k);
- ideal s_h1=h1;
- if (orig_ring != syz_ring)
- s_h1 = idrCopyR_NoSort(h1,orig_ring);
- else
- s_h1 = h1;
- ideal s_h3=idPrepare(s_h1,hi,k,&w); // main (syz) GB computation
- ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
- if (lift3) (*syz)=idInit(IDELEMS(s_h3),IDELEMS(h1));
- if (w!=NULL) delete w;
- i = 0;
- // now sort the result, SB : leave in s_h3
- // T: put in s_h2
- // syz: put in *syz
- for (j=0; j<IDELEMS(s_h3); j++)
- {
- if (s_h3->m[j] != NULL)
- {
- //if (p_MinComp(s_h3->m[j],syz_ring) <= k)
- if (pGetComp(s_h3->m[j]) <= k) // syz_ring == currRing
- {
- i++;
- q = s_h3->m[j];
- while (pNext(q) != NULL)
- {
- if (pGetComp(pNext(q)) > k)
- {
- s_h2->m[j] = pNext(q);
- pNext(q) = NULL;
- }
- else
- {
- pIter(q);
- }
- }
- if (!inputIsIdeal) pShift(&(s_h3->m[j]), -1);
- }
- else
- {
- // we a syzygy here:
- if (lift3)
- {
- pShift(&s_h3->m[j], -k);
- (*syz)->m[j]=s_h3->m[j];
- s_h3->m[j]=NULL;
- }
- else
- pDelete(&(s_h3->m[j]));
- }
- }
- }
- idSkipZeroes(s_h3);
- //extern char * iiStringMatrix(matrix im, int dim,char ch);
- //PrintS("SB: ----------------------------------------\n");
- //PrintS(iiStringMatrix((matrix)s_h3,k,'\n'));
- //PrintLn();
- //PrintS("T: ----------------------------------------\n");
- //PrintS(iiStringMatrix((matrix)s_h2,h1->rank,'\n'));
- //PrintLn();
- if (lift3) idSkipZeroes(*syz);
- j = IDELEMS(s_h1);
- if (syz_ring!=orig_ring)
- {
- idDelete(&s_h1);
- rChangeCurrRing(orig_ring);
- }
- *ma = mpNew(j,i);
- i = 1;
- for (j=0; j<IDELEMS(s_h2); j++)
- {
- if (s_h2->m[j] != NULL)
- {
- q = prMoveR( s_h2->m[j], syz_ring);
- s_h2->m[j] = NULL;
- while (q != NULL)
- {
- p = q;
- pIter(q);
- pNext(p) = NULL;
- t=pGetComp(p);
- pSetComp(p,0);
- pSetmComp(p);
- MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
- }
- i++;
- }
- }
- idDelete(&s_h2);
- for (i=0; i<IDELEMS(s_h3); i++)
- {
- s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring);
- }
- if (lift3)
- {
- for (i=0; i<IDELEMS(*syz); i++)
- {
- (*syz)->m[i] = prMoveR_NoSort((*syz)->m[i], syz_ring);
- }
- }
- if (syz_ring!=orig_ring) rKill(syz_ring);
- verbose = save_verbose;
- return s_h3;
- }
- static void idPrepareStd(ideal s_temp, int k)
- {
- int j,rk=idRankFreeModule(s_temp);
- poly p,q;
- if (rk == 0)
- {
- for (j=0; j<IDELEMS(s_temp); j++)
- {
- if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
- }
- k = si_max(k,1);
- }
- for (j=0; j<IDELEMS(s_temp); j++)
- {
- if (s_temp->m[j]!=NULL)
- {
- p = s_temp->m[j];
- q = pOne();
- //pGetCoeff(q)=nNeg(pGetCoeff(q)); //set q to -1
- pSetComp(q,k+1+j);
- pSetmComp(q);
- while (pNext(p)) pIter(p);
- pNext(p) = q;
- }
- }
- }
- /*2
- *computes a representation of the generators of submod with respect to those
- * of mod
- */
- ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
- BOOLEAN isSB, BOOLEAN divide, matrix *unit)
- {
- int lsmod =idRankFreeModule(submod), i, j, k;
- int comps_to_add=0;
- poly p;
- if (idIs0(submod))
- {
- if (unit!=NULL)
- {
- *unit=mpNew(1,1);
- MATELEM(*unit,1,1)=pOne();
- }
- if (rest!=NULL)
- {
- *rest=idInit(1,mod->rank);
- }
- return idInit(1,mod->rank);
- }
- if (idIs0(mod)) /* and not idIs0(submod) */
- {
- WerrorS("2nd module does not lie in the first");
- #if 0
- if (unit!=NULL)
- {
- i=IDELEMS(submod);
- *unit=mpNew(i,i);
- for (j=i;j>0;j--)
- {
- MATELEM(*unit,j,j)=pOne();
- }
- }
- if (rest!=NULL)
- {
- *rest=idCopy(submod);
- }
- return idInit(1,mod->rank);
- #endif
- return idInit(IDELEMS(submod),submod->rank);
- }
- if (unit!=NULL)
- {
- comps_to_add = IDELEMS(submod);
- while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
- comps_to_add--;
- }
- k=si_max(idRankFreeModule(mod),idRankFreeModule(submod));
- if ((k!=0) && (lsmod==0)) lsmod=1;
- k=si_max(k,(int)mod->rank);
- if (k<submod->rank) { WarnS("rk(submod) > rk(mod) ?");k=submod->rank; }
- ring orig_ring=currRing;
- ring syz_ring=rCurrRingAssure_SyzComp();
- rSetSyzComp(k);
- ideal s_mod, s_temp;
- if (orig_ring != syz_ring)
- {
- s_mod = idrCopyR_NoSort(mod,orig_ring);
- s_temp = idrCopyR_NoSort(submod,orig_ring);
- }
- else
- {
- s_mod = mod;
- s_temp = idCopy(submod);
- }
- ideal s_h3;
- if (isSB)
- {
- s_h3 = idCopy(s_mod);
- idPrepareStd(s_h3, k+comps_to_add);
- }
- else
- {
- s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL);
- }
- if (!goodShape)
- {
- for (j=0;j<IDELEMS(s_h3);j++)
- {
- if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
- pDelete(&(s_h3->m[j]));
- }
- }
- idSkipZeroes(s_h3);
- if (lsmod==0)
- {
- for (j=IDELEMS(s_temp);j>0;j--)
- {
- if (s_temp->m[j-1]!=NULL)
- pShift(&(s_temp->m[j-1]),1);
- }
- }
- if (unit!=NULL)
- {
- for(j = 0;j<comps_to_add;j++)
- {
- p = s_temp->m[j];
- if (p!=NULL)
- {
- while (pNext(p)!=NULL) pIter(p);
- pNext(p) = pOne();
- pIter(p);
- pSetComp(p,1+j+k);
- pSetmComp(p);
- p = pNeg(p);
- }
- }
- }
- ideal s_result = kNF(s_h3,currQuotient,s_temp,k);
- s_result->rank = s_h3->rank;
- ideal s_rest = idInit(IDELEMS(s_result),k);
- idDelete(&s_h3);
- idDelete(&s_temp);
- for (j=0;j<IDELEMS(s_result);j++)
- {
- if (s_result->m[j]!=NULL)
- {
- if (pGetComp(s_result->m[j])<=k)
- {
- if (!divide)
- {
- if (isSB)
- {
- WarnS("first module not a standardbasis\n"
- "// ** or second not a proper submodule");
- }
- else
- WerrorS("2nd module does not lie in the first");
- idDelete(&s_result);
- idDelete(&s_rest);
- s_result=idInit(IDELEMS(submod),submod->rank);
- break;
- }
- else
- {
- p = s_rest->m[j] = s_result->m[j];
- while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
- s_result->m[j] = pNext(p);
- pNext(p) = NULL;
- }
- }
- pShift(&(s_result->m[j]),-k);
- pNeg(s_result->m[j]);
- }
- }
- if ((lsmod==0) && (!idIs0(s_rest)))
- {
- for (j=IDELEMS(s_rest);j>0;j--)
- {
- if (s_rest->m[j-1]!=NULL)
- {
- pShift(&(s_rest->m[j-1]),-1);
- s_rest->m[j-1] = s_rest->m[j-1];
- }
- }
- }
- if(syz_ring!=orig_ring)
- {
- idDelete(&s_mod);
- rChangeCurrRing(orig_ring);
- s_result = idrMoveR_NoSort(s_result, syz_ring);
- s_rest = idrMoveR_NoSort(s_rest, syz_ring);
- rKill(syz_ring);
- }
- if (rest!=NULL)
- *rest = s_rest;
- else
- idDelete(&s_rest);
- //idPrint(s_result);
- if (unit!=NULL)
- {
- *unit=mpNew(comps_to_add,comps_to_add);
- int i;
- for(i=0;i<IDELEMS(s_result);i++)
- {
- poly p=s_result->m[i];
- poly q=NULL;
- while(p!=NULL)
- {
- if(pGetComp(p)<=comps_to_add)
- {
- pSetComp(p,0);
- if (q!=NULL)
- {
- pNext(q)=pNext(p);
- }
- else
- {
- pIter(s_result->m[i]);
- }
- pNext(p)=NULL;
- MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
- if(q!=NULL) p=pNext(q);
- else p=s_result->m[i];
- }
- else
- {
- q=p;
- pIter(p);
- }
- }
- pShift(&s_result->m[i],-comps_to_add);
- }
- }
- return s_result;
- }
- /*2
- *computes division of P by Q with remainder up to (w-weighted) degree n
- *P, Q, and w are not changed
- */
- void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
- {
- long N=0;
- int i;
- for(i=IDELEMS(Q)-1;i>=0;i--)
- if(w==NULL)
- N=si_max(N,pDeg(Q->m[i]));
- else
- N=si_max(N,pDegW(Q->m[i],w));
- N+=n;
- T=mpNew(IDELEMS(Q),IDELEMS(P));
- R=idInit(IDELEMS(P),P->rank);
- for(i=IDELEMS(P)-1;i>=0;i--)
- {
- poly p;
- if(w==NULL)
- p=ppJet(P->m[i],N);
- else
- p=ppJetW(P->m[i],N,w);
- int j=IDELEMS(Q)-1;
- while(p!=NULL)
- {
- if(pDivisibleBy(Q->m[j],p))
- {
- poly p0=pDivideM(pHead(p),pHead(Q->m[j]));
- if(w==NULL)
- p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
- else
- p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
- pNormalize(p);
- if((w==NULL)&&(pDeg(p0)>n)||(w!=NULL)&&(pDegW(p0,w)>n))
- pDelete(&p0);
- else
- MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
- j=IDELEMS(Q)-1;
- }
- else
- {
- if(j==0)
- {
- poly p0=p;
- pIter(p);
- pNext(p0)=NULL;
- if(((w==NULL)&&(pDeg(p0)>n))
- ||((w!=NULL)&&(pDegW(p0,w)>n)))
- pDelete(&p0);
- else
- R->m[i]=pAdd(R->m[i],p0);
- j=IDELEMS(Q)-1;
- }
- else
- j--;
- }
- }
- }
- }
- /*2
- *computes the quotient of h1,h2 : internal routine for idQuot
- *BEWARE: the returned ideals may contain incorrectly ordered polys !
- *
- */
- static ideal idInitializeQuot (ideal h1, ideal h2, BOOLEAN h1IsStb,
- BOOLEAN *addOnlyOne, int *kkmax)
- {
- ideal temph1;
- poly p,q = NULL;
- int i,l,ll,k,kkk,kmax;
- int j = 0;
- int k1 = idRankFreeModule(h1);
- int k2 = idRankFreeModule(h2);
- tHomog hom=isNotHomog;
- k=si_max(k1,k2);
- if (k==0)
- k = 1;
- if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
- intvec * weights;
- hom = (tHomog)idHomModule(h1,currQuotient,&weights);
- if (/**addOnlyOne &&*/ (!h1IsStb))
- temph1 = kStd(h1,currQuotient,hom,&weights,NULL);
- else
- temph1 = idCopy(h1);
- if (weights!=NULL) delete weights;
- idTest(temph1);
- /*--- making a single vector from h2 ---------------------*/
- for (i=0; i<IDELEMS(h2); i++)
- {
- if (h2->m[i] != NULL)
- {
- p = pCopy(h2->m[i]);
- if (k2 == 0)
- pShift(&p,j*k+1);
- else
- pShift(&p,j*k);
- q = pAdd(q,p);
- j++;
- }
- }
- *kkmax = kmax = j*k+1;
- /*--- adding a monomial for the result (syzygy) ----------*/
- p = q;
- while (pNext(p)!=NULL) pIter(p);
- pNext(p) = pOne();
- pIter(p);
- pSetComp(p,kmax);
- pSetmComp(p);
- /*--- constructing the big matrix ------------------------*/
- ideal h4 = idInit(16,kmax+k-1);
- h4->m[0] = q;
- if (k2 == 0)
- {
- if (k > IDELEMS(h4))
- {
- pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
- IDELEMS(h4) = k;
- }
- for (i=1; i<k; i++)
- {
- if (h4->m[i-1]!=NULL)
- {
- p = pCopy_noCheck(h4->m[i-1]);
- pShift(&p,1);
- h4->m[i] = p;
- }
- }
- }
- idSkipZeroes(h4);
- kkk = IDELEMS(h4);
- i = IDELEMS(temph1);
- for (l=0; l<i; l++)
- {
- if(temph1->m[l]!=NULL)
- {
- for (ll=0; ll<j; ll++)
- {
- p = pCopy(temph1->m[l]);
- if (k1 == 0)
- pShift(&p,ll*k+1);
- else
- pShift(&p,ll*k);
- if (kkk >= IDELEMS(h4))
- {
- pEnlargeSet(&(h4->m),IDELEMS(h4),16);
- IDELEMS(h4) += 16;
- }
- h4->m[kkk] = p;
- kkk++;
- }
- }
- }
- /*--- if h2 goes in as single vector - the h1-part is just SB ---*/
- if (*addOnlyOne)
- {
- idSkipZeroes(h4);
- p = h4->m[0];
- for (i=0;i<IDELEMS(h4)-1;i++)
- {
- h4->m[i] = h4->m[i+1];
- }
- h4->m[IDELEMS(h4)-1] = p;
- test |= Sy_bit(OPT_SB_1);
- }
- idDelete(&temph1);
- return h4;
- }
- /*2
- *computes the quotient of h1,h2
- */
- ideal idQuot (ideal h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
- {
- // first check for special case h1:(0)
- if (idIs0(h2))
- {
- ideal res;
- if (resultIsIdeal)
- {
- res = idInit(1,1);
- res->m[0] = pOne();
- }
- else
- res = idFreeModule(h1->rank);
- return res;
- }
- BITSET old_test=test;
- int i,l,ll,k,kkk,kmax;
- BOOLEAN addOnlyOne=TRUE;
- tHomog hom=isNotHomog;
- intvec * weights1;
- ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
- hom = (tHomog)idHomModule(s_h4,currQuotient,&weights1);
- ring orig_ring=currRing;
- ring syz_ring=rCurrRingAssure_SyzComp();
- rSetSyzComp(kmax-1);
- if (orig_ring!=syz_ring)
- // s_h4 = idrMoveR_NoSort(s_h4,orig_ring);
- s_h4 = idrMoveR(s_h4,orig_ring);
- idTest(s_h4);
- #if 0
- void ipPrint_MA0(matrix m, const char *name);
- matrix m=idModule2Matrix(idCopy(s_h4));
- PrintS("start:\n");
- ipPrint_MA0(m,"Q");
- idDelete((ideal *)&m);
- PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
- #endif
- ideal s_h3;
- if (addOnlyOne)
- {
- s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
- }
- else
- {
- s_h3 = kStd(s_h4,currQuotient,hom,&weights1,NULL,kmax-1);
- }
- test = old_test;
- #if 0
- // only together with the above debug stuff
- idSkipZeroes(s_h3);
- m=idModule2Matrix(idCopy(s_h3));
- Print("result, kmax=%d:\n",kmax);
- ipPrint_MA0(m,"S");
- idDelete((ideal *)&m);
- #endif
- idTest(s_h3);
- if (weights1!=NULL) delete weights1;
- idDelete(&s_h4);
- for (i=0;i<IDELEMS(s_h3);i++)
- {
- if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
- {
- if (resultIsIdeal)
- pShift(&s_h3->m[i],-kmax);
- else
- pShift(&s_h3->m[i],-kmax+1);
- }
- else
- pDelete(&s_h3->m[i]);
- }
- if (resultIsIdeal)
- s_h3->rank = 1;
- else
- s_h3->rank = h1->rank;
- if(syz_ring!=orig_ring)
- {
- rChangeCurrRing(orig_ring);
- s_h3 = idrMoveR_NoSort(s_h3, syz_ring);
- rKill(syz_ring);
- }
- idSkipZeroes(s_h3);
- idTest(s_h3);
- return s_h3;
- }
- /*2
- *computes recursively all monomials of a certain degree
- *in every step the actvar-th entry in the exponential
- *vector is incremented and the other variables are
- *computed by recursive calls of makemonoms
- *if the last variable is reached, the difference to the
- *degree is computed directly
- *vars is the number variables
- *actvar is the actual variable to handle
- *deg is the degree of the monomials to compute
- *monomdeg is the actual degree of the monomial in consideration
- */
- static void makemonoms(int vars,int actvar,int deg,int monomdeg)
- {
- poly p;
- int i=0;
- if ((idpowerpoint == 0) && (actvar ==1))
- {
- idpower[idpowerpoint] = pOne();
- monomdeg = 0;
- }
- while (i<=deg)
- {
- if (deg == monomdeg)
- {
- pSetm(idpower[idpowerpoint]);
- …
Large files files are truncated, but you can click here to view the full file