2 Euclidean Jordan Algebras. These are formally-real Jordan Algebras;
3 specifically those where u^2 + v^2 = 0 implies that u = v = 0. They
4 are used in optimization, and have some additional nice methods beyond
5 what can be supported in a general Jordan Algebra.
8 from sage
.algebras
.finite_dimensional_algebras
.finite_dimensional_algebra
import FiniteDimensionalAlgebra
9 from sage
.algebras
.finite_dimensional_algebras
.finite_dimensional_algebra_element
import FiniteDimensionalAlgebraElement
11 class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra
):
13 def __classcall__(cls
, field
, mult_table
, names
='e', category
=None):
14 fda
= super(FiniteDimensionalEuclideanJordanAlgebra
, cls
)
15 return fda
.__classcall
_private
__(cls
,
21 def __init__(self
, field
, mult_table
, names
='e', category
=None):
22 fda
= super(FiniteDimensionalEuclideanJordanAlgebra
, self
)
23 fda
.__init
__(field
, mult_table
, names
, category
)
28 Return a string representation of ``self``.
30 return "Euclidean Jordan algebra of degree {} over {}".format(self
.degree(), self
.base_ring())
34 Return the rank of this EJA.
36 raise NotImplementedError
39 class Element(FiniteDimensionalAlgebraElement
):
41 An element of a Euclidean Jordan algebra.
46 Return ``self`` raised to the power ``n``.
48 Jordan algebras are always power-associative; see for
49 example Faraut and Koranyi, Proposition II.1.2 (ii).
57 return A
.element_class(A
, self
.vector()*(self
.matrix()**(n
-1)))
62 Compute the degree of this element the straightforward way
63 according to the definition; by appending powers to a list
64 and figuring out its dimension (that is, whether or not
65 they're linearly dependent).
70 sage: J.one().degree()
72 sage: e0,e1,e2,e3 = J.gens()
73 sage: (e0 - e1).degree()
78 V
= self
.vector().parent()
79 vectors
= [(self
**d
).vector()]
80 while V
.span(vectors
).dimension() > d
:
82 vectors
.append((self
**d
).vector())
85 def minimal_polynomial(self
):
86 return self
.matrix().minimal_polynomial()
88 def characteristic_polynomial(self
):
89 return self
.matrix().characteristic_polynomial()
92 def eja_rn(dimension
, field
=QQ
):
94 Return the Euclidean Jordan Algebra corresponding to the set
95 `R^n` under the Hadamard product.
99 This multiplication table can be verified by hand::
102 sage: e0,e1,e2 = J.gens()
117 # The FiniteDimensionalAlgebra constructor takes a list of
118 # matrices, the ith representing right multiplication by the ith
119 # basis element in the vector space. So if e_1 = (1,0,0), then
120 # right (Hadamard) multiplication of x by e_1 picks out the first
121 # component of x; and likewise for the ith basis element e_i.
122 Qs
= [ matrix(field
, dimension
, dimension
, lambda k
,j
: 1*(k
== j
== i
))
123 for i
in xrange(dimension
) ]
125 # Assuming associativity is wrong here, but it works to
126 # temporarily trick the Jordan algebra constructor into using the
127 # multiplication table.
128 return FiniteDimensionalEuclideanJordanAlgebra(field
,Qs
)
131 def eja_ln(dimension
, field
=QQ
):
133 Return the Jordan algebra corresponding to the Lorentz "ice cream"
134 cone of the given ``dimension``.
138 This multiplication table can be verified by hand::
141 sage: e0,e1,e2,e3 = J.gens()
157 In one dimension, this is the reals under multiplication::
166 id_matrix
= identity_matrix(field
,dimension
)
167 for i
in xrange(dimension
):
168 ei
= id_matrix
.column(i
)
169 Qi
= zero_matrix(field
,dimension
)
172 Qi
+= diagonal_matrix(dimension
, [ei
[0]]*dimension
)
173 # The addition of the diagonal matrix adds an extra ei[0] in the
174 # upper-left corner of the matrix.
175 Qi
[0,0] = Qi
[0,0] * ~
field(2)
178 return FiniteDimensionalEuclideanJordanAlgebra(field
,Qs
)