]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_subalgebra.py
eja: expand an existing subalgebra test.
[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 sage: y = sum(A.gens())
60 sage: y
61 f0 + f1
62 sage: B = y.subalgebra_generated_by()
63 sage: B(y)
64 g1
65 sage: B(y).superalgebra_element()
66 f0 + f1
67
68 TESTS:
69
70 We can convert back and forth faithfully::
71
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
77 True
78 sage: y = A.random_element()
79 sage: A(y.superalgebra_element()) == y
80 True
81 sage: B = y.subalgebra_generated_by()
82 sage: B(y).superalgebra_element() == y
83 True
84
85 """
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)
92
93
94
95
96 class FiniteDimensionalEuclideanJordanSubalgebra(FiniteDimensionalEuclideanJordanAlgebra):
97 """
98 A subalgebra of an EJA with a given basis.
99
100 SETUP::
101
102 sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
103 ....: JordanSpinEJA,
104 ....: RealSymmetricEJA)
105 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
106
107 EXAMPLES:
108
109 The following Peirce subalgebras of the 2-by-2 real symmetric
110 matrices do not contain the superalgebra's identity element::
111
112 sage: J = RealSymmetricEJA(2)
113 sage: E11 = matrix(AA, [ [1,0],
114 ....: [0,0] ])
115 sage: E22 = matrix(AA, [ [0,0],
116 ....: [0,1] ])
117 sage: K1 = FiniteDimensionalEuclideanJordanSubalgebra(J, (J(E11),))
118 sage: K1.one().natural_representation()
119 [1 0]
120 [0 0]
121 sage: K2 = FiniteDimensionalEuclideanJordanSubalgebra(J, (J(E22),))
122 sage: K2.one().natural_representation()
123 [0 0]
124 [0 1]
125
126 TESTS:
127
128 Ensure that our generator names don't conflict with the superalgebra::
129
130 sage: J = JordanSpinEJA(3)
131 sage: J.one().subalgebra_generated_by().gens()
132 (f0,)
133 sage: J = JordanSpinEJA(3, prefix='f')
134 sage: J.one().subalgebra_generated_by().gens()
135 (g0,)
136 sage: J = JordanSpinEJA(3, prefix='b')
137 sage: J.one().subalgebra_generated_by().gens()
138 (c0,)
139
140 Ensure that we can find subalgebras of subalgebras::
141
142 sage: A = ComplexHermitianEJA(3).one().subalgebra_generated_by()
143 sage: B = A.one().subalgebra_generated_by()
144 sage: B.dimension()
145 1
146
147 """
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()
152 if category is None:
153 category = self._superalgebra.category()
154
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
160 # are off-limits.
161 prefixen = [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
162 try:
163 prefix = prefixen[prefixen.index(self._superalgebra.prefix()) + 1]
164 except ValueError:
165 prefix = prefixen[0]
166
167 basis_vectors = [ b.to_vector() for b in basis ]
168 superalgebra_basis = [ self._superalgebra.from_vector(b)
169 for b in basis_vectors ]
170
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 )
175
176 n = len(superalgebra_basis)
177 mult_table = [[W.zero() for i in range(n)] for j in range(n)]
178 for i in range(n):
179 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
184 # that case.
185 product_vector = V.from_vector(product.to_vector())
186 mult_table[i][j] = W.coordinate_vector(product_vector)
187
188 natural_basis = tuple( b.natural_representation()
189 for b in superalgebra_basis )
190
191
192 self._vector_space = W
193
194 fdeja = super(FiniteDimensionalEuclideanJordanSubalgebra, self)
195 fdeja.__init__(field,
196 mult_table,
197 prefix=prefix,
198 category=category,
199 natural_basis=natural_basis,
200 check_field=False,
201 check_axioms=check_axioms)
202
203
204
205 def _element_constructor_(self, elt):
206 """
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.
210
211 SETUP::
212
213 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
214 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
215
216 EXAMPLES::
217
218 sage: J = RealSymmetricEJA(3)
219 sage: X = matrix(AA, [ [0,0,1],
220 ....: [0,1,0],
221 ....: [1,0,0] ])
222 sage: x = J(X)
223 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
224 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J, basis)
225 sage: K(J.one())
226 f1
227 sage: K(J.one() + x)
228 f0 + f1
229
230 ::
231
232 """
233 if elt not in self.superalgebra():
234 raise ValueError("not an element of this subalgebra")
235
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))
242
243
244
245 def natural_basis_space(self):
246 """
247 Return the natural basis space of this algebra, which is identical
248 to that of its superalgebra.
249
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.
253 """
254 return self.superalgebra().natural_basis_space()
255
256
257 def superalgebra(self):
258 """
259 Return the superalgebra that this algebra was generated from.
260 """
261 return self._superalgebra
262
263
264 def vector_space(self):
265 """
266 SETUP::
267
268 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
269 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
270
271 EXAMPLES::
272
273 sage: J = RealSymmetricEJA(3)
274 sage: E11 = matrix(ZZ, [ [1,0,0],
275 ....: [0,0,0],
276 ....: [0,0,0] ])
277 sage: E22 = matrix(ZZ, [ [0,0,0],
278 ....: [0,1,0],
279 ....: [0,0,0] ])
280 sage: b1 = J(E11)
281 sage: b2 = J(E22)
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...
286 User basis matrix:
287 [1 0 0 0 0 0]
288 [0 0 1 0 0 0]
289 sage: b1.to_vector()
290 (1, 0, 0, 0, 0, 0)
291 sage: b2.to_vector()
292 (0, 0, 1, 0, 0, 0)
293
294 """
295 return self._vector_space
296
297
298 Element = FiniteDimensionalEuclideanJordanSubalgebraElement