Package $contrib/specvar /*-----[ suggestions for use: ]-----*\ Run CoCoA and type: Alias SV := $contrib/specvar; SV.About(); SV.Man(); \*--------------------------------------------*/ Alias SV := $contrib/specvar, Misc := $misc, SP := $sppoly, HP := $hp; Define About() PrintLn " Topic : Hilbert-Poincare series of special varieties Keywords: HilbertPoincare series, Veronese, Segre, Rees. Authors : A.M.Bigatti, L.Robbiano Version : CoCoA 4.1 Date : 18 April 2001 "; EndDefine; -- About ------[ help & examples ]-------- Define Man() PrintLn " Suggested alias for this package: Alias SV := $contrib/specvar; SYNTAX Ver(I: IDEAL, V: INT): IDEAL Segre(I1: IDEAL, I2: IDEAL): IDEAL Rees(I: IDEAL): IDEAL or Rees(L: LIST): IDEAL VerPoincare(I: IDEAL, V: INT): TAGGED('$hp.PSeries') SegrePoincare(I1: IDEAL, I2: IDEAL): TAGGED('$hp.PSeries') PowerPoincare(I: IDEAL, P: INT): TAGGED('$hp.PSeries') DESCRIPTION I, I1, I2 homogeneous ideals: Segre(I1, I2) Returns the ideal describing the Segre product of the two projective schemes defined by I1 and I2. Ver(I, V) Returns the ideal describing the Veronese embedding of order V of the projective scheme defined by I. Rees(L) Returns the ideal describing the Rees algebra defined by Ideal(L) with the relations y[J]-t*L[J]. Rees(I) Returns Rees(L), where L is given by Minimalized(I) VerPoincare, SegrePoincare, PowerPoincare Compute the Hilbert-Poincare series without computing the equations. >EXAMPLES< Alias SV := $contrib/specvar; -- proposed alias -- SEGRE -- R1 ::= Q[u,v,w]; R2 ::= Q[a,b,c,d]; I1 := R1 :: Ideal(uv,vw); I2 := R2 :: Ideal(d^5); SS := SV.Segre(I1, I2); Use Var(RingEnv(SS)); Poincare(CurrentRing()/SS); SV.SegrePoincare(I1, I2); SV.Hadamard(R1::Poincare(CurrentRing()/I1), R2::Poincare(CurrentRing()/I2)); -- SEPARATED ALGEBRAS -- Use R ::= Q[u,v,w, a,b,c,d]; I := Ideal(uv,vw, d^5, ua+vd); SV.PoincareOfSeparated(I,3); SV.PoincareDiagOfSeparated(I,3); -- VERONESE -- Use R ::= Q[x,y]; V := SV.Ver(4); V; -- Embedding of P^1 via quartics Var(RingEnv(V)):: Poincare(CurrentRing()/V); SV.VerPoincare(4); Use R ::= Z/(101)[x,y,z]; V := SV.Ver(Ideal(x^2,y^3), 4); V; Var(RingEnv(V)):: Poincare(CurrentRing()/V); SV.VerPoincare(Ideal(x^2,y^3), 4); -- REES -- Use R ::= Q[x[1..4]]; J := Ideal([ x[2]^2-x[3]^2, x[2]x[3]-x[2]x[4], x[3]x[4]^2-x[1]^2x[2]]); PS2 := Poincare(R/J^2); PS2; SV.PowerPoincare(J, 2); I := SV.Rees(J); I; PS := Var(RingEnv(I)) :: Poincare(CurrentRing()/I); SV.PSerPower(PS, 2); "; EndDefine; -- Man ------[ Main functions ]-------- --[ VERONESE EMBEDDING ]-- Define Ver(...) If Shape(ARGV) = [INT] Then I := Ideal(0); V := ARGV[1]; ElsIf Shape(ARGV) = [IDEAL, INT] Then I := ARGV[1]; V := ARGV[2]; Else Error("Ver: " + ERR.BAD_PARAMS); EndIf; Using Var(RingEnv(I)) Do Nx := NumIndets(); -- Var(RingEnv(I)) Ny := Bin(Nx+V-1, V); AuxRing := NewId(); Var(AuxRing) ::= CoeffRing[y[1..Ny] x[0..(Nx-1)]]; VerRing ::= CoeffRing[y[1..Ny]]; EndUsing; Using Var(AuxRing) Do Mon := Support( Sum(x)^V ); I2 := Ideal( [ y[J] - Mon[J] | J In 1..Len(Mon) ]); E := Elim(x, I2 + Image(I, RMap(x))); EndUsing; Result := VerRing :: SV.CanonicalImage(E); Destroy Var(AuxRing); Return Result; EndDefine; -- Ver Define VerPoincare(...) If Shape(ARGV) = [INT] Then I := Ideal(0); V := ARGV[1]; ElsIf Shape(ARGV) = [IDEAL, INT] Then I := ARGV[1]; V := ARGV[2]; Else Error("VerPoincare: " + ERR.BAD_PARAMS); EndIf; RE := RingEnv(I); PS := Var(RE) :: Poincare(CurrentRing()/I); Return SV.PSerVeronese(PS, V); EndDefine; -- VerPoincare --[ SEGRE PRODUCT ]-- Define Segre(I1, I2) If Shape([I1,I2])<>[IDEAL,IDEAL] Then Error("Segre: " + ERR.BAD_PARAMS) EndIf; N1 := NumIndets(Var(RingEnv(I1))); N2 := NumIndets(Var(RingEnv(I2))); AuxRing := NewId(); Using Var(RingEnv(I1)) Do Var(AuxRing) ::= CoeffRing[x[1..N1, 1..N2], y[1..N1], z[1..N2]]; SegreRing ::= CoeffRing[x[1..N1, 1..N2]]; EndUsing; Using Var(AuxRing) Do I3 := Ideal( [ x[C[1],C[2]] - y[C[1]]z[C[2]] | C In (1..N1)><(1..N2) ]); I := I3 + Image(I1, RMap(y)) + Image(I2, RMap(z)); E := Elim(y[1]..z[N2], I); EndUsing; Result := SegreRing :: SV.CanonicalImage(E); Destroy Var(AuxRing); Return Result; EndDefine; -- Segre Define SegrePoincare(I1, I2) If Shape([I1,I2]) <> [IDEAL, IDEAL] Then Error("SegrePoincare: " + ERR.BAD_PARAMS) EndIf; PS1 := Var(RingEnv(I1)) :: Poincare(CurrentRing()/I1); PS2 := Var(RingEnv(I2)) :: Poincare(CurrentRing()/I2); Return SV.Hadamard(PS1, PS2); EndDefine; -- SegrePoincare --[ SEPARATED ALGEBRA ]-- Define PoincareOfSeparated(I, N) If Type(I)<>IDEAL Then Error("PoincareOfSeparated: " + ERR.BAD_PARAMS) EndIf; Using Var(RingEnv(I)) Do NInd := NumIndets(); W := Mat[NewList(NInd, 1), Concat(NewList(N,1),NewList(NInd-N,0)), Concat(NewList(N,0),NewList(NInd-N,1))]; AuxRing := NewId(); Var(AuxRing) ::= CoeffRing[x[1..N],y[1..(NInd-N)]], Weights(W); EndUsing; PS := Var(AuxRing) :: Poincare(CurrentRing()/SV.CanonicalImage(I)); Destroy Var(AuxRing); PSNum := [ [ T[1], Tail(T[2]) ] | T In HP.Num(PS)]; PSDen := [ Tail(T) | T In HP.Den(PS)]; Return HP.Make(PSNum, PSDen); EndDefine; -- PoincareOfSeparated Define PoincareDiagOfSeparated(I, N) Return SV.PSerDiagOfSeparated(SV.PoincareOfSeparated(I, N)) EndDefine; -- PoincareDiagOfSeparated --[ REES ALGEBRA ]-- Define Rees(I) If Type(I)=IDEAL Then F := Gens(Minimalized(I)); ElsIf Type(I)=LIST Then F := I; Else Error("Rees: " + ERR.BAD_PARAMS) EndIf; Using Var(RingEnv(F[1])) Do N := NumIndets(); L := Concat(NewList(N,1), [ Deg(F[I])+1 | I In 1..Len(F)], [1]); AuxRing := NewId(); Var(AuxRing) ::= CoeffRing[x[1..N], y[1..Len(F)] t], Weights(L); M := Mat([ Concat(NewList(N,1), [ Deg(F[I]) | I In 1..Len(F)]), Concat(NewList(N,0), Concat(NewList(Len(F),1))) ]); ReesRing ::= CoeffRing[x[1..N], y[1..Len(F)]], Weights(M); EndUsing; Using Var(AuxRing) Do AuxF := SV.CanonicalImage(F); E := Elim(t, Ideal([ y[I] - AuxF[I]t | I In 1..Len(AuxF) ])); EndUsing; Result := ReesRing :: SV.CanonicalImage(E); Destroy Var(AuxRing); Return Result EndDefine; -- Rees Define PowerPoincare(I, P) If Shape([I,P])<>[IDEAL, INT] Then Error("PowerPoincare: " + ERR.BAD_PARAMS) EndIf; J := SV.Rees(I); PS := Var(RingEnv(J)) :: Poincare(CurrentRing()/J); Return SV.PSerPower(PS, P); EndDefine; -- PowerPoincare ------[ Auxiliary functions ]-------- Define CanonicalImage(X) T := Type(X); If T = IDEAL Then L := Gens(X) ElsIf T = LIST Then L := X ElsIf T = POLY Then L := [X] EndIf; RE := RingEnv(L[1]); NFrom := NumIndets(Var(RE)); NTo := NumIndets(); If NFrom >= NTo Then MapList := 1..NTo Else MapList := Concat(1..NFrom, NewList(NTo-NFrom,0)) EndIf; L := [$builtin.Map(X, RE, RingEnv(), MapList) | X In L]; If T = IDEAL Then Return Ideal(L) ElsIf T = LIST Then Return L ElsIf T = POLY Then Return L[1] EndIf; EndDefine; -- CanonicalImage --[ VERONESE EMBEDDING ]-- Define PSerVeronese(PS, V) Using Qt Do PS := HP.Simplified(PS); Num := HP.NumToPoly(PS); DenDeg := Len(HP.Den(PS)); Prod := Num*((1-t^V)/(1-t))^DenDeg; NewNum := Sum([ LC(M) * t^(Deg(M)/V) | M In Monomials(Prod) And $builtin.Mod(Deg(M), V)=0]); Return HP.PSeries(NewNum, DenDeg); EndUsing; EndDefine; -- PSerVeronese --[ SEGRE PRODUCT ]-- Define Regularity(PS) SPS := HP.Simplified(PS); Return SP.Deg(HP.Num(SPS)) - Len(HP.Den(SPS)) + 1; EndDefine; -- Regularity Define RegInd(PS) Return SP.Deg(HP.Num(PS)) - Len(HP.Den(PS)) + 1; EndDefine; -- RegInd Define Hadamard(PS1, PS2) DIM := HP.PSerDim(PS1) + HP.PSerDim(PS2) - 1; DEG := Max(SV.RegInd(PS1), SV.RegInd(PS2)) + DIM - 1; H1 := HP.PSerHilbert(PS1); H2 := HP.PSerHilbert(PS2); H := Concat([1],[ HP.EvalHilbertFn(H1,D)*HP.EvalHilbertFn(H2,D) | D In 1..DEG ]); P := Qt :: Sum([ H[I]t^(I-1) | I In 1..Len(H) ]) * (1-t)^DIM; Return Qt :: HP.PSeries(NR(P,[t^(DEG+1)]), DIM) EndDefine; -- Hadamard --[ SEPARATED ALGEBRA ]-- Define Diag1(N1,N2) ---- Diag( 1 / ((1-a)^N1*(1-b)^N2) ) Return Sum([Bin(N1-1,I)*Bin(N2-1,I)*t^I | I In 0..Min(N1-1,N2-1)])/(1-t)^(N1+N2-1); EndDefine; -- Diag1 Define Diag2(M1,M2, N1,N2) ---- Diag( a^M1*b^M2 / ((1-a)^N1*(1-b)^N2) ) If M1>M2 Then S := M1-M2-1; Return t^M1*Sum([ Bin(N2-K+S,S)*SV.Diag1(N1,K) | K In 1..N2]); EndIf; If M1