// $Id: elim.lib,v 1.11 2000-12-22 13:42:34 greuel Exp $ // (GMG, last modified 22.06.96) /////////////////////////////////////////////////////////////////////////////// version="$Id: elim.lib,v 1.11 2000-12-22 13:42:34 greuel Exp $"; category="Commutative Algebra"; info=" LIBRARY: elim.lib Elimination, Saturation and Blowing up PROCEDURES: blowup0(j[,s1,s2]); create presentation of blownup ring of ideal j elim(id,n,m); variable n..m eliminated from id (ideal/module) elim1(id,p); p=product of vars to be eliminated from id nselect(id,n[,m]); select generators not containing nth [..mth] variable sat(id,j); saturated quotient of ideal/module id by ideal j select(id,n[,m]); select generators containing all variables n...m select1(id,n[,m]); select generators containing one variable n...m (parameters in square brackets [] are optional) "; LIB "inout.lib"; LIB "general.lib"; LIB "poly.lib"; /////////////////////////////////////////////////////////////////////////////// proc blowup0 (ideal j,list #) "USAGE: blowup0(j[,s1,s2]); j ideal, s1,s2 nonempty strings CREATE: Create a presentation of the blowup ring of j RETURN: no return value NOTE: s1 and s2 are used to give names to the blownup ring and the blownup ideal (default: s1=\"j\", s2=\"A\") Assume R = char,x(1..n),ord is the basering of j, and s1=\"j\", s2=\"A\" then the procedure creates a new ring with name Bl_jR (equal to R[A,B,...]) Bl_jR = char,(A,B,...,x(1..n)),(dp(k),ord) with k=ncols(j) new variables A,B,... and ordering wp(d1..dk) if j is homogeneous with deg(j[i])=di resp. dp otherwise for these vars. If k>26 or size(s2)>1, say s2=\"A()\", the new vars are A(1),...,A(k). Let j_ be the kernel of the ring map Bl_jR -> R defined by A(i)->j[i], x(i)->x(i), then the quotient ring Bl_jR/j_ is the blowup ring of j in R (being isomorphic to R+j+j^2+...). Moreover the procedure creates a std basis of j_ with name j_ in Bl_jR. This proc uses 'execute' or calls a procedure using 'execute'. DISPLAY: printlevel >=0: explain created objects (default) EXAMPLE: example blowup0; shows examples "{ string bsr = nameof(basering); def br = basering; string cr,vr,o = charstr(br),varstr(br),ordstr(br); int n,k,i = nvars(br),ncols(j),0; int p = printlevel-voice+3; // p=printlevel+1 (default: p=1) //---------------- create coordinate ring of blown up space ------------------- if( size(#)==0 ) { #[1] = "j"; #[2] = "A"; } if( size(#)==1 ) { #[2] = "A"; } if( k<=26 and size(#[2])==1 ) { string nv = A_Z(#[2],k)+","; } else { string nv = (#[2])[1]+"(1.."+string(k)+"),"; } if( is_homog(j) ) { intvec v=1; for( i=1; i<=k; i=i+1) { v[i+1]=deg(j[i]); } string nor = "),(wp(v),"; } else { string nor = "),(dp(1+k),";} execute("ring Bl=("+cr+"),(t,"+nv+vr+nor+o+");"); //---------- map to new ring, eliminate and create blown up ideal ------------- ideal j=imap(br,j); for( i=1; i<=k; i=i+1) { j[i]=var(1+i)-t*j[i]; } j=eliminate(j,t); v=v[2..size(v)]; execute("ring Bl_"+#[1]+bsr+"=("+cr+"),("+nv+vr+nor+o+");"); ideal `#[1]+"_"`=imap(Bl,j); export basering; export `#[1]+"_"`; //keepring basering; setring br; //------------------- some comments about usage and names -------------------- dbprint(p,"", "// The proc created the ring Bl_"+#[1]+bsr+" (equal to "+bsr+"["+nv[1,size(nv)-1]+"])", "// it contains the ideal "+#[1]+"_ , such that", "// Bl_"+#[1]+bsr+"/"+#[1]+"_ is the blowup ring", "// show(Bl_"+#[1]+bsr+"); shows this ring.", "// Make Bl_"+#[1]+bsr+" the basering and see "+#[1]+"_ by typing:", " setring Bl_"+#[1]+bsr+";"," "+#[1]+"_;"); return(); } example { "EXAMPLE:"; echo = 2; ring R=0,(x,y),dp; poly f=y2+x3; ideal j=jacob(f); blowup0(j); show(Bl_jR); setring Bl_jR; j_;""; ring r=32003,(x,y,z),ds; blowup0(maxideal(1),"m","T()"); show(Bl_mr); setring Bl_mr; m_; kill Bl_jR, Bl_mr; } /////////////////////////////////////////////////////////////////////////////// proc elim (id, int n, int m) "USAGE: elim(id,n,m); id ideal/module, n,m integers RETURNS: ideal/module obtained from id by eliminating variables n..m NOTE: no special monomial ordering is required, result is a SB with respect to ordering dp (resp. ls) if the first var not to be eliminated belongs to a -p (resp. -s) blockordering This proc uses 'execute' or calls a procedure using 'execute'. EXAMPLE: example elim; shows examples " { //---- get variables to be eliminated and create string for new ordering ------ int ii; poly vars=1; for( ii=n; ii<=m; ii=ii+1 ) { vars=vars*var(ii); } if( n>1 ) { poly p = 1+var(1); } else { poly p = 1+var(m+1); } if( ord(p)==0 ) { string ordering = "),ls;"; } if( ord(p)>0 ) { string ordering = "),dp;"; } string mpoly=string(minpoly); //-------------- create new ring and map objects to new ring ------------------ def br = basering; string str = "ring @newr = ("+charstr(br)+"),("+varstr(br)+ordering; execute(str); if (mpoly!="0") { execute("minpoly="+mpoly+";"); } def i = imap(br,id); poly vars = imap(br,vars); //---------- now eliminate in new ring and map back to old ring --------------- i = eliminate(i,vars); setring br; return(imap(@newr,i)); } example { "EXAMPLE:"; echo = 2; ring r=0,(x,y,u,v,w),dp; ideal i=x-u,y-u2,w-u3,v-x+y3; elim(i,3,4); module m=i*gen(1)+i*gen(2); m=elim(m,3,4);show(m); } /////////////////////////////////////////////////////////////////////////////// proc elim1 (id, poly vars) "USAGE: elim1(id,p); id ideal/module, p product of vars to be eliminated RETURN: ideal/module obtained from id by eliminating vars occuring in poly NOTE: no special monomial ordering is required, result is a SB with respect to ordering dp (resp. ls) if the first var not to be eliminated belongs to a -p (resp. -s) blockordering This proc uses 'execute' or calls a procedure using 'execute'. EXAMPLE: example elim1; shows examples " { //---- get variables to be eliminated and create string for new ordering ------ int ii; for( ii=1; ii<=nvars(basering); ii=ii+1 ) { if( vars/var(ii)==0 ) { poly p = 1+var(ii); break;} } if( ord(p)==0 ) { string ordering = "),ls;"; } if( ord(p)>0 ) { string ordering = "),dp;"; } //-------------- create new ring and map objects to new ring ------------------ def br = basering; string str = "ring @newr = ("+charstr(br)+"),("+varstr(br)+ordering; execute(str); def id = fetch(br,id); poly vars = fetch(br,vars); //---------- now eliminate in new ring and map back to old ring --------------- id = eliminate(id,vars); setring br; return(imap(@newr,id)); } example { "EXAMPLE:"; echo = 2; ring r=0,(x,y,t,s,z),dp; ideal i=x-t,y-t2,z-t3,s-x+y3; elim1(i,ts); module m=i*gen(1)+i*gen(2); m=elim1(m,st); show(m); } /////////////////////////////////////////////////////////////////////////////// proc nselect (id, int n, list#) "USAGE: nselect(id,n[,m]); id a module or ideal, n, m integers RETURN: generators of id not containing the variable n [up to m] EXAMPLE: example nselect; shows examples "{ int j,k; if( size(#)==0 ) { #[1]=n; } for( k=1; k<=ncols(id); k=k+1 ) { for( j=n; j<=#[1]; j=j+1 ) { if( size(id[k]/var(j))!=0) { id[k]=0; break; } } } return(simplify(id,2)); } example { "EXAMPLE:"; echo = 2; ring r=0,(x,y,t,s,z),(c,dp); ideal i=x-y,y-z2,z-t3,s-x+y3; nselect(i,3); module m=i*(gen(1)+gen(2)); show(m); show(nselect(m,3,4)); } /////////////////////////////////////////////////////////////////////////////// proc sat (id, ideal j) "USAGE: sat(id,j); id=ideal/module, j=ideal RETURN: list of an ideal/module [1] and an integer [2]: [1] = saturation of id with respect to j (= union_(k=1...) of id:j^k) [2] = saturation exponent (= min( k | id:j^k = id:j^(k+1) )) NOTE: [1] is a standard basis in the basering DISPLAY: saturation exponent during computation if printlevel >=1 EXAMPLE: example sat; shows an example "{ int ii,kk; def i=id; id=std(id); int p = printlevel-voice+3; // p=printlevel+1 (default: p=1) while( ii<=size(i) ) { dbprint(p-1,"// compute quotient "+string(kk+1)); i=quotient(id,j); for( ii=1; ii<=size(i); ii=ii+1 ) { if( reduce(i[ii],id,1)!=0 ) break; } id=std(i); kk=kk+1; } dbprint(p-1,"// saturation becomes stable after "+string(kk-1)+" iteration(s)",""); list L = id,kk-1; return (L); } example { "EXAMPLE:"; echo = 2; int p = printlevel; ring r = 2,(x,y,z),dp; poly F = x5+y5+(x-y)^2*xyz; ideal j = jacob(F); sat(j,maxideal(1)); printlevel = 2; sat(j,maxideal(2)); printlevel = p; } /////////////////////////////////////////////////////////////////////////////// proc select (id, int n, list#) "USAGE: select(id,n[,m]); id ideal/module, n, m integers RETURN: generators of id containing the variable n [all variables up to m] NOTE: use 'select1' for selecting generators containing at least one of the variables between n and m EXAMPLE: example select; shows examples "{ if( size(#)==0 ) { #[1]=n; } int j,k; for( k=1; k<=ncols(id); k=k+1 ) { for( j=n; j<=#[1]; j=j+1 ) { if( size(id[k]/var(j))==0) { id[k]=0; break; } } } return(simplify(id,2)); } example { "EXAMPLE:"; echo = 2; ring r=0,(x,y,t,s,z),(c,dp); ideal i=x-y,y-z2,z-t3,s-x+y3; ideal j=select(i,1); j; module m=i*(gen(1)+gen(2)); m; select(m,1,2); } /////////////////////////////////////////////////////////////////////////////// proc select1 (id, int n, list#) "USAGE: select(id,n[,m]); id ideal/module, n, m integers RETURN: generators of id containing the variable n [at least one of the variables up to m] NOTE: use 'select' for selecting generators containing all the variables between n and m EXAMPLE: example select1; shows examples "{ if( size(#)==0 ) { #[1]=n; } int j,k; execute (typeof(id)+" I;"); for( k=1; k<=ncols(id); k=k+1 ) { for( j=n; j<=#[1]; j=j+1 ) { if( size(subst(id[k],var(j),0)) != size(id[k]) ) { I=I,id[k]; break; } } } return(simplify(I,2)); } example { "EXAMPLE:"; echo = 2; ring r=0,(x,y,t,s,z),(c,dp); ideal i=x-y,y-z2,z-t3,s-x+y3; ideal j=select1(i,1); j; module m=i*(gen(1)+gen(2)); m; select1(m,1,2); } ///////////////////////////////////////////////////////////////////////////////