1 from sage
.matrix
.constructor
import matrix
3 from mjo
.eja
.eja_algebra
import FiniteDimensionalEuclideanJordanAlgebra
4 from mjo
.eja
.eja_element
import FiniteDimensionalEuclideanJordanAlgebraElement
7 class FiniteDimensionalEuclideanJordanElementSubalgebraElement(FiniteDimensionalEuclideanJordanAlgebraElement
):
11 sage: from mjo.eja.eja_algebra import random_eja
15 The natural representation of an element in the subalgebra is
16 the same as its natural representation in the superalgebra::
18 sage: set_random_seed()
19 sage: A = random_eja().random_element().subalgebra_generated_by()
20 sage: y = A.random_element()
21 sage: actual = y.natural_representation()
22 sage: expected = y.superalgebra_element().natural_representation()
23 sage: actual == expected
28 def superalgebra_element(self
):
30 Return the object in our algebra's superalgebra that corresponds
35 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
40 sage: J = RealSymmetricEJA(3)
41 sage: x = sum(J.gens())
43 e0 + e1 + e2 + e3 + e4 + e5
44 sage: A = x.subalgebra_generated_by()
47 sage: A(x).superalgebra_element()
48 e0 + e1 + e2 + e3 + e4 + e5
52 We can convert back and forth faithfully::
54 sage: set_random_seed()
55 sage: J = random_eja()
56 sage: x = J.random_element()
57 sage: A = x.subalgebra_generated_by()
58 sage: A(x).superalgebra_element() == x
60 sage: y = A.random_element()
61 sage: A(y.superalgebra_element()) == y
65 return self
.parent().superalgebra().linear_combination(
66 zip(self
.parent()._superalgebra
_basis
, self
.to_vector()) )
71 class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclideanJordanAlgebra
):
73 The subalgebra of an EJA generated by a single element.
77 sage: from mjo.eja.eja_algebra import JordanSpinEJA
81 Ensure that our generator names don't conflict with the superalgebra::
83 sage: J = JordanSpinEJA(3)
84 sage: J.one().subalgebra_generated_by().gens()
86 sage: J = JordanSpinEJA(3, prefix='f')
87 sage: J.one().subalgebra_generated_by().gens()
89 sage: J = JordanSpinEJA(3, prefix='b')
90 sage: J.one().subalgebra_generated_by().gens()
94 def __init__(self
, elt
):
95 superalgebra
= elt
.parent()
97 # First compute the vector subspace spanned by the powers of
99 V
= superalgebra
.vector_space()
100 superalgebra_basis
= [superalgebra
.one()]
101 basis_vectors
= [superalgebra
.one().to_vector()]
102 W
= V
.span_of_basis(basis_vectors
)
103 for exponent
in range(1, V
.dimension()):
104 new_power
= elt
**exponent
105 basis_vectors
.append( new_power
.to_vector() )
107 W
= V
.span_of_basis(basis_vectors
)
108 superalgebra_basis
.append( new_power
)
110 # Vectors weren't independent; bail and keep the
111 # last subspace that worked.
114 # Make the basis hashable for UniqueRepresentation.
115 superalgebra_basis
= tuple(superalgebra_basis
)
117 # Now figure out the entries of the right-multiplication
118 # matrix for the successive basis elements b0, b1,... of
120 field
= superalgebra
.base_ring()
121 n
= len(superalgebra_basis
)
122 mult_table
= [[W
.zero() for i
in range(n
)] for j
in range(n
)]
125 product
= superalgebra_basis
[i
]*superalgebra_basis
[j
]
126 mult_table
[i
][j
] = W
.coordinate_vector(product
.to_vector())
128 # A half-assed attempt to ensure that we don't collide with
129 # the superalgebra's prefix (ignoring the fact that there
130 # could be super-superelgrbas in scope). If possible, we
131 # try to "increment" the parent algebra's prefix, although
132 # this idea goes out the window fast because some prefixen
134 prefixen
= [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
136 prefix
= prefixen
[prefixen
.index(superalgebra
.prefix()) + 1]
140 # The rank is the highest possible degree of a minimal
141 # polynomial, and is bounded above by the dimension. We know
142 # in this case that there's an element whose minimal
143 # polynomial has the same degree as the space's dimension
144 # (remember how we constructed the space?), so that must be
148 category
= superalgebra
.category().Associative()
149 natural_basis
= tuple( b
.natural_representation()
150 for b
in superalgebra_basis
)
152 self
._superalgebra
= superalgebra
153 self
._vector
_space
= W
154 self
._superalgebra
_basis
= superalgebra_basis
157 fdeja
= super(FiniteDimensionalEuclideanJordanElementSubalgebra
, self
)
158 return fdeja
.__init
__(field
,
163 natural_basis
=natural_basis
)
166 def _element_constructor_(self
, elt
):
168 Construct an element of this subalgebra from the given one.
169 The only valid arguments are elements of the parent algebra
170 that happen to live in this subalgebra.
174 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
175 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
179 sage: J = RealSymmetricEJA(3)
180 sage: x = sum( i*J.gens()[i] for i in range(6) )
181 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
182 sage: [ K(x^k) for k in range(J.rank()) ]
189 # Just as in the superalgebra class, we need to hack
190 # this special case to ensure that random_element() can
191 # coerce a ring zero into the algebra.
194 if elt
in self
.superalgebra():
195 coords
= self
.vector_space().coordinate_vector(elt
.to_vector())
196 return self
.from_vector(coords
)
201 Return the basis-element-index of this algebra's unit element.
208 Return the multiplicative identity element of this algebra.
210 The superclass method computes the identity element, which is
211 beyond overkill in this case: the algebra identity should be our
212 first basis element. We implement this via :meth:`one_basis`
213 because that method can optionally be used by other parts of the
218 sage: from mjo.eja.eja_algebra import (RealCartesianProductEJA,
223 sage: J = RealCartesianProductEJA(5)
225 e0 + e1 + e2 + e3 + e4
226 sage: x = sum(J.gens())
227 sage: A = x.subalgebra_generated_by()
230 sage: A.one().superalgebra_element()
231 e0 + e1 + e2 + e3 + e4
235 The identity element acts like the identity::
237 sage: set_random_seed()
238 sage: J = random_eja().random_element().subalgebra_generated_by()
239 sage: x = J.random_element()
240 sage: J.one()*x == x and x*J.one() == x
243 The matrix of the unit element's operator is the identity::
245 sage: set_random_seed()
246 sage: J = random_eja().random_element().subalgebra_generated_by()
247 sage: actual = J.one().operator().matrix()
248 sage: expected = matrix.identity(J.base_ring(), J.dimension())
249 sage: actual == expected
252 return self
.monomial(self
.one_basis())
255 def superalgebra(self
):
257 Return the superalgebra that this algebra was generated from.
259 return self
._superalgebra
262 def vector_space(self
):
266 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
267 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
271 sage: J = RealSymmetricEJA(3)
272 sage: x = sum( i*J.gens()[i] for i in range(6) )
273 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
274 sage: K.vector_space()
275 Vector space of degree 6 and dimension 3 over Rational Field
280 sage: (x^0).to_vector()
282 sage: (x^1).to_vector()
284 sage: (x^2).to_vector()
285 (10, 14, 21, 19, 31, 50)
288 return self
._vector
_space
291 Element
= FiniteDimensionalEuclideanJordanElementSubalgebraElement