]>
gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/basis_repr.py
2 In an `n`-dimensional vector space, representation with respect to
3 a basis is an isometry between that space and `\mathbb{R}^{n}`.
5 Sage is able to go back/forth relatively easy when you start with a
6 ``VectorSpace``, but unfortunately, it does not know that a
7 ``MatrixSpace`` is also a ``VectorSpace``. So, this module exists to
8 perform the "basis representation" isometry between a matrix space and
9 a vector space of the same dimension.
13 from sage
.all
import *
14 from sage
.matrix
.matrix_space
import is_MatrixSpace
17 return vector(m
.base_ring(), m
.list())
21 Return the forward (``MatrixSpace`` -> ``VectorSpace``) and
22 inverse isometries, as a pair, that take elements of the given
23 ``MatrixSpace`` `M` to their representations as "long vectors,"
26 The argument ``M`` can be either a ``MatrixSpace`` or a basis for
27 a space of matrices. This function is needed because SageMath does
28 not know that matrix spaces are vector spaces, and therefore
29 cannot perform common operations with them -- like computing the
30 basis representation of an element.
32 Moreover, the ability to pass in a basis (rather than a
33 ``MatrixSpace``) is needed because SageMath has no way to express
34 that e.g. a (sub)space of symmetric matrices is itself a
39 - ``M`` -- Either a ``MatrixSpace``, or a list of matrices that form
40 a basis for a matrix space.
44 A pair of isometries ``(phi, phi_inv)``.
46 If the matrix space associated with `M` has dimension `n`, then
47 ``phi`` will map its elements to vectors of length `n` over the
48 same base ring. The inverse map ``phi_inv`` reverses that
53 sage: from mjo.basis_repr import basis_repr
57 This function computes the correct coordinate representations (of
58 length 3) for a basis of the space of two-by-two symmetric
59 matrices, the the inverse does indeed invert the process::
61 sage: E11 = matrix(QQbar,[ [1,0],
63 sage: E12 = matrix(QQbar,[ [0, 1/sqrt(2)],
64 ....: [1/sqrt(2), 0] ])
65 sage: E22 = matrix(QQbar,[ [0,0],
67 sage: basis = [E11, E12, E22]
68 sage: phi, phi_inv = basis_repr(basis)
69 sage: phi(E11); phi(E12); phi(E22)
73 sage: phi_inv(phi(E11)) == E11
75 sage: phi_inv(phi(E12)) == E12
77 sage: phi_inv(phi(E22)) == E22
80 MatrixSpace arguments work too::
82 sage: M = MatrixSpace(QQ,2)
83 sage: phi, phi_inv = basis_repr(M)
84 sage: X = matrix(QQ, [ [1,2],
88 sage: phi_inv(phi(X)) == X
93 The inverse is generally an inverse::
95 sage: set_random_seed()
96 sage: n = ZZ.random_element(10)
97 sage: M = MatrixSpace(QQ,n)
98 sage: X = M.random_element()
99 sage: (phi, phi_inv) = basis_repr(M)
100 sage: phi_inv(phi(X)) == X
104 if is_MatrixSpace(M
):
106 basis
= list(M
.basis())
108 basis_space
= M
[0].matrix_space()
113 The isometry sending ``X`` to its representation as a long vector.
115 if X
not in basis_space
:
116 raise ValueError("X does not live in the domain of phi")
118 V
= VectorSpace(basis_space
.base_ring(), X
.nrows()*X
.ncols())
119 W
= V
.span_of_basis( _mat2vec(s
) for s
in basis
)
120 return W
.coordinate_vector(_mat2vec(X
))
124 The isometry sending the long vector `Y` to an element of either
125 `M` or the span of `M` (depending on whether or not ``M``
126 is a ``MatrixSpace`` or a basis).
128 return basis_space
.linear_combination( zip(Y
,basis
) )
130 return (phi
, phi_inv
)
134 def basis_repr_of_operator(M
, L
):
136 Return the matrix of the operator `L` with respect to the basis
137 `M` if `M` is a list of basis vectors for a matrix space; or with
138 respect to the standard basis of `M` if `M` is a ``MatrixSpace``.
140 This function is necessary because SageMath does not know that
141 matrix spaces are vector spaces, and it moreover it doesn't know
142 that (for example) the subspace of symmetric matrices is a matrix
143 space in its own right.
145 Use ``linear_transformation().matrix()`` instead if you have a
146 true ``VectorSpace``.
150 - ``M`` -- Either a ``MatrixSpace``, or a list of matrices that form
151 a basis for a matrix space.
155 If the matrix space associated with `M` has dimension `n`, then an
156 `n`-by-`n` matrix over the same base ring is returned.
160 sage: from mjo.basis_repr import (basis_repr,
161 ....: basis_repr_of_operator)
165 The matrix of the identity operator on the space of two-by-two
166 symmetric matrices is the identity matrix, regardless of the basis::
168 sage: E11 = matrix(QQbar,[ [1,0],
170 sage: E12 = matrix(QQbar,[ [0, 1/sqrt(2)],
171 ....: [1/sqrt(2), 0] ])
172 sage: E22 = matrix(QQbar,[ [0,0],
174 sage: basis = [E11, E12, E22]
175 sage: identity = lambda X: X
176 sage: basis_repr_of_operator(basis, identity)
180 sage: E11 = matrix(QQ,[[2,0],[0,0]])
181 sage: E12 = matrix(QQ,[[0,2],[2,0]])
182 sage: basis = [E11, E12, E22]
183 sage: basis_repr_of_operator(basis, identity)
188 A more complicated example confirms that we get a matrix consistent
189 with our ``matrix_to_vector`` function::
191 sage: M = MatrixSpace(QQ,3,3)
192 sage: Q = M([[0,1,0],[1,0,0],[0,0,1]])
194 ....: return Q*x*Q.inverse()
196 sage: F = basis_repr_of_operator(M, f)
207 sage: phi, phi_inv = basis_repr(M)
208 sage: X = M([[1,2,3],[4,5,6],[7,8,9]])
209 sage: F*phi(X) == phi(f(X))
213 if is_MatrixSpace(M
):
215 basis
= list(M
.basis())
217 basis_space
= M
[0].matrix_space()
220 (phi
, phi_inv
) = basis_repr(M
)
222 # Get a basis for the image space. Since phi is an isometry,
223 # it takes one basis to another.
224 image_basis
= [ phi(b
) for b
in basis
]
226 # Now construct the image space itself equipped with our custom basis.
227 W
= VectorSpace(basis_space
.base_ring(), len(basis
))
228 W
= W
.span_of_basis(image_basis
)
230 return matrix
.column( W
.coordinates(phi(L(b
))) for b
in basis
)