]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/eja_element_subalgebra.py
846c13b095cb812edff5c3340c1f0cc8337fe149
[sage.d.git] / mjo / eja / eja_element_subalgebra.py
1 from sage.matrix.constructor import matrix
2 from sage.misc.cachefunc import cached_method
3 from sage.rings.all import QQ
4
5 from mjo.eja.eja_subalgebra import FiniteDimensionalEJASubalgebra
6
7
8 class FiniteDimensionalEJAElementSubalgebra(FiniteDimensionalEJASubalgebra):
9 def __init__(self, elt, orthonormalize=True, **kwargs):
10 superalgebra = elt.parent()
11
12 # TODO: going up to the superalgebra dimension here is
13 # overkill. We should append p vectors as rows to a matrix
14 # and continually rref() it until the rank stops going
15 # up. When n=10 but the dimension of the algebra is 1, that
16 # can save a shitload of time (especially over AA).
17 powers = tuple( elt**k for k in range(superalgebra.dimension()) )
18 power_vectors = ( p.to_vector() for p in powers )
19 P = matrix(superalgebra.base_ring(), power_vectors)
20
21 # Echelonize the matrix ourselves, because otherwise the
22 # call to P.pivot_rows() below can choose a non-optimal
23 # row-reduction algorithm. In particular, scaling can
24 # help over AA because it avoids the RecursionError that
25 # gets thrown when we have to look too hard for a root.
26 #
27 # Beware: QQ supports an entirely different set of "algorithm"
28 # keywords than do AA and RR.
29 algo = None
30 if superalgebra.base_ring() is not QQ:
31 algo = "scaled_partial_pivoting"
32 P.echelonize(algorithm=algo)
33
34 # Figure out which powers form a linearly-independent set.
35 ind_rows = P.pivot_rows()
36
37 # Pick those out of the list of all powers.
38 basis = tuple(map(powers.__getitem__, ind_rows))
39
40
41 super().__init__(superalgebra,
42 basis,
43 associative=True,
44 **kwargs)
45
46 # The rank is the highest possible degree of a minimal
47 # polynomial, and is bounded above by the dimension. We know
48 # in this case that there's an element whose minimal
49 # polynomial has the same degree as the space's dimension
50 # (remember how we constructed the space?), so that must be
51 # its rank too.
52 self.rank.set_cache(self.dimension())
53
54
55 @cached_method
56 def one(self):
57 """
58 Return the multiplicative identity element of this algebra.
59
60 The superclass method computes the identity element, which is
61 beyond overkill in this case: the superalgebra identity
62 restricted to this algebra is its identity. Note that we can't
63 count on the first basis element being the identity -- it might
64 have been scaled if we orthonormalized the basis.
65
66 SETUP::
67
68 sage: from mjo.eja.eja_algebra import (HadamardEJA,
69 ....: random_eja)
70
71 EXAMPLES::
72
73 sage: J = HadamardEJA(5)
74 sage: J.one()
75 e0 + e1 + e2 + e3 + e4
76 sage: x = sum(J.gens())
77 sage: A = x.subalgebra_generated_by()
78 sage: A.one()
79 f0
80 sage: A.one().superalgebra_element()
81 e0 + e1 + e2 + e3 + e4
82
83 TESTS:
84
85 The identity element acts like the identity over the rationals::
86
87 sage: set_random_seed()
88 sage: x = random_eja(field=QQ,orthonormalize=False).random_element()
89 sage: A = x.subalgebra_generated_by()
90 sage: x = A.random_element()
91 sage: A.one()*x == x and x*A.one() == x
92 True
93
94 The identity element acts like the identity over the algebraic
95 reals with an orthonormal basis::
96
97 sage: set_random_seed()
98 sage: x = random_eja().random_element()
99 sage: A = x.subalgebra_generated_by(orthonormalize_basis=True)
100 sage: x = A.random_element()
101 sage: A.one()*x == x and x*A.one() == x
102 True
103
104 The matrix of the unit element's operator is the identity over
105 the rationals::
106
107 sage: set_random_seed()
108 sage: x = random_eja(field=QQ,orthonormalize=False).random_element()
109 sage: A = x.subalgebra_generated_by()
110 sage: actual = A.one().operator().matrix()
111 sage: expected = matrix.identity(A.base_ring(), A.dimension())
112 sage: actual == expected
113 True
114
115 The matrix of the unit element's operator is the identity over
116 the algebraic reals with an orthonormal basis::
117
118 sage: set_random_seed()
119 sage: x = random_eja().random_element()
120 sage: A = x.subalgebra_generated_by(orthonormalize_basis=True)
121 sage: actual = A.one().operator().matrix()
122 sage: expected = matrix.identity(A.base_ring(), A.dimension())
123 sage: actual == expected
124 True
125
126 """
127 if self.dimension() == 0:
128 return self.zero()
129
130 return self(self.superalgebra().one())
131