Quelle alco.gi
Sprache: unbekannt
|
|
# This file belongs to ALCO: Tools for Algebraic Combinatorics.
# Copyright (C) 2024, Benjamin Nasmith
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see < https://www.gnu.org/licenses/>.
# Cyclotomic tools
BindGlobal( "EisensteinIntegers", Objectify( NewType(
CollectionsFamily(CyclotomicsFamily),
IsEisensteinIntegers and IsAttributeStoringRep ),
rec() ) );
SetLeftActingDomain( EisensteinIntegers, Integers );
SetName( EisensteinIntegers, "EisensteinIntegers" );
SetString( EisensteinIntegers, "EisensteinIntegers" );
SetIsLeftActedOnByDivisionRing( EisensteinIntegers, false );
SetSize( EisensteinIntegers, infinity );
SetGeneratorsOfRing( EisensteinIntegers, [ E(3) ] );
SetGeneratorsOfLeftModule( EisensteinIntegers, [ 1, E(3) ] );
SetIsFinitelyGeneratedMagma( EisensteinIntegers, false );
SetUnits( EisensteinIntegers, Set([ -1, 1, -E(3), E(3), -E(3)^2, E(3)^2 ] ));
SetIsWholeFamily( EisensteinIntegers, false );
InstallMethod( \in,
"for Eisenstein integers",
IsElmsColls,
[ IsCyc, IsEisensteinIntegers ],
function( cyc, EisensteinIntegers )
return IsCycInt( cyc ) and 3 mod Conductor( cyc ) = 0;
end );
InstallMethod( IsEisenInt,
"for cyclotomics",
[ IsCyc ],
function(x)
return x in EisensteinIntegers;
end);
InstallMethod( Basis,
"for Eisenstein integers (delegate to `CanonicalBasis')",
[ IsEisensteinIntegers ], CANONICAL_BASIS_FLAGS,
CanonicalBasis );
InstallMethod( CanonicalBasis,
"for Eisenstein integers",
[ IsEisensteinIntegers ],
function( EisensteinIntegers )
local B;
B:= Objectify( NewType( FamilyObj( EisensteinIntegers ),
IsFiniteBasisDefault
and IsCanonicalBasis
and IsCanonicalBasisEisensteinIntegersRep ),
rec() );
SetUnderlyingLeftModule( B, EisensteinIntegers );
SetIsIntegralBasis( B, true );
SetBasisVectors( B, Immutable( [ 1, E(3) ] ) );
B!.conductor:= 3;
B!.zumbroichbase := [ 0, 1 ];
# Return the basis.
return B;
end );
InstallMethod( Coefficients,
"for the canonical basis of Eisenstein integers",
[ IsCanonicalBasisEisensteinIntegersRep,
IsCyc ], 0,
function( B, v )
return Coefficients(Basis(CF(3), BasisVectors(B)), v);
end );
BindGlobal( "KleinianIntegers", Objectify( NewType(
CollectionsFamily(CyclotomicsFamily),
IsKleinianIntegers and IsAttributeStoringRep ),
rec() ) );
SetLeftActingDomain( KleinianIntegers, Integers );
SetName( KleinianIntegers, "KleinianIntegers" );
SetString( KleinianIntegers, "KleinianIntegers" );
SetIsLeftActedOnByDivisionRing( KleinianIntegers, false );
SetSize( KleinianIntegers, infinity );
SetGeneratorsOfRing( KleinianIntegers, [ 1, EB(7) ] );
SetGeneratorsOfLeftModule( KleinianIntegers, [ 1, EB(7) ] );
SetIsFinitelyGeneratedMagma( KleinianIntegers, false );
SetUnits( KleinianIntegers, Set([ -1, 1 ] ));
SetIsWholeFamily( KleinianIntegers, false );
InstallMethod( IsKleinInt,
"for cyclotomics",
[ IsCyc ],
function(x)
if DegreeOverPrimeField(Field(Union(Basis(KleinianIntegers), [x]))) > 2 then
return false;
fi;
return ForAll(Coefficients(Basis(KleinianIntegers), x), IsInt);
end);
InstallMethod( \in,
"for Kleinian integers",
IsElmsColls,
[ IsCyc, IsKleinianIntegers ],
function( cyc, KleinianIntegers )
return IsKleinInt( cyc );
end );
InstallMethod( Basis,
"for Kleinian integers (delegate to `CanonicalBasis')",
[ IsKleinianIntegers ], CANONICAL_BASIS_FLAGS,
CanonicalBasis );
InstallMethod( CanonicalBasis,
"for Kleinian integers",
[ IsKleinianIntegers ],
function( KleinianIntegers )
local B;
B:= Objectify( NewType( FamilyObj( KleinianIntegers ),
IsFiniteBasisDefault
and IsCanonicalBasis
and IsCanonicalBasisKleinianIntegersRep ),
rec() );
SetUnderlyingLeftModule( B, KleinianIntegers );
SetIsIntegralBasis( B, true );
SetBasisVectors( B, Immutable( [ 1, EB(7) ] ) );
return B;
end );
InstallMethod( Coefficients,
"for the canonical basis of IcosianRing",
[ IsCanonicalBasisKleinianIntegersRep,
IsCyc ], 0,
function( B, v )
return Coefficients(Basis(Field(EB(7)), BasisVectors(B)), v);
end );
# Quaternion tools
InstallMethod( Trace,
"for a quaternion",
[ IsQuaternion and IsSCAlgebraObj ],
quat -> ExtRepOfObj(quat + ComplexConjugate(quat))[1]
);
InstallMethod( Norm,
"for a quaternion",
[ IsQuaternion and IsSCAlgebraObj ],
quat -> ExtRepOfObj(quat*ComplexConjugate(quat))[1]
);
BindGlobal( "QuaternionD4Basis", Basis(QuaternionAlgebra(Rationals),
List([ [ -1/2, -1/2, -1/2, 1/2 ],
[ -1/2, -1/2, 1/2, -1/2 ],
[ -1/2, 1/2, -1/2, -1/2 ],
[ 1, 0, 0, 0 ] ], x -> ObjByExtRep(FamilyObj(One(QuaternionAlgebra(Rationals))),x)
)) );
BindGlobal( "HurwitzIntegers", Objectify( NewType(
CollectionsFamily(FamilyObj(QuaternionAlgebra(Rationals))),
IsHurwitzIntegers and IsRingWithOne and IsQuaternionCollection and IsAttributeStoringR ep ),
rec() ) );
SetLeftActingDomain( HurwitzIntegers, Integers );
SetName( HurwitzIntegers, "HurwitzIntegers" );
SetString( HurwitzIntegers, "HurwitzIntegers" );
SetIsLeftActedOnByDivisionRing( HurwitzIntegers, false );
SetSize( HurwitzIntegers, infinity );
SetGeneratorsOfRing( HurwitzIntegers, AsList(QuaternionD4Basis));
SetGeneratorsOfLeftModule( HurwitzIntegers, AsList(QuaternionD4Basis) );
SetIsWholeFamily( HurwitzIntegers, false );
SetIsAssociative( HurwitzIntegers, false );
InstallMethod( Units,
"For Hurwitz integers",
[ IsHurwitzIntegers ],
function(O)
return Closure(Basis(O), \*);
end);
InstallMethod( IsHurwitzInt,
"for Quaternions",
[ IsQuaternion ],
function(x)
return ForAll(Coefficients(Basis(HurwitzIntegers), x), IsInt);
end);
InstallMethod( \in,
"for integers",
[ IsQuaternion, IsHurwitzIntegers ], 10000,
function( n, Integers )
return IsHurwitzInt( n );
end );
InstallMethod( Basis,
"for Hurwitz integers (delegate to `CanonicalBasis')",
[ IsHurwitzIntegers ], CANONICAL_BASIS_FLAGS,
CanonicalBasis );
InstallMethod( CanonicalBasis,
"for Hurwitz integers",
[ IsHurwitzIntegers ],
function( HurwitzIntegers )
local B;
B:= Objectify( NewType( FamilyObj( HurwitzIntegers ),
IsFiniteBasisDefault
and IsCanonicalBasis
and IsQuaternionCollection
and IsCanonicalBasisHurwitzIntegersRep ),
rec() );
SetUnderlyingLeftModule( B, HurwitzIntegers );
SetIsIntegralBasis( B, true );
SetBasisVectors( B, Immutable( BasisVectors(QuaternionD4Basis)));
# Return the basis.
return B;
end );
InstallMethod( Coefficients,
"for the canonical basis of HurwitzIntegers",
[ IsCanonicalBasisHurwitzIntegersRep,
IsQuaternion ], 0,
function( B, v )
return SolutionMat(List(B, ExtRepOfObj), ExtRepOfObj(v));
end );
# Icosian and Golden Field Tools
InstallGlobalFunction( GoldenModSigma, function(q)
# Check that q belongs to the quadratic field containing Sqrt(5).
if not q in NF(5,[1,4]) then return fail; fi;
# Compute the coefficients in the basis [1,(1-Sqrt(5))/2] and return the 1 coefficient.
return Coefficients(Basis(NF(5,[1,4]), [1, (1-Sqrt(5))/2]), q)[1];
end );
BindGlobal( "IcosianH4Generators", Basis(QuaternionAlgebra(Field(Sqrt(5))),
List([ [ 0, -1, 0, 0 ],
[ 0, -1/2*E(5)^2-1/2*E(5)^3, 1/2, -1/2*E(5)-1/2*E(5)^4 ],
[ 0, 0, -1, 0 ],
[ -1/2*E(5)-1/2*E(5)^4, 0, 1/2, -1/2*E(5)^2-1/2*E(5)^3 ] ],
x -> ObjByExtRep(FamilyObj(One(QuaternionAlgebra(Field(Sqrt(5))))),x)
)) );
BindGlobal( "IcosianRing", Objectify( NewType(
CollectionsFamily(FamilyObj(QuaternionAlgebra(Rationals))),
IsIcosianRing and IsRingWithOne and IsQuaternionCollection and IsAttributeStoringRep ),
rec() ) );
SetLeftActingDomain( IcosianRing, Integers );
SetName( IcosianRing, "IcosianRing" );
SetString( IcosianRing, "IcosianRing" );
SetIsLeftActedOnByDivisionRing( IcosianRing, false );
SetSize( IcosianRing, infinity );
SetGeneratorsOfRing( IcosianRing, AsList(IcosianH4Generators));
SetGeneratorsOfLeftModule( IcosianRing, AsList(IcosianH4Generators) );
SetIsWholeFamily( IcosianRing, false );
SetIsAssociative( IcosianRing, false );
InstallMethod( Units,
"For Icosians",
[ IsIcosianRing ],
function(O)
return Closure(Basis(O), \*);
end);
InstallMethod( IsIcosian,
"for Quaternions",
[ IsQuaternion ],
function(x)
return ForAll(Coefficients(Basis(IcosianRing), x), y ->
ForAll(Coefficients(Basis(NF(5,[1,4]), [1, (1-Sqrt(5))/2]), y), IsInt)
);
end);
InstallMethod( \in,
"for integers",
[ IsQuaternion, IsIcosianRing ], 10000,
function( n, Integers )
return IsIcosian( n );
end );
InstallMethod( Basis,
"for Icosians (delegate to `CanonicalBasis')",
[ IsIcosianRing ], CANONICAL_BASIS_FLAGS,
CanonicalBasis );
InstallMethod( CanonicalBasis,
"for Icosians",
[ IsIcosianRing ],
function( IcosianRing )
local B;
B:= Objectify( NewType( FamilyObj( IcosianRing ),
IsFiniteBasisDefault
and IsCanonicalBasis
and IsQuaternionCollection
and IsCanonicalBasisIcosianRingRep ),
rec() );
SetUnderlyingLeftModule( B, IcosianRing );
SetIsIntegralBasis( B, true );
SetBasisVectors( B, Immutable( BasisVectors(IcosianH4Generators)));
# Return the basis.
return B;
end );
InstallMethod( Coefficients,
"for the canonical basis of IcosianRing",
[ IsCanonicalBasisIcosianRingRep,
IsQuaternion ], 0,
function( B, v )
return SolutionMat(List(B, ExtRepOfObj), ExtRepOfObj(v));
end );
# Function to construct an octonion algebra in a standard basis (i.e. e[1]*e[2] = e[4], and cycle indices).
InstallGlobalFunction( OctonionAlgebra, function( F )
local e, stored, filter, T, A;
# Arguments checking
if not IsField(F) then
Error( "usage: OctonionAlgebra( <F> ) for a field <F>." );
fi;
e:= One( F );
if e = fail then
Error( "<F> must have an identity element" );
fi;
# Generators in the right family may be already available.
stored := GET_FROM_SORTED_CACHE( OctonionAlgebraData, [ Characteristic(F), FamilyObj( F ) ],
function()
# Construct a filter describing element properties,
# which will be stored in the family.
filter:= IsSCAlgebraObj and IsOctonion;
# if HasIsAssociative( F ) and IsAssociative( F ) then
# filter:= filter and IsAssociativeElement;
# fi;
T := [ [ [ [ 8 ], [ -1 ] ], [ [ 4 ], [ 1 ] ], [ [ 7 ], [ 1 ] ], [ [ 2 ], [ -1 ] ], [ [ 6 ], [ 1 ] ],
[ [ 5 ], [ -1 ] ], [ [ 3 ], [ -1 ] ], [ [ 1 ], [ 1 ] ] ],
[ [ [ 4 ], [ -1 ] ], [ [ 8 ], [ -1 ] ], [ [ 5 ], [ 1 ] ], [ [ 1 ], [ 1 ] ], [ [ 3 ], [ -1 ] ],
[ [ 7 ], [ 1 ] ], [ [ 6 ], [ -1 ] ], [ [ 2 ], [ 1 ] ] ],
[ [ [ 7 ], [ -1 ] ], [ [ 5 ], [ -1 ] ], [ [ 8 ], [ -1 ] ], [ [ 6 ], [ 1 ] ], [ [ 2 ], [ 1 ] ],
[ [ 4 ], [ -1 ] ], [ [ 1 ], [ 1 ] ], [ [ 3 ], [ 1 ] ] ],
[ [ [ 2 ], [ 1 ] ], [ [ 1 ], [ -1 ] ], [ [ 6 ], [ -1 ] ], [ [ 8 ], [ -1 ] ], [ [ 7 ], [ 1 ] ],
[ [ 3 ], [ 1 ] ], [ [ 5 ], [ -1 ] ], [ [ 4 ], [ 1 ] ] ],
[ [ [ 6 ], [ -1 ] ], [ [ 3 ], [ 1 ] ], [ [ 2 ], [ -1 ] ], [ [ 7 ], [ -1 ] ], [ [ 8 ], [ -1 ] ],
[ [ 1 ], [ 1 ] ], [ [ 4 ], [ 1 ] ], [ [ 5 ], [ 1 ] ] ],
[ [ [ 5 ], [ 1 ] ], [ [ 7 ], [ -1 ] ], [ [ 4 ], [ 1 ] ], [ [ 3 ], [ -1 ] ], [ [ 1 ], [ -1 ] ],
[ [ 8 ], [ -1 ] ], [ [ 2 ], [ 1 ] ], [ [ 6 ], [ 1 ] ] ],
[ [ [ 3 ], [ 1 ] ], [ [ 6 ], [ 1 ] ], [ [ 1 ], [ -1 ] ], [ [ 5 ], [ 1 ] ], [ [ 4 ], [ -1 ] ],
[ [ 2 ], [ -1 ] ], [ [ 8 ], [ -1 ] ], [ [ 7 ], [ 1 ] ] ],
[ [ [ 1 ], [ 1 ] ], [ [ 2 ], [ 1 ] ], [ [ 3 ], [ 1 ] ], [ [ 4 ], [ 1 ] ], [ [ 5 ], [ 1 ] ],
[ [ 6 ], [ 1 ] ], [ [ 7 ], [ 1 ] ], [ [ 8 ], [ 1 ] ] ], 0, Zero(F) ];
# Construct the algebra.
A:= AlgebraByStructureConstantsArg([ F, T, "e" ], filter );
SetFilterObj( A, IsAlgebraWithOne );
SetFilterObj( A, IsOctonionAlgebra );
return A;
end );
A:= AlgebraWithOne( F, CanonicalBasis( stored ), "basis" );
SetGeneratorsOfAlgebra( A, GeneratorsOfAlgebraWithOne( A ) );
SetIsFullSCAlgebra( A, true );
SetFilterObj( A, IsOctonionAlgebra );
# Return the octonion algebra.
return A;
end );
InstallMethod( Trace,
"for an octonion",
[ IsOctonion and IsSCAlgebraObj ],
oct -> 2*ExtRepOfObj(oct)[8]
);
InstallMethod( Norm,
"for an octonion",
[ IsOctonion and IsSCAlgebraObj ],
oct -> ExtRepOfObj(oct)*ExtRepOfObj(oct)
);
InstallMethod( Norm,
"for an octonion list",
[ IsOctonionCollection ],
function(vec)
return Sum(List(vec, Norm) );
end );
InstallMethod( ComplexConjugate,
"for an octonion",
[ IsOctonion and IsSCAlgebraObj ],
oct -> One(oct)*Trace(oct) - oct
);
InstallMethod( RealPart,
"for an octonion",
[ IsOctonion and IsSCAlgebraObj ],
oct -> (1/2)*Trace(oct)*One(oct)
);
# Avoiding use of ImaginaryPart for octonions since the built in GAP quaternion version of this command is easily misunderstood.
# InstallMethod( ImaginaryPart,
# "for an octonion",
# [ IsOctonion and IsSCAlgebraObj ],
# oct -> oct - RealPart(oct)
# );
# Octonion arithmetic tools
BindGlobal( "OctonionE8Basis", Basis(OctonionAlgebra(Rationals),
List(
[[ -1/2, 0, 0, 0, 1/2, 1/2, 1/2, 0 ],
[ -1/2, -1/2, 0, -1/2, 0, 0, -1/2, 0 ],
[ 0, 1/2, 1/2, 0, -1/2, 0, -1/2, 0 ],
[ 1/2, 0, -1/2, 1/2, 1/2, 0, 0, 0 ],
[ 0, -1/2, 1/2, 0, -1/2, 0, 1/2, 0 ],
[ 0, 1/2, 0, -1/2, 1/2, -1/2, 0, 0 ],
[ -1/2, 0, -1/2, 1/2, -1/2, 0, 0, 0 ],
[ 1/2, 0, 0, -1/2, 0, 1/2, 0, -1/2 ] ],
x -> ObjByExtRep(FamilyObj(One(OctonionAlgebra(Rationals))),x)
)) );
BindGlobal( "OctavianIntegers", Objectify( NewType(
CollectionsFamily(FamilyObj(OctonionAlgebra(Rationals))),
IsOctavianIntegers and IsRingWithOne and IsOctonionCollection and IsAttributeStoringRep ),
rec() ) );
SetLeftActingDomain( OctavianIntegers, Integers );
SetName( OctavianIntegers, "OctavianIntegers" );
SetString( OctavianIntegers, "OctavianIntegers" );
SetIsLeftActedOnByDivisionRing( OctavianIntegers, false );
SetSize( OctavianIntegers, infinity );
SetGeneratorsOfRing( OctavianIntegers, AsList(OctonionE8Basis));
SetGeneratorsOfLeftModule( OctavianIntegers, AsList(OctonionE8Basis) );
SetIsWholeFamily( OctavianIntegers, false );
SetIsAssociative( OctavianIntegers, false );
InstallMethod( Units,
"For octavian integers",
[ IsOctavianIntegers ],
function(O)
return Closure(Basis(O), \*);
end);
InstallMethod( IsOctavianInt,
"for Octonions",
[ IsOctonion ],
function(x)
return ForAll(Coefficients(Basis(OctavianIntegers), x), IsInt);
end);
InstallMethod( \in,
"for integers",
[ IsOctonion, IsOctavianIntegers ], 10000,
function( n, Integers )
return IsOctavianInt( n );
end );
InstallMethod( Basis,
"for Octavian integers (delegate to `CanonicalBasis')",
[ IsOctavianIntegers ], CANONICAL_BASIS_FLAGS,
CanonicalBasis );
InstallMethod( CanonicalBasis,
"for Octavian integers",
[ IsOctavianIntegers ],
function( OctavianIntegers )
local B;
B:= Objectify( NewType( FamilyObj( OctavianIntegers ),
IsFiniteBasisDefault
and IsCanonicalBasis
and IsOctonionCollection
and IsCanonicalBasisOctavianIntegersRep ),
rec() );
SetUnderlyingLeftModule( B, OctavianIntegers );
SetIsIntegralBasis( B, true );
SetBasisVectors( B, Immutable( BasisVectors(OctonionE8Basis)));
# Return the basis.
return B;
end );
InstallMethod( Coefficients,
"for the canonical basis of OctavianIntegers",
[ IsCanonicalBasisOctavianIntegersRep,
IsOctonion ], 0,
function( B, v )
return SolutionMat(List(B, ExtRepOfObj), ExtRepOfObj(v));
end );
InstallMethod( \mod,
"For an octonion integer",
[IsOctonion, IsPosInt], 0,
function(a,m)
local coeffs;
coeffs := Coefficients(Basis(OctavianIntegers), a);
if not ForAll(coeffs, IsInt) then
return fail;
fi;
return LinearCombination(Basis(OctavianIntegers), coeffs mod m);
end );
# Potentially replace the function below with a method.
# InstallMethod( OctonionToRealVector,
# "For an octonion basis and vector",
# [ IsBasis, IsRowVector ], 0,
# function(basis, x)
# if IsHomogeneousList(Flat(AsList(Basis), x)) and
# IsOctonionCollection(x)
# then
# return Flat(List(x, y -> Coefficients(basis, y)) );
# fi;
# return fail;
# end );
InstallGlobalFunction( OctonionToRealVector,
function(arg, x)
# In the case of an octonion basis return the concatenated octonion basis expansion.
if IsBasis(arg) and IsOctonionCollection(UnderlyingLeftModule(arg)) and IsOctonionCollection(x) then
return Concatenation(List(x, y -> Coefficients(arg, y)) );
fi;
return fail;
end );
InstallMethod( Coefficients,
"For an octonion lattice basis and an octonion vector",
[ IsOctonionLatticeBasis, IsOctonionCollection ], 0,
function(basis, x)
local L;
L := UnderlyingLeftModule(basis);
if x in L then
# return OctonionToRealVector(UnderlyingLeftModule(basis), x);
return SolutionMat(LLLReducedBasisCoefficients(L),
OctonionToRealVector((UnderlyingOctonionRingBasis(L)), x));
fi;
return fail;
end );
InstallGlobalFunction( RealToOctonionVector,
function(arg, x)
local n, temp;
# In the case of an octonion basis convert each length of 8 into an octonion,
# Check length of coefficient vector.
if IsBasis(arg) and IsOctonionCollection(UnderlyingLeftModule(arg)) then
if Length(x) mod 8 = 0 and IsHomogeneousList(x) then
n := Length(x)/8;
temp := List([1..n], m -> x{[(m-1)*8+1 .. m*8]} );;
return List(temp, y -> LinearCombination(arg, y) );
fi;
fi;
return fail;
end );
InstallGlobalFunction( VectorToIdempotentMatrix,
function(x)
local temp;
if not IsHomogeneousList(x) or not IsAssociative(x) or not (IsCyc(x[1]) or IsQuaternion(x[1]) or IsOctonion(x[1])) then
return fail;
fi;
if IsAssociative(x) then
temp := TransposedMat([ComplexConjugate(x)])*[x];
return temp/Trace(temp );
fi;
return fail;
end );
InstallGlobalFunction( WeylReflection,
function(r,x)
local R;
R := VectorToIdempotentMatrix(r );
if R = fail or not IsHomogeneousList(Flat([r,x])) then
return fail;
fi;
return x - 2*x*R;
end );
# Jordan Algebra Tools
InstallMethod( Rank,
"for a Jordan Algebra",
[ IsJordanAlgebra ],
J -> JordanRank(J)
);
InstallMethod( JordanRank,
"for a Jordan algebra element",
[ IsJordanAlgebraObj ],
j -> JordanRank(FamilyObj(j)!.fullSCAlgebra)
);
InstallMethod( Rank,
"for a Jordan algebra element",
[ IsJordanAlgebraObj ],
j -> JordanRank(j)
);
InstallMethod( JordanDegree,
"for a Jordan algebra element",
[ IsJordanAlgebraObj ],
j -> JordanDegree(FamilyObj(j)!.fullSCAlgebra)
);
InstallMethod( Degree,
"for a Jordan Algebra",
[ IsJordanAlgebra ],
J -> JordanDegree(J)
);
InstallMethod( Degree,
"for a Jordan algebra element",
[ IsJordanAlgebraObj ],
j -> JordanDegree(j)
);
InstallMethod( Trace,
"for a Jordan algebra element",
[ IsJordanAlgebraObj and IsSCAlgebraObj ],
# j -> (Rank(j)/Dimension(FamilyObj(j)!.fullSCAlgebra))*Trace(AdjointMatrix(Basis(FamilyObj(j)!.fullSCAlgebra), j))
j -> ExtRepOfObj(j)*JordanBasisTraces(FamilyObj(j)!.fullSCAlgebra)
);
InstallMethod( Norm,
"for a Jordan algebra element",
[ IsJordanAlgebraObj and IsSCAlgebraObj ],
j -> Trace(j^2)/2
);
InstallGlobalFunction( GenericMinimalPolynomial,
function(x)
local p, prx, p1xr, r, j, qjx;
p := [-Trace(x)];
p1xr := [-Trace(x)];
r := 1;
repeat
r := r + 1;
Append(p1xr, [-Trace(x^r)] );
prx := (1/r)*(p1xr[r] + Sum(List([1..r-1], j ->
p1xr[r-j]*p[j]
)) );
Append(p, [prx] );
until r = Rank(x );
p := Reversed(p );
Append(p, [1] );
return p;
end );
InstallMethod( Determinant,
"for a Jordan algebra element",
[ IsJordanAlgebraObj and IsSCAlgebraObj ],
j -> ValuePol(GenericMinimalPolynomial(j), 0)*(-1)^Rank(j)
);
InstallMethod( JordanAdjugate,
"for a Jordan algebra element",
[ IsJordanAlgebraObj ],
function(j) return (-1)^(1+Rank(j))*ValuePol(ShiftedCoeffs(GenericMinimalPolynomial(j), -1), j ); end
);
InstallMethod( IsPositiveDefinite,
"for a Jordan algebra element",
[ IsJordanAlgebraObj ],
function(j) local temp;
temp := GenericMinimalPolynomial(j );
if 0 in temp then return false; fi;
temp := Reversed(temp );
temp := List([0..Rank(j)], n -> temp[n+1]*(-1)^n > 0 );
if Set(temp) = [true] then return true; fi;
return false;
end );
# Function to construct basis matrices for a Hermitian simple Euclidean Jordan algebra.
InstallGlobalFunction( HermitianJordanAlgebraBasis, function(rho, comp_alg_basis)
local d, C, F, peirce, conj, mat, frame, realbasis;
# Ensure that the rank and degree are correct.
if not (IsInt(rho) and rho > 1 and IsBasis(comp_alg_basis)) then
return fail;
fi;
d := Length(comp_alg_basis);
if (not d in [1,2,4,8]) or (d = 8 and rho > 3) then
return fail;
fi;
# Record the composition algebra over F.
C := UnderlyingLeftModule(comp_alg_basis);
F := LeftActingDomain(C);
# Require that F is either integers or a field of characteristic zero.
if not (IsIntegers(F) or (IsField(F) and Characteristic(F) = 0)) then
return fail;
fi;
# It is possible that the d = 1 or 2 cases do not involve quaternions or octonion SCAlgebra objects.
if not (IsOctonionCollection(C) or IsQuaternionCollection(C)) then
# Only real and complex cases remain, which must be quadratic extensions of some number field.
if d > 2 then
return fail;
fi;
# Rule out subfields of the rationals for d = 2:
if d = 2 and Set(comp_alg_basis, x -> RealPart(x) = x ) = [true]
then return fail;
fi;
fi;
# Define a function to construct a single entry Hermitian matrix.
mat := function(n,x)
local temp;
if Length(n) <> 2 then return fail; fi;
temp := Zero(x)*IdentityMat( rho );
temp[n[1]][n[2]] := x;
temp[n[2]][n[1]] := ComplexConjugate( x );
return temp;
end;
# Construct the diagonal matrices.
frame := Concatenation(List(IdentityMat(rho), x -> List([One(C)], r -> DiagonalMat(x)*r)) );
# Construct the off-diagonal matrices.
peirce := List(Combinations([1..rho],2), n -> List(comp_alg_basis, x -> mat(n,x)) );
# Return the matrices.
return Concatenation(frame, Concatenation(peirce) );
end );
# Function to convert a Hermitian matrix to a vector, or coefficients of a vector, in a Jordan algebra.
InstallGlobalFunction( HermitianMatrixToJordanCoefficients, function(mat, comp_alg_basis)
local temp, rho, d, i, basis;
# Verify that the input is a Hermitian matrix.
if not IsMatrix(mat) and mat = TransposedMat(ComplexConjugate(mat)) then return fail; fi;
# Ensure that the second input is a basis.
if not IsBasis(comp_alg_basis) then return fail; fi;
# Record basic parameters.
basis := comp_alg_basis;
rho := Length(DiagonalOfMat(mat) );
d := Size(basis);
# Define a temporary list of coefficients.
temp := [];
# Determine the coefficients due to the diagonal components of the matrix.
for i in [1..rho] do
if IsQuaternionCollection(comp_alg_basis) or IsOctonionCollection(comp_alg_basis) then
Append(temp, [Trace(mat[i][i])/2] );
elif IsCyclotomicCollection(comp_alg_basis) then
Append(temp, [RealPart(mat[i][i])]);
else
Display("Here");
return fail;
fi;
od;
# Find the off-diagonal coefficients next.
for i in Combinations([1..rho],2) do
# if not (IsQuaternionCollection(comp_alg_basis) or IsOctonionCollection(comp_alg_basis) ) and LeftActingDomain(UnderlyingLeftModule(comp_alg_basis)) = Integers then
# Append(temp, Coefficients(Basis(Rationals,[1]), mat[i[1]][i[2]]) );
# else
# Append(temp, Coefficients(basis, mat[i[1]][i[2]]) );
# fi;
Append(temp, Coefficients(basis, mat[i[1]][i[2]]) );
od;
# Return the coefficients.
return temp;
end );
# Function to convert a Hermitian matrix into a Jordan algebra vector.
InstallGlobalFunction( HermitianMatrixToJordanVector, function(mat, J)
local temp;
# Verify that the second argument is a Jordan algebra with an off-diagonal basis defined.
if not (IsJordanAlgebra(J) and HasJordanOffDiagonalBasis(J)) then
return fail;
fi;
# Verify that the matrix entries belong to the algebra spanned by the off-diagonal basis.
if not IsHomogeneousList(Flat([mat, JordanOffDiagonalBasis(J)])) then return fail; fi;
# Compute the coefficients, if possible.
temp := HermitianMatrixToJordanCoefficients(mat, JordanOffDiagonalBasis(J) );
if temp = fail then return temp; fi;
# Return the coefficients in J-vector form.
return LinearCombination(Basis(J), temp );
end );
# Function to construct Jordan algebra of Hermitian type.
InstallGlobalFunction( HermitianSimpleJordanAlgebra, function(rho, comp_alg_basis, F...)
local jordan_basis, C, K, T, temp, coeffs, algebra, filter, n, m, z, l;
# Ensure inputs are correct by computing basis vectors:
if Length(F) > 1 then
return fail;
fi;
jordan_basis := HermitianJordanAlgebraBasis(rho, comp_alg_basis );
if jordan_basis = fail then
return jordan_basis;
fi;
# Record the composition algebra over F.
C := UnderlyingLeftModule(comp_alg_basis);
K := LeftActingDomain(C);
if Length(F) = 0 and IsSubset(Rationals, K) then
K := Rationals;
fi;
# Ensure that the optional field argument contains the left acting domain of the basis.
if Length(F) = 1 then
F := F[1];
if not (IsField(F) or IsIntegers(F)) then
return fail;
elif IsField(F) and not IsSubset(F, K) then
return fail;
fi;
K := F;
fi;
# Define an empty structure constants table.
T := EmptySCTable(Size(jordan_basis), Zero(K) );
# Compute the structure constants.
for n in [1..Size(jordan_basis)] do
for m in [1..Size(jordan_basis)] do
z := (1/2)*(jordan_basis[n]*jordan_basis[m] + jordan_basis[m]*jordan_basis[n] );
# z := (jordan_basis[n]*jordan_basis[m] + jordan_basis[m]*jordan_basis[n] );
temp := HermitianMatrixToJordanCoefficients(z, comp_alg_basis );
coeffs := [];
for l in [1..Size(jordan_basis)] do
if temp[l] <> 0 then
Append(coeffs, [temp[l], l] );
fi;
od;
SetEntrySCTable( T, n, m, coeffs );
od;
od;
# Construct the algebra.
filter:= IsSCAlgebraObj and IsJordanAlgebraObj;
algebra := AlgebraByStructureConstantsArg([K, T], filter );
SetFilterObj( algebra, IsJordanAlgebra );
SetFilterObj( algebra, IsAlgebraWithOne);
# Assign various attributes to the algebra.
SetJordanRank( algebra, rho );
SetJordanDegree( algebra, Length(comp_alg_basis) );
SetJordanMatrixBasis( algebra, jordan_basis );
SetJordanOffDiagonalBasis( algebra, comp_alg_basis );
SetJordanHomotopeVector( algebra, One(algebra) );
SetJordanBasisTraces( algebra, List(Basis(algebra),
j -> (Rank(j)/Dimension(FamilyObj(j)!.fullSCAlgebra))*Trace(AdjointMatrix(Basis(FamilyObj(j)!.fullSCAlgebra), j)))
);
return algebra;
end );
InstallGlobalFunction( JordanSpinFactor, function(gram_mat)
local result, T, n, m, z, temp, coeffs, filter;
if not IsMatrix(gram_mat) or Inverse(gram_mat) = fail or gram_mat <> TransposedMat(gram_mat) then
Display("Usage: JordanSpinFactor(G) requires <G> to be a positive definite symmetric matrix.");
return fail;
fi;
result := rec( );
result.F := Field(Flat(gram_mat) );
result.rho := 2;
result.d := DimensionsMat(gram_mat)[1]-1;
# Construct the algebra.
T := EmptySCTable(result.d + 2, Zero(0) );
SetEntrySCTable(T, 1, 1, [1, 1] );
for m in [2..result.d + 2] do
SetEntrySCTable(T, m, 1, [1, m] );
SetEntrySCTable(T, 1, m, [1, m] );
od;
for n in [2..result.d + 2] do
for m in [2..result.d + 2] do
SetEntrySCTable( T, n, m, [gram_mat[n-1][m-1], 1] );
od;
od;
filter:= IsSCAlgebraObj and IsJordanAlgebraObj;
result.algebra := AlgebraByStructureConstantsArg([result.F, T], filter );
SetFilterObj( result.algebra, IsJordanAlgebra );
SetFilterObj( result.algebra, IsAlgebraWithOne);
SetJordanRank( result.algebra, result.rho );
SetJordanDegree( result.algebra, result.d );
SetJordanHomotopeVector( result.algebra, One(result.algebra) );
SetJordanBasisTraces( result.algebra, List(Basis(result.algebra),
j -> (Rank(j)/Dimension(FamilyObj(j)!.fullSCAlgebra))*Trace(AdjointMatrix(Basis(FamilyObj(j)!.fullSCAlgebra), j)))
);
return result.algebra;
end );
InstallMethod( JordanAlgebraGramMatrix,
"for a Jordan algebra",
[ IsJordanAlgebra ],
j -> List(Basis(j), x -> List(Basis(j), y -> Trace(x*y)))
);
InstallGlobalFunction( JordanHomotope , function(ring, u, label...)
local result, temp, filter, T, n, m, z, l, coeffs;
if not IsJordanAlgebra(ring) then return fail; fi;
result := rec( );
result.rho := Rank(ring );
result.d := Degree(ring );
result.F := LeftActingDomain(ring );
T := EmptySCTable(Dimension(ring), Zero(result.F) );
for n in Basis(ring) do
for m in Basis(ring) do
z := n*(u*m) + (n*u)*m - u*(n*m );
temp := Coefficients(Basis(ring), z );
coeffs := [];
for l in [1..Dimension(ring)] do
if temp[l] <> Zero(temp[l]) then
Append(coeffs, [temp[l], l] );
fi;
od;
SetEntrySCTable( T, Position(Basis(ring), n), Position(Basis(ring), m), coeffs );
od;
od;
filter:= IsSCAlgebraObj and IsJordanAlgebraObj;
if Length(label) > 0 and IsString(label[1]) then
result.algebra := AlgebraByStructureConstantsArg([result.F, T, label[1]], filter );
else
result.algebra := AlgebraByStructureConstantsArg([result.F, T], filter );
fi;
SetFilterObj( result.algebra, IsJordanAlgebra );
if Inverse(u) <> fail then
SetFilterObj( result.algebra, IsAlgebraWithOne);
fi;
SetJordanRank( result.algebra, result.rho );
SetJordanDegree( result.algebra, result.d );
if HasJordanMatrixBasis( result.algebra) then
SetJordanMatrixBasis( result.algebra, JordanMatrixBasis(ring) );
fi;
if HasJordanOffDiagonalBasis(result.algebra) then
SetJordanOffDiagonalBasis( result.algebra, JordanOffDiagonalBasis(ring) );
fi;
SetJordanHomotopeVector( result.algebra, u );
SetJordanBasisTraces( result.algebra, List(Basis(result.algebra),
j -> (Rank(j)/Dimension(FamilyObj(j)!.fullSCAlgebra))*Trace(AdjointMatrix(Basis(FamilyObj(j)!.fullSCAlgebra), j)))
);
return result.algebra;
end );
InstallGlobalFunction( SimpleEuclideanJordanAlgebra, function(rho, d, args...)
local temp, F;
temp := rec( );
if not (IsInt(d) and IsInt(rho)) then return fail; fi;
if rho < 2 then return fail; fi;
if rho > 2 and not d in [1,2,4,8] then return fail; fi;
if d = 8 and rho > 3 then return fail; fi;
if rho = 2 then
if Length(args) = 0 then
return JordanSpinFactor(IdentityMat(d+1) );
elif IsMatrix(args[1]) and DimensionsMat(args[1]) = [d+1, d+1] and TransposedMat(args[1]) = args[1] and Inverse(args[1]) <> fail then
return JordanSpinFactor(args[1] );
elif d in [1,2,4,8] and IsBasis(args[1]) and Size(args[1]) = d then
return HermitianSimpleJordanAlgebra(rho, args[1] );
else
Display("Usage: SimpleEuclideanJordanAlgebra(2, d [, args]) where <args> is either empty, a symmetric invertible matrix, or when <d> = 1,2,4,8 <args> can also be a basis for a composition algebra.");
return fail;
fi;
fi;
if Length(args) = 0 then
if d = 8 then
return HermitianSimpleJordanAlgebra(rho, Basis(OctonionAlgebra(Rationals)) );
elif d = 4 then
return HermitianSimpleJordanAlgebra(rho, Basis(QuaternionAlgebra(Rationals)) );
elif d = 2 then
return HermitianSimpleJordanAlgebra(rho, Basis(CF(4), [1, E(4)]) );
elif d = 1 then
return HermitianSimpleJordanAlgebra(rho, Basis(Rationals, [1]) );
fi;
elif IsBasis(args[1]) and Size(args[1]) = d then
return HermitianSimpleJordanAlgebra(rho, args[1] );
else
return fail;
fi;
end );
# Albert Algebra tools
InstallGlobalFunction( AlbertAlgebra, function( F )
local e, i, j, k, jordan_basis, stored, filter, T, A;
# Arguments checking
if not IsField(F) then
Error( "usage: AlbertAlgebra( <F> ) for a field <F>." );
fi;
e:= One( F );
if e = fail then
Error( "<F> must have an identity element" );
fi;
# Generators in the right family may be already available.
stored := GET_FROM_SORTED_CACHE( AlbertAlgebraData, [ Characteristic(F), FamilyObj( F ) ],
function()
filter:= IsSCAlgebraObj and IsJordanAlgebraObj and IsAlbertAlgebraObj;
T := [ [ [ [ 26, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 24 ], [ -1/2 ] ], [ [ 20 ], [ -1/2 ] ],
[ [ 23 ], [ -1/2 ] ], [ [ 18 ], [ 1/2 ] ], [ [ 22 ], [ -1/2 ] ], [ [ 21 ], [ 1/2 ] ],
[ [ 19 ], [ 1/2 ] ], [ [ 17 ], [ -1/2 ] ], [ [ 16 ], [ -1/2 ] ], [ [ 12 ], [ 1/2 ] ],
[ [ 15 ], [ 1/2 ] ], [ [ 10 ], [ -1/2 ] ], [ [ 14 ], [ 1/2 ] ], [ [ 13 ], [ -1/2 ] ],
[ [ 11 ], [ -1/2 ] ], [ [ 9 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ 1 ], [ 1/2 ] ],
[ [ 1 ], [ 1/2 ] ] ],
[ [ [ ], [ ] ], [ [ 26, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 20 ], [ 1/2 ] ], [ [ 24 ], [ -1/2 ] ],
[ [ 21 ], [ -1/2 ] ], [ [ 17 ], [ -1/2 ] ], [ [ 19 ], [ 1/2 ] ], [ [ 23 ], [ -1/2 ] ],
[ [ 22 ], [ 1/2 ] ], [ [ 18 ], [ -1/2 ] ], [ [ 12 ], [ -1/2 ] ], [ [ 16 ], [ -1/2 ] ],
[ [ 13 ], [ 1/2 ] ], [ [ 9 ], [ 1/2 ] ], [ [ 11 ], [ -1/2 ] ], [ [ 15 ], [ 1/2 ] ],
[ [ 14 ], [ -1/2 ] ], [ [ 10 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ 2 ], [ 1/2 ] ],
[ [ 2 ], [ 1/2 ] ] ],
[ [ [ ], [ ] ], [ [ ], [ ] ], [ [ 26, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 23 ], [ 1/2 ] ], [ [ 21 ], [ 1/2 ] ],
[ [ 24 ], [ -1/2 ] ], [ [ 22 ], [ -1/2 ] ], [ [ 18 ], [ -1/2 ] ], [ [ 20 ], [ 1/2 ] ],
[ [ 17 ], [ -1/2 ] ], [ [ 19 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ], [ [ 13 ], [ -1/2 ] ],
[ [ 16 ], [ -1/2 ] ], [ [ 14 ], [ 1/2 ] ], [ [ 10 ], [ 1/2 ] ], [ [ 12 ], [ -1/2 ] ],
[ [ 9 ], [ 1/2 ] ], [ [ 11 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ 3 ], [ 1/2 ] ],
[ [ 3 ], [ 1/2 ] ] ],
[ [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 26, 27 ], [ 1, 1 ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 18 ], [ -1/2 ] ], [ [ 17 ], [ 1/2 ] ],
[ [ 22 ], [ 1/2 ] ], [ [ 24 ], [ -1/2 ] ], [ [ 23 ], [ -1/2 ] ], [ [ 19 ], [ -1/2 ] ],
[ [ 21 ], [ 1/2 ] ], [ [ 20 ], [ -1/2 ] ], [ [ 10 ], [ 1/2 ] ], [ [ 9 ], [ -1/2 ] ],
[ [ 14 ], [ -1/2 ] ], [ [ 16 ], [ -1/2 ] ], [ [ 15 ], [ 1/2 ] ], [ [ 11 ], [ 1/2 ] ],
[ [ 13 ], [ -1/2 ] ], [ [ 12 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ 4 ], [ 1/2 ] ],
[ [ 4 ], [ 1/2 ] ] ], [ [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 26, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 22 ], [ 1/2 ] ], [ [ 19 ], [ -1/2 ] ], [ [ 18 ], [ 1/2 ] ], [ [ 23 ], [ 1/2 ] ],
[ [ 24 ], [ -1/2 ] ], [ [ 17 ], [ -1/2 ] ], [ [ 20 ], [ -1/2 ] ], [ [ 21 ], [ -1/2 ] ],
[ [ 14 ], [ -1/2 ] ], [ [ 11 ], [ 1/2 ] ], [ [ 10 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ],
[ [ 16 ], [ -1/2 ] ], [ [ 9 ], [ 1/2 ] ], [ [ 12 ], [ 1/2 ] ], [ [ 13 ], [ -1/2 ] ],
[ [ ], [ ] ], [ [ 5 ], [ 1/2 ] ], [ [ 5 ], [ 1/2 ] ] ],
[ [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 26, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 21 ], [ -1/2 ] ],
[ [ 23 ], [ 1/2 ] ], [ [ 20 ], [ -1/2 ] ], [ [ 19 ], [ 1/2 ] ], [ [ 17 ], [ 1/2 ] ],
[ [ 24 ], [ -1/2 ] ], [ [ 18 ], [ -1/2 ] ], [ [ 22 ], [ -1/2 ] ], [ [ 13 ], [ 1/2 ] ],
[ [ 15 ], [ -1/2 ] ], [ [ 12 ], [ 1/2 ] ], [ [ 11 ], [ -1/2 ] ], [ [ 9 ], [ -1/2 ] ],
[ [ 16 ], [ -1/2 ] ], [ [ 10 ], [ 1/2 ] ], [ [ 14 ], [ -1/2 ] ], [ [ ], [ ] ],
[ [ 6 ], [ 1/2 ] ], [ [ 6 ], [ 1/2 ] ] ],
[ [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ 26, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ 19 ], [ -1/2 ] ],
[ [ 22 ], [ -1/2 ] ], [ [ 17 ], [ 1/2 ] ], [ [ 21 ], [ -1/2 ] ], [ [ 20 ], [ 1/2 ] ],
[ [ 18 ], [ 1/2 ] ], [ [ 24 ], [ -1/2 ] ], [ [ 23 ], [ -1/2 ] ], [ [ 11 ], [ 1/2 ] ],
[ [ 14 ], [ 1/2 ] ], [ [ 9 ], [ -1/2 ] ], [ [ 13 ], [ 1/2 ] ], [ [ 12 ], [ -1/2 ] ],
[ [ 10 ], [ -1/2 ] ], [ [ 16 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ], [ [ ], [ ] ],
[ [ 7 ], [ 1/2 ] ], [ [ 7 ], [ 1/2 ] ] ],
[ [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ 26, 27 ], [ 1, 1 ] ], [ [ 17 ], [ -1/2 ] ],
[ [ 18 ], [ -1/2 ] ], [ [ 19 ], [ -1/2 ] ], [ [ 20 ], [ -1/2 ] ], [ [ 21 ], [ -1/2 ] ],
[ [ 22 ], [ -1/2 ] ], [ [ 23 ], [ -1/2 ] ], [ [ 24 ], [ 1/2 ] ], [ [ 9 ], [ -1/2 ] ],
[ [ 10 ], [ -1/2 ] ], [ [ 11 ], [ -1/2 ] ], [ [ 12 ], [ -1/2 ] ], [ [ 13 ], [ -1/2 ] ],
[ [ 14 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ], [ [ 16 ], [ 1/2 ] ], [ [ ], [ ] ],
[ [ 8 ], [ 1/2 ] ], [ [ 8 ], [ 1/2 ] ] ],
[ [ [ 24 ], [ -1/2 ] ], [ [ 20 ], [ 1/2 ] ], [ [ 23 ], [ 1/2 ] ], [ [ 18 ], [ -1/2 ] ],
[ [ 22 ], [ 1/2 ] ], [ [ 21 ], [ -1/2 ] ], [ [ 19 ], [ -1/2 ] ], [ [ 17 ], [ -1/2 ] ],
[ [ 25, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 8 ], [ -1/2 ] ], [ [ 4 ], [ -1/2 ] ],
[ [ 7 ], [ -1/2 ] ], [ [ 2 ], [ 1/2 ] ], [ [ 6 ], [ -1/2 ] ], [ [ 5 ], [ 1/2 ] ],
[ [ 3 ], [ 1/2 ] ], [ [ 1 ], [ -1/2 ] ], [ [ 9 ], [ 1/2 ] ], [ [ ], [ ] ],
[ [ 9 ], [ 1/2 ] ] ], [ [ [ 20 ], [ -1/2 ] ], [ [ 24 ], [ -1/2 ] ], [ [ 21 ], [ 1/2 ] ],
[ [ 17 ], [ 1/2 ] ], [ [ 19 ], [ -1/2 ] ], [ [ 23 ], [ 1/2 ] ], [ [ 22 ], [ -1/2 ] ],
[ [ 18 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ 25, 27 ], [ 1, 1 ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 4 ], [ 1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 5 ], [ -1/2 ] ], [ [ 1 ], [ -1/2 ] ],
[ [ 3 ], [ 1/2 ] ], [ [ 7 ], [ -1/2 ] ], [ [ 6 ], [ 1/2 ] ], [ [ 2 ], [ -1/2 ] ],
[ [ 10 ], [ 1/2 ] ], [ [ ], [ ] ], [ [ 10 ], [ 1/2 ] ] ],
[ [ [ 23 ], [ -1/2 ] ], [ [ 21 ], [ -1/2 ] ], [ [ 24 ], [ -1/2 ] ], [ [ 22 ], [ 1/2 ] ],
[ [ 18 ], [ 1/2 ] ], [ [ 20 ], [ -1/2 ] ], [ [ 17 ], [ 1/2 ] ], [ [ 19 ], [ -1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ 25, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 7 ], [ 1/2 ] ], [ [ 5 ], [ 1/2 ] ],
[ [ 8 ], [ -1/2 ] ], [ [ 6 ], [ -1/2 ] ], [ [ 2 ], [ -1/2 ] ], [ [ 4 ], [ 1/2 ] ],
[ [ 1 ], [ -1/2 ] ], [ [ 3 ], [ -1/2 ] ], [ [ 11 ], [ 1/2 ] ], [ [ ], [ ] ],
[ [ 11 ], [ 1/2 ] ] ], [ [ [ 18 ], [ 1/2 ] ], [ [ 17 ], [ -1/2 ] ], [ [ 22 ], [ -1/2 ] ],
[ [ 24 ], [ -1/2 ] ], [ [ 23 ], [ 1/2 ] ], [ [ 19 ], [ 1/2 ] ], [ [ 21 ], [ -1/2 ] ],
[ [ 20 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 25, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 2 ], [ -1/2 ] ], [ [ 1 ], [ 1/2 ] ], [ [ 6 ], [ 1/2 ] ], [ [ 8 ], [ -1/2 ] ],
[ [ 7 ], [ -1/2 ] ], [ [ 3 ], [ -1/2 ] ], [ [ 5 ], [ 1/2 ] ], [ [ 4 ], [ -1/2 ] ],
[ [ 12 ], [ 1/2 ] ], [ [ ], [ ] ], [ [ 12 ], [ 1/2 ] ] ],
[ [ [ 22 ], [ -1/2 ] ], [ [ 19 ], [ 1/2 ] ], [ [ 18 ], [ -1/2 ] ], [ [ 23 ], [ -1/2 ] ],
[ [ 24 ], [ -1/2 ] ], [ [ 17 ], [ 1/2 ] ], [ [ 20 ], [ 1/2 ] ], [ [ 21 ], [ -1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 25, 27 ], [ 1, 1 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 6 ], [ 1/2 ] ], [ [ 3 ], [ -1/2 ] ],
[ [ 2 ], [ 1/2 ] ], [ [ 7 ], [ 1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 1 ], [ -1/2 ] ],
[ [ 4 ], [ -1/2 ] ], [ [ 5 ], [ -1/2 ] ], [ [ 13 ], [ 1/2 ] ], [ [ ], [ ] ],
[ [ 13 ], [ 1/2 ] ] ], [ [ [ 21 ], [ 1/2 ] ], [ [ 23 ], [ -1/2 ] ], [ [ 20 ], [ 1/2 ] ],
[ [ 19 ], [ -1/2 ] ], [ [ 17 ], [ -1/2 ] ], [ [ 24 ], [ -1/2 ] ], [ [ 18 ], [ 1/2 ] ],
[ [ 22 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ 25, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 5 ], [ -1/2 ] ], [ [ 7 ], [ 1/2 ] ], [ [ 4 ], [ -1/2 ] ], [ [ 3 ], [ 1/2 ] ],
[ [ 1 ], [ 1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 2 ], [ -1/2 ] ], [ [ 6 ], [ -1/2 ] ],
[ [ 14 ], [ 1/2 ] ], [ [ ], [ ] ], [ [ 14 ], [ 1/2 ] ] ],
[ [ [ 19 ], [ 1/2 ] ], [ [ 22 ], [ 1/2 ] ], [ [ 17 ], [ -1/2 ] ], [ [ 21 ], [ 1/2 ] ],
[ [ 20 ], [ -1/2 ] ], [ [ 18 ], [ -1/2 ] ], [ [ 24 ], [ -1/2 ] ], [ [ 23 ], [ -1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ 25, 27 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ 3 ], [ -1/2 ] ],
[ [ 6 ], [ -1/2 ] ], [ [ 1 ], [ 1/2 ] ], [ [ 5 ], [ -1/2 ] ], [ [ 4 ], [ 1/2 ] ],
[ [ 2 ], [ 1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 7 ], [ -1/2 ] ], [ [ 15 ], [ 1/2 ] ],
[ [ ], [ ] ], [ [ 15 ], [ 1/2 ] ] ],
[ [ [ 17 ], [ -1/2 ] ], [ [ 18 ], [ -1/2 ] ], [ [ 19 ], [ -1/2 ] ], [ [ 20 ], [ -1/2 ] ],
[ [ 21 ], [ -1/2 ] ], [ [ 22 ], [ -1/2 ] ], [ [ 23 ], [ -1/2 ] ], [ [ 24 ], [ 1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ 25, 27 ], [ 1, 1 ] ], [ [ 1 ], [ -1/2 ] ],
[ [ 2 ], [ -1/2 ] ], [ [ 3 ], [ -1/2 ] ], [ [ 4 ], [ -1/2 ] ], [ [ 5 ], [ -1/2 ] ],
[ [ 6 ], [ -1/2 ] ], [ [ 7 ], [ -1/2 ] ], [ [ 8 ], [ 1/2 ] ], [ [ 16 ], [ 1/2 ] ],
[ [ ], [ ] ], [ [ 16 ], [ 1/2 ] ] ],
[ [ [ 16 ], [ -1/2 ] ], [ [ 12 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ], [ [ 10 ], [ 1/2 ] ],
[ [ 14 ], [ -1/2 ] ], [ [ 13 ], [ 1/2 ] ], [ [ 11 ], [ 1/2 ] ], [ [ 9 ], [ -1/2 ] ],
[ [ 8 ], [ -1/2 ] ], [ [ 4 ], [ 1/2 ] ], [ [ 7 ], [ 1/2 ] ], [ [ 2 ], [ -1/2 ] ],
[ [ 6 ], [ 1/2 ] ], [ [ 5 ], [ -1/2 ] ], [ [ 3 ], [ -1/2 ] ], [ [ 1 ], [ -1/2 ] ],
[ [ 25, 26 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 17 ], [ 1/2 ] ], [ [ 17 ], [ 1/2 ] ],
[ [ ], [ ] ] ], [ [ [ 12 ], [ 1/2 ] ], [ [ 16 ], [ -1/2 ] ], [ [ 13 ], [ -1/2 ] ],
[ [ 9 ], [ -1/2 ] ], [ [ 11 ], [ 1/2 ] ], [ [ 15 ], [ -1/2 ] ], [ [ 14 ], [ 1/2 ] ],
[ [ 10 ], [ -1/2 ] ], [ [ 4 ], [ -1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 5 ], [ 1/2 ] ],
[ [ 1 ], [ 1/2 ] ], [ [ 3 ], [ -1/2 ] ], [ [ 7 ], [ 1/2 ] ], [ [ 6 ], [ -1/2 ] ],
[ [ 2 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ 25, 26 ], [ 1, 1 ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 18 ], [ 1/2 ] ], [ [ 18 ], [ 1/2 ] ], [ [ ], [ ] ] ],
[ [ [ 15 ], [ 1/2 ] ], [ [ 13 ], [ 1/2 ] ], [ [ 16 ], [ -1/2 ] ], [ [ 14 ], [ -1/2 ] ],
[ [ 10 ], [ -1/2 ] ], [ [ 12 ], [ 1/2 ] ], [ [ 9 ], [ -1/2 ] ], [ [ 11 ], [ -1/2 ] ],
[ [ 7 ], [ -1/2 ] ], [ [ 5 ], [ -1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 6 ], [ 1/2 ] ],
[ [ 2 ], [ 1/2 ] ], [ [ 4 ], [ -1/2 ] ], [ [ 1 ], [ 1/2 ] ], [ [ 3 ], [ -1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ 25, 26 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 19 ], [ 1/2 ] ], [ [ 19 ], [ 1/2 ] ],
[ [ ], [ ] ] ], [ [ [ 10 ], [ -1/2 ] ], [ [ 9 ], [ 1/2 ] ], [ [ 14 ], [ 1/2 ] ],
[ [ 16 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ], [ [ 11 ], [ -1/2 ] ], [ [ 13 ], [ 1/2 ] ],
[ [ 12 ], [ -1/2 ] ], [ [ 2 ], [ 1/2 ] ], [ [ 1 ], [ -1/2 ] ], [ [ 6 ], [ -1/2 ] ],
[ [ 8 ], [ -1/2 ] ], [ [ 7 ], [ 1/2 ] ], [ [ 3 ], [ 1/2 ] ], [ [ 5 ], [ -1/2 ] ],
[ [ 4 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 25, 26 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 20 ], [ 1/2 ] ], [ [ 20 ], [ 1/2 ] ], [ [ ], [ ] ] ],
[ [ [ 14 ], [ 1/2 ] ], [ [ 11 ], [ -1/2 ] ], [ [ 10 ], [ 1/2 ] ], [ [ 15 ], [ 1/2 ] ],
[ [ 16 ], [ -1/2 ] ], [ [ 9 ], [ -1/2 ] ], [ [ 12 ], [ -1/2 ] ], [ [ 13 ], [ -1/2 ] ],
[ [ 6 ], [ -1/2 ] ], [ [ 3 ], [ 1/2 ] ], [ [ 2 ], [ -1/2 ] ], [ [ 7 ], [ -1/2 ] ],
[ [ 8 ], [ -1/2 ] ], [ [ 1 ], [ 1/2 ] ], [ [ 4 ], [ 1/2 ] ], [ [ 5 ], [ -1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 25, 26 ], [ 1, 1 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 21 ], [ 1/2 ] ], [ [ 21 ], [ 1/2 ] ],
[ [ ], [ ] ] ], [ [ [ 13 ], [ -1/2 ] ], [ [ 15 ], [ 1/2 ] ], [ [ 12 ], [ -1/2 ] ],
[ [ 11 ], [ 1/2 ] ], [ [ 9 ], [ 1/2 ] ], [ [ 16 ], [ -1/2 ] ], [ [ 10 ], [ -1/2 ] ],
[ [ 14 ], [ -1/2 ] ], [ [ 5 ], [ 1/2 ] ], [ [ 7 ], [ -1/2 ] ], [ [ 4 ], [ 1/2 ] ],
[ [ 3 ], [ -1/2 ] ], [ [ 1 ], [ -1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 2 ], [ 1/2 ] ],
[ [ 6 ], [ -1/2 ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ 25, 26 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 22 ], [ 1/2 ] ], [ [ 22 ], [ 1/2 ] ], [ [ ], [ ] ] ],
[ [ [ 11 ], [ -1/2 ] ], [ [ 14 ], [ -1/2 ] ], [ [ 9 ], [ 1/2 ] ], [ [ 13 ], [ -1/2 ] ],
[ [ 12 ], [ 1/2 ] ], [ [ 10 ], [ 1/2 ] ], [ [ 16 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ],
[ [ 3 ], [ 1/2 ] ], [ [ 6 ], [ 1/2 ] ], [ [ 1 ], [ -1/2 ] ], [ [ 5 ], [ 1/2 ] ],
[ [ 4 ], [ -1/2 ] ], [ [ 2 ], [ -1/2 ] ], [ [ 8 ], [ -1/2 ] ], [ [ 7 ], [ -1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ 25, 26 ], [ 1, 1 ] ], [ [ ], [ ] ], [ [ 23 ], [ 1/2 ] ],
[ [ 23 ], [ 1/2 ] ], [ [ ], [ ] ] ],
[ [ [ 9 ], [ -1/2 ] ], [ [ 10 ], [ -1/2 ] ], [ [ 11 ], [ -1/2 ] ], [ [ 12 ], [ -1/2 ] ],
[ [ 13 ], [ -1/2 ] ], [ [ 14 ], [ -1/2 ] ], [ [ 15 ], [ -1/2 ] ], [ [ 16 ], [ 1/2 ] ],
[ [ 1 ], [ -1/2 ] ], [ [ 2 ], [ -1/2 ] ], [ [ 3 ], [ -1/2 ] ], [ [ 4 ], [ -1/2 ] ],
[ [ 5 ], [ -1/2 ] ], [ [ 6 ], [ -1/2 ] ], [ [ 7 ], [ -1/2 ] ], [ [ 8 ], [ 1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ 25, 26 ], [ 1, 1 ] ], [ [ 24 ], [ 1/2 ] ],
[ [ 24 ], [ 1/2 ] ], [ [ ], [ ] ] ],
[ [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 9 ], [ 1/2 ] ], [ [ 10 ], [ 1/2 ] ],
[ [ 11 ], [ 1/2 ] ], [ [ 12 ], [ 1/2 ] ], [ [ 13 ], [ 1/2 ] ], [ [ 14 ], [ 1/2 ] ],
[ [ 15 ], [ 1/2 ] ], [ [ 16 ], [ 1/2 ] ], [ [ 17 ], [ 1/2 ] ], [ [ 18 ], [ 1/2 ] ],
[ [ 19 ], [ 1/2 ] ], [ [ 20 ], [ 1/2 ] ], [ [ 21 ], [ 1/2 ] ], [ [ 22 ], [ 1/2 ] ],
[ [ 23 ], [ 1/2 ] ], [ [ 24 ], [ 1/2 ] ], [ [ 25 ], [ 1 ] ], [ [ ], [ ] ], [ [ ], [ ] ]
], [ [ [ 1 ], [ 1/2 ] ], [ [ 2 ], [ 1/2 ] ], [ [ 3 ], [ 1/2 ] ], [ [ 4 ], [ 1/2 ] ],
[ [ 5 ], [ 1/2 ] ], [ [ 6 ], [ 1/2 ] ], [ [ 7 ], [ 1/2 ] ], [ [ 8 ], [ 1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ 17 ], [ 1/2 ] ], [ [ 18 ], [ 1/2 ] ],
[ [ 19 ], [ 1/2 ] ], [ [ 20 ], [ 1/2 ] ], [ [ 21 ], [ 1/2 ] ], [ [ 22 ], [ 1/2 ] ],
[ [ 23 ], [ 1/2 ] ], [ [ 24 ], [ 1/2 ] ], [ [ ], [ ] ], [ [ 26 ], [ 1 ] ], [ [ ], [ ] ]
], [ [ [ 1 ], [ 1/2 ] ], [ [ 2 ], [ 1/2 ] ], [ [ 3 ], [ 1/2 ] ], [ [ 4 ], [ 1/2 ] ],
[ [ 5 ], [ 1/2 ] ], [ [ 6 ], [ 1/2 ] ], [ [ 7 ], [ 1/2 ] ], [ [ 8 ], [ 1/2 ] ],
[ [ 9 ], [ 1/2 ] ], [ [ 10 ], [ 1/2 ] ], [ [ 11 ], [ 1/2 ] ], [ [ 12 ], [ 1/2 ] ],
[ [ 13 ], [ 1/2 ] ], [ [ 14 ], [ 1/2 ] ], [ [ 15 ], [ 1/2 ] ], [ [ 16 ], [ 1/2 ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ], [ [ ], [ ] ],
[ [ 27 ], [ 1 ] ] ], 1, Zero(F) ];
# Construct the algebra.
A:= AlgebraByStructureConstantsArg([F, T, "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8",
"j1", "j2", "j3", "j4", "j5", "j6", "j7", "j8",
"k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8",
"ei", "ej", "ek"], filter );
SetFilterObj( A, IsAlgebraWithOne );
SetFilterObj( A, IsJordanAlgebra );
SetJordanRank( A, 3 );
SetJordanDegree( A, 8 );
SetJordanOffDiagonalBasis( A, Basis(OctonionAlgebra(Rationals)) );
SetJordanHomotopeVector( A, One(A) );
SetJordanBasisTraces( A, List(Basis(A),
j -> (Rank(j)/Dimension(FamilyObj(j)!.fullSCAlgebra))*Trace(AdjointMatrix(Basis(FamilyObj(j)!.fullSCAlgebra), j)))
);
return A;
end );
A:= AlgebraWithOne( F, CanonicalBasis( stored ), "basis" );
SetGeneratorsOfAlgebra( A, GeneratorsOfAlgebraWithOne( A ) );
SetIsFullSCAlgebra( A, true );
SetFilterObj( A, IsJordanAlgebra );
SetFilterObj( A, IsAlgebraWithOne);
SetJordanRank( A, 3 );
SetJordanDegree( A, 8 );
SetJordanOffDiagonalBasis( A, Basis(OctonionAlgebra(Rationals)) );
SetJordanHomotopeVector( A, One(A) );
SetJordanBasisTraces( A, List(Basis(A),
j -> (Rank(j)/Dimension(FamilyObj(j)!.fullSCAlgebra))*Trace(AdjointMatrix(Basis(FamilyObj(j)!.fullSCAlgebra), j)))
);
jordan_basis := HermitianJordanAlgebraBasis(3, CanonicalBasis(OctonionAlgebra(Rationals)) );
e := jordan_basis{[1..3]};
i := jordan_basis{[20..27]};
j := ComplexConjugate(jordan_basis{[12..19]});
k := jordan_basis{[4..11]};
jordan_basis := Concatenation([i,j,k,e]);
SetJordanMatrixBasis( A, jordan_basis );
return A;
end );
InstallGlobalFunction( HermitianMatrixToAlbertVector,
function(mat)
local temp;
if not IsMatrix(mat) or not DimensionsMat(mat) = [3,3] or not IsSubset(OctonionAlgebra(Rationals), Flat(mat)) then
return fail;
fi;
if ComplexConjugate(TransposedMat(mat)) <> mat then
return fail;
fi;
temp := HermitianMatrixToJordanCoefficients(mat, Basis(OctonionAlgebra(Rationals)));
temp := Concatenation([temp{[20..27]}, -temp{[12..18]}, temp{[19]}, temp{[4..11]}, temp{[1..3]}]);
return LinearCombination(Basis(AlbertAlgebra(Rationals)), temp);
end);
InstallGlobalFunction( AlbertVectorToHermitianMatrix,
function(vec)
if not IsAlbertAlgebraObj(vec) then return fail; fi;
return LinearCombination(JordanMatrixBasis(AlbertAlgebra(Rationals)), ExtRepOfObj(vec));
end);
# See Faraut and Koranyi p. 32
InstallMethod( JordanQuadraticOperator,
"for a Jordan algebra element",
[ IsJordanAlgebraObj ],
function(j)
return 2*AdjointMatrix(CanonicalBasis(FamilyObj(j)!.fullSCAlgebra), j)^2 - AdjointMatrix(CanonicalBasis(FamilyObj(j)!.fullSCAlgebra), j^2);
end);
InstallMethod( JordanQuadraticOperator,
"for a pair of Jordan algebra elements",
[ IsJordanAlgebraObj, IsJordanAlgebraObj ],
function(j, k)
return 2*j*(j*k) - (j^2)*k;
end);
InstallMethod( JordanTripleSystem,
"for three Jordan algebra elements",
[IsJordanAlgebraObj, IsJordanAlgebraObj, IsJordanAlgebraObj],
{x,y,z} -> x*(y*z) + (x*y)*z - (x*z)*y
);
# T-Design Tools
InstallGlobalFunction( JacobiPolynomial, function(k, a, b)
local temp, a1, a2, a3, a4, n, x;
if not IsInt(k) and k > -1 then
return fail;
fi;
if not (IsPolynomial(a) or (IsRat(a) and a > -1)) then
return fail;
fi;
if not (IsPolynomial(b) or (IsRat(b) and a > -1)) then
return fail;
fi;
n := k - 1;
a1 := 2*(n+1)*(n+a+b+1)*(2*n+a+b );
a2 := (2*n+a+b+1)*(a^2 - b^2 );
a3 := (2*n + a + b)*(2*n + a + b + 1)*(2*n + a + b + 2 );
a4 := 2*(n+a)*(n+b)*(2*n+a+b+2 );
x := [0,1];
if k = 0 then
return [1];
elif k = -1 then
return [0];
elif k = 1 then
return (1/2)*[a-b,(a+b+2)];
fi;
return ProductCoeffs([a2/a1, a3/a1], JacobiPolynomial(k-1,a,b))-(a4/a1)*JacobiPolynomial(k-2,a,b );
end );
InstallGlobalFunction( Q_k_epsilon, function(k, epsilon, rank, degree, x)
local temp, p, poch, N, m;
if k = 0 and epsilon = 0 then return 1+0*x; fi;
m := degree/2;
N := rank*m;
p := ValuePol(JacobiPolynomial(k, N-m-1, m-1+epsilon), 2*x - 1 );
poch := function(a,n)
if n = 1 then return a;
elif n = 0 then return 1;
elif n < 0 then return 0;
fi;
return Product(List([1..n], b -> a + b -1) );
end;
temp := poch(N, k + epsilon - 1)*poch(N-m, k)*(2*k + N + epsilon - 1 );
temp := temp/(Factorial(k)*poch(m,k+epsilon) );
return temp*p/Value(p, [x], [1] );
end );
InstallGlobalFunction( R_k_epsilon, function(k, epsilon, rank, degree, x)
local temp, n;
temp := 0*x;
for n in [0..k] do
temp := temp + Q_k_epsilon(n, epsilon, rank, degree, x );
od;
return temp;
end );
InstallGlobalFunction( JordanDesignByParameters, function(rank, degree)
local obj, F, x;
# Check that the inputs match a Jordan primitive idempotent space
if not IsInt(rank) or rank < 2 then return fail; fi;
if rank > 2 and not degree in [1,2,4,8] then return fail; fi;
if degree = 8 and rank > 3 then return fail; fi;
# Create the object
obj := Objectify(NewType(NewFamily( "Design"), IsJordanDesign and IsComponentObjectRep, rec()), rec() );
SetFilterObj(obj, IsAttributeStoringRep );
# Assign rank and degree attributes.
SetJordanDesignRank(obj, rank );
SetJordanDesignDegree(obj, degree );
# Assign Spherical or Projective filters.
if rank = 2 then
SetFilterObj(obj, IsSphericalJordanDesign );
fi;
if degree in [1,2,4,8] then
SetFilterObj(obj, IsProjectiveJordanDesign );
fi;
return obj;
end );
InstallMethod( PrintObj,
"for a design",
[ IsJordanDesign ],
function(x)
local text;
Print( "<design with rank ", JordanDesignRank(x), " and degree ", JordanDesignDegree(x), ">" );
end );
InstallMethod(JordanDesignQPolynomials,
"Generic method for designs",
[ IsJordanDesign ],
function(D)
local x, temp;
x := Indeterminate(Rationals, "x" );
temp := function(k)
if IsInt(k) and k > -1 then
return CoefficientsOfUnivariatePolynomial((Q_k_epsilon(k, 0, JordanDesignRank(D), JordanDesignDegree(D), x)) );
fi;
return fail;
end;
return temp;
end );
InstallMethod( JordanDesignConnectionCoefficients,
"Generic method for designs",
[ IsJordanDesign ],
function(D)
local temp;
temp := function(s)
local x, Q, V, basis, mat, k, i;
x := Indeterminate(Rationals, "x" );
Q := List([0..s], i -> Q_k_epsilon(i,0, JordanDesignRank(D), JordanDesignDegree(D), x) );
V := VectorSpace(Rationals, Q );
basis := Basis(V, Q );
mat := [];
for k in [0..s] do
Append(mat, [
Coefficients(basis, x^k)
] );
od;
return mat;
end;
return temp;
end );
InstallMethod( JordanDesignAddAngleSet,
"for designs",
[ IsJordanDesign, IsList ],
function(D, A)
if not (ForAll(A, IsCyc) and
ForAll(A, x -> ComplexConjugate(x) = x) and
ForAll(A, x -> not IsRat(x) or (x < 1 and x >= 0)))
then
return fail;
fi;
SetJordanDesignAngleSet(D, Set(A) );
SetFilterObj(D, IsJordanDesignWithAngleSet );
# Assign Positive Indicator Coefficients filter if applicable.
if [true] = Set(JordanDesignNormalizedIndicatorCoefficients(D), x -> x > 0) then
SetFilterObj(D, IsJordanDesignWithPositiveIndicatorCoefficients );
fi;
return D;
end );
InstallGlobalFunction( JordanDesignByAngleSet, function(rank, degree, A)
local obj, F, x;
obj := JordanDesignByParameters(rank, degree );
if obj = fail then return obj; fi;
# Test the angle set:
if not (ForAll(A, IsCyc) and
ForAll(A, x -> ComplexConjugate(x) = x) and
ForAll(A, x -> not IsRat(x) or (x < 1 and x >= 0)))
then
return fail;
fi;
# Assign angle set.
SetJordanDesignAngleSet(obj, Set(A) );
SetFilterObj(obj, IsJordanDesignWithAngleSet );
# Assign Positive Indicator Coefficients filter if applicable.
if [true] = Set(JordanDesignNormalizedIndicatorCoefficients(obj), x -> x > 0) then
SetFilterObj(obj, IsJordanDesignWithPositiveIndicatorCoefficients );
fi;
return obj;
end );
InstallMethod( PrintObj,
"for a design with angle set",
[ IsJordanDesignWithAngleSet ],
function(x)
local text;
Print( "<design with rank ", JordanDesignRank(x), ", degree ", JordanDesignDegree(x), ", and angle set ", JordanDesignAngleSet(x), ">" );
end );
InstallMethod( JordanDesignNormalizedAnnihilatorPolynomial,
"generic method for designs",
[ IsJordanDesignWithAngleSet ],
function(D)
local x, F, A;
A := JordanDesignAngleSet(D );
x := Indeterminate(Field(A), "x" );
F := Product(List(A, a -> (x - a)/(1-a)) );
return CoefficientsOfUnivariatePolynomial(F );
end );
InstallMethod( JordanDesignNormalizedIndicatorCoefficients,
"generic method for designs",
[ IsJordanDesignWithAngleSet ],
function(D)
local x, r, d, Q, F, V, basis;
r := JordanDesignRank(D );
d := JordanDesignDegree(D );
x := Indeterminate(Field(JordanDesignAngleSet(D)), "x" );
Q := k -> Q_k_epsilon(k, 0, r, d, x );
F := ValuePol(JordanDesignNormalizedAnnihilatorPolynomial(D), x );
V := VectorSpace(Field(JordanDesignAngleSet(D)), List([0..Degree(F)], Q) );
basis := Basis(V, List([0..Degree(F)], Q) );
return Coefficients(basis, F );
end );
InstallMethod( JordanDesignSpecialBound,
"generic method for designs",
[ IsJordanDesignWithAngleSet and IsJordanDesignWithPositiveIndicatorCoefficients ],
function(D)
if Filtered(JordanDesignNormalizedIndicatorCoefficients(D), x -> x < 0) <> [] then
return fail;
fi;
return 1/JordanDesignNormalizedIndicatorCoefficients(D)[1];
end );
InstallMethod( JordanDesignAddCardinality,
"for designs with angle sets",
[ IsJordanDesignWithAngleSet, IsInt ],
function(D, v)
local obj;
SetJordanDesignCardinality(D, v );
SetFilterObj(D, IsJordanDesignWithCardinality );
if JordanDesignSpecialBound(D) = JordanDesignCardinality(D) then
SetFilterObj(D, IsSpecialBoundJordanDesign );
JordanDesignStrength(D );
fi;
return D;
end );
InstallMethod( PrintObj,
"for a design with cardinality",
[ IsJordanDesignWithCardinality ],
function(x)
Print( "<design with rank ", JordanDesignRank(x), ", degree ", JordanDesignDegree(x), ", cardinality ", JordanDesignCardinality(x), ", and angle set ", JordanDesignAngleSet(x), ">" );
end );
InstallMethod( JordanDesignStrength,
"method for designs with positive indicator coefficients",
[ IsJordanDesignWithPositiveIndicatorCoefficients and IsJordanDesignWithCardinality and IsSpecialBoundJordanDesign ],
function(D)
local s, i, t, e;
s := Size(JordanDesignAngleSet(D) );
for i in [0..s] do
if JordanDesignIndicatorCoefficients(D)[i+1] = 1 then
t := s + i;
fi;
od;
SetFilterObj(D, IsJordanDesignWithStrength );
if 0 in JordanDesignAngleSet(D) then
e := 1;
else
e := 0;
fi;
# Check for tightness, etc
if t = 2*s - e then
SetFilterObj(D, IsTightJordanDesign );
return t;
fi;
if t >= 2*s - 2 then
SetFilterObj(D, IsAssociationSchemeJordanDesign );
return t;
fi;
return t;
end );
InstallMethod( JordanDesignAnnihilatorPolynomial,
"generic method for designs",
[ IsJordanDesignWithAngleSet and IsJordanDesignWithCardinality ],
function(D)
return JordanDesignCardinality(D)*JordanDesignNormalizedAnnihilatorPolynomial(D );
end );
InstallMethod( JordanDesignIndicatorCoefficients,
"generic method for designs",
[ IsJordanDesignWithAngleSet and IsJordanDesignWithCardinality ],
function(D)
return JordanDesignCardinality(D)*JordanDesignNormalizedIndicatorCoefficients(D );
end );
InstallMethod( PrintObj,
"for a design with angle set and strength",
[IsJordanDesignWithAngleSet and IsJordanDesignWithStrength],
function(x)
local text;
Print( "<", JordanDesignStrength(x), "-design with rank ", JordanDesignRank(x), ", degree ", JordanDesignDegree(x), ", cardinality ", JordanDesignCardinality(x), ", and angle set ", JordanDesignAngleSet(x), ">" );
end );
InstallMethod( PrintObj,
"for a tight design",
[IsTightJordanDesign],
function(x)
Print( "<Tight ", JordanDesignStrength(x), "-design with rank ", JordanDesignRank(x), ", degree ", JordanDesignDegree(x), ", cardinality ", JordanDesignCardinality(x), ", and angle set ", JordanDesignAngleSet(x), ">" );
end );
InstallMethod( JordanDesignSubdegrees,
"method for a regular scheme design",
[ IsRegularSchemeJordanDesign and IsJordanDesignWithCardinality and IsJordanDesignWithAngleSet ],
function(D)
local rank, degree, v, A, f, s, mat, vec, i;
--> --------------------
--> maximum size reached
--> --------------------
[ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet)
]
|
2026-04-02
|