]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_subalgebra.py
eja: fix tests and pre-cache ranks.
[sage.d.git] / mjo / eja / eja_subalgebra.py
1 from sage.matrix.constructor import matrix
2
3 from mjo.eja.eja_algebra import FiniteDimensionalEuclideanJordanAlgebra
4 from mjo.eja.eja_element import FiniteDimensionalEuclideanJordanAlgebraElement
5
6 class FiniteDimensionalEuclideanJordanSubalgebraElement(FiniteDimensionalEuclideanJordanAlgebraElement):
7 """
8 SETUP::
9
10 sage: from mjo.eja.eja_algebra import random_eja
11
12 TESTS::
13
14 The natural representation of an element in the subalgebra is
15 the same as its natural representation in the superalgebra::
16
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
23 True
24
25 The left-multiplication-by operator for elements in the subalgebra
26 works like it does in the superalgebra, even if we orthonormalize
27 our basis::
28
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
34 True
35
36 """
37
38 def superalgebra_element(self):
39 """
40 Return the object in our algebra's superalgebra that corresponds
41 to myself.
42
43 SETUP::
44
45 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
46 ....: random_eja)
47
48 EXAMPLES::
49
50 sage: J = RealSymmetricEJA(3)
51 sage: x = sum(J.gens())
52 sage: x
53 e0 + e1 + e2 + e3 + e4 + e5
54 sage: A = x.subalgebra_generated_by()
55 sage: A(x)
56 f1
57 sage: A(x).superalgebra_element()
58 e0 + e1 + e2 + e3 + e4 + e5
59
60 TESTS:
61
62 We can convert back and forth faithfully::
63
64 sage: set_random_seed()
65 sage: J = random_eja()
66 sage: x = J.random_element()
67 sage: A = x.subalgebra_generated_by()
68 sage: A(x).superalgebra_element() == x
69 True
70 sage: y = A.random_element()
71 sage: A(y.superalgebra_element()) == y
72 True
73
74 """
75 return self.parent().superalgebra().linear_combination(
76 zip(self.parent()._superalgebra_basis, self.to_vector()) )
77
78
79
80
81 class FiniteDimensionalEuclideanJordanSubalgebra(FiniteDimensionalEuclideanJordanAlgebra):
82 """
83 A subalgebra of an EJA with a given basis.
84
85 SETUP::
86
87 sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
88 ....: JordanSpinEJA,
89 ....: RealSymmetricEJA)
90 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
91
92 EXAMPLES:
93
94 The following Peirce subalgebras of the 2-by-2 real symmetric
95 matrices do not contain the superalgebra's identity element::
96
97 sage: J = RealSymmetricEJA(2)
98 sage: E11 = matrix(AA, [ [1,0],
99 ....: [0,0] ])
100 sage: E22 = matrix(AA, [ [0,0],
101 ....: [0,1] ])
102 sage: K1 = FiniteDimensionalEuclideanJordanSubalgebra(J, (J(E11),))
103 sage: K1.one().natural_representation()
104 [1 0]
105 [0 0]
106 sage: K2 = FiniteDimensionalEuclideanJordanSubalgebra(J, (J(E22),))
107 sage: K2.one().natural_representation()
108 [0 0]
109 [0 1]
110
111 TESTS:
112
113 Ensure that our generator names don't conflict with the superalgebra::
114
115 sage: J = JordanSpinEJA(3)
116 sage: J.one().subalgebra_generated_by().gens()
117 (f0,)
118 sage: J = JordanSpinEJA(3, prefix='f')
119 sage: J.one().subalgebra_generated_by().gens()
120 (g0,)
121 sage: J = JordanSpinEJA(3, prefix='b')
122 sage: J.one().subalgebra_generated_by().gens()
123 (c0,)
124
125 Ensure that we can find subalgebras of subalgebras::
126
127 sage: A = ComplexHermitianEJA(3).one().subalgebra_generated_by()
128 sage: B = A.one().subalgebra_generated_by()
129 sage: B.dimension()
130 1
131
132 """
133 def __init__(self, superalgebra, basis, category=None):
134 self._superalgebra = superalgebra
135 V = self._superalgebra.vector_space()
136 field = self._superalgebra.base_ring()
137 if category is None:
138 category = self._superalgebra.category()
139
140 # A half-assed attempt to ensure that we don't collide with
141 # the superalgebra's prefix (ignoring the fact that there
142 # could be super-superelgrbas in scope). If possible, we
143 # try to "increment" the parent algebra's prefix, although
144 # this idea goes out the window fast because some prefixen
145 # are off-limits.
146 prefixen = [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
147 try:
148 prefix = prefixen[prefixen.index(self._superalgebra.prefix()) + 1]
149 except ValueError:
150 prefix = prefixen[0]
151
152 basis_vectors = [ b.to_vector() for b in basis ]
153 superalgebra_basis = [ self._superalgebra.from_vector(b)
154 for b in basis_vectors ]
155
156 W = V.span_of_basis( V.from_vector(v) for v in basis_vectors )
157 n = len(superalgebra_basis)
158 mult_table = [[W.zero() for i in range(n)] for j in range(n)]
159 for i in range(n):
160 for j in range(n):
161 product = superalgebra_basis[i]*superalgebra_basis[j]
162 # product.to_vector() might live in a vector subspace
163 # if our parent algebra is already a subalgebra. We
164 # use V.from_vector() to make it "the right size" in
165 # that case.
166 product_vector = V.from_vector(product.to_vector())
167 mult_table[i][j] = W.coordinate_vector(product_vector)
168
169 natural_basis = tuple( b.natural_representation()
170 for b in superalgebra_basis )
171
172
173 self._vector_space = W
174 self._superalgebra_basis = superalgebra_basis
175
176
177 fdeja = super(FiniteDimensionalEuclideanJordanSubalgebra, self)
178 fdeja.__init__(field,
179 mult_table,
180 prefix=prefix,
181 category=category,
182 natural_basis=natural_basis)
183
184
185
186 def _element_constructor_(self, elt):
187 """
188 Construct an element of this subalgebra from the given one.
189 The only valid arguments are elements of the parent algebra
190 that happen to live in this subalgebra.
191
192 SETUP::
193
194 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
195 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
196
197 EXAMPLES::
198
199 sage: J = RealSymmetricEJA(3)
200 sage: X = matrix(AA, [ [0,0,1],
201 ....: [0,1,0],
202 ....: [1,0,0] ])
203 sage: x = J(X)
204 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
205 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J, basis)
206 sage: K(J.one())
207 f1
208 sage: K(J.one() + x)
209 f0 + f1
210
211 ::
212
213 """
214 if elt not in self.superalgebra():
215 raise ValueError("not an element of this subalgebra")
216
217 # The extra hackery is because foo.to_vector() might not
218 # live in foo.parent().vector_space()!
219 coords = sum( a*b for (a,b)
220 in zip(elt.to_vector(),
221 self.superalgebra().vector_space().basis()) )
222 return self.from_vector(self.vector_space().coordinate_vector(coords))
223
224
225
226 def natural_basis_space(self):
227 """
228 Return the natural basis space of this algebra, which is identical
229 to that of its superalgebra.
230
231 This is correct "by definition," and avoids a mismatch when the
232 subalgebra is trivial (with no natural basis to infer anything
233 from) and the parent is not.
234 """
235 return self.superalgebra().natural_basis_space()
236
237
238 def superalgebra(self):
239 """
240 Return the superalgebra that this algebra was generated from.
241 """
242 return self._superalgebra
243
244
245 def vector_space(self):
246 """
247 SETUP::
248
249 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
250 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
251
252 EXAMPLES::
253
254 sage: J = RealSymmetricEJA(3)
255 sage: E11 = matrix(ZZ, [ [1,0,0],
256 ....: [0,0,0],
257 ....: [0,0,0] ])
258 sage: E22 = matrix(ZZ, [ [0,0,0],
259 ....: [0,1,0],
260 ....: [0,0,0] ])
261 sage: b1 = J(E11)
262 sage: b2 = J(E22)
263 sage: basis = (b1, b2)
264 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J,basis)
265 sage: K.vector_space()
266 Vector space of degree 6 and dimension 2 over...
267 User basis matrix:
268 [1 0 0 0 0 0]
269 [0 0 1 0 0 0]
270 sage: b1.to_vector()
271 (1, 0, 0, 0, 0, 0)
272 sage: b2.to_vector()
273 (0, 0, 1, 0, 0, 0)
274
275 """
276 return self._vector_space
277
278
279 Element = FiniteDimensionalEuclideanJordanSubalgebraElement