]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_subalgebra.py
eja: fix the multiplication table in subalgebras.
[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
7 class FiniteDimensionalEuclideanJordanElementSubalgebraElement(FiniteDimensionalEuclideanJordanAlgebraElement):
8 """
9 SETUP::
10
11 sage: from mjo.eja.eja_algebra import random_eja
12
13 TESTS::
14
15 The natural representation of an element in the subalgebra is
16 the same as its natural representation in the superalgebra::
17
18 sage: set_random_seed()
19 sage: A = random_eja().random_element().subalgebra_generated_by()
20 sage: y = A.random_element()
21 sage: actual = y.natural_representation()
22 sage: expected = y.superalgebra_element().natural_representation()
23 sage: actual == expected
24 True
25
26 """
27
28 def superalgebra_element(self):
29 """
30 Return the object in our algebra's superalgebra that corresponds
31 to myself.
32
33 SETUP::
34
35 sage: from mjo.eja.eja_algebra import (RealSymmetricEJA,
36 ....: random_eja)
37
38 EXAMPLES::
39
40 sage: J = RealSymmetricEJA(3)
41 sage: x = sum(J.gens())
42 sage: x
43 e0 + e1 + e2 + e3 + e4 + e5
44 sage: A = x.subalgebra_generated_by()
45 sage: A(x)
46 f1
47 sage: A(x).superalgebra_element()
48 e0 + e1 + e2 + e3 + e4 + e5
49
50 TESTS:
51
52 We can convert back and forth faithfully::
53
54 sage: set_random_seed()
55 sage: J = random_eja()
56 sage: x = J.random_element()
57 sage: A = x.subalgebra_generated_by()
58 sage: A(x).superalgebra_element() == x
59 True
60 sage: y = A.random_element()
61 sage: A(y.superalgebra_element()) == y
62 True
63
64 """
65 return self.parent().superalgebra().linear_combination(
66 zip(self.parent()._superalgebra_basis, self.to_vector()) )
67
68
69
70
71 class FiniteDimensionalEuclideanJordanElementSubalgebra(FiniteDimensionalEuclideanJordanAlgebra):
72 """
73 The subalgebra of an EJA generated by a single element.
74 """
75 def __init__(self, elt):
76 superalgebra = elt.parent()
77
78 # First compute the vector subspace spanned by the powers of
79 # the given element.
80 V = superalgebra.vector_space()
81 superalgebra_basis = [superalgebra.one()]
82 basis_vectors = [superalgebra.one().to_vector()]
83 W = V.span_of_basis(basis_vectors)
84 for exponent in range(1, V.dimension()):
85 new_power = elt**exponent
86 basis_vectors.append( new_power.to_vector() )
87 try:
88 W = V.span_of_basis(basis_vectors)
89 superalgebra_basis.append( new_power )
90 except ValueError:
91 # Vectors weren't independent; bail and keep the
92 # last subspace that worked.
93 break
94
95 # Make the basis hashable for UniqueRepresentation.
96 superalgebra_basis = tuple(superalgebra_basis)
97
98 # Now figure out the entries of the right-multiplication
99 # matrix for the successive basis elements b0, b1,... of
100 # that subspace.
101 field = superalgebra.base_ring()
102 mult_table = []
103 for b_right in superalgebra_basis:
104 b_right_cols = []
105 # The first column of the left-multiplication matrix by
106 # b1 is what we get if we apply that matrix to b1. The
107 # second column of the left-multiplication matrix by b1
108 # is what we get when we apply that matrix to b2...
109 for b_left in superalgebra_basis:
110 # Multiply in the original EJA, but then get the
111 # coordinates from the subalgebra in terms of its
112 # basis.
113 this_col = W.coordinates((b_left*b_right).to_vector())
114 b_right_cols.append(this_col)
115 b_right_matrix = matrix.column(field, b_right_cols)
116 mult_table.append(b_right_matrix)
117
118 for m in mult_table:
119 m.set_immutable()
120 mult_table = tuple(mult_table)
121
122 # TODO: We'll have to redo this and make it unique again...
123 prefix = 'f'
124
125 # The rank is the highest possible degree of a minimal
126 # polynomial, and is bounded above by the dimension. We know
127 # in this case that there's an element whose minimal
128 # polynomial has the same degree as the space's dimension
129 # (remember how we constructed the space?), so that must be
130 # its rank too.
131 rank = W.dimension()
132
133 category = superalgebra.category().Associative()
134 natural_basis = tuple( b.natural_representation()
135 for b in superalgebra_basis )
136
137 self._superalgebra = superalgebra
138 self._vector_space = W
139 self._superalgebra_basis = superalgebra_basis
140
141
142 fdeja = super(FiniteDimensionalEuclideanJordanElementSubalgebra, self)
143 return fdeja.__init__(field,
144 mult_table,
145 rank,
146 prefix=prefix,
147 category=category,
148 natural_basis=natural_basis)
149
150
151 def _element_constructor_(self, elt):
152 """
153 Construct an element of this subalgebra from the given one.
154 The only valid arguments are elements of the parent algebra
155 that happen to live in this subalgebra.
156
157 SETUP::
158
159 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
160 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
161
162 EXAMPLES::
163
164 sage: J = RealSymmetricEJA(3)
165 sage: x = sum( i*J.gens()[i] for i in range(6) )
166 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
167 sage: [ K(x^k) for k in range(J.rank()) ]
168 [f0, f1, f2]
169
170 ::
171
172 """
173 if elt in self.superalgebra():
174 coords = self.vector_space().coordinate_vector(elt.to_vector())
175 return self.from_vector(coords)
176
177
178 def superalgebra(self):
179 """
180 Return the superalgebra that this algebra was generated from.
181 """
182 return self._superalgebra
183
184
185 def vector_space(self):
186 """
187 SETUP::
188
189 sage: from mjo.eja.eja_algebra import RealSymmetricEJA
190 sage: from mjo.eja.eja_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra
191
192 EXAMPLES::
193
194 sage: J = RealSymmetricEJA(3)
195 sage: x = sum( i*J.gens()[i] for i in range(6) )
196 sage: K = FiniteDimensionalEuclideanJordanElementSubalgebra(x)
197 sage: K.vector_space()
198 Vector space of degree 6 and dimension 3 over Rational Field
199 User basis matrix:
200 [ 1 0 1 0 0 1]
201 [ 0 1 2 3 4 5]
202 [10 14 21 19 31 50]
203 sage: (x^0).to_vector()
204 (1, 0, 1, 0, 0, 1)
205 sage: (x^1).to_vector()
206 (0, 1, 2, 3, 4, 5)
207 sage: (x^2).to_vector()
208 (10, 14, 21, 19, 31, 50)
209
210 """
211 return self._vector_space
212
213
214 Element = FiniteDimensionalEuclideanJordanElementSubalgebraElement