1 from sage
.matrix
.constructor
import matrix
2 from sage
.structure
.category_object
import normalize_names
4 from mjo
.eja
.eja_algebra
import FiniteDimensionalEuclideanJordanAlgebra
5 from mjo
.eja
.eja_element
import FiniteDimensionalEuclideanJordanAlgebraElement
8 class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclideanJordanAlgebra
):
10 The subalgebra of an EJA generated by a single element.
14 sage: from mjo.eja.eja_algebra import FiniteDimensionalEuclideanJordanAlgebra
18 Ensure that non-clashing names are chosen::
20 sage: m1 = matrix.identity(QQ,2)
21 sage: m2 = matrix(QQ, [[0,1],
23 sage: J = FiniteDimensionalEuclideanJordanAlgebra(QQ,
27 sage: J.variable_names()
29 sage: A = sum(J.gens()).subalgebra_generated_by()
30 sage: A.variable_names()
35 def __classcall_private__(cls
, elt
):
36 superalgebra
= elt
.parent()
38 # First compute the vector subspace spanned by the powers of
40 V
= superalgebra
.vector_space()
41 superalgebra_basis
= [superalgebra
.one()]
42 basis_vectors
= [superalgebra
.one().vector()]
43 W
= V
.span_of_basis(basis_vectors
)
44 for exponent
in range(1, V
.dimension()):
45 new_power
= elt
**exponent
46 basis_vectors
.append( new_power
.vector() )
48 W
= V
.span_of_basis(basis_vectors
)
49 superalgebra_basis
.append( new_power
)
51 # Vectors weren't independent; bail and keep the
52 # last subspace that worked.
55 # Make the basis hashable for UniqueRepresentation.
56 superalgebra_basis
= tuple(superalgebra_basis
)
58 # Now figure out the entries of the right-multiplication
59 # matrix for the successive basis elements b0, b1,... of
61 F
= superalgebra
.base_ring()
63 for b_right
in superalgebra_basis
:
65 # The first row of the right-multiplication matrix by
66 # b1 is what we get if we apply that matrix to b1. The
67 # second row of the right multiplication matrix by b1
68 # is what we get when we apply that matrix to b2...
70 # IMPORTANT: this assumes that all vectors are COLUMN
71 # vectors, unlike our superclass (which uses row vectors).
72 for b_left
in superalgebra_basis
:
73 # Multiply in the original EJA, but then get the
74 # coordinates from the subalgebra in terms of its
76 this_row
= W
.coordinates((b_left
*b_right
).vector())
77 b_right_rows
.append(this_row
)
78 b_right_matrix
= matrix(F
, b_right_rows
)
79 mult_table
.append(b_right_matrix
)
83 mult_table
= tuple(mult_table
)
85 # The rank is the highest possible degree of a minimal
86 # polynomial, and is bounded above by the dimension. We know
87 # in this case that there's an element whose minimal
88 # polynomial has the same degree as the space's dimension
89 # (remember how we constructed the space?), so that must be
93 # EJAs are power-associative, and this algebra is nothin but
95 assume_associative
=True
97 # Figure out a non-conflicting set of names to use.
98 valid_names
= ['f','g','h','a','b','c','d']
100 names
= normalize_names(W
.dimension(), valid_names
[0])
101 # This loops so long as the list of collisions is nonempty.
102 # Just crash if we run out of names without finding a set that
103 # don't conflict with the parent algebra.
104 while [y
for y
in names
if y
in superalgebra
.variable_names()]:
106 names
= normalize_names(W
.dimension(), valid_names
[name_idx
])
108 cat
= superalgebra
.category().Associative()
109 natural_basis
= tuple( b
.natural_representation()
110 for b
in superalgebra_basis
)
112 fdeja
= super(FiniteDimensionalEuclideanJordanElementSubalgebra
, cls
)
113 return fdeja
.__classcall
__(cls
,
119 assume_associative
=assume_associative
,
122 natural_basis
=natural_basis
)
130 assume_associative
=True,
135 self
._superalgebra
= superalgebra_basis
[0].parent()
136 self
._vector
_space
= vector_space
137 self
._superalgebra
_basis
= superalgebra_basis
139 fdeja
= super(FiniteDimensionalEuclideanJordanElementSubalgebra
, self
)
140 fdeja
.__init
__(field
,
143 assume_associative
=assume_associative
,
146 natural_basis
=natural_basis
)
149 def superalgebra(self
):
151 Return the superalgebra that this algebra was generated from.
153 return self
._superalgebra
156 def vector_space(self
):
160 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
161 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
165 sage: J = RealSymmetricEJA(3)
166 sage: x = sum( i*J.gens()[i] for i in range(6) )
167 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
168 sage: K.vector_space()
169 Vector space of degree 6 and dimension 3 over Rational Field
179 (5, 11, 14, 26, 34, 45)
182 return self
._vector
_space
185 class Element(FiniteDimensionalEuclideanJordanAlgebraElement
):
190 sage: from mjo.eja.eja_algebra import random_eja
194 The natural representation of an element in the subalgebra is
195 the same as its natural representation in the superalgebra::
197 sage: set_random_seed()
198 sage: A = random_eja().random_element().subalgebra_generated_by()
199 sage: y = A.random_element()
200 sage: actual = y.natural_representation()
201 sage: expected = y.superalgebra_element().natural_representation()
202 sage: actual == expected
206 def __init__(self
, A
, elt
=None):
210 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
211 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
215 sage: J = RealSymmetricEJA(3)
216 sage: x = sum( i*J.gens()[i] for i in range(6) )
217 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
218 sage: [ K(x^k) for k in range(J.rank()) ]
224 if elt
in A
.superalgebra():
225 # Try to convert a parent algebra element into a
226 # subalgebra element...
228 coords
= A
.vector_space().coordinates(elt
.vector())
230 except AttributeError:
231 # Catches a missing method in elt.vector()
234 FiniteDimensionalEuclideanJordanAlgebraElement
.__init
__(self
,
238 def superalgebra_element(self
):
240 Return the object in our algebra's superalgebra that corresponds
245 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
250 sage: J = RealSymmetricEJA(3)
251 sage: x = sum(J.gens())
253 e0 + e1 + e2 + e3 + e4 + e5
254 sage: A = x.subalgebra_generated_by()
257 sage: A(x).superalgebra_element()
258 e0 + e1 + e2 + e3 + e4 + e5
262 We can convert back and forth faithfully::
264 sage: set_random_seed()
265 sage: J = random_eja()
266 sage: x = J.random_element()
267 sage: A = x.subalgebra_generated_by()
268 sage: A(x).superalgebra_element() == x
270 sage: y = A.random_element()
271 sage: A(y.superalgebra_element()) == y
275 return self
.parent().superalgebra().linear_combination(
276 zip(self
.vector(), self
.parent()._superalgebra
_basis
) )