<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPE Book SYSTEM "gapdoc.dtd">
<Book Name="ALCO">
<#Include SYSTEM "title.xml">
<TableOfContents />
<Body>
<Chapter>
<Heading>Introduction</Heading> The <Package>ALCO</Package> package provides tools for
algebraic combinatorics, most of which was written for &GAP; during the author's Ph.D. program
Key="nasmith_tight_2023" />. This package provides implementations in &GAP; of octonion
algebras, Jordan algebras, and certain important integer subrings of those algebras. It also
provides tools to compute the parameters of t-designs in spherical and projective spaces
(modeled as manifolds of primitive idempotent elements in a simple Euclidean Jordan algebra).
Finally, this package provides tools to explore octonion lattice constructions, including
octonion Leech lattices. The following examples illustrate how one might use this package to
explore these structures.<P /> The <Package>ALCO</Package> package allows users to work with
the octavian integer ring (also known as the octonion arithmetic), which is described
carefully in <Cite Key="conway_quaternions_2003" Where="chaps. 9-11" />. In the example
below, we verify that the octavian integers define an <Math>E_8</Math> (Gossett) lattice
relative to the standard octonion inner product: <Example><![CDATA[gap> O := OctavianIntegers;
OctavianIntegers
gap> g := List(Basis(O), x -> List(Basis(O), y ->
> Norm(x+y) - Norm(x) - Norm(y)));;
gap> Display(g);
[ [ 2, 0, -1, 0, 0, 0, 0, 0 ],
[ 0, 2, 0, -1, 0, 0, 0, 0 ],
[ -1, 0, 2, -1, 0, 0, 0, 0 ],
[ 0, -1, -1, 2, -1, 0, 0, 0 ],
[ 0, 0, 0, -1, 2, -1, 0, 0 ],
[ 0, 0, 0, 0, -1, 2, -1, 0 ],
[ 0, 0, 0, 0, 0, -1, 2, -1 ],
[ 0, 0, 0, 0, 0, 0, -1, 2 ] ]
gap> IsGossetLatticeGramMatrix(g);
true]]></Example> <P /> The <Package>ALCO</Package>
package also provides tools to construct octonion lattices, including octonion Leech lattices
(see for example <Cite Key="wilson_octonions_2009" />). In the following example we compute
the shortest vectors in the <Code>OctavianIntegers</Code> lattice and select one that is a
root of polynomial <Math>x^2 + x + 2</Math>. We use this root <Code>s</Code> to define a set
<Code>gens</Code> of octonion triples to serve as generators for the lattice. Finally, we construct
the lattice <Code>L</Code> and confirm that it is a Leech lattice.
<Example><![CDATA[gap> short := Set(ShortestVectors(g,4).vectors, y ->
> LinearCombination(Basis(OctavianIntegers), y));;
gap> s := First(short, x -> x^2 + x + 2*One(x) = Zero(x));
(-1)*e1+(-1/2)*e2+(-1/2)*e3+(-1/2)*e4+(-1/2)*e8
gap> gens := List(Basis(OctavianIntegers), x ->
> x*[[s,s,0],[0,s,s],ComplexConjugate([s,s,s])]);;
gap> gens := Concatenation(gens);;
gap> L := OctonionLatticeByGenerators(gens, One(O)*IdentityMat(3)/2);
<free left module over Integers, with 24 generators>
gap> IsLeechLatticeGramMatrix(GramMatrix(L));
true]]></Example> We can also construct and study simple Euclidean Jordan algebras (described well in <Cite Key="faraut_analysis_1994" />), including the Albert algebra: <Example><![CDATA[gap> J := AlbertAlgebra(Rationals);
<algebra-with-one of dimension 27 over Rationals>
gap> SemiSimpleType(Derivations(Basis(J))); "F4"
gap> i := Basis(J){[1..8]};
[ i1, i2, i3, i4, i5, i6, i7, i8 ]
gap> j := Basis(J){[9..16]};
[ j1, j2, j3, j4, j5, j6, j7, j8 ]
gap> k := Basis(J){[17..24]};
[ k1, k2, k3, k4, k5, k6, k7, k8 ]
gap> e := Basis(J){[25..27]};
[ ei, ej, ek ]
gap> ForAll(e, IsIdempotent);
true
gap> Set(i, x -> x^2);
[ ej+ek ]
gap> Set(j, x -> x^2);
[ ei+ek ]
gap> One(J);
ei+ej+ek
gap> Determinant(One(J));
1
gap> Trace(One(J));
3]]></Example>
</Chapter>
<Chapter>
<Heading>Octonions</Heading> Let <Math>C</Math> be a vector space over field <Math>k</Math>
equipped with a non-degenerate quadratic form <Math>N:C \rightarrow k</Math>. If <Math>C</Math>
is also an algebra with a product that satifies the composition rule <Math>N(x y) = N(x) N(y)</Math> for all <Math>x,y</Math> in <Math>C</Math> then we call <Math>C</Math> a <Emph>composition algebra</Emph>. Quaternions and octonions are
examples of composition algebras.<P /> As described in <Cite Key="springer_octonions_2000"
Where="Theorm 1.6.2" />, a composition algebra has dimension <Math>1</Math>, <Math>2</Math>, <Math>
4</Math>, or <Math>8</Math>. Compositions algebras of dimension <Math>1</Math> or <Math>2</Math>
are commutative and associative. A <Emph>quaternion algebra</Emph> is a composition algebra of
dimension <Math>4</Math>. Quaternion algebras are associative but noncommutative. An <Emph>octonion
algebra</Emph> is a composition algebra of dimension <Math>8</Math>. Octonion algebras are
both noncommutative and nonassociative but still have many interesting properties. <P /> The
non-degenerate quadratic form <Math>N</Math> of a composition algebra is called the <Emph>norm</Emph>
of that algebra. In fact, a composition algebra is determined up to isomorphism by its norm so
the task of classifying composition algebras is equivalent to the task of classifying the
possible norms in that vector space <Cite Key="springer_octonions_2000"
Where="chap. 1, sec. 7" />. A norm is either isotropic or anisotropic according to whether
or not there exists a non-zero element <Math>x</Math> such that <Math>N(x) = 0</Math>. A
composition algebra with a isotropic norm is called a <Emph>split composition algebra</Emph>.
A composition algebra with an anisotropic norm is called a <Emph>division composition algebra</Emph>
since each non-zero element has an inverse. An important theorem <Cite
Key="springer_octonions_2000" Where="Theorem 1.8.1" /> shows that for each field <Math>k</Math>
there exists up to isomorphism one split composition algebra of dimension <Math>2</Math>, <Math>
4</Math>, and <Math>8</Math>.<!-- The built-in <Ref Func="OctaveAlgebra"/> function in &GAP; constructs the split-octonion
algebra over the field given as the argument. <P/> -->
in &GAP; constructs the split-octonion algebra over the field given as the argument. <P /> As
described in <Cite Key="springer_octonions_2000" Where="chap. 1, sec. 10" />, there are
precisely one division composition algebra of dimension <Math>4</Math> and one of dimension <Math>
8</Math> over the real number field (likewise over the rationals). The <Package>ALCO</Package>
package provides constructions of <Emph>non-split</Emph> octonion algebras, provided that the
algebra is constructed over a suitable field (e.g., octonions over any finite field are
split). <Section Label="sec:octalg">
<Heading>Octonion Algebras</Heading>
<ManSection>
<Heading>Octonion Filters</Heading>
<Filt Name="IsOctonion" />
<Filt Name="IsOctonionCollection" />
<Filt Name="IsOctonionAlgebra" />
<Description>These filters determine whether an element is an octonion, an octonion
collection, or an octonion algebra.</Description>
</ManSection>
<ManSection>
<Func Name="OctonionAlgebra" Arg="F" />
<Description> Returns an octonion algebra over field <Arg>F</Arg> in a standard
orthonormal basis <Math>\{e_{i}, i = 1,...,8\}</Math> such that <Math>1 = e_8</Math> is the
identity element and <Math>e_{i} = e_{i+1}e_{i+3} = - e_{i+3}e_{i+1}</Math> for <Math>i =
1,...,7</Math>, with indices evaluated modulo 7. This corresponds to the basis provided in <Cite
Key="baez_octonions_2002" /> and <Cite Key="conway_quaternions_2003" /> (except that <Code>
e7</Code> corresponds to <Math>e_0</Math> in the literature, since the first entry in a &GAP;
list has index 1). Whether or not the algebra constructed is a division algebra or a
split-octonion algebra depends on the choice of field <Arg>F</Arg>. For example,
<Code>OctonionAlgebra(Rationals)</Code> is a division composition algebra, but
<Code>OctonionAlgebra(GF(3))</Code> is a split composition algebra.
Other examples are discussed in <Cite
Key="springer_octonions_2000" Where="chap. 1, sec. 10" />.
<Example><![CDATA[gap> O := OctonionAlgebra(Rationals);
<algebra-with-one of dimension 8 over Rationals>
gap> LeftActingDomain(O);
Rationals
gap> IsAssociative(O);
false
gap> e := BasisVectors(Basis(O));
[ e1, e2, e3, e4, e5, e6, e7, e8 ]
gap> One(O);
e8
gap> e[1]*e[2];
e4
gap> e[2]*e[1];
(-1)*e4
gap> Derivations(Basis(O));
<Lie algebra of dimension 14 over Rationals>
gap> SemiSimpleType(last); "G2"]]></Example>
</Description>
</ManSection>
<ManSection>
<Heading>Octavian Integers</Heading>
<Var Name="OctavianIntegers" />
<Oper Name="IsOctavianInt" Arg="x" />
<Description> The <Code>OctavianIntegers</Code> are a subring of the octonion algebra with
elements that have the geometry of scaled <Math>E_8</Math> lattice. This ring is named and
studied in <Cite Key="conway_quaternions_2003" Where="p. 105" />. <Code>
CanonicalBasis(OctavianIntegers)</Code> returns <Ref Var="OctonionE8Basis" />. We can test
whether an octonion is in <Code>OctavianIntegers</Code> using the operation
<Code>IsOctavianInt(<Arg>x</Arg>)</Code>.
<Example><![CDATA[gap> a := BasisVectors(Basis(OctavianIntegers));;
gap> for x in a do Display(x); od;
(-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7
(-1/2)*e1+(-1/2)*e2+(-1/2)*e4+(-1/2)*e7
(1/2)*e2+(1/2)*e3+(-1/2)*e5+(-1/2)*e7
(1/2)*e1+(-1/2)*e3+(1/2)*e4+(1/2)*e5
(-1/2)*e2+(1/2)*e3+(-1/2)*e5+(1/2)*e7
(1/2)*e2+(-1/2)*e4+(1/2)*e5+(-1/2)*e6
(-1/2)*e1+(-1/2)*e3+(1/2)*e4+(-1/2)*e5
(1/2)*e1+(-1/2)*e4+(1/2)*e6+(-1/2)*e8
gap> ForAll(a, IsOctavianInt);
true
gap> ForAll(a/2, IsOctavianInt);
false]]></Example>
</Description>
</ManSection>
<ManSection>
<Var Name="OctonionE8Basis" />
<Description> The <Package>ALCO</Package> package also loads a basis for
<Code>OctonionAlgebra(<Arg>Rationals</Arg>)</Code> which also serves as generators for
<Ref Var="OctavianIntegers" />. This octonion integer lattice has the geometry of a
<Math>E_8</Math> (Gossett) lattice relative to the inner product defined by the octonion norm.
<Example><![CDATA[gap> BasisVectors(OctonionE8Basis) = BasisVectors(Basis(OctavianIntegers));
true
gap> g := List(OctonionE8Basis, x -> List(OctonionE8Basis, y ->
> Norm(x+y) - Norm(x) - Norm(y)));;
gap> IsGossetLatticeGramMatrix(g);
true]]></Example>
</Description>
</ManSection>
</Section>
<Section
Label="sec:octattr">
<Heading>Properties of Octonions</Heading>
<ManSection>
<Meth Name="Norm" Arg="x" Label="Octonions" />
<Description>Returns the norm of octonion <Arg>x</Arg>. Recall that an octonion algebra
with norm <Math>N</Math> satisfies the composition property <Math>N(xy) = N(x)N(y)</Math>.
In the canonical basis for <Ref Func="OctonionAlgebra" />, the norm is the sum of the squares
of the coefficients.
<Example><![CDATA[gap> Oct := OctonionAlgebra(Rationals);;
gap> List(Basis(Oct), Norm);
[ 1, 1, 1, 1, 1, 1, 1, 1 ]
gap> x := Random(Oct);; y := Random(Oct);;
gap> Norm(x*y) = Norm(x)*Norm(y);
true]]></Example>
</Description>
</ManSection>
<ManSection>
<Meth Name="Trace" Arg="x" Label="Octonions" />
<Description>Returns the trace of octonion <Arg>x</Arg>. In the canonical basis for <Ref
Func="OctonionAlgebra" />, the trace is twice the coefficient of the identity element
<Code>e8</Code>. The trace and real part are related via
<Code>RealPart(<Arg>x</Arg>) = Trace(<Arg>x</Arg>)*One(<Arg>x</Arg>)/2</Code>.
Note that <Code>Trace(<Arg>x</Arg>)</Code> is an element of
<Code>LeftActingDomain(<Arg>A</Arg>)</Code>, where <Arg>A</Arg> is the octonion algebra
containing <Arg>x</Arg>.
<Example><![CDATA[gap> e := BasisVectors(Basis(OctonionAlgebra(Rationals)));
[ e1, e2, e3, e4, e5, e6, e7, e8 ]
gap> List(e, Trace);
[ 0, 0, 0, 0, 0, 0, 0, 2 ]
gap> List(e, RealPart);
[ 0*e1, 0*e1, 0*e1, 0*e1, 0*e1, 0*e1, 0*e1, e8 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Meth Name="ComplexConjugate" Arg="x" Label="Octonions" />
<Description>Returns the octonion conjugate of octonion <Arg>x</Arg>, defined by <Code>One(x)*Trace(x)
- x</Code>. In the canonical basis of <Ref Func="OctonionAlgebra" />, this method negates the
coefficients of <Math>e_1, e_2, \ldots, e_7</Math> but leaves the identity <Math>e_8</Math>
fixed. <Example><![CDATA[gap> e := BasisVectors(Basis(OctonionAlgebra(Rationals)));
[ e1, e2, e3, e4, e5, e6, e7, e8 ]
gap> List(e, ComplexConjugate);
[ (-1)*e1, (-1)*e2, (-1)*e3, (-1)*e4, (-1)*e5, (-1)*e6, (-1)*e7, e8 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Meth Name="RealPart" Arg="x" Label="Octonions" />
<Description>Returns the real component of octonion <Arg>x</Arg>, defined by <Code>
(1/2)*One(x)*Trace(x)</Code>. Note that <Code>RealPart</Code> returns an octonion in the subspace spanned by the octonion identity element while <Code>Trace</Code> returns an element in the coefficient field of the octonion algebra.
<Example><![CDATA[gap> e := BasisVectors(Basis(OctonionAlgebra(Rationals)));
[ e1, e2, e3, e4, e5, e6, e7, e8 ]
gap> List(e, RealPart);
[ 0*e1, 0*e1, 0*e1, 0*e1, 0*e1, 0*e1, 0*e1, e8 ]]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>Other Octonion Tools</Heading>
<ManSection>
<Heading>Converting Octonion Vectors</Heading>
<Func Name="OctonionToRealVector" Arg="B, x" />
<Func Name="RealToOctonionVector" Arg="B, y" />
<Description> Let <Arg>x</Arg> be an octonion vector of the form <Math>x = (x_1, x_2, ...,
x_n)</Math>, for <Math>x_i</Math> octonion valued coefficients. Let <Arg>B</Arg> be a
basis for the octonion algebra containing coefficients <Math>x_i</Math>.
The function <Code>OctonionToRealVector(<Arg>B</Arg>, <Arg>x</Arg>)</Code> returns
a vector <Arg>y</Arg> of length <Math>8n</Math> containing the concatenation of the
coefficients of <Math>x_i</Math> in the octonion basis given by <Arg>B</Arg>.
The function <Code>RealToOctonionVector(<Arg>B</Arg>, <Arg>y</Arg>)</Code> provides the inverse operation.
<Example><![CDATA[gap> O := UnderlyingLeftModule(OctonionE8Basis);
<algebra-with-one of dimension 8 over Rationals>
gap> BasisVectors(CanonicalBasis(O));
[ e1, e2, e3, e4, e5, e6, e7, e8 ]
gap> x := 2*OctonionE8Basis{[1,2]};
[ (-1)*e1+e5+e6+e7, (-1)*e1+(-1)*e2+(-1)*e4+(-1)*e7 ]
gap> y := OctonionToRealVector(CanonicalBasis(O), x);
[ -1, 0, 0, 0, 1, 1, 1, 0, -1, -1, 0, -1, 0, 0, -1, 0 ]
gap> RealToOctonionVector(CanonicalBasis(O), y);
[ (-1)*e1+e5+e6+e7, (-1)*e1+(-1)*e2+(-1)*e4+(-1)*e7 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="VectorToIdempotentMatrix" Arg="x" />
<Description> Let <Arg>x</Arg> be a vector satisfying <Code>IsHomogeneousList</Code> and
<Code>IsAssociative</Code> with elements that satisfy <Code>IsCyc</Code>,
<Code>IsQuaternion</Code>, or <Code>IsOctonion</Code>. Then this function returns
the idempotent matrix <Code>M/Trace(M)</Code> where
<Code>M = TransposedMat([ComplexConjugate(<Arg>x</Arg>)])*[<Arg>x</Arg>]</Code>.
<Example><![CDATA[gap> Oct := OctonionAlgebra(Rationals);;
gap> x := Basis(Oct){[8,1,2]};
[ e8, e1, e2 ]
gap> y := VectorToIdempotentMatrix(x);; Display(y);
[ [ (1/3)*e8, (1/3)*e1, (1/3)*e2 ],
[ (-1/3)*e1, (1/3)*e8, (-1/3)*e4 ],
[ (-1/3)*e2, (1/3)*e4, (1/3)*e8 ] ]
gap> IsIdempotent(y);
true]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="WeylReflection" Arg="r, x" />
<Description> Let <Arg>r</Arg> be a vector satisfying <Code>IsHomogeneousList</Code> and <Code>
IsAssociative</Code> with elements in <Code>IsCyc</Code>, <Code>IsQuaternion</Code>, or <Code>
IsOctonion</Code> and let <Code>IsHomogeneousList(Flat([<Arg>r</Arg>,<Arg>x</Arg>]))</Code>.
Then this function returns the Weyl reflection of vector <Arg>x</Arg> using the projector
defined by <Code>VectorToIdempotentMatrix(<Arg>r</Arg>)</Code>. Specifically, the result is <Code>x
- 2*x*VectorToIdempotentMatrix(r)</Code>.
<Example><![CDATA[gap> WeylReflection([1,0,1],[0,1,1]);
[ -1, 1, 0 ]]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>Quaternion Tools</Heading>
The <Package>ALCO</Package> package provides some additional tools for studying quaternion algebras in &GAP;. These tools include methods to compute the quaternion norm and trace, certain important bases, and the subrings generated by those bases. &GAP; already provides some built-in tools to construct and study the quaternion algebra in the standard Hamiltonian basis. The following example illustrates these tools:
<Example><![CDATA[gap> H := QuaternionAlgebra(Rationals);
<algebra-with-one of dimension 4 over Rationals>
gap> IsQuaternion(Random(H));
true
gap> IsAssociative(H);
true
gap> IsCommutative(H);
false
gap> One(H);
e
gap> b := BasisVectors(CanonicalBasis(H));
[ e, i, j, k ]
gap> List(b, ComplexConjugate);
[ e, (-1)*i, (-1)*j, (-1)*k ]
gap> List(b, Inverse);
[ e, (-1)*i, (-1)*j, (-1)*k ]
gap> List(b, RealPart);
[ e, 0*e, 0*e, 0*e ]
gap> List(b, ImaginaryPart);
[ 0*e, e, k, (-1)*j ]]]></Example>
Note that the &GAP; method <Code>ImaginaryPart</Code> acting on objects that satisfy <Code>IsQuaternion</Code> involves dividing by <Code>i</Code>, which yields a different result than the <Code>x - RealPart(x)</Code> that some users may expect. The <Package>ALCO</Package> package does not define an <Code>ImaginaryPart</Code> method for octonions in order to avoid confusion about the behaviour of that method when applied to quaternions or octonions.
<ManSection>
<Meth Name="Norm" Arg="x" Label="Quaternions" />
<Description>Returns the norm of quaternion <Arg>x</Arg>. Recall that a quaternion algebra with
norm <Math>N</Math>
satisfies the composition property <Math>N(xy) = N(x)N(y)</Math>. In the canonical basis of
<Code>QuaternionAlgebra</Code>, the norm is the sum of the squares of the coefficients.
<Example><![CDATA[gap> H := QuaternionAlgebra(Rationals);;
gap> b := BasisVectors(CanonicalBasis(H));
[ e, i, j, k ]
gap> List(b, Norm);
[ 1, 1, 1, 1 ]
gap> x := Random(H);; y := Random(H);;
gap> Norm(x*y) = Norm(x)*Norm(y);
true]]></Example>
</Description>
</ManSection>
<ManSection>
<Meth Name="Trace" Arg="x" Label="Quaternions" />
<Description>Returns the trace of quaternion <Arg>x</Arg>, such that <Code>RealPart(<Arg>x</Arg>)
= Trace(<Arg>x</Arg>)*One(<Arg>x</Arg>)/2</Code>. In the canonical basis of
<Code>QuaternionAlgebra</Code>, the trace is twice the coefficient of the identity element.
<Example><![CDATA[gap> H := QuaternionAlgebra(Rationals);;
gap> b := BasisVectors(CanonicalBasis(H));
[ e, i, j, k ]
gap> List(b, Trace);
[ 2, 0, 0, 0 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Heading>Hurwitz Integers</Heading>
<Var Name="HurwitzIntegers" />
<Oper Name="IsHurwitzInt" Arg="x" />
<Description> The <Code>HurwitzIntegers</Code> are a subring of the quaternion algebra
with elements that have the geometry of scaled <Math>D_4</Math> lattice. This ring is named
and studied in <Cite Key="conway_quaternions_2003" Where="p. 55" />.
<Code>CanonicalBasis(HurwitzIntegers)</Code> returns <Ref
Var="QuaternionD4Basis" />. We can test
whether a quaternion is in <Code>HurwitzIntegers</Code> using the operation
<Code>IsHurwitzInt(<Arg>x</Arg>)</Code>. <Example><![CDATA[gap> f := BasisVectors(Basis(HurwitzIntegers));;
gap> for x in f do Display(x); od;
(-1/2)*e+(-1/2)*i+(-1/2)*j+(1/2)*k
(-1/2)*e+(-1/2)*i+(1/2)*j+(-1/2)*k
(-1/2)*e+(1/2)*i+(-1/2)*j+(-1/2)*k
e
gap> ForAll(f, IsHurwitzInt);
true
gap> ForAll(f/2, IsHurwitzInt);
false]]></Example>
</Description>
</ManSection>
<ManSection>
<Var Name="QuaternionD4Basis" />
<Description> The <Package>ALCO</Package> package loads a basis for a quaternion algebra
over &QQ; with the geometry of a <Math>D_4</Math> simple root system. The &ZZ;-span of this
basis is the <Ref Var="HurwitzIntegers" /> ring. These basis vectors close under pairwise
reflection or multiplication to form a <Math>
D_4</Math> root system. <Example><![CDATA[gap> B := QuaternionD4Basis;;
gap> for x in BasisVectors(B) do Display(x); od;
(-1/2)*e+(-1/2)*i+(-1/2)*j+(1/2)*k
(-1/2)*e+(-1/2)*i+(1/2)*j+(-1/2)*k
(-1/2)*e+(1/2)*i+(-1/2)*j+(-1/2)*k
e]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>Icosian Tools</Heading>
The icosian ring is a subring of the quaternion algebra over the "golden field" <Math>\mathbb{Q}(\sqrt{5})</Math>
This ring is described and studied in <Cite Key="conway_sphere_2013" Where="pp. 207-211" /> and <Cite Key="wilson_finite_2009" Where="p. 220" />.
The icosian ring has <Math>120</Math> units, or elements with quaternion norm of <Math>1</Math>. These units are closed under quaternion multiplication.
These icosian units also exhibit a <Math>H_4</Math> geometry in the sense that they are closed under Weyl reflection relative to the standard Euclidean inner product defined by the quaternion norm. The Coxeter group generated by these reflections is the group <Math>W(H_4)</Math>.
The coefficients of an icosian in the standard quaternion basis belong to the integer subring of the golden field, meaning that these coefficients have the form <Math>a + b \sigma</Math>, where <Math>a,b</Math> are rational integers and <Math>\sigma = (1-\sqrt{5})/2</Math>.
The Euclidean inner product between any two icosians will be a golden field integer. As described in the references given above, if we define a new inner product between icosians that discards the <Math>\sigma</Math>-coefficient <Math>b</Math> then the icosian ring will exhibit the geometry of an <Math>E_8</Math> lattice relative to this new inner product.
It is also possible to define a Leech lattice geometry on icosian triples. <P/>
The <Package>ALCO</Package> package provides tools to explore these icosian properties and construct certain important lattices using icosians. Note that the golden field can be constructed in &GAP; as <Code>NF(5, [ 1, 4 ])</Code> or <Code>Field(Sqrt(5))</Code> and that <Math>\sigma</Math> is given by <Code>-EB(5)</Code>.
<ManSection>
<Heading>Icosian Ring</Heading>
<Var Name="IcosianRing" />
<Oper Name="IsIcosian" Arg="x" />
<Description> The <Code>IcosianRing</Code> is a subring of the the quaternion algebra over
<Code>NF(5,[1,4])</Code> generated by a set of vectors with an <Math>H_4</Math> geometry. This ring
is described well in <Cite Key="wilson_finite_2009" Where="p. 220" />.
<Code>CanonicalBasis(IcosianRing)</Code> returns <Ref
Var="IcosianH4Generators" />. We can test whether a
quaternion is in <Code>IcosianRing</Code> using the operation <Code>IsIcosian(<Arg>x</Arg>)</Code>.
Note that a quaternion is an icosian when it is a &ZZ;-linear combination of the union of
<Code>Basis(IcosianRing)</Code> and <Code>Basis(IcosianRing)*EB(5)</Code>.
<Example><![CDATA[gap> f := BasisVectors(Basis(IcosianRing));;
gap> for x in f do Display(x); od;
(-1)*i
(-1/2*E(5)^2-1/2*E(5)^3)*i+(1/2)*j+(-1/2*E(5)-1/2*E(5)^4)*k
(-1)*j
(-1/2*E(5)-1/2*E(5)^4)*e+(1/2)*j+(-1/2*E(5)^2-1/2*E(5)^3)*k
gap> ForAll(f, IsIcosian);
true
gap> ForAll(f/2, IsIcosian);
false
gap> ForAll(f*EB(5), IsIcosian);
true
gap> ForAll(f*Sqrt(5), IsIcosian);
true
gap> ForAll(f*(1-Sqrt(5))/2, IsIcosian);
true
gap> ForAll(f*(1+Sqrt(5))/2, IsIcosian);
true]]></Example>
</Description>
</ManSection>
<ManSection>
<Var Name="IcosianH4Generators" />
<Description> The <Package>ALCO</Package> package loads this variable as a basis for a
quaternion algebra over <Code>NF(5,[1,4])</Code>. Note that a quaternion is an icosian when it
is a &ZZ;-linear combination of the union of <Code>
IcosianH4Generators</Code> and <Code>IcosianH4Generators*EB(5)</Code>. These basis vectors close
under pairwise reflection or multiplication to form a <Math>H_4</Math> set of vectors. <Example><![CDATA[gap> f := BasisVectors(IcosianH4Generators);;
gap> for x in f do Display(x); od;
(-1)*i
(-1/2*E(5)^2-1/2*E(5)^3)*i+(1/2)*j+(-1/2*E(5)-1/2*E(5)^4)*k
(-1)*j
(-1/2*E(5)-1/2*E(5)^4)*e+(1/2)*j+(-1/2*E(5)^2-1/2*E(5)^3)*k]]></Example>
</Description>
</ManSection>
<ManSection>
<Heading>GoldenModSigma</Heading>
<Func Name="GoldenModSigma" Arg="x" />
<Description> For <Arg>x</Arg> in the golden field <Code>NF(5,[ 1, 4 ])</Code>, this
function returns the rational coefficient of <Code>1</Code> in the basis
<Code>Basis(NF(5,[ 1, 4 ]), [1, (1-Sqrt(5))/2])</Code>.
<Example><![CDATA[gap> sigma := (1-Sqrt(5))/2;; tau := (1+Sqrt(5))/2;;
gap> x := 5 + 3*sigma;; GoldenModSigma(x);
5
gap> GoldenModSigma(sigma);
0
gap> GoldenModSigma(tau);
1]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>Other Integer Rings</Heading> Certain addition integer subrings of elements
satisfying <Code>IsCyc</Code> are also included in the <Package>ALCO</Package> package.
The rings constructed below are described in <Cite Key="conway_quaternions_2003" Where="pp. 16-18" />.
<ManSection>
<Var Name="EisensteinIntegers" />
<Oper Name="IsEisenInt" Arg="x" />
<Description> The <Code>EisensteinIntegers</Code> is a subring of the complex numbers
generated by <Code>1</Code> and <Code>E(3)</Code>. This subring has the geometry of an
<Math>A_2</Math> lattice. This ring is described well in
<Cite Key="conway_quaternions_2003"
Where="p. 16" />. We can test whether an element in <Code>IsCyc</Code> is an
Eisenstein integer using the operation <Code>IsEisenInt(<Arg>x</Arg>)</Code>.
<Example><![CDATA[gap> f := BasisVectors(Basis(EisensteinIntegers));
[ 1, E(3) ]
gap> IsEisenInt(E(4));
false
gap> IsEisenInt(1+E(3)^2);
true]]></Example>
</Description>
</ManSection>
<ManSection>
<Var Name="KleinianIntegers" />
<Oper Name="IsKleinInt" Arg="x" />
<Description> The <Code>KleinianIntegers</Code> is a subring of the complex numbers
generated by <Code>1</Code> and <Code>(1/2)*(-1+Sqrt(-7))</Code>. This ring is described in
<Cite Key="conway_quaternions_2003" Where="p. 18" />. We can test whether an element in
<Code>IsCyc</Code> is an Kleinian integer using the operation
<Code>IsKleinInt(<Arg>x</Arg>)</Code>.
<Example><![CDATA[gap> f := BasisVectors(Basis(KleinianIntegers));
[ 1, E(7)+E(7)^2+E(7)^4 ]
gap> IsKleinInt(E(4));
false
gap> IsKleinInt(1+E(7)+E(7)^2+E(7)^4);
true]]></Example>
</Description>
</ManSection>
</Section>
</Chapter>
<Chapter>
<Heading>Simple Euclidean Jordan Algebras</Heading> A Jordan algebra is a commutative yet
nonassociative algebra with product <Math>\circ</Math> that satisfies the Jordan identity
<Math>x\circ(x^2 \circ y) = x^2 \circ (x\circ y)</Math>. Given an associative algebra, we can define a
Jordan algebra on the same elements using the product <Math>x \circ y = (xy + yx)/2</Math>. A
Jordan algebra <Math>V</Math> is <Emph>Euclidean</Emph> when there exists an inner product
<Math>(x,y)</Math> on <Math>V</Math> that satisfies <Math>(x\circ y, z) = (y, x\circ z)</Math> for
all <Math>x,y,z</Math> in <Math>V</Math> <Cite Key="faraut_analysis_1994" Where="p. 42" />.
Euclidean Jordan algebras are in one-to-one correspondence with structures known as symmetric
cones, and any Euclidean Jordan algebra is the direct sum of simple Euclidean Jordan algebras
<Cite Key="faraut_analysis_1994" Where="chap. 3" />. <P />
The simple Euclidean Jordan algebras,
in turn, are classified by rank and degree into four families and one exception
<Cite Key="faraut_analysis_1994" Where="chap. 5" />. The first family consists of rank 2 algebras
with degree any positive integer. The remaining three families consist Jordan algebras with
degree 1, 2, or 4 with rank a positive integer greater than 2. The exceptional algebra has
rank 3 and degree 8. <P /> The <Package>ALCO</Package> package provides a number of tools to
construct and manipulate simple Euclidean Jordan algebras (described well in <Cite
Key="faraut_analysis_1994" />), including their homotope and isotopes algebras (defined in <Cite
Key="mccrimmon_taste_2004" Where="p. 86" />). Among other applications, these tools can
reproduce many of the examples found in <Cite Key="elkies_exceptional_1996" /> and <Cite
Key="elkies_cubic_2001" />.
<Section>
<Heading>Filters and Basic Attributes</Heading>
<ManSection>
<Heading>Jordan Filters</Heading>
<Filt Name="IsJordanAlgebra" />
<Filt Name="IsJordanAlgebraObj" />
<Description>These filters determine whether an element is a Jordan algebra
(<Code>IsJordanAlgebra</Code>) or is an element in a Jordan algebra
(<Code>IsJordanAlgebraObj</Code>).
</Description>
</ManSection>
<ManSection>
<Heading>Jordan Rank</Heading>
<Meth Name="JordanRank" Arg="x" />
<Meth Name="Rank" Arg="x" Label="Jordan Algebras" />
<Description>The rank of a Jordan algeba is the size of a maximal set of mutually
orthogonal primitive idempotents in the algebra. The rank and degree are used to classify the
simple Euclidean Jordan algebras. This method returns the rank of <Arg>x</Arg> when
<Code>IsJordanAlgebra(<Arg>x</Arg>)</Code> or the rank of the Jordan algebra containing
<Arg>x</Arg> (computed as <Code>FamilyObj(x)!.fullSCAlgebra</Code>) when
<Code>IsJordanAlgebraObj(<Arg>x</Arg>)</Code>. The method <Code>Rank(<Arg>x</Arg>)</Code>
returns <Code>JordanRank(<Arg>x</Arg>)</Code> when <Arg>x</Arg> satisfies either
<Code>IsJordanAlgebra</Code> or <Code>IsJordanAlgebraObj</Code>.
</Description>
</ManSection>
<ManSection>
<Heading>Jordan Degree</Heading>
<Meth Name="JordanDegree" Arg="x" />
<Meth Name="Degree" Arg="x" Label="Jordan Algebras" />
<Description> The degree of a Jordan algebra is the dimension of the off-diagonal entries
in a Pierce decomposition of the Jordan algebra. For example, a Jordan algebra of quaternion
hermitian matrices has degree 4. This method returns the degree of <Arg>x</Arg> when
<Code>IsJordanAlgebra(<Arg>x</Arg>)</Code> or the degree of the Jordan algebra containing
<Arg>x</Arg> (computed as <Code>FamilyObj(x)!.fullSCAlgebra</Code>)
when <Code>IsJordanAlgebraObj(<Arg>x</Arg>)</Code>. The method
<Code>Degree(<Arg>x</Arg>)</Code>
returns <Code>JordanDegree(<Arg>x</Arg>)</Code> when <Arg>x</Arg> satisfies either
<Code>IsJordanAlgebra</Code> or <Code>IsJordanAlgebraObj</Code>.
</Description>
</ManSection>
Each vector in a simple Euclidean Jordan algebra can be written as a &RR;-linear combination
of mutually orthogonal primitive idempotents. This is called the <Emph>spectral decomposition</Emph>
of a Jordan algebra element. The coefficients in the decomposition are the <Emph>eigenvalues</Emph>
of the element. The Jordan trace and determinant, described below, are respectively the sum
and product of these eigenvalues with multiplicities included <Cite Key="faraut_analysis_1994" Where="p. 44" />.
<ManSection>
<Meth Name="Trace" Arg="x" Label="Jordan Algebras" />
<Description>Returns the Jordan trace of <Arg>x</Arg> when <Code>IsJordanAlgebraObj(<Arg>x</Arg>)</Code>.
The trace of a Jordan algebra element is the sum of the eigenvalues of that element
(with multiplicies included). </Description>
</ManSection>
<ManSection>
<Meth Name="Determinant" Arg="x" Label="Jordan Algebras" />
<Description>Returns the Jordan determinant of <Arg>x</Arg> when <Code>IsJordanAlgebraObj(<Arg>x</Arg>)</Code>. The determinant of a Jordan algebra element is the product of the eigenvalues
of that element (with multiplicies included).</Description>
</ManSection>
<ManSection>
<Meth Name="Norm" Arg="x" Label="Jordan Algebras" />
<Description>Returns the Jordan norm of <Arg>x</Arg> when <Code>IsJordanAlgebraObj(<Arg>x</Arg>)</Code>.
The Jordan norm has the value <Code>Trace(<Arg>x</Arg>^2)/2</Code>.
</Description>
</ManSection>
<ManSection>
<Attr Name="GenericMinimalPolynomial" Arg="x" />
<Description> Returns the generic minimal polynomial of <Arg>x</Arg> when
<Code>IsJordanAlgebraObj(<Arg>x</Arg>)</Code> as defined in
<Cite Key="faraut_analysis_2000"
Where="p. 478" /> (see also <Cite Key="faraut_analysis_1994" Where="pp. 27-31" />).
The output is given as a list of polynomial coefficients. Note that the generic minimal
polynomial is a monic polynomial of degree equal to the rank of the Jordan algebra. The trace
and determinant of a Jordan algebra element are, to within a sign, given by the coefficients
of the second highest degree term and the constant term.
<Example><![CDATA[gap> J := AlbertAlgebra(Rationals);;
gap> x := Sum(Basis(J){[4,5,6,25,26,27]});
i4+i5+i6+ei+ej+ek
gap> [JordanRank(J), JordanDegree(J)];
[ 3, 8 ]
gap> [JordanRank(x), JordanDegree(x)];
[ 3, 8 ]
gap> p := GenericMinimalPolynomial(x);
[ 2, 0, -3, 1 ]
gap> Trace(x);
3
gap> Determinant(x);
-2
gap> Norm(x);
9/2]]></Example>
</Description>
</ManSection>
The classification of simple Euclidean Jordan algebras is described in
<Cite Key="faraut_analysis_1994" Where="chap. 5" />.
A simple Euclidean Jordan algebra can be constructed in the following two ways.
A rank <Math>2</Math> algebra can be constructed from a positive definite Gram matrix in the manner described in
<Cite Key="faraut_analysis_1994" Where="p. 25" />.
A degree <Math>1</Math>, <Math>2</Math>, <Math>4</Math>, or <Math>8</Math> algebra can be constructed using Hermitian matrices over a composition algebra of dimension equal to the degree with the product <Math>(xy+yx)/2</Math>.
In certain cases both constructions are possible.
The <Package>ALCO</Package> package provides tools to use both constructions to create simple Euclidean Jordan algebras with elements that satisfy <Code>IsSCAlgebraObj</Code>.
<ManSection>
<Func Name="SimpleEuclideanJordanAlgebra" Arg="rho, d[, args]" />
<Description> Returns a simple Euclidean Jordan algebra over &QQ;.
The construction used depends on the arguments given in the following manner. <P/>
For Jordan algebras of rank <Arg>rho</Arg> equal to <Math>2</Math>, the <Ref Func="JordanSpinFactor"/>
construction is used.
If optional <Arg>args</Arg> is empty then the result is
<Code>JordanSpinFactor(IdentityMat(<Arg>d</Arg>+1))</Code>.
If optional <Arg>args</Arg> is a symmetric matrix of dimension <Arg>d</Arg>+1, then
<Code>JordanSpinFactor(args)</Code> is used.
If neither of these rank 2 cases apply, and <Arg>d</Arg> is equal to 1,2,4, or 8, and if
<Arg>args</Arg> is a composition algebra basis, then
<Code>HermitianSimpleJordanAlgebra(<Arg>rho</Arg>, <Arg>args</Arg>)</Code> is used.<P/>
In the cases where rank <Arg>rho</Arg> is greater than <Math>2</Math>, we must have
<Arg>d</Arg> equal to one of <Math>1</Math>, <Math>2</Math>, <Math>4</Math>, or <Math>8</Math>.
Note that <Arg>d</Arg> equals <Math>8</Math> is only permitted when <Arg>rho</Arg> equals <Math>3</Math>.
When optional <Arg>args</Arg> is a composition algebra basis of dimension <Arg>d</Arg>, <Code>HermitianSimpleJordanAlgebra(<Arg>rho</Arg>, <Arg>args</Arg>)</Code> is used.
Otherwise, when optional <Arg>args</Arg> is empty, this function uses
<Code>HermitianSimpleJordanAlgebra(<Arg>rho</Arg>, <Arg>B</Arg>)</Code> for <Arg>B</Arg> either
<Code>CanonicalBasis(Rationals)</Code>, <Code>Basis(CF(4), [1, E(4)])</Code>,
<Code>CanonicalBasis(QuaternionAlgebra(Rationals))</Code>, or
<Code>CanonicalBasis(OctonionAlgebra(Rationals))</Code>. <P/>
Note that (in contrast to <Ref Func="AlbertAlgebra" />) the Hermitian Jordan algebras constructed using <Code>SimpleEuclideanJordanAlgebra</Code> uses the upper triangular entries of the Hermitian matrices define the basis vectors.
<Example><![CDATA[gap> J := SimpleEuclideanJordanAlgebra(3,8);
<algebra-with-one of dimension 27 over Rationals>
gap> Derivations(Basis(J));; SemiSimpleType(last); "F4"]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="JordanSpinFactor" Arg="G" />
<Description> Returns a Jordan spin factor algebra when <Arg>G</Arg> is a positive
definite Gram matrix. This is the Jordan algebra of rank 2 constructed from a symmetric
bilinear form, as described in <Cite Key="faraut_analysis_1994" Where="p. 25" />.
<Example><![CDATA[gap> J := JordanSpinFactor(IdentityMat(8));
<algebra-with-one of dimension 9 over Rationals>
gap> One(J);
v.1
gap> [JordanRank(J), JordanDegree(J)];
[ 2, 7 ]
gap> Derivations(Basis(J));
<Lie algebra of dimension 28 over Rationals>
gap> SemiSimpleType(last); "D4"
gap> x := Sum(Basis(J){[4,5,6,7]});
v.4+v.5+v.6+v.7
gap> [Trace(x), Determinant(x)];
[ 0, -4 ]
gap> p := GenericMinimalPolynomial(x);
[ -4, 0, 1 ]
gap> ValuePol(p,x);
0*v.1]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="HermitianSimpleJordanAlgebra" Arg="r, B" />
<Description> Returns a simple Euclidean Jordan algebra of rank <Arg>r</Arg> with the
basis for the off-diagonal components defined using composition algebra basis <Arg>B</Arg>.
<Example><![CDATA[gap> J := HermitianSimpleJordanAlgebra(3,QuaternionD4Basis);
<algebra-with-one of dimension 15 over Rationals>
gap> [JordanRank(J), JordanDegree(J)];
[ 3, 4 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="JordanHomotope" Arg="J, u[, s]" />
<Description> For <Arg>J</Arg> a Jordan algebra satisfying
<Code>IsJordanAlgebra(<Arg>J</Arg>
)</Code>, and for <Arg>u</Arg> a vector in <Arg>J</Arg>, this function returns the
corresponding <Arg>u</Arg>-homotope algebra with the product of <Math>x</Math> and <Math>y</Math>
defined as <Math>x(uy)+(xu)y - u(xy)</Math>. The <Arg>u</Arg>-homotope algebra also belongs to
the filter <Code>IsJordanAlgebra</Code>. <P/>
Of note, if <Arg>u</Arg> is invertible in <Arg>J</Arg>
then the corresponding <Arg>u</Arg>-homotope algebra is called a <Arg>u</Arg>-isotope. The
optional argument <Arg>s</Arg> is a string that determines the labels of the canonical basis
vectors in the new algebra. The main definitions and properties of Jordan homotopes and
isotopes are given in <Cite Key="mccrimmon_taste_2004" Where="pp.82-86" />.
<Example><![CDATA[gap> J := SimpleEuclideanJordanAlgebra(2,7);
<algebra-with-one of dimension 9 over Rationals>
gap> u := Sum(Basis(J){[1,2,7,8]});
v.1+v.2+v.7+v.8
gap> Inverse(u);
(-1/2)*v.1+(1/2)*v.2+(1/2)*v.7+(1/2)*v.8
gap> GenericMinimalPolynomial(u);
[ -2, -2, 1 ]
gap> H := JordanHomotope(J, u, "w.");
<algebra-with-one of dimension 9 over Rationals>
gap> One(H);
(-1/2)*w.1+(1/2)*w.2+(1/2)*w.7+(1/2)*w.8]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>The Albert Algebra</Heading> The exceptional simple Euclidean Jordan algebra, or
Albert algebra, may be constructed using <Ref Func="SimpleEuclideanJordanAlgebra" /> with rank
3 and degree 8. However, that construction uses the upper triangular entries of the Hermitian
matrices define the basis vectors (i.e., the <Code>[1][2], [2][3], [1][3]</Code> entries).
Much of the literature on the Albert algebra instead uses the <Code>[1][2], [2][3], [3][1]</Code>
entries of the Hermitian matrices to define the basis vectors (see for example
<Cite
Key="wilson_finite_2009" Where="pp. 147-148" />). The <Package>ALCO</Package> package
provides a specific construction of the Albert algebra that uses this convention for defining
basis vectors, described below. <ManSection>
<Func Name="AlbertAlgebra" Arg="F" />
<Description> For <Arg>F</Arg> a field, this function returns an Albert algebra over
<Arg>F</Arg>. For <Code><Arg>F</Arg> = Rationals</Code>, this algebra is isomorphic to
<Code>HermitianSimpleJordanAlgebra(3,8,Basis(Oct))</Code> but in a basis that is
more convenient for
reproducing certain calculations in the literature. Specifically, while
<Code>HermitianSimpleJordanAlgebra(3,8,Basis(Oct))</Code> uses the upper-triangular elements of a
Hermitian matrix as representative, <Code>AlbertAlgebra(<Arg>F</Arg>)</Code> uses the
<Code>[1][2], [2][3], [3][1]</Code> entries as representative. These are respectively labeled using
<Code>k,i,j</Code>.
<Example><![CDATA[gap> A := AlbertAlgebra(Rationals);
<algebra-with-one of dimension 27 over Rationals>
gap> i := Basis(A){[1..8]};;
gap> j := Basis(A){[9..16]};;
gap> k := Basis(A){[17..24]};;
gap> e := Basis(A){[25..27]};;
gap> Display(i); Display(j); Display(k); Display(e);
[ 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 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="AlbertVectorToHermitianMatrix" Arg="x" />
<Description>For an element <Arg>x</Arg> in <Code>AlbertAlgebra(<Arg>Rationals</Arg>)</Code>,
this function returns the corresponding 3 x 3 Hermitian matrix with octonion entries in
<Code>OctonionAlgebra(<Arg>Rationals</Arg>)</Code>.
</Description>
</ManSection>
<ManSection>
<Func Name="HermitianMatrixToAlbertVector" Arg="x" />
<Description>For 3 x 3 Hermitian matrix with elements in <Code>OctonionAlgebra(<Arg>Rationals</Arg>)</Code>, this function returns the corresponding vector in in <Code>AlbertAlgebra(<Arg>Rationals</Arg>)</Code>. <Example><![CDATA[gap> j := Basis(AlbertAlgebra(Rationals)){[9..16]};
[ j1, j2, j3, j4, j5, j6, j7, j8 ]
gap> mat := AlbertVectorToHermitianMatrix(j[3]);; Display(mat);
[ [ 0*e1, 0*e1, (-1)*e3 ],
[ 0*e1, 0*e1, 0*e1 ],
[ e3, 0*e1, 0*e1 ] ]
gap> HermitianMatrixToAlbertVector(mat);
j3]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>The Quadratic Representation</Heading> Many important features of simple Euclidean
Jordan algebra and their isotopes are related to the quadratic representation. This aspect of
Jordan algebras is described well in <Cite Key="mccrimmon_taste_2004" Where="pp.82-86" /> and <Cite
Key="faraut_analysis_1994" Where="pp. 32-38" />. The following methods allow for the
construction of Jordan quadratic maps and the standard triple product on a Jordan algebra.
<ManSection>
<Oper Name="JordanQuadraticOperator" Arg="x [,y]" />
<Description> For <Arg>x</Arg> and <Arg>y</Arg> Jordan algebra elements, satisfying <Code>IsJordanAlgebraObj</Code> this operation applies two methods.
In the case of <Code>JordanQuadraticOperator(<Arg>x</Arg>, y)</Code>, this operation returns
<Code>2*x*(x*y) - (x^2)*y</Code>.
In the case of <Code>JordanQuadraticOperator(x)</Code>, this operation returns
the matrix representing the quadratic map in the canonical basis of the Jordan algebra <Arg>J</Arg>
containing <Arg>x</Arg>. For <Code>L(x)</Code> the matrix <Code>AdjointMatrix(CanonicalBasis(J), x)</Code>, the operation <Code>JordanQuadraticOperator(<Arg>x</Arg>)</Code> returns the matrix <Code>2 L(x)^2 - L(x^2)</Code>.
<Example><![CDATA[gap> J := JordanSpinFactor(IdentityMat(3));
<algebra-with-one of dimension 4 over Rationals>
gap> x := [-1,4/3,-1,1]*Basis(J);
(-1)*v.1+(4/3)*v.2+(-1)*v.3+v.4
gap> y := [-1, -1/2, 2, -1/2]*Basis(J);
(-1)*v.1+(-1/2)*v.2+(2)*v.3+(-1/2)*v.4
gap> JordanQuadraticOperator(x,y);
(14/9)*v.1+(-79/18)*v.2+(-11/9)*v.3+(-53/18)*v.4
gap> JordanQuadraticOperator(x);; Display(last);
[ [ 43/9, -8/3, 2, -2 ],
[ -8/3, 7/9, -8/3, 8/3 ],
[ 2, -8/3, -7/9, -2 ],
[ -2, 8/3, -2, -7/9 ] ]
gap> LinearCombination(Basis(J), JordanQuadraticOperator(x)
> *ExtRepOfObj(y)) = JordanQuadraticOperator(x,y);
true
gap> ExtRepOfObj(JordanQuadraticOperator(x,y)) =
> JordanQuadraticOperator(x)*ExtRepOfObj(y);
true
gap> JordanQuadraticOperator(2*x) = 4*JordanQuadraticOperator(x);
true]]></Example>
</Description>
</ManSection>
<ManSection>
<Oper Name="JordanTripleSystem" Arg="x,y,z" />
<Description> For Jordan algebra elements <Arg>x</Arg>, <Arg>y</Arg>, <Arg>z</Arg>
satisfying <Code>IsJordanAlgebraObj</Code>, the operation
<Code>JordanTripleSystem(<Arg>x</Arg>,<Arg>y</Arg>,<Arg>z</Arg>)</Code>
returns the Jordan triple product defined in terms of the Jordan product as
<Code><Arg>x</Arg>*(<Arg>y</Arg>*<Arg>z</Arg>) + (<Arg>x</Arg>*<Arg>y</Arg>)*<Arg>z</Arg> - <Arg>y</Arg>*(<Arg>x</Arg>*<Arg>z</Arg>)</Code>.
Equivalently, <Code>2*JordanTripleSystem(<Arg>x</Arg>,<Arg>y</Arg>,<Arg>z</Arg>)</Code> is equal to
<Code>JordanQuadraticOperator(x+z, y) - JordanQuadraticOperator(x, y) - JordanQuadraticOperator(z, y)</Code>.
<Example><![CDATA[gap> J := AlbertAlgebra(Rationals);
<algebra-with-one of dimension 27 over Rationals>
gap> i := Basis(J){[1..8]};
[ i1, i2, i3, i4, i5, i6, i7, i8 ]
gap> j := Basis(J){[9..16]};
[ j1, j2, j3, j4, j5, j6, j7, j8 ]
gap> k := Basis(J){[17..24]};
[ k1, k2, k3, k4, k5, k6, k7, k8 ]
gap> e := Basis(J){[25..27]};
[ ei, ej, ek ]
gap> List(i, x -> JordanTripleSystem(i[1],i[1],x));
[ i1, i2, i3, i4, i5, i6, i7, i8 ]
gap> List(j, x -> 2*JordanTripleSystem(i[1],i[1],x));
[ j1, j2, j3, j4, j5, j6, j7, j8 ]
gap> List(k, x -> 2*JordanTripleSystem(i[1],i[1],x));
[ k1, k2, k3, k4, k5, k6, k7, k8 ]
gap> List(e, x -> JordanTripleSystem(i[1],i[1],x));
[ 0*i1, ej, ek ]]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>Additional Tools and Properties</Heading>
<ManSection>
<Func Name="HermitianJordanAlgebraBasis" Arg="r, B" />
<Description> Returns a set of Hermitian matrices to serve as a basis for the Jordan
algebra of rank <Arg>r</Arg> and degree given by the cardinality of composition algebra
basis <Arg>B</Arg>. The elements spanning each off-diagonal components are determined by basis
<Arg>B</Arg>. <Example><![CDATA[gap> H := QuaternionAlgebra(Rationals);;
gap> for x in HermitianJordanAlgebraBasis(2, Basis(H)) do Display(x); od;
[ [ e, 0*e ],
[ 0*e, 0*e ] ]
[ [ 0*e, 0*e ],
[ 0*e, e ] ]
[ [ 0*e, e ],
[ e, 0*e ] ]
[ [ 0*e, i ],
[ (-1)*i, 0*e ] ]
[ [ 0*e, j ],
[ (-1)*j, 0*e ] ]
[ [ 0*e, k ],
[ (-1)*k, 0*e ] ]
gap> AsList(Basis(H));
[ e, i, j, k ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Attr Name="JordanMatrixBasis" Arg="J" />
<Description> If <Code>IsJordanAlgebra( <Arg>J</Arg> )</Code> and <Arg>J</Arg> has been
constructed using <Ref Func="HermitianSimpleJordanAlgebra" />, then the set of matrices corresponding to
<Code>CanonicalBasis( <Arg>J</Arg> )</Code> can be obtained using
<Code>JordanMatrixBasis( <Arg>J</Arg> )</Code>.
</Description>
</ManSection>
<ManSection>
<Func Name="HermitianMatrixToJordanVector" Arg="mat, J" />
<Description> Converts matrix <Arg>mat</Arg> into an element of Jordan algebra
<Arg>J</Arg>.
<Example><![CDATA[gap> H := QuaternionAlgebra(Rationals);;
gap> J := HermitianSimpleJordanAlgebra(2,Basis(H));
<algebra-with-one of dimension 6 over Rationals>
gap> AsList(CanonicalBasis(J));
[ v.1, v.2, v.3, v.4, v.5, v.6 ]
gap> JordanMatrixBasis(J);; for x in last do Display(x); od;
[ [ e, 0*e ],
[ 0*e, 0*e ] ]
[ [ 0*e, 0*e ],
[ 0*e, e ] ]
[ [ 0*e, e ],
[ e, 0*e ] ]
[ [ 0*e, i ],
[ (-1)*i, 0*e ] ]
[ [ 0*e, j ],
[ (-1)*j, 0*e ] ]
[ [ 0*e, k ],
[ (-1)*k, 0*e ] ]
gap> List(JordanMatrixBasis(J), x -> HermitianMatrixToJordanVector(x, J));
[ v.1, v.2, v.3, v.4, v.5, v.6 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Attr Name="JordanAlgebraGramMatrix" Arg="J" />
<Description> For <Code>IsJordanAlgebra( <Arg>J</Arg> )</Code>, returns the Gram matrix on
<Code>CanonicalBasis( <Arg>J</Arg> )</Code> using inner product <Code>Trace(x*y)</Code>.
<Example><![CDATA[gap> J := HermitianSimpleJordanAlgebra(2,OctonionE8Basis);
<algebra-with-one of dimension 10 over Rationals>
gap> List(Basis(J), x -> List(Basis(J), y -> Trace(x*y))) =
> JordanAlgebraGramMatrix(J);
true
gap> DiagonalOfMat(JordanAlgebraGramMatrix(J));
[ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="JordanAdjugate" Arg="x" />
<Description> For <Code>IsJordanAlgebraObj( <Arg>x</Arg> )</Code>, returns the adjugate of <Arg>x</Arg>,
which satisfies <Code>x*JordanAdjugate(<Arg>x</Arg>) = One(<Arg>x</Arg>)*Determinant(<Arg>x</Arg>)</Code>.
When <Code>Determinant(<Arg>x</Arg>)</Code> is non-zero, <Code>JordanAdjugate(<Arg>x</Arg>)</Code> is
proportional to <Code>Inverse(<Arg>x</Arg>)</Code>.
</Description>
</ManSection>
<ManSection>
<Filt Name="IsPositiveDefinite" Arg="x" />
<Description> For <Code>IsJordanAlgebraObj( <Arg>x</Arg> )</Code>, returns <Code>true</Code>
when <Arg>x</Arg> is positive definite and <Code>false</Code> otherwise. This filter uses
<Ref Func="GenericMinimalPolynomial" /> to determine whether <Arg>x</Arg> is positive
definite.
</Description>
</ManSection>
</Section>
</Chapter>
<Chapter>
<Heading>Spherical and Projective Designs</Heading>
A spherical or projective design is a finite subset of a sphere or projective space (see <Cite
Key="delsarte_spherical_1977" /> and <Cite Key="hoggar_t-designs_1982" /> for more details).
Certain designs have special properties and interesting symmetries.
The <Package>ALCO</Package> package allows users to study both spherical and projective designs
by modelling both as finite sets of primitive idempotents of a simple Euclidean Jordan algebra. <P/>
Specifically, the primitive idempotents of simple Euclidean Jordan algebras of rank <Math>2</Math>
have the geometry of a sphere.
The correspondence involves converting Euclidean inner product <Math>\cos(\alpha)</Math> between two
unit vectors on a sphere into the corresponding Jordan inner product <Math>\mathrm{Tr}(x\circ y)</Math>
given by <Math>(1 + \cos(\alpha))/2</Math> (described in <Cite Key="nasmith_tight_2023" Where="p. 72" />).
Likewise, the primitive idempotents of a simple Euclidean Jordan algebras of degrees <Math>1</Math>,
<Math>2</Math>, <Math>4</Math>, or <Math>8</Math> have the geometry of a real, complex, quaternion,
or octonion projective space. <P/>
The tools below allow one to construct a &GAP; object to represent a design and collect various
computed attributes. Constructing a design and its parameters using these tools does not guarantee
the existence of such a design, although known examples and possible instances may be studied
using these tools.
<Section>
<Heading>Jacobi Polynomials</Heading>
One advantage of studying spherical and projective designs together as sets of Jordan primitive
idempotents is both the spherical and projective cases can be studied together using Jacobi
polynomials, with suitable parameters chosen for the appropriate simple Euclidean Jordan algebra.
<ManSection>
<Func Name="JacobiPolynomial" Arg="k, a, b" />
<Description> This function returns the Jacobi polynomial <Math>P_k^{(a,b)}(x)</Math> of
degree <Arg>k</Arg> and type <Arg>(a,b)</Arg> as defined in <Cite Key="abramowitz_handbook_1972" Where="chap. 22" />.
The argument <Arg>k</Arg> must be a non-negative integer.
The arguments <Arg>a</Arg> and <Arg>b</Arg> must be either rational numbers greater than <Math>-1</Math> or must satisfy <Code>IsPolynomial</Code>.
<Example><![CDATA[gap> a := Indeterminate(Rationals, "a");;
gap> b := Indeterminate(Rationals, "b");;
gap> x := Indeterminate(Rationals, "x");;
gap> JacobiPolynomial(0,a,b);
[ 1 ]
gap> JacobiPolynomial(1,a,b);
[ 1/2*a-1/2*b, 1/2*a+1/2*b+1 ]
gap> ValuePol(last,x);
1/2*a*x+1/2*b*x+1/2*a-1/2*b+x]]></Example>
</Description>
</ManSection>
<ManSection>
<Heading>Renormalized Jacobi Polynomials</Heading>
<Func Name="Q_k_epsilon" Arg="k, epsilon, rank, degree, x" />
<Func Name="R_k_epsilon" Arg="k, epsilon, rank, degree, x" />
<Description> These functions return polynomials of degree <Arg>k</Arg> in the
indeterminate <Arg>x</Arg> corresponding the the renormalized Jacobi polynomials given in <Cite
Key="hoggar_t-designs_1982" />. The value of <Arg>epsilon</Arg> must be 0 or 1. The
arguments <Arg>rank</Arg> and <Arg>degree</Arg> correspond to the rank and degree of the
relevant simple Euclidean Jordan algebra. </Description>
</ManSection>
</Section>
<Section>
<Heading>Jordan Designs</Heading>
The <Package>ALCO</Package> package defines new categories within <Code>IsObject</Code> in order to construct and study Jordan designs.
<ManSection>
<Heading>Jordan Design Categories</Heading>
<Filt Name="IsJordanDesign" />
<Filt Name="IsSphericalJordanDesign" />
<Filt Name="IsProjectiveJordanDesign" />
<Description>These filters determine whether an object is a Jordan design and whether the
design is constructed in a spherical or projective manifold of Jordan primitive
idempotents.</Description>
</ManSection>
<ManSection>
<Func Name="JordanDesignByParameters" Arg="rank, degree" />
<Description> This function constructs a Jordan design in the manifold of Jordan primitive
idempotents of rank <Arg>rank</Arg> and degree <Arg>degree</Arg>. <Example><![CDATA[gap> D := JordanDesignByParameters(3,8);
<design with rank 3 and degree 8>
gap> IsJordanDesign(D);
true
gap> IsSphericalJordanDesign(D);
false
gap> IsProjectiveJordanDesign(D);
true
gap> JordanDesignByParameters(4,8);
fail
gap> JordanDesignByParameters(3,9);
fail]]></Example>
</Description>
</ManSection>
<ManSection>
<Heading>Jordan Rank and Degree</Heading>
<Attr Name="JordanDesignRank" Arg="D" />
<Attr Name="JordanDesignDegree" Arg="D" />
<Description> The rank and degree of an object satisfying filter <Code>IsJordanDesign</Code> are
stored as attributes. <Example><![CDATA[gap> D := JordanDesignByParameters(3,8);
<design with rank 3 and degree 8>
gap> [JordanDesignRank(D), JordanDesignDegree(D)];
[ 3, 8 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Attr Name="JordanDesignQPolynomials" Arg="D" />
<Description>
Many properties of a Jordan design are computed using the family of renormalized Jacobi polynomials that correspond to the spherical or projective space in question.
This attribute stores a function <Code>DesignQPolynomial(<Arg>D</Arg>)(<Arg>k</Arg>)</Code> that returns the <Arg>k</Arg>-th polynomial in the family, as a list of coefficients, where <Arg>k</Arg> is a non-negative integer.
<Example><![CDATA[gap> D := JordanDesignByParameters(3,8);
<design with rank 3 and degree 8>
gap> r := JordanDesignRank(D);; d := JordanDesignDegree(D);;
gap> x := Indeterminate(Rationals, "x");;
gap> JordanDesignQPolynomials(D);
function( k ) ... end
gap> JordanDesignQPolynomials(D)(2);
[ 90, -585, 819 ]
gap> CoefficientsOfUnivariatePolynomial(Q_k_epsilon(2,0,r,d,x));
[ 90, -585, 819 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Attr Name="JordanDesignConnectionCoefficients" Arg="D" />
<Description>
The connection coefficients of a design <Arg>D</Arg> determine which linear combinations of
<Code>JordanDesignQPolynomials(<Arg>D</Arg>)</Code> yield each power of the indeterminate <Cite
Key="hoggar_t-designs_1992" Where="p. 261" />.
This attribute stores a function <Code>JordanDesignConnectionCoefficients(<Arg>D</Arg>)(<Arg>s</Arg>)</Code> that computes the connection coefficients of each power up to positive integer <Arg>s</Arg>.
<Example><![CDATA[gap> D := JordanDesignByParameters(3,8);
<design with rank 3 and degree 8>
gap> JordanDesignConnectionCoefficients(D);
function( s ) ... end
gap> f := JordanDesignConnectionCoefficients(D)(3);; Display(f);
[ [ 1, 0, 0, 0 ],
[ 1/3, 1/39, 0, 0 ],
[ 5/39, 5/273, 1/819, 0 ],
[ 5/91, 1/91, 1/728, 1/12376 ] ]
gap> for j in [1..4] do Display(Sum(List([1..4], i ->
> f[j][i]*JordanDesignQPolynomials(D)(i-1)))); od;
[ 1, 0, 0, 0 ]
[ 0, 1, 0, 0 ]
[ 0, 0, 1, 0 ]
[ 0, 0, 0, 1 ]]]></Example>
</Description>
</ManSection>
</Section>
<Section>
<Heading>Designs with an Angle Set</Heading>
The angle set of a design is the set of all inner products between distinct elements in the design.
In the case of a Jordan design, each inner product is computed as <Math>\mathrm{Tr}(x\circ y)</Math>
for <Math>x</Math> and <Math>y</Math> primitive idempotents.
This means that the angle set of a design is a set of real numbers in the interval <Math>[0, 1)</Math>.
We can compute many additional properties of a design once the angle set is known.
<ManSection>
<Filt Name="IsJordanDesignWithAngleSet" />
<Description>This filter identifies whether an object that satisfies <Code>IsJordanDesign</Code> is
equipped with an angle set.
</Description>
</ManSection>
<ManSection>
<Heading>Design Angle Sets</Heading>
<Oper Name="JordanDesignAddAngleSet" Arg="D, A" />
<Attr Name="JordanDesignAngleSet" Arg="D" />
<Description>For a design <Arg>D</Arg> without an angle set, records the angle set <Arg>A</Arg>
as an attribute <Code>JordanDesignAngleSet</Code>.
The angle set <Arg>A</Arg> must be a list of real-valued elements in <Code>IsCyc</Code> in the interval <Math>[0, 1)</Math>.
Note that when <Arg>A</Arg> contains irrational elements for which < does not provide an ordering, inclusion in the interval given above is not checked.
Also note that the angle set cannot be modified once set as an attribute of the design.
<Example><![CDATA[gap> D := JordanDesignByParameters(4,4);
<design with rank 4 and degree 4>
gap> JordanDesignAddAngleSet(D, [2]);
fail
gap> D;
<design with rank 4 and degree 4>
gap> JordanDesignAddAngleSet(D, [1/3,1/9]);
<design with rank 4, degree 4, and angle set [ 1/9, 1/3 ]>
gap> JordanDesignAngleSet(D);
[ 1/9, 1/3 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Func Name="JordanDesignByAngleSet" Arg="rank, degree, A" />
<Description>This function constructs a new design with Jordan rank and degree given by <Arg>rank</Arg>
and <Arg>degree</Arg>, with angle set <Arg>A</Arg>. The same constrains on angle set <Arg>A</Arg> given in <Ref Oper="JordanDesignAddAngleSet" /> apply.
<Example><![CDATA[gap> D := JordanDesignByAngleSet(4, 4, [1/3, 1/9]);
<design with rank 4, degree 4, and angle set [ 1/9, 1/3 ]>
gap> JordanDesignAngleSet(D);
[ 1/9, 1/3 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Attr Name="JordanDesignNormalizedAnnihilatorPolynomial" Arg="D" />
<Description>The normalized annihilator polynomial is defined for an angle set <Math>A</Math> as
the polynomial <Math>p(x)</Math> of degree equal to the cardinality of <Math>A</Math> with the
elements of <Math>A</Math> for roots and normalization such that <Math>p(1) = 1</Math> <Cite Key="bannai_algebraic_2021" Where="p. 185" />.
The coefficients of this polynomial are stored as an attribute of a design with an angle set.
<Example><![CDATA[gap> D := JordanDesignByAngleSet(4, 4, [1/3, 1/9]);
<design with rank 4, degree 4, and angle set [ 1/9, 1/3 ]>
gap> p := JordanDesignNormalizedAnnihilatorPolynomial(D);
[ 1/16, -3/4, 27/16 ]
gap> ValuePol(p, 1/9);
0
gap> ValuePol(p, 1/3);
0
gap> ValuePol(p, 1);
1]]></Example>
</Description>
</ManSection>
<ManSection>
<Attr Name="JordanDesignNormalizedIndicatorCoefficients" Arg="D" />
<Description>
The normalized indicator coefficients are the <Code>JordanDesignQPolynomials(<Arg>D</Arg>)</Code>-expansion
coefficients of <Code>JordanDesignNormalizedAnnihilatorPolynomial(<Arg>D</Arg>)</Code>, discussed for the spherical case in <Cite Key="bannai_algebraic_2021" Where="p. 185" />. These coefficients are stored as an
attribute of a design with an angle set.
<Example><![CDATA[gap> D := JordanDesignByAngleSet(4, 4, [1/3, 1/9]);
<design with rank 4, degree 4, and angle set [ 1/9, 1/3 ]>
gap> f := JordanDesignNormalizedIndicatorCoefficients(D);
[ 1/64, 7/960, 9/3520 ]
gap> Sum(List([1..3], i -> f[i]*JordanDesignQPolynomials(D)(i-1)));
[ 1/16, -3/4, 27/16 ]
gap> JordanDesignNormalizedAnnihilatorPolynomial(D);
[ 1/16, -3/4, 27/16 ]]]></Example>
</Description>
</ManSection>
<ManSection>
<Filt Name="IsJordanDesignWithPositiveIndicatorCoefficients" />
<Description>
This filter determines whether the normalized indicator coefficients of a design are
positive, which has significance for certain theorems about designs.
</Description>
</ManSection>
<ManSection>
<Attr Name="JordanDesignSpecialBound" Arg="D" />
<Description> The special bound of a design satisfying
<Code>IsJordanDesignWithPositiveIndicatorCoefficients</Code> is the upper limit on the possible
cardinality for the given angle set <Cite Key="hoggar_t-designs_1992" Where="pp. 257-258"/>.
--> --------------------
--> maximum size reached
--> --------------------
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.