]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_subalgebra.py
eja: fix the field on subalgebras.
[sage.d.git] / mjo / eja / eja_subalgebra.py
1 from sage.matrix.constructor import matrix
2
3 from mjo.eja.eja_algebra import FiniteDimensionalEJA
4 from mjo.eja.eja_element import FiniteDimensionalEJAElement
5
6 class FiniteDimensionalEJASubalgebraElement(FiniteDimensionalEJAElement):
7 """
8 SETUP::
9
10 sage: from mjo.eja.eja_algebra import random_eja
11
12 TESTS::
13
14 The matrix representation of an element in the subalgebra is
15 the same as its matrix representation in the superalgebra::
16
17 sage: set_random_seed()
18 sage: x = random_eja(field=QQ,orthonormalize=False).random_element()
19 sage: A = x.subalgebra_generated_by(orthonormalize=False)
20 sage: y = A.random_element()
21 sage: actual = y.to_matrix()
22 sage: expected = y.superalgebra_element().to_matrix()
23 sage: actual == expected
24 True
25
26 The left-multiplication-by operator for elements in the subalgebra
27 works like it does in the superalgebra, even if we orthonormalize
28 our basis::
29
30 sage: set_random_seed()
31 sage: x = random_eja(field=AA).random_element()
32 sage: A = x.subalgebra_generated_by(orthonormalize=True)
33 sage: y = A.random_element()
34 sage: y.operator()(A.one()) == y
35 True
36
37 """
38
39 def superalgebra_element(self):
40 """
41 Return the object in our algebra's superalgebra that corresponds
42 to myself.
43
44 SETUP::
45
46 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
47 ....: random_eja)
48
49 EXAMPLES::
50
51 sage: J = RealSymmetricEJA(3)
52 sage: x = sum(J.gens())
53 sage: x
54 e0 + e1 + e2 + e3 + e4 + e5
55 sage: A = x.subalgebra_generated_by(orthonormalize=False)
56 sage: A(x)
57 f1
58 sage: A(x).superalgebra_element()
59 e0 + e1 + e2 + e3 + e4 + e5
60 sage: y = sum(A.gens())
61 sage: y
62 f0 + f1
63 sage: B = y.subalgebra_generated_by(orthonormalize=False)
64 sage: B(y)
65 g1
66 sage: B(y).superalgebra_element()
67 f0 + f1
68
69 TESTS:
70
71 We can convert back and forth faithfully::
72
73 sage: set_random_seed()
74 sage: J = random_eja()
75 sage: x = J.random_element()
76 sage: A = x.subalgebra_generated_by()
77 sage: A(x).superalgebra_element() == x
78 True
79 sage: y = A.random_element()
80 sage: A(y.superalgebra_element()) == y
81 True
82 sage: B = y.subalgebra_generated_by()
83 sage: B(y).superalgebra_element() == y
84 True
85
86 """
87 return self.parent().superalgebra()(self.to_matrix())
88
89
90
91
92 class FiniteDimensionalEJASubalgebra(FiniteDimensionalEJA):
93 """
94 A subalgebra of an EJA with a given basis.
95
96 SETUP::
97
98 sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
99 ....: JordanSpinEJA,
100 ....: RealSymmetricEJA)
101 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
102
103 EXAMPLES:
104
105 The following Peirce subalgebras of the 2-by-2 real symmetric
106 matrices do not contain the superalgebra's identity element::
107
108 sage: J = RealSymmetricEJA(2)
109 sage: E11 = matrix(AA, [ [1,0],
110 ....: [0,0] ])
111 sage: E22 = matrix(AA, [ [0,0],
112 ....: [0,1] ])
113 sage: K1 = FiniteDimensionalEJASubalgebra(J, (J(E11),))
114 sage: K1.one().to_matrix()
115 [1 0]
116 [0 0]
117 sage: K2 = FiniteDimensionalEJASubalgebra(J, (J(E22),))
118 sage: K2.one().to_matrix()
119 [0 0]
120 [0 1]
121
122 TESTS:
123
124 Ensure that our generator names don't conflict with the superalgebra::
125
126 sage: J = JordanSpinEJA(3)
127 sage: J.one().subalgebra_generated_by().gens()
128 (f0,)
129 sage: J = JordanSpinEJA(3, prefix='f')
130 sage: J.one().subalgebra_generated_by().gens()
131 (g0,)
132 sage: J = JordanSpinEJA(3, prefix='b')
133 sage: J.one().subalgebra_generated_by().gens()
134 (c0,)
135
136 Ensure that we can find subalgebras of subalgebras::
137
138 sage: A = ComplexHermitianEJA(3).one().subalgebra_generated_by()
139 sage: B = A.one().subalgebra_generated_by()
140 sage: B.dimension()
141 1
142
143 """
144 def __init__(self, superalgebra, basis, **kwargs):
145 self._superalgebra = superalgebra
146 V = self._superalgebra.vector_space()
147 field = self._superalgebra.base_ring()
148
149 # A half-assed attempt to ensure that we don't collide with
150 # the superalgebra's prefix (ignoring the fact that there
151 # could be super-superelgrbas in scope). If possible, we
152 # try to "increment" the parent algebra's prefix, although
153 # this idea goes out the window fast because some prefixen
154 # are off-limits.
155 prefixen = [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
156 try:
157 prefix = prefixen[prefixen.index(self._superalgebra.prefix()) + 1]
158 except ValueError:
159 prefix = prefixen[0]
160
161 # The superalgebra constructor expects these to be in original matrix
162 # form, not algebra-element form.
163 matrix_basis = tuple( b.to_matrix() for b in basis )
164 def jordan_product(x,y):
165 return (self._superalgebra(x)*self._superalgebra(y)).to_matrix()
166
167 def inner_product(x,y):
168 return self._superalgebra(x).inner_product(self._superalgebra(y))
169
170 super().__init__(matrix_basis,
171 jordan_product,
172 inner_product,
173 field=field,
174 prefix=prefix,
175 **kwargs)
176
177
178
179 def _element_constructor_(self, elt):
180 """
181 Construct an element of this subalgebra from the given one.
182 The only valid arguments are elements of the parent algebra
183 that happen to live in this subalgebra.
184
185 SETUP::
186
187 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
188 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
189
190 EXAMPLES::
191
192 sage: J = RealSymmetricEJA(3)
193 sage: X = matrix(AA, [ [0,0,1],
194 ....: [0,1,0],
195 ....: [1,0,0] ])
196 sage: x = J(X)
197 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
198 sage: K = FiniteDimensionalEJASubalgebra(J, basis, orthonormalize=False)
199 sage: K(J.one())
200 f1
201 sage: K(J.one() + x)
202 f0 + f1
203
204 ::
205
206 """
207 if elt in self.superalgebra():
208 return super()._element_constructor_(elt.to_matrix())
209 else:
210 return super()._element_constructor_(elt)
211
212
213
214 def matrix_space(self):
215 """
216 Return the matrix space of this algebra, which is identical to
217 that of its superalgebra.
218
219 This is correct "by definition," and avoids a mismatch when
220 the subalgebra is trivial (with no matrix basis elements to
221 infer anything from) and the parent is not.
222 """
223 return self.superalgebra().matrix_space()
224
225
226 def superalgebra(self):
227 """
228 Return the superalgebra that this algebra was generated from.
229 """
230 return self._superalgebra
231
232
233 Element = FiniteDimensionalEJASubalgebraElement