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()
110 # TODO: compute this and actually specify it.
113 fdeja
= super(FiniteDimensionalEuclideanJordanElementSubalgebra
, cls
)
114 return fdeja
.__classcall
__(cls
,
120 assume_associative
=assume_associative
,
123 natural_basis
=natural_basis
)
131 assume_associative
=True,
136 self
._superalgebra
= superalgebra_basis
[0].parent()
137 self
._vector
_space
= vector_space
138 self
._superalgebra
_basis
= superalgebra_basis
140 fdeja
= super(FiniteDimensionalEuclideanJordanElementSubalgebra
, self
)
141 fdeja
.__init
__(field
,
144 assume_associative
=assume_associative
,
147 natural_basis
=natural_basis
)
150 def superalgebra(self
):
152 Return the superalgebra that this algebra was generated from.
154 return self
._superalgebra
157 def vector_space(self
):
161 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
162 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
166 sage: J = RealSymmetricEJA(3)
167 sage: x = sum( i*J.gens()[i] for i in range(6) )
168 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
169 sage: K.vector_space()
170 Vector space of degree 6 and dimension 3 over Rational Field
180 (5, 11, 14, 26, 34, 45)
183 return self
._vector
_space
186 class Element(FiniteDimensionalEuclideanJordanAlgebraElement
):
187 def __init__(self
, A
, elt
=None):
191 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
192 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
196 sage: J = RealSymmetricEJA(3)
197 sage: x = sum( i*J.gens()[i] for i in range(6) )
198 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
199 sage: [ K(x^k) for k in range(J.rank()) ]
205 if elt
in A
.superalgebra():
206 # Try to convert a parent algebra element into a
207 # subalgebra element...
209 coords
= A
.vector_space().coordinates(elt
.vector())
211 except AttributeError:
212 # Catches a missing method in elt.vector()
215 FiniteDimensionalEuclideanJordanAlgebraElement
.__init
__(self
,
219 def superalgebra_element(self
):
221 Return the object in our algebra's superalgebra that corresponds
226 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
231 sage: J = RealSymmetricEJA(3)
232 sage: x = sum(J.gens())
234 e0 + e1 + e2 + e3 + e4 + e5
235 sage: A = x.subalgebra_generated_by()
238 sage: A(x).superalgebra_element()
239 e0 + e1 + e2 + e3 + e4 + e5
243 We can convert back and forth faithfully::
245 sage: set_random_seed()
246 sage: J = random_eja()
247 sage: x = J.random_element()
248 sage: A = x.subalgebra_generated_by()
249 sage: A(x).superalgebra_element() == x
251 sage: y = A.random_element()
252 sage: A(y.superalgebra_element()) == y
256 return self
.parent().superalgebra().linear_combination(
257 zip(self
.vector(), self
.parent()._superalgebra
_basis
) )