You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added function Filter Formspace to compute Symmetric/Symplectic/Hermitian matrices: TODO: The case of characteristic two is still open for hermitian matrices and probably very poorly implemented for symmetric matrices
# #! @Returns a basis of the formspace preserved by <A>group</A> modulo <A>scalars</A> consisting of bilinear forms if <A>unitary = false</A> and unitary forms if <A>unitary = true</>
3
1
DeclareOperation("PreservedFormspace", [IsMatrixGroup, IsVector and IsFFECollection, IsBool]);
# Evaluates the univariate polynomial p (given as coefficients) in the matrix g \in F^{n\times n}. frob_base = FrobeniusNormalForm(g) must be satisfied and frob_base_inv = Inverse(FrobeniusNormalForm(g)[2]). The reason these two parameters are given, and not computed in the function itself is to not compute FrobeniusNormalForm(g) multiple times when evaluating multiple polynomials in g.
112
122
__FORMSPACE__INTERNAL__EvaluatePolynomialWithFrobenius:=function(p, g, frob_base, frob_base_inv, F, n) # frob_base_inv useless, right now this is not actually evaluating the polynomial frob_base_inv missing
CloseMutableBasis(symplectic_base, form - transposed_form);
314
+
od;
315
+
316
+
# this does not create compressed matrices, rather it returns lists consisting of compressed vectors... TODO: investigate how MutableBasis works on the inside, and maybe change it to use compressed matrices since they are faster to deal with
if Size(symmetric_base_vecs) + Size(symplectic_base_vecs) <> Size(Forms) then
321
+
Error("This should not have happend!! there are supposedly ", Size(symmetric_base_vecs), " linearly independent symmetric forms and ", Size(symplectic_base_vecs), " linearly independent symplectic forms, yet the dimension of the formspace is ", Size(Forms), "\n");
# TODO: ignore the diagonal entries for the symmetric matrices, for symplectic these need to be zero.
327
+
# TODO: solve this in some efficient way that does not formulate this by solving sets of linear equations of matrices. Instead it would be better to gradually consider entries of the matrices. Then use some heuristic to determine we are done and just check wether the resulting matrices are infact symmetric. this should be faster because now worst case we are solving a system of linear equations that consists of n^2 equations and Size(Forms) indeterminates.
328
+
# TODO: maybe do these todos for all characteristics the nice thing about the current algorithm for char F <> 2 is that we do not have to solve many systems of equations, rather just check wether we have the zero matrix
329
+
330
+
char_2_eqs :=[];
331
+
for form in Forms do
332
+
Add(char_2_eqs, __FORMSPACE__INTERNAL__MatrixReorganize(form - TransposedMat(form), n, F, n));
333
+
od;
334
+
sol := NullspaceMatDestructive(char_2_eqs);
335
+
out :=[];
336
+
for form in sol do
337
+
Add(out, __FORMSPACE__INTERNAL__VectorReorganize(form, n, F, n));
338
+
od;
339
+
return out;
239
340
end;
240
341
241
342
# tries to filter the F = GF(q^2) vectorspace generated by <Forms> and return the GF(q) vector space A such that A = <Forms> \cap B where B = {A \in F^{n\times n}, A* = A} TODO: THIS NEEDS SOME FURTHER INVESTIGATION
242
343
# there must be a better way to compute these matrices..
243
344
__FORMSPACE__INTERNAL__FilterUnitaryForms:=function(Forms, F, n, hom)
244
-
local i, j, ent, q, half, O, l, FF, p, tr_form, Base, baseVecs;
345
+
local i, j, ent, q, half, O, l, FF, p, tr_form, Base, baseVecs, gf_base;
245
346
if Size(Forms) =0then
246
347
return[];
247
348
fi;
@@ -257,7 +358,7 @@ __FORMSPACE__INTERNAL__FilterUnitaryForms := function(Forms, F, n, hom)
257
358
return[];
258
359
fi;
259
360
260
-
return[HermitianFormByMatrix(Forms[1]* l, F)];
361
+
return[Forms[1]* l];
261
362
fi;
262
363
# this is where it gets interesting
263
364
# Print("ahhh this needs work!\n");
@@ -267,31 +368,45 @@ __FORMSPACE__INTERNAL__FilterUnitaryForms := function(Forms, F, n, hom)
267
368
268
369
## we use (A + A*) is a hermitian form if gAg* = A the problem here is that for A, B such that gA*g = A and gB*g = B we may loose information namely it may be the case that 1/2 (A + A*) = c/2 (B + B*) this is annoying.... one thing one could do is check whether these matrices <1/2 (A + A*), 1/2 (B + B*), ...> are lineraly independent. if that is the case, we know that all forms must have been found (but do we???). but what if not? then there might be another form... this is annoying. Then we may add matrices A, B and so on such that <C1,C2, ., D1, D2..> is a basis of F where C1 and so on are hermitian and D1, D2 and so on are not. We may write D1 = A + B where A is hermitian and B is not. we can then try to write B in terms of the other matrices??? does this help... idk :(
269
370
## for char = 2 this can be a bad idea as it can make the diagonal disaapear.. oh well
270
-
Base := MutableBasis(F, [NullMat(n, n, F)]);
271
-
for FF in Forms do
272
-
l := __FORMSPACE__INTERNAL__ScalarFormIdentifyCheck(FF, F, n, hom, p, q);
273
-
if l =failthen
371
+
if Characteristic(F) mod2<>0then
372
+
Base := MutableBasis(F, [NullMat(n, n, F)]);
373
+
gf_base := BasisVectors(Basis(GF(GF(q), 2)))[2];
374
+
for FF in Forms do
375
+
Add(FF, gf_base * FF);
376
+
od;
377
+
for FF in Forms do
378
+
# l := __FORMSPACE__INTERNAL__ScalarFormIdentifyCheck(FF, F, n, hom, p, q);
379
+
# if l = fail then
274
380
tr_form := TransposedMat(FF^hom);
275
381
CloseMutableBasis(Base, FF + tr_form);
276
-
else
277
-
CloseMutableBasis(Base, l * FF);
278
-
fi;
279
-
od;
382
+
#else
383
+
#CloseMutableBasis(Base, l * FF);
384
+
#fi;
385
+
od;
280
386
281
-
O :=[];
282
-
baseVecs := ImmutableBasis(Base);
283
-
for FF in baseVecs do
284
-
Add(O, HermitianFormByMatrix(FF, F));
285
-
od;
387
+
O :=[];
388
+
baseVecs := ImmutableBasis(Base);
389
+
#for FF in baseVecs do
390
+
#Add(O, HermitianFormByMatrix(FF, F));
391
+
#od;
286
392
287
-
if Size(O) = Size(Forms) then
288
-
return O;
289
-
fi;
393
+
# if Size(O) = Size(Forms) then
394
+
# return O;
395
+
# fi;
396
+
# if Size(baseVecs) = Size(Forms) then
397
+
# return baseVecs;
398
+
# fi;
290
399
291
-
Print("Could not find a basis of Forms. Returned hermitian Forms, Bigger space of matrices that contains all possible hermitian forms. \n");
292
-
return[O, Forms];
400
+
return BasisVectors(baseVecs);
401
+
fi;
402
+
Print("char 2 case is missing!!");
403
+
# # TODO this function definetly needs work!!!
404
+
# Print("Could not find a basis of hermitian Forms. Returned hermitian Forms and a Bigger space of matrices that contains all possible hermitian forms. \n");
405
+
# return [baseVecs, Forms];
293
406
end;
294
407
408
+
409
+
295
410
# Compute the formspace for cyclic matrix group. TODO!!
#! @Returns basis of the spaces of symmetric/symplectic matrices or a basis of the hermitian matrices contained in Forms
652
+
#! @Description
653
+
#! In the case where unitary is false, this will return a list that contains to lists of matrices. The first is a basis of the symmetric matrices, the second is a basis of the symplectic matrices. Be carefull: If the characteristic of the field is 2, then symplectic matrices and symmetric matrices are the same. Hence only one basis will be returned. If unitary is false this will return a basis of the hermitian matrices.
654
+
#! The reason the the field must be given as an argument, is so that the Field automorphims of order two, which is used to compute the adjoined, is specified.
655
+
InstallMethod(FilterFormspace, "for list of matrices, F finite field, bool hermitian", [IsList, IsFinite and IsField, IsBool], function(Forms, F, unitary)
656
+
local n, hom, p_exponent;
657
+
if Size(Forms) =0then
658
+
return[];
659
+
fi;
660
+
n := NrRows(Forms[1]);
661
+
662
+
if Size(Forms) = n^2then
663
+
# TODO: special case where we should just return a precomputed basis...
0 commit comments