]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_subalgebra.py
eja: add a comment about sub-subalgebra representations.
[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, check_axioms=True):
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 # If our superalgebra is a subalgebra of something else, then
157 # these vectors won't have the right coordinates for
158 # V.span_of_basis() unless we use V.from_vector() on them.
159 W = V.span_of_basis( V.from_vector(v) for v in basis_vectors )
160
161 n = len(superalgebra_basis)
162 mult_table = [[W.zero() for i in range(n)] for j in range(n)]
163 for i in range(n):
164 for j in range(n):
165 product = superalgebra_basis[i]*superalgebra_basis[j]
166 # product.to_vector() might live in a vector subspace
167 # if our parent algebra is already a subalgebra. We
168 # use V.from_vector() to make it "the right size" in
169 # that case.
170 product_vector = V.from_vector(product.to_vector())
171 mult_table[i][j] = W.coordinate_vector(product_vector)
172
173 natural_basis = tuple( b.natural_representation()
174 for b in superalgebra_basis )
175
176
177 self._vector_space = W
178 self._superalgebra_basis = superalgebra_basis
179
180
181 fdeja = super(FiniteDimensionalEuclideanJordanSubalgebra, self)
182 fdeja.__init__(field,
183 mult_table,
184 prefix=prefix,
185 category=category,
186 natural_basis=natural_basis,
187 check_field=False,
188 check_axioms=check_axioms)
189
190
191
192 def _element_constructor_(self, elt):
193 """
194 Construct an element of this subalgebra from the given one.
195 The only valid arguments are elements of the parent algebra
196 that happen to live in this subalgebra.
197
198 SETUP::
199
200 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
201 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
202
203 EXAMPLES::
204
205 sage: J = RealSymmetricEJA(3)
206 sage: X = matrix(AA, [ [0,0,1],
207 ....: [0,1,0],
208 ....: [1,0,0] ])
209 sage: x = J(X)
210 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
211 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J, basis)
212 sage: K(J.one())
213 f1
214 sage: K(J.one() + x)
215 f0 + f1
216
217 ::
218
219 """
220 if elt not in self.superalgebra():
221 raise ValueError("not an element of this subalgebra")
222
223 # The extra hackery is because foo.to_vector() might not
224 # live in foo.parent().vector_space()!
225 coords = sum( a*b for (a,b)
226 in zip(elt.to_vector(),
227 self.superalgebra().vector_space().basis()) )
228 return self.from_vector(self.vector_space().coordinate_vector(coords))
229
230
231
232 def natural_basis_space(self):
233 """
234 Return the natural basis space of this algebra, which is identical
235 to that of its superalgebra.
236
237 This is correct "by definition," and avoids a mismatch when the
238 subalgebra is trivial (with no natural basis to infer anything
239 from) and the parent is not.
240 """
241 return self.superalgebra().natural_basis_space()
242
243
244 def superalgebra(self):
245 """
246 Return the superalgebra that this algebra was generated from.
247 """
248 return self._superalgebra
249
250
251 def vector_space(self):
252 """
253 SETUP::
254
255 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
256 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanSubalgebra
257
258 EXAMPLES::
259
260 sage: J = RealSymmetricEJA(3)
261 sage: E11 = matrix(ZZ, [ [1,0,0],
262 ....: [0,0,0],
263 ....: [0,0,0] ])
264 sage: E22 = matrix(ZZ, [ [0,0,0],
265 ....: [0,1,0],
266 ....: [0,0,0] ])
267 sage: b1 = J(E11)
268 sage: b2 = J(E22)
269 sage: basis = (b1, b2)
270 sage: K = FiniteDimensionalEuclideanJordanSubalgebra(J,basis)
271 sage: K.vector_space()
272 Vector space of degree 6 and dimension 2 over...
273 User basis matrix:
274 [1 0 0 0 0 0]
275 [0 0 1 0 0 0]
276 sage: b1.to_vector()
277 (1, 0, 0, 0, 0, 0)
278 sage: b2.to_vector()
279 (0, 0, 1, 0, 0, 0)
280
281 """
282 return self._vector_space
283
284
285 Element = FiniteDimensionalEuclideanJordanSubalgebraElement