// Functions used in paper 8:
// _Support varieties for modules_ by Jon F. Carlson
// Section 2: Notes on projectivity
IsProjective := function(M, B, n)
V := VectorSpace(BaseRing(B[1]), Dimension(M));
S := &+[ sub< V | RowSpace(x) > : x in B ];
if (Dimension(M) - Dimension(S))*n eq Dimension(M) then
return true;
end if;
return false;
end function;
LeftProjectiveStrip := function(M, G)
MM := Restriction(M, G);
repeat
flag := true;
for i := 1 to 5 do
a := Random(MM);
SM := sub< MM | a >;
if Dimension(SM) eq #G then
MM := quo< MM | SM >;
flag := false;
break;
end if;
end for;
until flag;
return MM;
end function;
// Section 4: Finding points on the variety
DimensionOfVariety := function(M, G, num)
phi := Representation(M);
n := Ngens(G);
dim := Dimension(M);
ff := ext< CoefficientRing(M) | 6 >;
NM := ExtendField(M, ff);
V := VectorSpace(ff, n);
MA := MatrixAlgebra(ff, dim);
newmatlist := [ MA!Representation(NM)(G.i) - Id(MA) : i in [1..n] ];
for r := 1 to n do
g := AbelianGroup(GrpPerm, [ 2 : i in [1..r] ]);
RRL := [ ];
flag := true;
for j := 1 to num do
a := [ Random(V) : i in [1..r] ];
mmmlist := [ Id(MA) + &+[ a[i][j]*newmatlist[j] :
j in [1..n] ] : i in [1..r] ];
mmm := GModule(g, mmmlist);
str := LeftProjectiveStrip(mmm, g);
if Dimension(str) eq 0 and r lt n then
flag := false;
break j;
end if;
if Dimension(str) eq 0 and r eq n then
return g, [ ], newmatlist;
end if;
RRL := Append(RRL, );
if #RRL eq 8 and r eq 1 then
return g, RRL, newmatlist;
end if;
end for;
if flag then
return g, RRL, newmatlist;
end if;
end for;
end function;
StandardForm := function(M)
r := Ngens(Group(M));
id := MatrixAlgebra(BaseRing(M), Dimension(M))!1;
LL := [ ActionGenerator(M, i) - id : i in [1..r] ];
W := sub< M | &cat[ &cat[ Basis(RowSpace(LL[i]*LL[j])) :
j in [1..i] ]: i in [1..r-1] ] >;
MM := quo< M | W >;
idd := MatrixAlgebra(BaseRing(MM), Dimension(MM)) ! 1;
Rad := sub< MM | &cat[ Basis(RowSpace(ActionGenerator(MM, i) - idd)) :
i in [1..r-1] ] >;
Gen := [ MM ! ExtendBasis(Rad, MM)[i] :
i in [ Dimension(Rad)+1 .. Dimension(MM) ] ];
Bas := Gen cat &cat[ [ x*ActionGenerator(MM, i) - x : x in Gen ] :
i in [1..r-1] ];
b := Matrix(Dimension(MM), Dimension(MM), [ Vector(x) : x in Bas ]);
NL := [ b*ActionGenerator(MM, i)*b^-1 : i in [1..r] ];
return NL;
end function;
PointsOnVariety := function(M)
G := Group(M);
PL := [ ];
BL := [ ];
Npoints := 2^Ngens(G)*(Dimension(M) div #G + 1) + 20;
GG, vl, ACT := DimensionOfVariety(M, G, Npoints);
r := Ngens(GG);
if r eq 1 then
return [ ], 0, 0;
end if;
ff := CoefficientRing(vl[1][2]);
if Dimension(vl[1][2]) eq 0 then
return [0], Ngens(G), 0;
end if;
mini := Minimum([ Dimension(x[2]) : x in vl ]);
w := mini div (2^(r-1));
for x in vl do
mm := x[2];
if Dimension(mm) eq mini then
bool := IsProjective(mm, [ ActionGenerator(mm, i)
- MatrixAlgebra(ff, mini) ! 1 : i in [1..r-1] ], 2^(r-1));
if bool then
SF := StandardForm(mm);
blocks := [ Submatrix(SF[r], 1, w*i + 1, w, w) : i in [1..r-1] ];
minpolys := [ MinimalPolynomial(y) : y in blocks ];
Append(~PL, );
Append(~BL, blocks);
end if;
end if;
end for;
degrees := [ Degree(Factorization(PL[i][2][j])[k][1]) : k in
[1..#Factorization(PL[i][2][j])], j in [1..#PL[i][2]], i in [1..#PL] ];
xd := LCM(degrees);
if xd eq 1 then
RL := [ : i in [1..#PL] ];
NPL := PL;
fff := ff;
else
NPL:= [ ];
RL := [ ];
fff, gamma := ext< ff | xd >;
VV := VectorSpace(fff, Ngens(G));
Q := PolynomialRing(fff);
for i := 1 to #PL do
npl := <[ VV ! a : a in PL[i][1] ], [ Q!f : f in PL[i][2] ]>;
Append(~NPL, npl);
rl := ;
Append(~RL, rl);
end for;
end if;
VL1 := [ ];
for w in RL do
rt := w[2];
rl := [ [ rt[j][k][1] : k in [1..#rt[j]] ] : j in [1..#rt] ];
if #rl eq 1 then
RL1 := [ [x,1] : x in rl[1] ];
else
RL1 := [ [x] : x in rl[1] ];
for i := 2 to #rl do
RL1 := [ Append(x, y) : x in RL1, y in rl[i] ];
end for;
RL1 := [ Append(x, 1) : x in RL1 ];
end if;
RL2 := [ &+[ w[1][j]*RL1[k][j] : j in [1..r] ] : k in [1..#RL1] ];
VL1 := VL1 cat RL2;
end for;
VL := [ ]; m := Nrows(ACT[1]);
if xd gt 1 then
NACT := [ MatrixAlgebra(fff, m) ! x : x in ACT ];
else
NACT := ACT;
end if;
for w in VL1 do
MAT := &+[ w[i]*NACT[i] : i in [1..Ngens(G)] ];
if 2*Rank(MAT) lt m then
Append(~VL, w);
end if;
end for;
return VL, r-1, w;
end function;
// Section 5: Computing the variety from a set of points
VarietyPolynomials := function(P, pts, deg)
V := Parent(pts[1]);
F := CoefficientField(V);
Mons := MonomialsOfDegree(P, deg);
M := RMatrixSpace(F, #Mons, #pts);
phi := [ hom< P -> F | ElementToSequence(pts[i]) > : i in [1..#pts] ];
A := M ! &cat[ [ phi[i](Mons[j]) : i in [1..#pts], j in [1..#Mons] ] ];
_, Null := Solution(A, Zero(VectorSpace(F, #pts)));
return [ &+[ Basis(Null)[j][i] * Mons[i] :
i in [1.. #Mons] ] : j in [1..Dimension(Null)] ];
end function;
SupportVariety := function(M)
G := Group(M);
MM := LeftProjectiveStrip(M, G);
if Dimension(MM) eq 0 then
P := PolynomialRing(CoefficientRing(M), Ngens(G));
return [ P.i: i in [1..Rank(P)] ], P;
end if;
pts, codim, deg := PointsOnVariety(MM);
if #pts eq 0 then
P := PolynomialRing(CoefficientRing(M), Ngens(G));
return [ ], P;
end if;
s := Ngens(G);
ff := BaseRing(pts[1]);
P := PolynomialRing(ff, s);
POLS := &cat[ VarietyPolynomials(P, pts, t) : t in [1..deg] ];
I := ideal< P | POLS >;
Groebner(I);
B := Basis(I);
dd := [ TotalDegree(B[j]) : j in [1..#B] ];
flag := true;
MinGens := [ ];
for i := 1 to #Basis(I) do
a,b := Minimum(dd);
if flag then
II := ideal< P | MinGens >;
end if;
if B[b] notin II then
Append(~MinGens, B[b]);
flag := true;
else
flag := false;
end if;
Remove(~B, b);
Remove(~dd, b);
end for;
variables := [ "z", "y", "x", "w", "v", "u", "t", "s" ];
AssignNames(~P, [ variables[i] : i in [1..Rank(P)] ]);
return MinGens, P;
end function;
// Section 6: Varieties of truncated syzygy modules
SyzygyModule := function(M, FM)
r := Dimension(M) - Dimension(JacobsonRadical(M));
F, _, prj := DirectSum([ FM : i in [1..r] ]);
Hom := GHom(FM, M);
flag := true;
while flag do
lf := [ Random(Hom) : i in [1..r] ];
f := &+[ MapToMatrix(prj[i])*lf[i] : i in [1..r] ];
if Rank(f) eq Dimension(M) then
flag := false;
end if;
end while;
OM := Kernel(f);
return OM;
end function;