1 from sage
.matrix
.constructor
import matrix
3 from sage
.combinat
.free_module
import CombinatorialFreeModule_CartesianProduct
5 from mjo
.eja
.eja_algebra
import (CartesianProductEJA
,
7 from mjo
.eja
.eja_element
import (CartesianProductEJAElement
,
8 FiniteDimensionalEJAElement
)
10 class FiniteDimensionalEJASubalgebraElement(FiniteDimensionalEJAElement
):
14 sage: from mjo.eja.eja_algebra import random_eja
18 The matrix representation of an element in the subalgebra is
19 the same as its matrix representation in the superalgebra::
21 sage: set_random_seed()
22 sage: x = random_eja(field=QQ,orthonormalize=False).random_element()
23 sage: A = x.subalgebra_generated_by(orthonormalize=False)
24 sage: y = A.random_element()
25 sage: actual = y.to_matrix()
26 sage: expected = y.superalgebra_element().to_matrix()
27 sage: actual == expected
30 The left-multiplication-by operator for elements in the subalgebra
31 works like it does in the superalgebra, even if we orthonormalize
34 sage: set_random_seed()
35 sage: x = random_eja(field=AA).random_element()
36 sage: A = x.subalgebra_generated_by(orthonormalize=True)
37 sage: y = A.random_element()
38 sage: y.operator()(A.one()) == y
43 def superalgebra_element(self
):
45 Return the object in our algebra's superalgebra that corresponds
50 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
55 sage: J = RealSymmetricEJA(3)
56 sage: x = sum(J.gens())
58 e0 + e1 + e2 + e3 + e4 + e5
59 sage: A = x.subalgebra_generated_by(orthonormalize=False)
62 sage: A(x).superalgebra_element()
63 e0 + e1 + e2 + e3 + e4 + e5
64 sage: y = sum(A.gens())
67 sage: B = y.subalgebra_generated_by(orthonormalize=False)
70 sage: B(y).superalgebra_element()
75 We can convert back and forth faithfully::
77 sage: set_random_seed()
78 sage: J = random_eja()
79 sage: x = J.random_element()
80 sage: A = x.subalgebra_generated_by()
81 sage: A(x).superalgebra_element() == x
83 sage: y = A.random_element()
84 sage: A(y.superalgebra_element()) == y
86 sage: B = y.subalgebra_generated_by()
87 sage: B(y).superalgebra_element() == y
91 return self
.parent().superalgebra()(self
.to_matrix())
96 class FiniteDimensionalEJASubalgebra(FiniteDimensionalEJA
):
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 FiniteDimensionalEJASubalgebra
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 = FiniteDimensionalEJASubalgebra(J, (J(E11),))
118 sage: K1.one().to_matrix()
121 sage: K2 = FiniteDimensionalEJASubalgebra(J, (J(E22),))
122 sage: K2.one().to_matrix()
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
, **kwargs
):
149 self
._superalgebra
= superalgebra
150 V
= self
._superalgebra
.vector_space()
151 field
= self
._superalgebra
.base_ring()
153 # A half-assed attempt to ensure that we don't collide with
154 # the superalgebra's prefix (ignoring the fact that there
155 # could be super-superelgrbas in scope). If possible, we
156 # try to "increment" the parent algebra's prefix, although
157 # this idea goes out the window fast because some prefixen
159 prefixen
= [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
161 prefix
= prefixen
[prefixen
.index(self
._superalgebra
.prefix()) + 1]
165 # The superalgebra constructor expects these to be in original matrix
166 # form, not algebra-element form.
167 matrix_basis
= tuple( b
.to_matrix() for b
in basis
)
168 def jordan_product(x
,y
):
169 return (self
._superalgebra
(x
)*self
._superalgebra
(y
)).to_matrix()
171 def inner_product(x
,y
):
172 return self
._superalgebra
(x
).inner_product(self
._superalgebra
(y
))
174 super().__init
__(matrix_basis
,
182 def _element_constructor_(self
, elt
):
184 Construct an element of this subalgebra from the given one.
185 The only valid arguments are elements of the parent algebra
186 that happen to live in this subalgebra.
190 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
191 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
195 sage: J = RealSymmetricEJA(3)
196 sage: X = matrix(AA, [ [0,0,1],
200 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
201 sage: K = FiniteDimensionalEJASubalgebra(J, basis, orthonormalize=False)
210 if elt
in self
.superalgebra():
211 return super()._element
_constructor
_(elt
.to_matrix())
213 return super()._element
_constructor
_(elt
)
217 def matrix_space(self
):
219 Return the matrix space of this algebra, which is identical to
220 that of its superalgebra.
222 This is correct "by definition," and avoids a mismatch when
223 the subalgebra is trivial (with no matrix basis elements to
224 infer anything from) and the parent is not.
226 return self
.superalgebra().matrix_space()
229 def superalgebra(self
):
231 Return the superalgebra that this algebra was generated from.
233 return self
._superalgebra
236 Element
= FiniteDimensionalEJASubalgebraElement
240 class CartesianProductEJASubalgebraElement(CartesianProductEJAElement
,
241 FiniteDimensionalEJASubalgebraElement
):
244 class CartesianProductEJASubalgebra(CartesianProductEJA
,
245 FiniteDimensionalEJASubalgebra
):
247 def __init__(self
, superalgebra
, basis
, **kwargs
):
248 CombinatorialFreeModule_CartesianProduct
.__init
__(self
,
249 superalgebra
.cartesian_factors())
250 FiniteDimensionalEJASubalgebra
.__init
__(self
,
253 cartesian_product
=True,
257 Element
= CartesianProductEJASubalgebraElement