Skip to content

Commit

Permalink
Add new intrinsic SubspaceProcess
Browse files Browse the repository at this point in the history
This new intrinsic allows us to iterate over subspaces of a (finite) 
vector space having fixed dimension
  • Loading branch information
mjrodgers committed Oct 28, 2022
1 parent 3708b9f commit fb33daa
Showing 1 changed file with 132 additions and 0 deletions.
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 fb33daa

Please sign in to comment.