  
  [1X5 [33X[0;0YOctonion Lattice Constructions[133X[101X
  
  [33X[0;0YAn  [13Xoctonion  vector[113X  is  a  tuple  of octonions. Vector addition and scalar
  multiplication  are defined in the usual way, as component-wise addition and
  scalar   multiplication.   We  can  define  the  [13Xoctonion  vector  norm[113X  and
  corresponding  inner product for an octonion vector in a number of ways, but
  require  that the octonion norm of an octonion vector belongs to the ring of
  scalars.[133X
  
  [33X[0;0YAn  [13Xoctonion  lattice[113X  is  a free left ℤ-module generated by a finite set of
  octonion  vectors  along  with  some  octonion vector norm. Octonion lattice
  constructions of the Leech lattice are explored in several places, including
  [EG96], [Wil09b], [Wil11], [Nas22], [Nas23].[133X
  
  [33X[0;0YThe  [5XALCO[105X  package  provides tools to construct and study octonion lattices,
  including  the  Leech  lattice  constructions given in the references above.
  This  package constructs octonion lattices in [5XGAP[105X as free left modules (that
  satisfy  [10XIsFreeLeftModule[110X)  with  the additional structure needed to compute
  the  norms of lattice points and their inner product. It also includes tools
  to identify the Leech lattice and Gosset ([23XE_8[123X) lattice by examining the Gram
  matrix of a lattice.[133X
  
  
  [1X5.1 [33X[0;0YGram Matrices and Octonion Lattices[133X[101X
  
  [33X[0;0YThe  Gram  matrix  of  a  lattice  basis  is  a computed by taking the inner
  products  of  the  basis vectors. When the inner product is real-valued, the
  Gram  matrix of a lattice basis must be a positive definite symmetric matrix
  (see  [CS13, chap. 1]). Certain important lattices may be identified using a
  Gram  matrix  of that lattice. The [5XALCO[105X package provides the following tools
  to identify a Gosset or Leech lattice Gram matrix.[133X
  
  [1X5.1-1 IsLeechLatticeGramMatrix[101X
  
  [33X[1;0Y[29X[2XIsLeechLatticeGramMatrix[102X( [3XG[103X ) [32X function[133X
  
  [33X[0;0YThis  function  tests  whether  [3XG[103X  is a Gram matrix of the Leech lattice. In
  order  for  the  function  to  return  [10Xtrue[110X,  argument  [3XG[103X  must  satisfy the
  following.  First,  [3XG[103X  must  satisfy [10XIsOrdinaryMatrix([3XG[103X[10X)[110X, [10XDimensionsMat([3XG[103X[10X) =
  [24,24][110X,  [10XTransposedMat([3XG[103X[10X) = [3XG[103X[10X[110X, and [10XForAll(Flat([3XG[103X[10X), IsInt)[110X. If so, then this
  function  verifies  that  [3XG[103X  belongs  to  a  unimodular lattice and computes
  [10XShortestVectors([3XG[103X[10X,  3)[110X.  Provided  that no vectors of norm [23X1[123X, [23X2[123X, or [23X3[123X exist,
  then  by  the  classification  of unimodular lattices in [23X24[123X dimensions, Gram
  matrix   [3XG[103X   must   belong  to  a  Leech  lattice.  For  details  about  the
  classification see [CS13, chaps. 16-18].[133X
  
  [1X5.1-2 IsGossetLatticeGramMatrix[101X
  
  [33X[1;0Y[29X[2XIsGossetLatticeGramMatrix[102X( [3XG[103X ) [32X function[133X
  
  [33X[0;0YThis  function  tests whether [3XG[103X is a Gram matrix of the Gosset lattice, also
  known as the [23XE_8[123X lattice. In order for the function to return [10Xtrue[110X, argument
  [3XG[103X  must  satisfy  the  following. First, [3XG[103X must satisfy [10XIsOrdinaryMatrix([3XG[103X[10X)[110X,
  [10XDimensionsMat([3XG[103X[10X)  = [8,8][110X, [10XTransposedMat([3XG[103X[10X) = [3XG[103X[10X[110X, and [10XForAll(Flat([3XG[103X[10X), IsInt)[110X.
  If  so,  then  this function verifies that [3XG[103X belongs to a unimodular lattice
  and  computes  [10XShortestVectors([3XG[103X[10X,  1)[110X.  Provided  that  no vectors of norm [23X1[123X
  exist,  then  by  the classification of unimodular lattices in [23X8[123X dimensions,
  Gram  matrix  [3XG[103X  must  belong  to  a  Gosset  lattice. For details about the
  classification see [CS13, chaps. 16-18].[133X
  
  
  [1X5.1-3 [33X[0;0YMiracle Octad Generator (MOG) Coordinates[133X[101X
  
  [33X[1;0Y[29X[2XMOGLeechLatticeGeneratorMatrix[102X [32X global variable[133X
  [33X[1;0Y[29X[2XMOGLeechLatticeGramMatrix[102X [32X global variable[133X
  
  [33X[0;0YThe  Leech  lattice  is  studied in detail in [CS13] using a specific set of
  coordinates,  known  as "Miracle Octad Generator" coordinates. The choice of
  MOG  coordinates  exhibits  the  [23XM_{24}[123X  symmetries of the lattice. The [5XALCO[105X
  package  loads the following variables to construct the Leech lattice in MOG
  coordinates.  The  variable  [10XMOGLeechLatticeGeneratorMatrix[110X  stores  the  [23X24
  \times  24[123X  integer matrix with rows that span a MOG Leech lattice [CS13, p.
  133].  The  variable [10XMOGLeechLatticeGramMatrix[110X stores the Gram matrix of the
  generator matrix rows, with the inner product computed as [10Xx*y/8[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XM := MOGLeechLatticeGeneratorMatrix;;[127X[104X
    [4X[25Xgap>[125X [27XG := M*TransposedMat(M)/8;;[127X[104X
    [4X[25Xgap>[125X [27XG = MOGLeechLatticeGramMatrix;[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XIsLeechLatticeGramMatrix(G);[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [1X5.1-4 IsOctonionLattice[101X
  
  [33X[1;0Y[29X[2XIsOctonionLattice[102X [32X filter[133X
  
  [33X[0;0YAs described above, an octonion lattice is a free left ℤ-module generated by
  a  finite  set  of  octonion  vectors and equipped with some octonion vector
  norm.  The  category  [10XIsOctonionLattice[110X is a subcategory of [10XIsFreeLeftModule[110X
  used by the [5XALCO[105X package to construct octonion lattices as free left modules
  with  the  additional  structure of a norm on octonion vectors. The simplest
  available  norm  is  perhaps to set the norm of an octonion vector to be the
  sum  of  the  norms  of  the octonion coefficients. The norm for an octonion
  lattice  in  the  [5XALCO[105X  package  is defined (via an inner product) in a more
  general way, described below.[133X
  
  [33X[0;0YLet  [3XL[103X  be an object that satisfies [10XIsOctonionLattice([3XL[103X[10X)[110X. Then [3XL[103X is equipped
  with  an  attribute  [10X[3XG[103X[10X  = OctonionGramMatrix([3XL[103X[10X)[110X. The matrix [3XG[103X is a Hermitian
  octonion  matrix used to define the octonion lattice norm and inner product.
  For  [3Xx[103X, [3Xy[103X octonion vectors in [3XL[103X, the inner product of [3Xx[103X and [3Xy[103X is computed as
  [10XTrace([3Xx[103X[10X*[3XG[103X[10X*ComplexConjugate([3Xy[103X[10X))[110X.  The  trace  (twice the real part) satisfies
  [10XTrace(([3Xx[103X[10X*[3Xy[103X[10X)*[3Xz[103X[10X) = Trace([3Xx[103X[10X*([3Xy[103X[10X*[3Xz[103X[10X))[110X for any octonions [3Xx,y,z[103X [Wil09a, p. 145]. It
  follows  that  the  inner product defined above for octonion vectors is also
  well  defined  despite  the non-associativity of the octonion algebra. If we
  define  the  norm  as the inner product of a vector with itself, then we can
  set  the vector norm to be the sum of the norms of the octonion coefficients
  by setting [10X[3XG[103X[10X = OctonionGramMatrix([3XL[103X[10X)[110X to be half the identity matrix.[133X
  
  [1X5.1-5 OctonionLatticeByGenerators[101X
  
  [33X[1;0Y[29X[2XOctonionLatticeByGenerators[102X( [3Xgens[103X[, [3XG[103X[, [3XB[103X]] ) [32X function[133X
  
  [33X[0;0YThis  function  returns  a free left module that satisfies [2XIsOctonionLattice[102X
  ([14X5.1-4[114X).  The  attribute  [10XLeftActingDomain[110X is automatically set to [10XIntegers[110X.
  Argument  [3Xgens[103X  must  be  a  list  of equal length octonion row vectors that
  satisfies [10XIsOctonionCollColl([3Xgens[103X[10X)[110X. The inner product is defined by optional
  argument  [3XG[103X, which is an octonion Hermitian matrix that defaults to half the
  identity  matrix.  Optional  argument  [3XB[103X is a basis for the octonion algebra
  used  to  construct  the vectors and defaults to the canonical basis of that
  algebra.  All  three arguments must satisfy [10XIsHomogeneousList(Flat([[3Xgens[103X[10X, [3XG[103X[10X,
  [3XB[103X[10X]))[110X in order to ensure that the same octonion algebra is being used in each
  argument.[133X
  
  [33X[0;0YThe      input      [3Xgens[103X      is      stored      as      the      attribute
  [10XGeneratorsOfLeftOperatorAdditiveGroup[110X.  The  vectors  in  [3Xgens[103X  need  not be
  linearly  independent.  The octonion algebra basis [3XB[103X is used to convert [3Xgens[103X
  to  a  list of real coefficients using [10XOctonionToRealVector([3XB[103X[10X, [3Xx[103X[10X)[110X for each [3Xx[103X
  in   [3Xgens[103X.   These   converted   vectors   are   stored   as  the  attribute
  [10XGeneratorsAsCoefficients[110X  and  are  used  to compute a basis for the lattice
  which is stored as the attribute [10X LLLReducedBasisCoefficients[110X.[133X
  
  [33X[0;0YThe  argument [3XG[103X is stored as the attribute [10XOctonionGramMatrix[110X and is used to
  define   [10XScalarProduct([3XL[103X[10X,   [3Xx[103X[10X,   [3Xy[103X[10X)   =  Trace([3Xx[103X[10X*[3XG[103X[10X*ComplexConjugate([3Xy[103X[10X))[110X  for
  [10XIsOctonionLattice([3XL[103X[10X)[110X and [3Xx,y[103X octonion vectors in [3XL[103X.[133X
  
  [33X[0;0YIn  the  following  example, we construct the octonion lattice consisting of
  all  octavian  integer  triples where the norm of a vector is the sum of the
  norms  of  the  coefficients.  We also supply the [23XE_8[123X basis for the octavian
  integers as the underlying octonion ring basis [3XB[103X for the construction.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XO := OctavianIntegers;;[127X[104X
    [4X[25Xgap>[125X [27Xgens := Concatenation(List(IdentityMat(3), x -> List(Basis(O), y -> x*y)));[127X[104X
    [4X[28X[ [ (-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (-1/2)*e1+(-1/2)*e2+(-1/2)*e4+(-1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e2+(1/2)*e3+(-1/2)*e5+(-1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e1+(-1/2)*e3+(1/2)*e4+(1/2)*e5, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (-1/2)*e2+(1/2)*e3+(-1/2)*e5+(1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e2+(-1/2)*e4+(1/2)*e5+(-1/2)*e6, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (-1/2)*e1+(-1/2)*e3+(1/2)*e4+(-1/2)*e5, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e1+(-1/2)*e4+(1/2)*e6+(-1/2)*e8, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (-1/2)*e1+(-1/2)*e2+(-1/2)*e4+(-1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e2+(1/2)*e3+(-1/2)*e5+(-1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e1+(-1/2)*e3+(1/2)*e4+(1/2)*e5, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (-1/2)*e2+(1/2)*e3+(-1/2)*e5+(1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e2+(-1/2)*e4+(1/2)*e5+(-1/2)*e6, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (-1/2)*e1+(-1/2)*e3+(1/2)*e4+(-1/2)*e5, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e1+(-1/2)*e4+(1/2)*e6+(-1/2)*e8, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (-1/2)*e1+(-1/2)*e2+(-1/2)*e4+(-1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e2+(1/2)*e3+(-1/2)*e5+(-1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e1+(-1/2)*e3+(1/2)*e4+(1/2)*e5 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (-1/2)*e2+(1/2)*e3+(-1/2)*e5+(1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e2+(-1/2)*e4+(1/2)*e5+(-1/2)*e6 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (-1/2)*e1+(-1/2)*e3+(1/2)*e4+(-1/2)*e5 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e1+(-1/2)*e4+(1/2)*e6+(-1/2)*e8 ] ][128X[104X
    [4X[25Xgap>[125X [27XG := IdentityMat(3)*One(O)/2;;[127X[104X
    [4X[25Xgap>[125X [27XB := CanonicalBasis(O);;[127X[104X
    [4X[25Xgap>[125X [27XO3 := OctonionLatticeByGenerators(gens, G, B);[127X[104X
    [4X[28X<free left module over Integers, with 24 generators>[128X[104X
    [4X[25Xgap>[125X [27XKnownAttributesOfObject(O3);[127X[104X
    [4X[28X[ "LeftActingDomain", "Dimension", "GeneratorsOfLeftOperatorAdditiveGroup",[128X[104X
    [4X[28X  "UnderlyingOctonionRing", "UnderlyingOctonionRingBasis",[128X[104X
    [4X[28X  "OctonionGramMatrix", "GeneratorsAsCoefficients",[128X[104X
    [4X[28X  "LLLReducedBasisCoefficients" ][128X[104X
  [4X[32X[104X
  
  
  [1X5.2 [33X[0;0YOctonion Lattice Attributes[133X[101X
  
  [33X[0;0YAn  free  left  module  [3XL[103X  that  satisfies  [10XIsOctonionLattice([3XL[103X[10X)[110X has several
  attributes   in   addition   to  those  of  a  free  left  module  (such  as
  [10XLeftActingDomain[110X and [10XGeneratorsOfLeftOperatorAdditiveGroup[110X). In the examples
  of  this  section,  we  use  the  octonion  lattice  [10XO3[110X constructed above to
  illustrate these attributes.[133X
  
  [1X5.2-1 UnderlyingOctonionRing[101X
  
  [33X[1;0Y[29X[2XUnderlyingOctonionRing[102X( [3XL[103X ) [32X attribute[133X
  
  [33X[0;0YWhen  [3XL[103X  satisfies  [10XIsOctonionLattice([3XL[103X[10X)[110X, this attribute stores the octonion
  algebra  to  which  the coefficients of the generating octonion vectors [3Xgens[103X
  belong.         This         algebra         is         determined        by
  [10XFamilyObj(One(Flat([3Xgens[103X[10X)))!.fullSCAlgebra[110X    where    [3Xgens[103X   is   given   by
  [10XGeneratorsOfLeftOperatorAdditiveGroup([3XL[103X[10X)[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XUnderlyingOctonionRing(O3);[127X[104X
    [4X[28X<algebra-with-one of dimension 8 over Rationals>[128X[104X
  [4X[32X[104X
  
  [1X5.2-2 OctonionGramMatrix[101X
  
  [33X[1;0Y[29X[2XOctonionGramMatrix[102X( [3XL[103X ) [32X attribute[133X
  
  [33X[0;0YWhen  [3XL[103X  satisfies  [10XIsOctonionLattice([3XL[103X[10X)[110X, this attribute stores the optional
  argument   [3XG[103X  of  [2XOctonionLatticeByGenerators[102X  ([14X5.1-5[114X).  When  the  optional
  argument is not supplied, the default value is half the appropriate octonion
  identity  matrix.  This  octonion  matrix  is  used to compute [2XScalarProduct[102X
  ([14X5.3-2[114X) between lattice vectors.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XOctonionGramMatrix(O3);; Display(last);[127X[104X
    [4X[28X[ [  (1/2)*e8,      0*e1,      0*e1 ],[128X[104X
    [4X[28X  [      0*e1,  (1/2)*e8,      0*e1 ],[128X[104X
    [4X[28X  [      0*e1,      0*e1,  (1/2)*e8 ] ][128X[104X
  [4X[32X[104X
  
  [1X5.2-3 GeneratorsAsCoefficients[101X
  
  [33X[1;0Y[29X[2XGeneratorsAsCoefficients[102X( [3XL[103X ) [32X attribute[133X
  
  [33X[0;0YWhen  [3XL[103X  satisfies [10XIsOctonionLattice([3XL[103X[10X)[110X, this attribute converts the lattice
  generators,   [10XGeneratorsOfLeftOperatorAdditiveGroup([3XL[103X[10X)[110X,   into   a  list  of
  coefficients  using  [10XOctonionToRealVector([3XB[103X[10X, [3Xx[103X[10X)[110X for each generator [3Xx[103X. Recall
  that  [3XB[103X  is an optional argument of [2XOctonionLatticeByGenerators[102X ([14X5.1-5[114X) that
  defaults to [10XCanonicalBasis(UnderlyingOctonionRing([3XL[103X[10X))[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XGeneratorsAsCoefficients(O3);[127X[104X
    [4X[28X[ [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ] ][128X[104X
  [4X[32X[104X
  
  [1X5.2-4 LLLReducedBasisCoefficients[101X
  
  [33X[1;0Y[29X[2XLLLReducedBasisCoefficients[102X( [3XL[103X ) [32X attribute[133X
  
  [33X[0;0YWhen [3XL[103X satisfies [10XIsOctonionLattice([3XL[103X[10X)[110X, this attribute stores the LLL reduced
  basis  computed  from  [10XGeneratorsAsCoefficients([3XL[103X[10X)[110X. These vectors define the
  [2XCanonicalBasis[102X  ([14X5.2-7[114X)  for  [3XL[103X  and  are  used  to  compute  the  attribute
  [2XGramMatrix[102X ([14X5.2-6[114X).[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XLLLReducedBasisCoefficients(O3);[127X[104X
    [4X[28X[ [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0 ],[128X[104X
    [4X[28X  [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 ] ][128X[104X
  [4X[32X[104X
  
  
  [1X5.2-5 [33X[0;0YOctonion Lattice Dimension[133X[101X
  
  [33X[1;0Y[29X[2XDimension[102X( [3XL[103X ) [32X attribute[133X
  [33X[1;0Y[29X[2XRank[102X( [3XL[103X ) [32X attribute[133X
  
  [33X[0;0YWhen  [3XL[103X  satisfies  [10XIsOctonionLattice([3XL[103X[10X)[110X, these attributes store the lattice
  dimension,  also  known  as  rank.  This  is  calculated by evaluating [10XRank(
  GeneratorsAsCoefficients([3XL[103X[10X) )[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XDimension(O3);[127X[104X
    [4X[28X24[128X[104X
    [4X[25Xgap>[125X [27XRank(O3);[127X[104X
    [4X[28X24[128X[104X
  [4X[32X[104X
  
  [1X5.2-6 GramMatrix[101X
  
  [33X[1;0Y[29X[2XGramMatrix[102X( [3XL[103X ) [32X attribute[133X
  
  [33X[0;0YWhen [3XL[103X satisfies [10XIsOctonionLattice([3XL[103X[10X)[110X, this attribute stores the Gram matrix
  defined  by  the  basis stored using the [2XLLLReducedBasisCoefficients[102X ([14X5.2-4[114X)
  attribute  and  the  inner  product  defined on the lattice by [2XScalarProduct[102X
  ([14X5.3-2[114X).[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xg := 2*GramMatrix(O3);;[127X[104X
    [4X[25Xgap>[125X [27XDimensionsMat(g);[127X[104X
    [4X[28X[ 24, 24 ][128X[104X
    [4X[25Xgap>[125X [27XDeterminantMat(g);[127X[104X
    [4X[28X1[128X[104X
  [4X[32X[104X
  
  
  [1X5.2-7 [33X[0;0YLattice Basis[133X[101X
  
  [33X[1;0Y[29X[2XBasis[102X( [3XL[103X ) [32X attribute[133X
  [33X[1;0Y[29X[2XCanonicalBasis[102X( [3XL[103X ) [32X attribute[133X
  [33X[1;0Y[29X[2XBasisVectors[102X( [3XB[103X ) [32X attribute[133X
  [33X[1;0Y[29X[2XIsOctonionLatticeBasis[102X [32X filter[133X
  
  [33X[0;0YWhen  [3XL[103X  satisfies  [10XIsOctonionLattice([3XL[103X[10X)[110X, these attributes are used to store
  the   lattice  canonical  basis  determined  by  [2XLLLReducedBasisCoefficients[102X
  ([14X5.2-4[114X).  The  attributes  [10XBasis([3XL[103X[10X)[110X and [10XCanonicalBasis([3XL[103X[10X)[110X are equivalent and
  satisfy   the  filter  [10XIsOctonionLatticeBasis[110X.  The  attribute  [10XBasisVectors[110X
  returns  the  vectors  stored  in  the attribute [2XLLLReducedBasisCoefficients[102X
  ([14X5.2-4[114X)        converted       into       octonion       vectors       using
  [10XRealToOctonionVector(UnderlyingOctonionRingBasis([3XL[103X[10X),   [3Xx[103X[10X)[110X   for  each  [3Xx[103X  in
  [10XLLLReducedBasisCoefficients([3XL[103X[10X)[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XIsOctonionLatticeBasis(Basis(O3));[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27Xb := BasisVectors(Basis(O3));[127X[104X
    [4X[28X[ [ (-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (-1/2)*e1+(-1/2)*e2+(-1/2)*e4+(-1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e1+(1/2)*e2+(1/2)*e4+(-1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e2+(1/2)*e3+(-1/2)*e5+(-1/2)*e7, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e1+(1/2)*e3+(1/2)*e4+(-1/2)*e5, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e1+(1/2)*e2+(1/2)*e3+(-1/2)*e6, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e2+(1/2)*e4+(-1/2)*e5+(-1/2)*e6, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ (1/2)*e1+(1/2)*e2+(-1/2)*e5+(-1/2)*e8, 0*e1, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (-1/2)*e1+(-1/2)*e2+(-1/2)*e4+(-1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e1+(1/2)*e2+(1/2)*e4+(-1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e2+(1/2)*e3+(-1/2)*e5+(-1/2)*e7, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e1+(1/2)*e3+(1/2)*e4+(-1/2)*e5, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e1+(1/2)*e2+(1/2)*e3+(-1/2)*e6, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e2+(1/2)*e4+(-1/2)*e5+(-1/2)*e6, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, (1/2)*e1+(1/2)*e2+(-1/2)*e5+(-1/2)*e8, 0*e1 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (-1/2)*e1+(-1/2)*e2+(-1/2)*e4+(-1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e1+(1/2)*e2+(1/2)*e4+(-1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e2+(1/2)*e3+(-1/2)*e5+(-1/2)*e7 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e1+(1/2)*e3+(1/2)*e4+(-1/2)*e5 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e1+(1/2)*e2+(1/2)*e3+(-1/2)*e6 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e2+(1/2)*e4+(-1/2)*e5+(-1/2)*e6 ],[128X[104X
    [4X[28X  [ 0*e1, 0*e1, (1/2)*e1+(1/2)*e2+(-1/2)*e5+(-1/2)*e8 ] ][128X[104X
    [4X[25Xgap>[125X [27XGramMatrix(O3) = List(b, x -> List(b, y -> ScalarProduct(O3, x, y)));[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  
  [1X5.3 [33X[0;0YOctonion Lattice Operations[133X[101X
  
  [33X[0;0YThere  are  some additional operations available to study octonion lattices.
  In  the  examples  that follow, we continue to use the lattice [10XO3[110X defined in
  the example of [2XOctonionLatticeByGenerators[102X ([14X5.1-5[114X).[133X
  
  [1X5.3-1 \in[101X
  
  [33X[1;0Y[29X[2X\in[102X( [3Xx[103X, [3XL[103X ) [32X operation[133X
  
  [33X[0;0YWhen  [3XL[103X  satisfies [10XIsOctonionLattice([3XL[103X[10X)[110X and [3Xx[103X is an octonion row vector that
  satisfies  [10XIsOctonionCollection and IsRowVector[110X, this operation test whether
  vector  [3Xx[103X  is  in lattice [3XL[103X. This operation will return [10Xfail[110X when [3Xx[103X and [3XL[103X do
  not  share  the same underlying octonion ring. Note that [10X\in([3Xx[103X[10X,[3XL[103X[10X)[110X and [10X[3Xx[103X[10X in [3XL[103X[10X[110X
  are equivalent expression.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xx := Sum(BasisVectors(Basis(O3)){[2,3,4]});[127X[104X
    [4X[28X[ (1/2)*e2+(1/2)*e3+(-1/2)*e5+(-3/2)*e7, 0*e1, 0*e1 ][128X[104X
    [4X[25Xgap>[125X [27Xx in O3;[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27X\in( x, O3);[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [1X5.3-2 ScalarProduct[101X
  
  [33X[1;0Y[29X[2XScalarProduct[102X( [3XL[103X, [3Xx[103X, [3Xy[103X ) [32X operation[133X
  
  [33X[0;0YWhen  [3XL[103X satisfies [10XIsOctonionLattice([3XL[103X[10X)[110X and [3Xx[103X, [3Xy[103X satisfy [10XIsOctonionCollection
  and        IsRowVector[110X        then        this       operation       returns
  [10XTrace([3Xx[103X[10X*OctonionGramMatrix([3XL[103X[10X)*ComplexConjugate([3Xy[103X[10X))[110X.  Here  the  trace is the
  method  [2XTrace[102X ([14X2.2-2[114X) acting on an octonion argument (corresponding to twice
  the    real    part,    or    identity    coefficient,   of   the   octonion
  [10X[3Xx[103X[10X*OctonionGramMatrix([3XL[103X[10X)*ComplexConjugate([3Xy[103X[10X)[110X).  When  [3Xx[103X,  [3Xy[103X  are not octonion
  vectors   but   rather   coefficient  vectors  of  the  appropriate  length,
  with[10XIsHomogeneousList(Flat([x,y,GeneratorsAsCoefficients(L)]))[110X,   then   the
  operation  [10XScalarProduct[110X  converts  [3Xx[103X  and [3Xy[103X to suitable octonion vectors to
  compute the scalar product.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xb := BasisVectors(Basis(O3));;[127X[104X
    [4X[25Xgap>[125X [27Xb[1];[127X[104X
    [4X[28X[ (-1/2)*e1+(1/2)*e5+(1/2)*e6+(1/2)*e7, 0*e1, 0*e1 ][128X[104X
    [4X[25Xgap>[125X [27XGramMatrix(O3) = List(b, x -> List(b, y -> ScalarProduct(O3, x, y)));[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27Xc := LLLReducedBasisCoefficients(O3);;[127X[104X
    [4X[25Xgap>[125X [27Xc[1];[127X[104X
    [4X[28X[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ][128X[104X
    [4X[25Xgap>[125X [27XGramMatrix(O3) = List(c, x -> List(c, y -> ScalarProduct(O3, x, y)));[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  
  [1X5.3-3 [33X[0;0YSublattice Identification[133X[101X
  
  [33X[1;0Y[29X[2XIsSublattice[102X( [3XL[103X, [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2XIsSubset[102X( [3XL[103X, [3XM[103X ) [32X operation[133X
  [33X[1;0Y[29X[2X\=[102X( [3XL[103X, [3XM[103X ) [32X operation[133X
  
  [33X[0;0YWhen  [3XL[103X  and [3XM[103X both satisfy [10XIsOctonionLattice([3XL[103X[10X)[110X, these operations determine
  whether  [3XM[103X  is a sublattice of [3XL[103X by checking whether the basis vectors for [3XM[103X
  are   in   [3XL[103X.   If   the   lattices   [3XL[103X   and   [3XM[103X  do  not  share  the  same
  [2XUnderlyingOctonionRing[102X  ([14X5.2-1[114X)  then  the  operation  will return [10Xfail[110X. The
  operation [10X\=[110X returns the value of [10XIsSublattice([3XL[103X[10X, [3XM[103X[10X) and IsSublattice([3XL[103X[10X, [3XM[103X[10X)[110X.
  In the example below we construct an octonion Leech lattice [10XLeech[110X and verify
  that it is a sublattice of [10XO3[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xs := LinearCombination(OctonionE8Basis, [ 1, 2, 1, 2, 2, 2, 2, 1 ]);;[127X[104X
    [4X[25Xgap>[125X [27Xleech_gens := List(Basis(OctavianIntegers), x -> [127X[104X
    [4X[25X>[125X [27Xx*[[s,s,0],[0,s,s],ComplexConjugate([s,s,s])]);;[127X[104X
    [4X[25Xgap>[125X [27Xleech_gens := Concatenation(leech_gens);;[127X[104X
    [4X[25Xgap>[125X [27XLeech := OctonionLatticeByGenerators(leech_gens, G, B);[127X[104X
    [4X[28X<free left module over Integers, with 24 generators>[128X[104X
    [4X[25Xgap>[125X [27XIsLeechLatticeGramMatrix(GramMatrix(Leech));[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XIsSublattice(Leech, O3);[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[25Xgap>[125X [27XIsSublattice(O3, Leech);[127X[104X
    [4X[28Xtrue[128X[104X
    [4X[25Xgap>[125X [27XIsSubset(O3, Leech);[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  
  [1X5.3-4 [33X[0;0YLattice Vector Coefficients[133X[101X
  
  [33X[1;0Y[29X[2XCoefficients[102X( [3XB[103X, [3Xy[103X ) [32X operation[133X
  
  [33X[0;0YLet  [3XB[103X  satisfy [10XIsOctonionLatticeBasis([3XB[103X[10X)[110X with basis [3XB[103X belonging to octonion
  lattice [3XL[103X. For [10X[3Xy[103X[10X in [3XL[103X[10X[110X such that [10XIsOctonionCollection([3Xy[103X[10X)[110X, the coefficients in
  [3Xy[103X  in  the lattice basis [3XB[103X can be determined by [10XCoefficients([3XB[103X[10X, [3Xy[103X[10X)[110X. For [10X[3Xx[103X[10X[110X an
  integer  row  vector  of  suitable  length,  the linear combination of basis
  vectors is computed in the usual way as [10XLinearCombination([3XB[103X[10X, [3Xx[103X[10X)[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xrand := Random(O3);;[127X[104X
    [4X[25Xgap>[125X [27Xcoeffs := Coefficients(Basis(O3), rand);;[127X[104X
    [4X[25Xgap>[125X [27Xrand = LinearCombination(Basis(O3), coeffs);[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
