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
]
168 superalgebra_basis
= [ self
._superalgebra
.from_vector(b
)
169 for b
in basis_vectors
]
171 # If our superalgebra is a subalgebra of something else, then
172 # these vectors won't have the right coordinates for
173 # V.span_of_basis() unless we use V.from_vector() on them.
174 W
= V
.span_of_basis( V
.from_vector(v
) for v
in basis_vectors
)
176 n
= len(superalgebra_basis
)
177 mult_table
= [[W
.zero() for i
in range(n
)] for j
in range(n
)]
180 product
= superalgebra_basis
[i
]*superalgebra_basis
[j
]
181 # product.to_vector() might live in a vector subspace
182 # if our parent algebra is already a subalgebra. We
183 # use V.from_vector() to make it "the right size" in
185 product_vector
= V
.from_vector(product
.to_vector())
186 mult_table
[i
][j
] = W
.coordinate_vector(product_vector
)
188 natural_basis
= tuple( b
.natural_representation()
189 for b
in superalgebra_basis
)
192 self
._vector
_space
= W
194 fdeja
= super(FiniteDimensionalEuclideanJordanSubalgebra
, self
)
195 fdeja
.__init
__(field
,
199 natural_basis
=natural_basis
,
201 check_axioms
=check_axioms
)
205 def _element_constructor_(self
, elt
):
207 Construct an element of this subalgebra from the given one.
208 The only valid arguments are elements of the parent algebra
209 that happen to live in this subalgebra.
213 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
214 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
218 sage: J = RealSymmetricEJA(3)
219 sage: X = matrix(AA, [ [0,0,1],
223 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
224 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J, basis)
233 if elt
not in self
.superalgebra():
234 raise ValueError("not an element of this subalgebra")
236 # The extra hackery is because foo.to_vector() might not
237 # live in foo.parent().vector_space()!
238 coords
= sum( a
*b
for (a
,b
)
239 in zip(elt
.to_vector(),
240 self
.superalgebra().vector_space().basis()) )
241 return self
.from_vector(self
.vector_space().coordinate_vector(coords
))
245 def natural_basis_space(self
):
247 Return the natural basis space of this algebra, which is identical
248 to that of its superalgebra.
250 This is correct "by definition," and avoids a mismatch when the
251 subalgebra is trivial (with no natural basis to infer anything
252 from) and the parent is not.
254 return self
.superalgebra().natural_basis_space()
257 def superalgebra(self
):
259 Return the superalgebra that this algebra was generated from.
261 return self
._superalgebra
264 def vector_space(self
):
268 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
269 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
273 sage: J = RealSymmetricEJA(3)
274 sage: E11 = matrix(ZZ, [ [1,0,0],
277 sage: E22 = matrix(ZZ, [ [0,0,0],
282 sage: basis = (b1, b2)
283 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J,basis)
284 sage: K.vector_space()
285 Vector space of degree 6 and dimension 2 over...
295 return self
._vector
_space
298 Element
= FiniteDimensionalEuclideanJordanSubalgebraElement