]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_subalgebra.py
eja: begin major overhaul of class hierarchy and naming.
[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: A = random_eja().random_element().subalgebra_generated_by()
19 sage: y = A.random_element()
20 sage: actual = y.to_matrix()
21 sage: expected = y.superalgebra_element().to_matrix()
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(field=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 return self._superalgebra(self.to_matrix())
87
88
89
90
91 class FiniteDimensionalEJASubalgebra(FiniteDimensionalEJA):
92 """
93 A subalgebra of an EJA with a given basis.
94
95 SETUP::
96
97 sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA,
98 ....: JordanSpinEJA,
99 ....: RealSymmetricEJA)
100 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
101
102 EXAMPLES:
103
104 The following Peirce subalgebras of the 2-by-2 real symmetric
105 matrices do not contain the superalgebra's identity element::
106
107 sage: J = RealSymmetricEJA(2)
108 sage: E11 = matrix(AA, [ [1,0],
109 ....: [0,0] ])
110 sage: E22 = matrix(AA, [ [0,0],
111 ....: [0,1] ])
112 sage: K1 = FiniteDimensionalEJASubalgebra(J, (J(E11),))
113 sage: K1.one().to_matrix()
114 [1 0]
115 [0 0]
116 sage: K2 = FiniteDimensionalEJASubalgebra(J, (J(E22),))
117 sage: K2.one().to_matrix()
118 [0 0]
119 [0 1]
120
121 TESTS:
122
123 Ensure that our generator names don't conflict with the superalgebra::
124
125 sage: J = JordanSpinEJA(3)
126 sage: J.one().subalgebra_generated_by().gens()
127 (f0,)
128 sage: J = JordanSpinEJA(3, prefix='f')
129 sage: J.one().subalgebra_generated_by().gens()
130 (g0,)
131 sage: J = JordanSpinEJA(3, prefix='b')
132 sage: J.one().subalgebra_generated_by().gens()
133 (c0,)
134
135 Ensure that we can find subalgebras of subalgebras::
136
137 sage: A = ComplexHermitianEJA(3).one().subalgebra_generated_by()
138 sage: B = A.one().subalgebra_generated_by()
139 sage: B.dimension()
140 1
141
142 """
143 def __init__(self, superalgebra, basis, **kwargs):
144 self._superalgebra = superalgebra
145 V = self._superalgebra.vector_space()
146 field = self._superalgebra.base_ring()
147
148 # A half-assed attempt to ensure that we don't collide with
149 # the superalgebra's prefix (ignoring the fact that there
150 # could be super-superelgrbas in scope). If possible, we
151 # try to "increment" the parent algebra's prefix, although
152 # this idea goes out the window fast because some prefixen
153 # are off-limits.
154 prefixen = [ 'f', 'g', 'h', 'a', 'b', 'c', 'd' ]
155 try:
156 prefix = prefixen[prefixen.index(self._superalgebra.prefix()) + 1]
157 except ValueError:
158 prefix = prefixen[0]
159
160 # The superalgebra constructor expects these to be in original matrix
161 # form, not algebra-element form.
162 matrix_basis = tuple( b.to_matrix() for b in basis )
163 def jordan_product(x,y):
164 return (self._superalgebra(x)*self._superalgebra(y)).to_matrix()
165
166 def inner_product(x,y):
167 return self._superalgebra(x).inner_product(self._superalgebra(y))
168
169 super().__init__(matrix_basis,
170 jordan_product,
171 inner_product,
172 prefix=prefix,
173 **kwargs)
174
175
176
177 def _element_constructor_(self, elt):
178 """
179 Construct an element of this subalgebra from the given one.
180 The only valid arguments are elements of the parent algebra
181 that happen to live in this subalgebra.
182
183 SETUP::
184
185 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
186 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
187
188 EXAMPLES::
189
190 sage: J = RealSymmetricEJA(3)
191 sage: X = matrix(AA, [ [0,0,1],
192 ....: [0,1,0],
193 ....: [1,0,0] ])
194 sage: x = J(X)
195 sage: basis = ( x, x^2 ) # x^2 is the identity matrix
196 sage: K = FiniteDimensionalEJASubalgebra(J, basis, orthonormalize=False)
197 sage: K(J.one())
198 f1
199 sage: K(J.one() + x)
200 f0 + f1
201
202 ::
203
204 """
205 if elt in self.superalgebra():
206 return super()._element_constructor_(elt.to_matrix())
207 else:
208 return super()._element_constructor_(elt)
209
210
211
212 def matrix_space(self):
213 """
214 Return the matrix space of this algebra, which is identical to
215 that of its superalgebra.
216
217 This is correct "by definition," and avoids a mismatch when
218 the subalgebra is trivial (with no matrix basis elements to
219 infer anything from) and the parent is not.
220 """
221 return self.superalgebra().matrix_space()
222
223
224 def superalgebra(self):
225 """
226 Return the superalgebra that this algebra was generated from.
227 """
228 return self._superalgebra
229
230
231 Element = FiniteDimensionalEJASubalgebraElement