1 from sage
.matrix
.constructor
import matrix
2 from sage
.misc
.cachefunc
import cached_method
4 from mjo
.eja
.eja_algebra
import FiniteDimensionalEJA
5 from mjo
.eja
.eja_element
import FiniteDimensionalEJAElement
7 class FiniteDimensionalEJASubalgebraElement(FiniteDimensionalEJAElement
):
11 sage: from mjo.eja.eja_algebra import random_eja
15 The matrix representation of an element in the subalgebra is
16 the same as its matrix representation in the superalgebra::
18 sage: set_random_seed()
19 sage: x = random_eja(field=QQ,orthonormalize=False).random_element()
20 sage: A = x.subalgebra_generated_by(orthonormalize=False)
21 sage: y = A.random_element()
22 sage: actual = y.to_matrix()
23 sage: expected = y.superalgebra_element().to_matrix()
24 sage: actual == expected
27 The left-multiplication-by operator for elements in the subalgebra
28 works like it does in the superalgebra, even if we orthonormalize
31 sage: set_random_seed()
32 sage: x = random_eja(field=AA).random_element()
33 sage: A = x.subalgebra_generated_by(orthonormalize=True)
34 sage: y = A.random_element()
35 sage: y.operator()(A.one()) == y
40 def superalgebra_element(self
):
42 Return the object in our algebra's superalgebra that corresponds
47 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
52 sage: J = RealSymmetricEJA(3)
53 sage: x = sum(J.gens())
55 b0 + b1 + b2 + b3 + b4 + b5
56 sage: A = x.subalgebra_generated_by(orthonormalize=False)
59 sage: A(x).superalgebra_element()
60 b0 + b1 + b2 + b3 + b4 + b5
61 sage: y = sum(A.gens())
64 sage: B = y.subalgebra_generated_by(orthonormalize=False)
67 sage: B(y).superalgebra_element()
72 We can convert back and forth faithfully::
74 sage: set_random_seed()
75 sage: J = random_eja(field=QQ, orthonormalize=False)
76 sage: x = J.random_element()
77 sage: A = x.subalgebra_generated_by(orthonormalize=False)
78 sage: A(x).superalgebra_element() == x
80 sage: y = A.random_element()
81 sage: A(y.superalgebra_element()) == y
83 sage: B = y.subalgebra_generated_by(orthonormalize=False)
84 sage: B(y).superalgebra_element() == y
88 return self
.parent().superalgebra_embedding()(self
)
93 class FiniteDimensionalEJASubalgebra(FiniteDimensionalEJA
):
95 A subalgebra of an EJA with a given basis.
99 sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
101 ....: RealSymmetricEJA)
102 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
106 The following Peirce subalgebras of the 2-by-2 real symmetric
107 matrices do not contain the superalgebra's identity element::
109 sage: J = RealSymmetricEJA(2)
110 sage: E11 = matrix(AA, [ [1,0],
112 sage: E22 = matrix(AA, [ [0,0],
114 sage: K1 = FiniteDimensionalEJASubalgebra(J, (J(E11),), associative=True)
115 sage: K1.one().to_matrix()
118 sage: K2 = FiniteDimensionalEJASubalgebra(J, (J(E22),), associative=True)
119 sage: K2.one().to_matrix()
125 Ensure that our generator names don't conflict with the
128 sage: J = JordanSpinEJA(3)
129 sage: J.one().subalgebra_generated_by().gens()
131 sage: J = JordanSpinEJA(3, prefix='f')
132 sage: J.one().subalgebra_generated_by().gens()
134 sage: J = JordanSpinEJA(3, prefix='a')
135 sage: J.one().subalgebra_generated_by().gens()
138 Ensure that we can find subalgebras of subalgebras::
140 sage: A = ComplexHermitianEJA(3).one().subalgebra_generated_by()
141 sage: B = A.one().subalgebra_generated_by()
145 def __init__(self
, superalgebra
, basis
, **kwargs
):
146 self
._superalgebra
= superalgebra
147 V
= self
._superalgebra
.vector_space()
148 field
= self
._superalgebra
.base_ring()
150 # A half-assed attempt to ensure that we don't collide with
151 # the superalgebra's prefix (ignoring the fact that there
152 # could be super-superelgrbas in scope). If possible, we
153 # try to "increment" the parent algebra's prefix, although
154 # this idea goes out the window fast because some prefixen
156 prefixen
= ["b","c","d","e","f","g","h","l","m"]
158 prefix
= prefixen
[prefixen
.index(self
._superalgebra
.prefix()) + 1]
162 # The superalgebra constructor expects these to be in original matrix
163 # form, not algebra-element form.
164 matrix_basis
= tuple( b
.to_matrix() for b
in basis
)
165 def jordan_product(x
,y
):
166 return (self
._superalgebra
(x
)*self
._superalgebra
(y
)).to_matrix()
168 def inner_product(x
,y
):
169 return self
._superalgebra
(x
).inner_product(self
._superalgebra
(y
))
171 super().__init
__(matrix_basis
,
175 matrix_space
=superalgebra
.matrix_space(),
181 def _element_constructor_(self
, elt
):
183 Construct an element of this subalgebra from the given one.
184 The only valid arguments are elements of the parent algebra
185 that happen to live in this subalgebra.
189 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
190 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
194 sage: J = RealSymmetricEJA(3)
195 sage: X = matrix(AA, [ [0,0,1],
199 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
200 sage: K = FiniteDimensionalEJASubalgebra(J,
202 ....: associative=True,
203 ....: orthonormalize=False)
212 if elt
in self
.superalgebra():
213 # If the subalgebra is trivial, its _matrix_span will be empty
214 # but we still want to be able convert the superalgebra's zero()
215 # element into the subalgebra's zero() element. There's no great
216 # workaround for this because sage checks that your basis is
217 # linearly-independent everywhere, so we can't just give it a
218 # basis consisting of the zero element.
220 if self
.is_trivial() and m
.is_zero():
223 return super()._element
_constructor
_(m
)
225 return super()._element
_constructor
_(elt
)
228 def superalgebra(self
):
230 Return the superalgebra that this algebra was generated from.
232 return self
._superalgebra
236 def superalgebra_embedding(self
):
238 Return the embedding from this subalgebra into the superalgebra.
242 sage: from mjo.eja.eja_algebra import HadamardEJA
246 sage: J = HadamardEJA(4)
247 sage: A = J.one().subalgebra_generated_by()
248 sage: iota = A.superalgebra_embedding()
250 Linear operator between finite-dimensional Euclidean Jordan algebras represented by the matrix:
255 Domain: Euclidean Jordan algebra of dimension 1 over Algebraic Real Field
256 Codomain: Euclidean Jordan algebra of dimension 4 over Algebraic Real Field
257 sage: iota(A.one()) == J.one()
261 from mjo
.eja
.eja_operator
import FiniteDimensionalEJAOperator
262 mm
= self
._module
_morphism
(lambda j
: self
.superalgebra()(self
.monomial(j
).to_matrix()),
263 codomain
=self
.superalgebra())
264 return FiniteDimensionalEJAOperator(self
,
270 Element
= FiniteDimensionalEJASubalgebraElement