Skip to content

Commit

Permalink
Merge pull request #2 from mjrodgers/develop
Browse files Browse the repository at this point in the history
New SubspaceProcess intrinsic
  • Loading branch information
mjrodgers authored Oct 28, 2022
2 parents 01e6806 + fb33daa commit f862283
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 3 deletions.
2 changes: 1 addition & 1 deletion FiniteGeometry/ClassificationTools.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Tools for classifying objects based on isomorphism testing.


intrinsic CanonicalVertexSet(S::Set, Gr::Graph) -> SetEnum
intrinsic CanonicalVertexSet(S::Set, Gr::Grph) -> SetEnum
{ Takes a set S of vertices of a graph Gr, returns a canonically isomorphic set of vertices. }
require S subset VertexSet(Gr): "S must be a set of vertices of Gr.";
AssignLabels(~Gr, {@ v : v in S @}, [1 : i in [1..#S]]);
Expand Down
7 changes: 5 additions & 2 deletions FiniteGeometry/MatrixTools.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ intrinsic IncidenceMatrix(S::SetEnum, I::Map) -> AlgMatElt, SetEnum
return IncidenceMatrix(S,I), S;
end intrinsic;


// TODO: there is no reason that we need P1 and P2 to be ordered, they are simply partitions.
// we can just order them arbitrarily.
// TODO: We should check that they actually partition the row/column sets though.
intrinsic TDColSumMatrix(M::Mtrx,P1::SeqEnum[SetEnum],P2::SeqEnum[SetEnum]) -> Mtrx, Map
{ P1 partitions the rows, P2 partitions the columns, returns column sum matrix }
R := CoefficientRing(M);
V := RSpace(R, Nrows(M));
CSelMat := Matrix(R, Ncols(M), #P2, [<Rep(P2[i]), i, 1> : i in [1..#P2]]);
CSumMat := Matrix([CharacteristicVector(V,r) : r in P1]);
return CSumMat*(M*CSelMat), map< RSpace(R, #P1) -> V | v :-> v*CSumMat>;
return CSumMat*(M*CSelMat),
hom< RSpace(R, #P1) -> V | [v*CSumMat : v in Basis(RSpace(R, #P1))]>;
end intrinsic;


Expand Down
132 changes: 132 additions & 0 deletions FiniteGeometry/SubsetProcess.m
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,135 @@ intrinsic SubsetProcess(S::SetEnum, k::RngIntElt) -> Process
requirerange k, 0, #S;
return SubsetProcess(SetToIndexedSet(S), k);
end intrinsic;



// For subspaces:

// Takes an integer Q. returns a sequence of Fq elements.
function qAry(Q,q)
F := FiniteField(q);
d := Degree(F);
p := #BaseField(F);

// Do we want to allow empty sequence as a result?
// if not, we should use a do->until
S := [];
while Q ne 0 do
R := Q mod p;
Q := Q div p;
Append(~S,R);
end while;

if (#S mod d) ne 0 then
S cat:= [0 : i in [1..((-#S) mod d)]];
end if;

S2 := [F|];
for i in [1..(#S div d)] do
s2 := S[(i-1)*d + 1 .. i*d];
Append(~S2, F!s2);
end for;
return S2;
end function;

function MapFunc(n, q, S)
F := FiniteField(q);
k := #S;
positions := [ [i,j] : i in [1..k], j in [1..n] | j gt S[i] and not j in S];
function f( u)
u := qAry(u, q);
u cat:= [0 : i in [1..#positions - #u]];
K := Matrix(F, k, n, [<i,j, x >
where i,j is Explode(positions[c])
where x is u[c] : c in [1..#positions]]);
for c in [1..k] do
K[c,S[c]] := 1;
end for;

return RowSpace(K);
end function;

return f, q^(#positions)-1;
end function;



intrinsic InternalSubspaceProcessIsEmpty(p::Tup) -> BoolElt
{Returns true iff the transitive group process has passed its last group}
return IsEmpty(p[2]);
end intrinsic;

intrinsic InternalNextSubspace(~p::Tup)
{Moves the subset process tuple p to its next subset}
error if InternalSubspaceProcessIsEmpty(p), "Process finished";
if p[3][2] ge p[3][3] then
Advance(~(p[2]));
if IsEmpty(p[2]) then
p[3][1] := {@ @};
p[3][2] := 0;
p[3][3] := -1;
else
p[3][1] := Sort(SetToIndexedSet(Current(p[2])));
p[3][2] := 0;
f, M := MapFunc(Dimension(p[1]), #CoefficientField(p[1]), p[3][1]);
p[3][3] := M;
p[4] := f;
end if;
else
p[3][2] +:= 1;
end if;
end intrinsic;





intrinsic InternalExtractSubspace(p::Tup) -> { }
{Returns the current subset of the transitive group process tuple p}
error if InternalSubspaceProcessIsEmpty(p), "Process finished";
// I will contain ordered pair: k-set, and an integer
// Do we need to coerce the subspace to be in U?
// U := p[1];
// q := #CoefficientField(U);
I := p[3];
phi := p[4];

return phi(I[2]);
end intrinsic;

intrinsic InternalExtractSubspaceLabel(p::Tup) -> RngIntElt, SetEnum
{Returns the index of the current subset, along with the parent set.}
error if InternalSubspaceProcessIsEmpty(p), "Process finished";
return p[3];
end intrinsic;



intrinsic SubspaceProcess(U::ModTupFld, k::RngIntElt) -> Process
{Gives a process for iterating through all subsets from a set of size n having size k.}
require IsFinite(CoefficientField(U)): "Coefficient field must be finite.";
requirerange k, 0, Dimension(U);
n := Dimension(U);
Fq := CoefficientField(U);
Fp := BaseField(Fq);


P1 := SubsetProcess(n,k);
S := Sort(SetToIndexedSet(Current(P1)));
f, M := MapFunc(n,#Fq, S);
I := <S, 0, M>;

info := <U, P1, I, f>;

P := InternalCreateProcess(
"Subspace",
info,
InternalSubspaceProcessIsEmpty,
InternalNextSubspace,
InternalExtractSubspace,
InternalExtractSubspaceLabel
);

return P;
end intrinsic;

0 comments on commit f862283

Please sign in to comment.