------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --INVARIANT DEFORMATION THEORY OF AFFINE SCHEMES WITH REDUCTIVE GROUP ACTION --Christian LEHN and Ronan TERPEREAU --22/02/2014 (preliminary version) --Situations 2 and 3 of our paper ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Initialisation ------------------------------------------------------------------------------------------------------------------------------------------------------------------ RX=QQ[x1,x2,x3,y1,y2,y3,z1,z2,z3]; --RX=k[W] x={x1,x2,x3,y1,y2,y3,z1,z2,z3}; --the variables of RX g=3; --the dimension of the group G(=SO_3 or O_3 here) --the variable "type" will define the situation we are interested in: --type=0 then G=SO_3 and I is the ideal of X_0 (the unique singular fixed point for the B-action on the invariant Hilbert scheme) --type=1 then G=0_3 and I is the ideal of X_1 --type=2 then G=0_3 and I is the ideal of X_2 type=1; --Now we initialise the ideal I \subset RX, and some rings that we will use later on --Let us mention that the rings kk and RR will be useful in the routine "Reynolds" only --the weights of the t_i have to be computed by hand once we know a basis of the tangent space T_{X_k}\HH initialisation=method(); initialisation(ZZ):= () => (para) -> ( if para==0 then ( I=ideal{x1^2+x2^2+x3^2, y1^2+y2^2+y3^2, z1^2+z2^2+z3^2, x1*y1+x2*y2+x3*y3, x1*z1+x2*z2+x3*z3, y1*z1+y2*z2+y3*z3, x1^2-x3^2, x1*x2,x2^2-x3^2, x2*x3, x1*x3, x1*y2-x2*y1, x1*y3-x3*y1, x2*y3-x3*y2, x2*z3-x3*z2, x1*z2-x2*z1, x1*z3-x3*z1, y2*z3-y3*z2, y1*z2-y2*z1, y1*z3-y3*z1}; RT=QQ[t1,t2,t3,t4,t5,t6,t7,t8,Degrees=>{2,2,1,2,2,2,1,1}]; --t1,...,t_8 is a basis of the cotangent space (T_{X_0}\HH)* and thus RT is the ring S of the article kk=frac RT; RRR=kk[x1,x2,x3,y1,y2,y3,z1,z2,z3, MonomialOrder => Lex]; R=QQ[t1,t2,t3,t4,t5,t6,t7,t8,Degrees=>{2,2,1,2,2,2,1,1}][x1,x2,x3,y1,y2,y3,z1,z2,z3, MonomialOrder => Lex]; --R is the ring k[W] \otimes S of the article t={t1,t2,t3,t4,t5,t6,t7,t8}; ); if para==1 then ( I=ideal{x1^2+x2^2+x3^2, y1^2+y2^2+y3^2, z1^2+z2^2+z3^2, x1*y1+x2*y2+x3*y3, x1*z1+x2*z2+x3*z3, y1*z1+y2*z2+y3*z3, x2^2, x3^2, x1*x2, x2*x3, x1*x3,2*y1*z1*x2-x1*z1*y2-x1*y1*z2,2*y1*z1*x3-x1*z1*y3-x1*y1*z3,2*y3*z3*x2-x3*z3*y2-x3*y3*z2, 2*y3*z3*x1-x3*z3*y1-x3*y3*z1, 2*y2*z2*x3-x2*z2*y3-x2*y2*z3,2*y2*z2*x1-x2*z2*y1-x2*y2*z1,x1*(y2*z3+z2*y3)-x3*(y1*z2+y2*z1),x1*(y2*z3+z2*y3)-x2*(y1*z3+y3*z1)}; RT=QQ[t1,t2,t3,t4,t5,t6,t7,Degrees=>{2,2,0,1,1,0,0}]; --t1,...,t_7 is a basis of the cotangent space (T_{X_1}\HH)* and thus RT is the ring S of the article kk=frac RT; RRR=kk[x1,x2,x3,y1,y2,y3,z1,z2,z3, MonomialOrder => Lex]; R=QQ[t1,t2,t3,t4,t5,t6,t7,Degrees=>{2,2,0,1,1,0,0}][x1,x2,x3,y1,y2,y3,z1,z2,z3, MonomialOrder => Lex]; --R is the ring k[W] \otimes S of the article t={t1,t2,t3,t4,t5,t6,t7}; ); if para==2 then ( I=ideal{x1^2+x2^2+x3^2, y1^2+y2^2+y3^2, z1^2+z2^2+z3^2, x1*y1+x2*y2+x3*y3, x1*z1+x2*z2+x3*z3, y1*z1+y2*z2+y3*z3, x2^2, x3^2, x1*x2, x2*x3, x1*x3, y3*(x1*y2-x2*y1), y2*(x1*y3-x3*y1), y3*(x1*y3-x3*y1), y2*(x2*y3-x3*y2),y3*(x2*y3-x3*y2),y1*(x1*y2-x2*y1), y2*(x1*y2-x2*y1),y1*(x1*y3-x3*y1),y1*(x2*y3-x3*y2)}; RT=QQ[t1,t2,t3,t4,t5,t6,t7,Degrees=>{2,2,2,1,1,2,1}]; --t1,...,t_7 is a basis of the cotangent space (T_{X_2}\HH)* and thus RT is the ring S of the article kk=frac RT; RRR=kk[x1,x2,x3,y1,y2,y3,z1,z2,z3, MonomialOrder => Lex]; R=QQ[t1,t2,t3,t4,t5,t6,t7,Degrees=>{2,2,2,1,1,2,1}][x1,x2,x3,y1,y2,y3,z1,z2,z3, MonomialOrder => Lex]; --R is the ring k[W] \otimes S of the article t={t1,t2,t3,t4,t5,t6,t7}; ); ); initialisation(type); ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Some general routines ------------------------------------------------------------------------------------------------------------------------------------------------------------------ -------------------------------------------------------------------------------------------- --the next routine takes a polynomial P and a list Lfi of polynomials f1...fn --and it determines a n-uplet a1...an of rational numbers such that P=a1f1+...+anfn --However f1...fn are not linearly independant in general and thus the ai are non-unique --the output is the list Lai which contains the coefficients a1...an -------------------------------------------------------------------------------------------- --This routine is an implementation of Algorithm 4.5.19 of Derksen and Klemper and here we follow their notation combilinear=method(); combilinear(RingElement,List):= (List) => (P,Lfi) -> ( Lfi=Lfi|{P}; --Lfi is the list which contains the fi, and we add the polynomial P at the end of the list nf:=length Lfi; Lgi:={}; Lai:={}; --Lgi is the list which will contain the gi, Lai is the list which will contain the ai MatBli:=mutableMatrix(QQ,nf,nf); --MatBli is the matrix which contains the bli for l from 0 to nf-1 do ( --we are going to fill in the list Lgi, if P is linear combination of the fi then we will get Lgi_(nf-1)=0 gl=Lfi_l; MatBli_(l,l)=1; p:=0; while p (M) -> ( zeilen=numRows M; spalten=numColumns M; for i from 0 to zeilen-1 do ( for j from 0 to spalten-1 do ( if M_(i,j)!=0 then return (leadTerm M_(i,j),i,j); ););); leitMonom=method(); --return the leading monomial of a matrix M leitMonom(Matrix):= (RingElement) => (M) -> ( lt=leitTerm M; return (leadMonomial(lt_0),lt_1,lt_2); ); leitKoeffizient=method(); --return the leading coefficient of a matrix M leitKoeffizient(Matrix):= (RingElement) => (M) -> ( lt=leitTerm M; return (leadCoefficient(lt_0),lt_1,lt_2); ); -- given a list li of polynomials and a matrix M the next routine checks if there is an index such that LeadingMonomial(li_i)==LeadingMonomial(M) -- If this equality holds for some i, then the routine returns (true, the smallest such i), else it returns (false, 1+Card(li)) existequalLM=method(); existequalLM(List,Matrix):= (Boolean,ZZ) => (li,M) -> ( existequal=false; indexi=#li+1; if M==0 then return (existequal,indexi); for i from 0 to #li-1 do ( if (leitMonom(li_i)==leitMonom(M)) then (existequal=true;indexi = i;return(existequal,indexi););); return (existequal,indexi);); leitTerm2=method(); --return the leading term of a vector v and the corresponding coordinate i leitTerm2(Vector):=(RingElement,ZZ)=>(v)->( w=leadTerm v; n=#entries v -1; for i from 0 to n do (if w_i!=0 then return(w_i,i)); return (0,n+1);); leitKoeffizient2=method(); --return the leading coefficient of a vector v and the corresponding coordinate i leitKoeffizient2(Vector):=(RingElement,ZZ)=>(v)->( w=leadTerm v; n=#entries v -1; for i from 0 to n do (if w_i!=0 then return(leadCoefficient(w_i),i)); return (0,n+1);); -- the input is an integer indi and a list si of vectors with leading coefficient equals 1 -- if there exists a vector si_i in the list si such that LM(si_i)=LM(si_indi) with i (si,indi) ->( if indi<=0 then return(false,#si+1); if si=={} then return(false,#si+1); if #si<=indi then return(false,#si+1); if matrix(si_indi)==0 then return(false,#si+1); for i from 0 to indi-1 do (if leitTerm2(si_i)==leitTerm2(si_indi) then return(true,i);); return(false,indi+1);); -- Given a list li of non-zero vectors, the next routine compute a list "simple" which contains -- vectors with leading coefficient=1 et whose the leading terms are pairwise differents -- In particular the vectors of the list simple form a basis of the vector space generated by the vectors of li -- The output is the list "base" which is a sublist of li whose vectors form a basis of the vector space generated by the vectors of li lindeplist=method(); lindeplist(List):=(List)=>(li)->( base:={}; simple:=new MutableList from li; nn=#simple-1; for j from 0 to nn do (simple#j=substitute(1/((leitKoeffizient2(simple#j))_0),QQ) * simple#j); for i from 0 to nn do ( (existe,indexi)=existequalLM2(toList(simple),i); while existe do (simple#i=simple#i-simple#indexi; if (matrix(simple#i)!=0) then simple#i=substitute(1/((leitKoeffizient2(simple#i))_0),QQ) * simple#i; (existe,indexi)=existequalLM2(toList(simple),i);); if (matrix(simple#i)!=0) then base=base|{li_i}; ); return base;); ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Routines to make the Lie algebra Lie(G) act on RX=k[W], and on the matrices A_i and B_i --From now on we will denote by D1,D2...Dg the canonical basis of the Lie algebra g=Lie(G) ------------------------------------------------------------------------------------------------------------------------------------------------------------------ actionLieAlgebra=method(); --Given a polynomial f in k[W] and an integer p between 1 and 3, we return the polynomial Dp.f actionLieAlgebra(RingElement,ZZ):= (RingElement) => (f,p) -> ( if p==1 then return x1*diff(x2,f)-x2*diff(x1,f)+y1*diff(y2,f)-y2*diff(y1,f)+z1*diff(z2,f)-z2*diff(z1,f); if p==2 then return x1*diff(x3,f)-x3*diff(x1,f)+y1*diff(y3,f)-y3*diff(y1,f)+z1*diff(z3,f)-z3*diff(z1,f); if p==3 then return x2*diff(x3,f)-x3*diff(x2,f)+y2*diff(y3,f)-y3*diff(y2,f)+z2*diff(z3,f)-z3*diff(z2,f); ); --The next routine is useful only for the forthcoming routine "actionN2" in which we have to consider relations x1 \otimes f1+x2 \otimes f2+... --that we represent as an element xx1f1+xx2f2+... of the ring Rb --and thus to make Lie(G) act on these relations, we will use this routine actionLieAlgebraBis=method(); actionLieAlgebraBis(RingElement,ZZ):= (RingElement) => (f,p) -> ( if p==1 then return xx1*diff(xx2,f)-xx2*diff(xx1,f)+yy1*diff(yy2,f)-yy2*diff(yy1,f)+zz1*diff(zz2,f)-zz2*diff(zz1,f); if p==2 then return xx1*diff(xx3,f)-xx3*diff(xx1,f)+yy1*diff(yy3,f)-yy3*diff(yy1,f)+zz1*diff(zz3,f)-zz3*diff(zz1,f); if p==3 then return xx2*diff(xx3,f)-xx3*diff(xx2,f)+yy2*diff(yy3,f)-yy3*diff(yy2,f)+zz2*diff(zz3,f)-zz3*diff(zz2,f); ); ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Computation of A_0, initialisation of n1 ------------------------------------------------------------------------------------------------------------------------------------------------------------------ A={}; --A is a list which will contain the matrices Ai if (length A)==0 then A=A|{substitute(gens I,R)}; --we construct A0 (if it does not already exist) n1:=numColumns A_0; --n1 is the number of generators of the ideal I --Given A0, the next routine determines a liste LLN1 of g matrices of size n1*n1 with rational coefficients such that Dp.gen_i=sum_j (LLN1_p)_(j,i) gen_j --where gen_i is the i-th generator of the ideal I, that is the i-th coefficient of A0 --In other words, we have Dp.A0=A0*LLN1_p for p=1...g --This routine encodes the action of Lie(G) on N1 and thus it will be useful to make Dp act on the matrices Ai actionN1=method(); actionN1(Matrix):= (List) => (A0) -> ( use(RX); LLN1={}; LA0={}; LM={}; for i from 0 to n1-1 do LA0=LA0|{substitute(A0_(0,i),RX)}; --LA0 is a list which contains the coefficients of A0 Z=mutableMatrix(QQ,n1,n1); for p from 1 to g do (for i from 0 to n1-1 do ( LM=combilinear(actionLieAlgebra(LA0_i,p),LA0); --here we use the routine "combilinear" to express each Dp.A0_i as a linear combination of the A0_j for j from 0 to n1-1 do Z_(j,i)=LM_j; ); LLN1=LLN1|{matrix(Z)}; ); return LLN1; ); LN1:=actionN1(A_0); ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Computation of B_0, initialisation of n2 ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --The next routine takes a matrix M of size n1*b2 which contains relations between the generators of the ideal I --and for each columns Cl of M it constructs a matrix Z whose columns are D1.Cl, D2.Cl,...,Dg.Cl --then it makes M=M|Z for each column Cl and at the end it returns "mingens image M" --Hence if we repeat this procedure enough times, we can replace the matrix M by a matrix Mbis whose every column CMi verifies Dp.CMi is a linear combination of the CMj --Rk: The image of the matrix M generates the vector space N'_2 in the article, while Mbis generates the G-module N2 Gstabilization=method(); Gstabilization(Matrix):= (Matrix) => (M) -> ( b2=numColumns M; for c from 0 to b2-1 do ( Z=mutableMatrix(RX,n1,g); for p from 1 to g do ( for l from 0 to n1-1 do Z_(l,p-1)=actionLieAlgebra(M_(l,c),p)+sum(n1,k->M_(k,c)*substitute((LN1_(p-1))_(l,k),RX)); ); M=M|matrix(Z); ); return mingens image M ); use(RX); G2 = gb(I, Syzygies=>true); B0=mingens image syz G2; --B0 is the first syzygies matrix of the ideal I --now we have relations between the genrators of I but a priori the vector subspace of R \otimes N1 generated by this set of relations is not G-stable --so we have to make it G-stable by using the method "Gstabilization" above --In our situation, it is enough to apply it only once if type==1 then ( C1=submatrix(B0,,{0..16}); --kernel of I3, already G-stable C2=submatrix(B0,,{17..74}); --kernel of I4 C3=submatrix(B0,,{75..79}); ); --kernel of I5 if type==2 then ( C1=submatrix(B0,,{0..17}); --kernel of I3, already G-stable C2=submatrix(B0,,{18..75}); --kernel of I4 C3=submatrix(B0,,{76..80}); ); --kernel of I5 if type!=0 then ( C2=Gstabilization(C2); C3=Gstabilization(C3); c1=numColumns C1; c2=numColumns C2; c3=numColumns C3; B0=(C1|C2|C3); ); use(R); B={}; --the list B will contain matrices Bi if (length B)==0 then B=B|{substitute(B0,R)}; --we define the matrix B0 (if it has not been already defined) n2:=numColumns B_0; --Given B0, the next routine determines a liste LLN2 of g matrices of size n2*n2 with rational coefficients such that Dp.r_j=sum_i (LLN2_p)_(i,j) r_i --where r_i is the i-th relation between the generators of the ideal I, that is r_i corresponds to the i-th column of B0 --In other words, we have Dp.B0=B0*LLN2_p for p=1...g --This routine encodes the action of Lie(G) on N2 and thus it will be useful to make Dp act on the matrices Bi actionN2=method(); actionN2(Matrix):= (List) => (B0) -> ( b2=numColumns B0; LLN2={}; Lrel={}; LM={}; Rb=QQ[x1,x2,x3,y1,y2,y3,z1,z2,z3,xx1,xx2,xx3,yy1,yy2,yy3,zz1,zz2,zz3]; use(Rb); B0b=substitute(B0,Rb); if type==0 then A0b=matrix{{xx1^2+xx2^2+xx3^2, yy1^2+yy2^2+yy3^2, zz1^2+zz2^2+zz3^2, xx1*yy1+xx2*yy2+xx3*yy3, xx1*zz1+xx2*zz2+xx3*zz3, yy1*zz1+yy2*zz2+yy3*zz3, xx1^2-xx3^2, xx1*xx2,xx2^2-xx3^2, xx2*xx3, xx1*xx3, xx1*yy2-xx2*yy1, xx1*yy3-xx3*yy1, xx2*yy3-xx3*yy2, xx2*zz3-xx3*zz2, xx1*zz2-xx2*zz1, xx1*zz3-xx3*zz1, yy2*zz3-yy3*zz2, yy1*zz2-yy2*zz1, yy1*zz3-yy3*zz1}}; if type==1 then A0b=matrix{{xx1^2+xx2^2+xx3^2, yy1^2+yy2^2+yy3^2, zz1^2+zz2^2+zz3^2, xx1*yy1+xx2*yy2+xx3*yy3, xx1*zz1+xx2*zz2+xx3*zz3, yy1*zz1+yy2*zz2+yy3*zz3, xx2^2, xx3^2, xx1*xx2, xx2*xx3, xx1*xx3,2*yy1*zz1*xx2-xx1*zz1*yy2-xx1*yy1*zz2,2*yy1*zz1*xx3-xx1*zz1*yy3-xx1*yy1*zz3,2*yy3*zz3*xx2-xx3*zz3*yy2-xx3*yy3*zz2, 2*yy3*zz3*xx1-xx3*zz3*yy1-xx3*yy3*zz1, 2*yy2*zz2*xx3-xx2*zz2*yy3-xx2*yy2*zz3,2*yy2*zz2*xx1-xx2*zz2*yy1-xx2*yy2*zz1,xx1*(yy2*zz3+zz2*yy3)-xx3*(yy1*zz2+yy2*zz1),xx1*(yy2*zz3+zz2*yy3)-xx2*(yy1*zz3+yy3*zz1)}}; if type==2 then A0b=matrix{{xx1^2+xx2^2+xx3^2, yy1^2+yy2^2+yy3^2, zz1^2+zz2^2+zz3^2, xx1*yy1+xx2*yy2+xx3*yy3, xx1*zz1+xx2*zz2+xx3*zz3, yy1*zz1+yy2*zz2+yy3*zz3, xx2^2, xx3^2, xx1*xx2, xx2*xx3, xx1*xx3, yy3*(xx1*yy2-xx2*yy1), yy2*(xx1*yy3-xx3*yy1), yy3*(xx1*yy3-xx3*yy1), yy2*(xx2*yy3-xx3*yy2),yy3*(xx2*yy3-xx3*yy2),yy1*(xx1*yy2-xx2*yy1), yy2*(xx1*yy2-xx2*yy1),yy1*(xx1*yy3-xx3*yy1),yy1*(xx2*yy3-xx3*yy2)}}; Rel=mutableMatrix(Rb,1,b2); for i from 0 to b2-1 do ( for j from 0 to n1-1 do Rel_(0,i)=Rel_(0,i)+A0b_(0,j)*B0b_(j,i);); Rell=matrix(Rel); --the matrix Rell contains the relations r_1,...,r_n2 for i from 0 to b2-1 do Lrel=Lrel|{Rell_(0,i)}; --the lements of the list Lrel contains the relations r_1,...,r_n2 Z=mutableMatrix(QQ,b2,b2); for p from 1 to g do (for i from 0 to b2-1 do (use(Rb); LM=combilinear(actionLieAlgebra(Lrel_i,p)+actionLieAlgebraBis(Lrel_i,p),Lrel); for j from 0 to b2-1 do Z_(j,i)=LM_j; ); LLN2=LLN2|{matrix(Z)}; ); return LLN2; ); --We have three types of relations (depending on the degree of the coefficients) --and the Lie algebra action preserves each of these type, so we can compute LN2 by blocks to compute faster if type==0 then LN2:=actionN2(B_0) else ( LN21:=actionN2(C1); LN22:=actionN2(C2); --around 20 secs LN23:=actionN2(C3); LN2={};--now it remains to stick the blocks together to construct the matrices of the list LN2 for p from 1 to g do ( Z=mutableMatrix(QQ,n2,n2); for i from 0 to c1-1 do (for j from 0 to c1-1 do Z_(i,j)=(LN21_(p-1))_(i,j); ); for i from 0 to c2-1 do (for j from 0 to c2-1 do Z_(c1+i,c1+j)=(LN22_(p-1))_(i,j); ); for i from 0 to c3-1 do (for j from 0 to c3-1 do Z_(c1+c2+i,c1+c2+j)=(LN23_(p-1))_(i,j); ); LN2=LN2|{matrix Z} ); ); ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Computation of the action of the Casimir (of Lie(G)) on the matrices Ai and Bi ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --If nb==1, then M is a matrix Ai, that is a matrix Rn1->R --If nb==2, then M is a matrix Bi, that is a matrix Rn2->Rn1 --The next routine take a matrix M and computes the matrix Dp.M (where Lie(G) acts on the coefficients but also on the basis vectors) actionLieAlgebraSurMat=method(); actionLieAlgebraSurMat(Matrix,ZZ,ZZ):= (Matrix) => (M,p,nb) -> ( if nb==1 then ( ZZ1=mutableMatrix(R,1,n1); for i from 0 to n1-1 do ZZ1_(0,i)=actionLieAlgebra(M_(0,i),p); ZZ2=matrix(ZZ1)-M*LN1_(p-1); ); if nb==2 then ( ZZ1=mutableMatrix(R,n1,n2); for i from 0 to n1-1 do ( for j from 0 to n2-1 do ZZ1_(i,j)=actionLieAlgebra(M_(i,j),p); ); ZZ2=matrix(ZZ1)+LN1_(p-1)*M-M*LN2_(p-1); ); return ZZ2; ); actionLieAlgebraSurMat = memoize actionLieAlgebraSurMat; --optional, cf doc MACAULAY2 casimir=method(); --Compute the action of the Casimir on the matrix M casimir(Matrix,ZZ):= (Matrix) => (M,nb) -> ( if nb==1 then (ln=1; col=n1;); if nb==2 then (ln=n1; col=n2;); Z=matrix(mutableMatrix(R,ln,col)); for i from 1 to g do ( Z1=actionLieAlgebraSurMat(M,i,nb); Z1=actionLieAlgebraSurMat(Z1,i,nb); Z=Z+Z1; ); return Z; ); casimir=memoize casimir; --optional, cf doc MACAULAY2 ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Computation of the Reynolds operator applied on the matrices Ai and Bi --This routine is an implementation of Algorithm 4.5.19 of Derksen and Klemper and here we follow their notation ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --the list deglist1 and deglist2 will be useful in the next routines when we will compute the Reynolds operator deglist1={}; for i from 0 to n1-1 do deglist1=deglist1|degree (substitute(A_0,RX))_(0,i); deglist2={}; if type!=0 then ( for i from 0 to c1-1 do deglist2=deglist2|{3}; for i from 0 to c2-1 do deglist2=deglist2|{4}; for i from 0 to c3-1 do deglist2=deglist2|{5}; ); reynoldsZmod2Z=method(); --to compute Reynolds(MR) for the action of the group Z/2Z reynoldsZmod2Z(Matrix,ZZ):=(Matrix)=>(M,nb)->( M=substitute(M,R); if nb==1 then ( SigM=mutableMatrix(R,1,n1); for i from 0 to n1-1 do ( if M_(0,i)!=0 then ( (M1,C1)=coefficients M_(0,i); for k from 0 to numColumns M1-1 do SigM_(0,i)=SigM_(0,i)+M1_(0,k)*C1_(k,0)*(-1)^((degree M1_(0,k))_0); SigM_(0,i)=SigM_(0,i)*(-1)^(deglist1_i); ); ); ); if nb==2 then ( SigM=mutableMatrix(R,n1,n2); for i from 0 to n1-1 do ( for j from 0 to n2-1 do ( if M_(i,j)!=0 then ( (M2,C2)=coefficients M_(i,j); for k from 0 to numColumns M2-1 do SigM_(i,j)=SigM_(i,j)+M2_(0,k)*C2_(k,0)*(-1)^((degree M2_(0,k))_0); SigM_(i,j)=SigM_(i,j)*(-1)^(deglist2_j+deglist1_i); ); ); ); ); return 1/2 *(M+matrix SigM); ); reynolds=method(); --to compute Reynolds(MR) for the action of the group G reynolds(Matrix,ZZ):= (Matrix) => (MR,nb) -> ( if MR==0 then return MR; ff={MR}; use(RRR); M=substitute(MR,RRR); reyf=matrix mutableMatrix(RRR,numRows(MR),numColumns(MR)); gg:={}; ell=0; bb:={}; a:=0; gell:=0; gellnonzero=(M!=0); while gellnonzero do ( use RRR; bell={}; for i from 0 to ell-1 do bell=bell|{0}; bell=bell|{1}; bell=new MutableList from bell; gell=substitute(ff_ell,RRR); if gell!=0 then a=leitKoeffizient(gell); (existe,indexi) = existequalLM(gg,gell); while existe do ( gell=gell-a_0*(gg_indexi); for j from 0 to indexi do bell#j=bell#j-a_0*bb_indexi_j; if gell!=0 then a=leitKoeffizient(gell); (existe,indexi) = existequalLM(gg,gell);); if gell==0 then ( gellnonzero=false; if bell#0==0 then (for k from 1 to ell do reyf=reyf+bell#k*substitute(ff_(k-1),RRR);); return(1/bell#1 * reyf);); gell=1/a_0 * gell; bell=1/a_0 * toList bell; bb=bb|{bell}; gg=gg|{gell}; ell= ell+1; use R; ff=ff|{casimir(ff_(ell-1),nb)};); use(R); reyf2=substitute(reyf,R); if type!=0 then reyf2=reynoldsZmod2Z(reyf2,nb); return reyf2; ); reynolds=memoize reynolds; --optional, cf doc MACAULAY2 ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Computation of the tangent space of the invariant Hilbert scheme at the point I ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Here the computation of the tangent space is partially by hand to save computation time use(RX); H=Hom(I,RX/I); --H is a RX/I module G=gens H; if type==0 then MM=matrix(G_6)|matrix(G_9)|matrix(G_11)|matrix(G_12)|matrix(G_13)|matrix(G_14)|(z3*matrix(G_2))|(y3*matrix(G_2)); if type==1 then MM=matrix(G_0)|matrix(G_16)|matrix(G_17)|(y3*matrix(G_7))|(z3*matrix(G_7))|(z3*matrix(G_12))|(y3*matrix(G_15)); if type==2 then MM=matrix(G_0)|matrix(G_19)|matrix(G_23)|matrix(G_25)|matrix(G_26)|(z3*matrix(G_12))|(y3*matrix(G_12)); --the columns of the matrix MM are the vectors on which we have to apply the Reynolds operator in order to obtain a basis of the tangent space use(R); MM=substitute(lift(MM,RX),R); A1=sum(numColumns MM,l->t_l*substitute(transpose matrix(MM_l),R)); A1=matrix(mutableMatrix A1); --trick to kill the multidegree A1=substitute(reynolds(A1,1),R); if length A==1 then (A=A|{A1}); ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Computation of the obstruction map ------------------------------------------------------------------------------------------------------------------------------------------------------------------ kfinal=method(); --this routines takes and ideal Kn and an integer n and returns the subideal obtained by keeping the generators of degree at most n kfinal(Ideal,ZZ):= (Ideal) => (Kn,n) -> ( k=numgens(Kn)-1; liste=for i from 0 to k list (if (degree(Kn_i) > {0,n}) then continue; Kn_i); Kfinaln=ideal liste ; return substitute(Kfinaln,R); ); --here we construct some matrices wich will be useful in the routine "obs" Z=mutableMatrix(R,n1*n2,n2); for i from 0 to n1-1 do for j from 0 to n2-1 do Z_(plus(times(i,n2),j),j)=(A_0)_(0,i); T1= transpose matrix(Z); T2=transpose B_0; T3= T2|T1; Q2=image T3; Q1=super Q2; Q=Q1/Q2; h=inducedMap(Q,Q1); --here we have to be careful with the direction of the arrow: Q<--Q1, around 45 seconds --the next routine works with the lists of matrices A, B (defined above) and P (defined below) obs=method(); obs(ZZ):= (Ideal,Boolean) => (n) -> ( -- the n means that we are going to compute An, Bn and the ideal Kn bool=false; (q,r)=quotientRemainder(h*transpose P_(n-2),h*T3); rc=cover r; (mm,cc) = coefficients rc; Knp=ideal cc; K=kfinal(Knp,n); K=ideal mingens K; --to simplify the presentation of the ideal K Rnp=R/Knp; use(Rnp); PPn=transpose(P_(n-2))**Rnp; Sn=T3**Rnp; (X1,X2)=quotientRemainder(PPn,Sn); --X1 give us the matrices An and Bn, X2=0 is the rest X3=X1^{0..n1-1}; x4=mutableMatrix(Rnp,n1,n2); for i from 0 to n1-1 do for j from 0 to n2-1 do x4_(i,j)=X1_(plus(plus(n1,times(n2,i)),j),0); X5=matrix(x4); --X5 will be the matrix Bn if (length A)==n then A=A|{substitute(reynolds(lift(transpose X3,R),1),R)}; if (length B)==n then B=B|{substitute(reynolds(lift(X5,R),2),R)}; if ((sum(n+1,l->A_l)*sum(n+1,l->B_l))**(R/K))==0 then bool=true; return (K,bool); ); ------------------------------------------------------------------------------------------------------------------------------------------------------------------ --Computation of the universal invariant deformation ------------------------------------------------------------------------------------------------------------------------------------------------------------------ B1=(-(A_1*B_0)//A_0); if (length B)==1 then B=B|{substitute(reynolds(B1,2),R)}; P={}; --will contain the sum of products Ai*Bj required to compute the obstruction at each step if (length P)==0 then P=P|{-A_1*B_1}; n=2; --n is the integer such that (A0+...+An,B0+...+Bn) gives the universal deformation bb=false; if P_0==0 then bb=true; while not bb do ( (K,bb)=obs(n); if length P==n-1 then (P=P|{P_(n-2)-A_n*B_0-A_0*B_n-sum(n,l->A_(l+1)*B_(n-l))}); n=n+1; ); AA=sum(n,l->A_l); --the ideal K is such that RT/K is the base space of the universal invariant deformation --the image of the matrix AA in k[W] \otimes RT/K is the ideal of the universal subscheme ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------