]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_subalgebra.py
eja: more orthonormalization fixes.
[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()
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()
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 prefix=prefix,
174 **kwargs)
175
176
177
178 def _element_constructor_(self, elt):
179 """
180 Construct an element of this subalgebra from the given one.
181 The only valid arguments are elements of the parent algebra
182 that happen to live in this subalgebra.
183
184 SETUP::
185
186 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
187 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
188
189 EXAMPLES::
190
191 sage: J = RealSymmetricEJA(3)
192 sage: X = matrix(AA, [ [0,0,1],
193 ....: [0,1,0],
194 ....: [1,0,0] ])
195 sage: x = J(X)
196 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
197 sage: K = FiniteDimensionalEJASubalgebra(J, basis, orthonormalize=False)
198 sage: K(J.one())
199 f1
200 sage: K(J.one() + x)
201 f0 + f1
202
203 ::
204
205 """
206 if elt in self.superalgebra():
207 return super()._element_constructor_(elt.to_matrix())
208 else:
209 return super()._element_constructor_(elt)
210
211
212
213 def matrix_space(self):
214 """
215 Return the matrix space of this algebra, which is identical to
216 that of its superalgebra.
217
218 This is correct "by definition," and avoids a mismatch when
219 the subalgebra is trivial (with no matrix basis elements to
220 infer anything from) and the parent is not.
221 """
222 return self.superalgebra().matrix_space()
223
224
225 def superalgebra(self):
226 """
227 Return the superalgebra that this algebra was generated from.
228 """
229 return self._superalgebra
230
231
232 Element = FiniteDimensionalEJASubalgebraElement