1 from sage
.matrix
.constructor
import matrix
3 from mjo
.eja
.eja_algebra
import FiniteDimensionalEuclideanJordanAlgebra
4 from mjo
.eja
.eja_element
import FiniteDimensionalEuclideanJordanAlgebraElement
6 class FiniteDimensionalEuclideanJordanSubalgebraElement(FiniteDimensionalEuclideanJordanAlgebraElement
):
10 sage: from mjo.eja.eja_algebra import random_eja
14 The natural representation of an element in the subalgebra is
15 the same as its natural representation in the superalgebra::
17 sage: set_random_seed()
18 sage: A = random_eja().random_element().subalgebra_generated_by()
19 sage: y = A.random_element()
20 sage: actual = y.natural_representation()
21 sage: expected = y.superalgebra_element().natural_representation()
22 sage: actual == expected
25 The left-multiplication-by operator for elements in the subalgebra
26 works like it does in the superalgebra, even if we orthonormalize
29 sage: set_random_seed()
30 sage: x = random_eja(AA).random_element()
31 sage: A = x.subalgebra_generated_by(orthonormalize_basis=True)
32 sage: y = A.random_element()
33 sage: y.operator()(A.one()) == y
38 def superalgebra_element(self
):
40 Return the object in our algebra's superalgebra that corresponds
45 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
50 sage: J = RealSymmetricEJA(3)
51 sage: x = sum(J.gens())
53 e0 + e1 + e2 + e3 + e4 + e5
54 sage: A = x.subalgebra_generated_by()
57 sage: A(x).superalgebra_element()
58 e0 + e1 + e2 + e3 + e4 + e5
59 sage: y = sum(A.gens())
62 sage: B = y.subalgebra_generated_by()
65 sage: B(y).superalgebra_element()
70 We can convert back and forth faithfully::
72 sage: set_random_seed()
73 sage: J = random_eja()
74 sage: x = J.random_element()
75 sage: A = x.subalgebra_generated_by()
76 sage: A(x).superalgebra_element() == x
78 sage: y = A.random_element()
79 sage: A(y.superalgebra_element()) == y
81 sage: B = y.subalgebra_generated_by()
82 sage: B(y).superalgebra_element() == y
86 W
= self
.parent().vector_space()
87 V
= self
.parent().superalgebra().vector_space()
88 A
= W
.basis_matrix().transpose()
89 W_coords
= A
*self
.to_vector()
90 V_coords
= V
.coordinate_vector(W_coords
)
91 return self
.parent().superalgebra().from_vector(V_coords
)
96 class FiniteDimensionalEuclideanJordanSubalgebra(FiniteDimensionalEuclideanJordanAlgebra
):
98 A subalgebra of an EJA with a given basis.
102 sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
104 ....: RealSymmetricEJA)
105 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
109 The following Peirce subalgebras of the 2-by-2 real symmetric
110 matrices do not contain the superalgebra's identity element::
112 sage: J = RealSymmetricEJA(2)
113 sage: E11 = matrix(AA, [ [1,0],
115 sage: E22 = matrix(AA, [ [0,0],
117 sage: K1 = FiniteDimensionalEuclideanJordanSubalgebra(J, (J(E11),))
118 sage: K1.one().natural_representation()
121 sage: K2 = FiniteDimensionalEuclideanJordanSubalgebra(J, (J(E22),))
122 sage: K2.one().natural_representation()
128 Ensure that our generator names don't conflict with the superalgebra::
130 sage: J = JordanSpinEJA(3)
131 sage: J.one().subalgebra_generated_by().gens()
133 sage: J = JordanSpinEJA(3, prefix='f')
134 sage: J.one().subalgebra_generated_by().gens()
136 sage: J = JordanSpinEJA(3, prefix='b')
137 sage: J.one().subalgebra_generated_by().gens()
140 Ensure that we can find subalgebras of subalgebras::
142 sage: A = ComplexHermitianEJA(3).one().subalgebra_generated_by()
143 sage: B = A.one().subalgebra_generated_by()
148 def __init__(self
, superalgebra
, basis
, category
=None, check_axioms
=True):
149 self
._superalgebra
= superalgebra
150 V
= self
._superalgebra
.vector_space()
151 field
= self
._superalgebra
.base_ring()
153 category
= self
._superalgebra
.category()
155 # A half-assed attempt to ensure that we don't collide with
156 # the superalgebra's prefix (ignoring the fact that there
157 # could be super-superelgrbas in scope). If possible, we
158 # try to "increment" the parent algebra's prefix, although
159 # this idea goes out the window fast because some prefixen
161 prefixen
= [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
163 prefix
= prefixen
[prefixen
.index(self
._superalgebra
.prefix()) + 1]
167 basis_vectors
= [ b
.to_vector() for b
in basis
]
169 # If our superalgebra is a subalgebra of something else, then
170 # these vectors won't have the right coordinates for
171 # V.span_of_basis() unless we use V.from_vector() on them.
172 W
= V
.span_of_basis( V
.from_vector(v
) for v
in basis_vectors
)
175 mult_table
= [[W
.zero() for i
in range(n
)] for j
in range(n
)]
178 product
= basis
[i
]*basis
[j
]
179 # product.to_vector() might live in a vector subspace
180 # if our parent algebra is already a subalgebra. We
181 # use V.from_vector() to make it "the right size" in
183 product_vector
= V
.from_vector(product
.to_vector())
184 mult_table
[i
][j
] = W
.coordinate_vector(product_vector
)
186 natural_basis
= tuple( b
.natural_representation() for b
in basis
)
189 self
._vector
_space
= W
191 fdeja
= super(FiniteDimensionalEuclideanJordanSubalgebra
, self
)
192 fdeja
.__init
__(field
,
196 natural_basis
=natural_basis
,
198 check_axioms
=check_axioms
)
202 def _element_constructor_(self
, elt
):
204 Construct an element of this subalgebra from the given one.
205 The only valid arguments are elements of the parent algebra
206 that happen to live in this subalgebra.
210 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
211 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
215 sage: J = RealSymmetricEJA(3)
216 sage: X = matrix(AA, [ [0,0,1],
220 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
221 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J, basis)
230 if elt
not in self
.superalgebra():
231 raise ValueError("not an element of this subalgebra")
233 # The extra hackery is because foo.to_vector() might not
234 # live in foo.parent().vector_space()!
235 coords
= sum( a
*b
for (a
,b
)
236 in zip(elt
.to_vector(),
237 self
.superalgebra().vector_space().basis()) )
238 return self
.from_vector(self
.vector_space().coordinate_vector(coords
))
242 def natural_basis_space(self
):
244 Return the natural basis space of this algebra, which is identical
245 to that of its superalgebra.
247 This is correct "by definition," and avoids a mismatch when the
248 subalgebra is trivial (with no natural basis to infer anything
249 from) and the parent is not.
251 return self
.superalgebra().natural_basis_space()
254 def superalgebra(self
):
256 Return the superalgebra that this algebra was generated from.
258 return self
._superalgebra
261 def vector_space(self
):
265 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
266 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
270 sage: J = RealSymmetricEJA(3)
271 sage: E11 = matrix(ZZ, [ [1,0,0],
274 sage: E22 = matrix(ZZ, [ [0,0,0],
279 sage: basis = (b1, b2)
280 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J,basis)
281 sage: K.vector_space()
282 Vector space of degree 6 and dimension 2 over...
292 return self
._vector
_space
295 Element
= FiniteDimensionalEuclideanJordanSubalgebraElement