]>
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: n = ZZ.random_element(10)
96 sage: M = MatrixSpace(QQ,n)
97 sage: X = M.random_element()
98 sage: (phi, phi_inv) = basis_repr(M)
99 sage: phi_inv(phi(X)) == X
103 if is_MatrixSpace(M
):
105 basis
= list(M
.basis())
107 basis_space
= M
[0].matrix_space()
112 The isometry sending ``X`` to its representation as a long vector.
114 if X
not in basis_space
:
115 raise ValueError("X does not live in the domain of phi")
117 V
= VectorSpace(basis_space
.base_ring(), X
.nrows()*X
.ncols())
118 W
= V
.span_of_basis( _mat2vec(s
) for s
in basis
)
119 return W
.coordinate_vector(_mat2vec(X
))
123 The isometry sending the long vector `Y` to an element of either
124 `M` or the span of `M` (depending on whether or not ``M``
125 is a ``MatrixSpace`` or a basis).
127 return basis_space
.linear_combination( zip(Y
,basis
) )
129 return (phi
, phi_inv
)
133 def basis_repr_of_operator(M
, L
):
135 Return the matrix of the operator `L` with respect to the basis
136 `M` if `M` is a list of basis vectors for a matrix space; or with
137 respect to the standard basis of `M` if `M` is a ``MatrixSpace``.
139 This function is necessary because SageMath does not know that
140 matrix spaces are vector spaces, and it moreover it doesn't know
141 that (for example) the subspace of symmetric matrices is a matrix
142 space in its own right.
144 Use ``linear_transformation().matrix()`` instead if you have a
145 true ``VectorSpace``.
149 - ``M`` -- Either a ``MatrixSpace``, or a list of matrices that form
150 a basis for a matrix space.
154 If the matrix space associated with `M` has dimension `n`, then an
155 `n`-by-`n` matrix over the same base ring is returned.
159 sage: from mjo.basis_repr import (basis_repr,
160 ....: basis_repr_of_operator)
164 The matrix of the identity operator on the space of two-by-two
165 symmetric matrices is the identity matrix, regardless of the basis::
167 sage: E11 = matrix(QQbar,[ [1,0],
169 sage: E12 = matrix(QQbar,[ [0, 1/sqrt(2)],
170 ....: [1/sqrt(2), 0] ])
171 sage: E22 = matrix(QQbar,[ [0,0],
173 sage: basis = [E11, E12, E22]
174 sage: identity = lambda X: X
175 sage: basis_repr_of_operator(basis, identity)
179 sage: E11 = matrix(QQ,[[2,0],[0,0]])
180 sage: E12 = matrix(QQ,[[0,2],[2,0]])
181 sage: basis = [E11, E12, E22]
182 sage: basis_repr_of_operator(basis, identity)
187 A more complicated example confirms that we get a matrix consistent
188 with our ``matrix_to_vector`` function::
190 sage: M = MatrixSpace(QQ,3,3)
191 sage: Q = M([[0,1,0],[1,0,0],[0,0,1]])
193 ....: return Q*x*Q.inverse()
195 sage: F = basis_repr_of_operator(M, f)
206 sage: phi, phi_inv = basis_repr(M)
207 sage: X = M([[1,2,3],[4,5,6],[7,8,9]])
208 sage: F*phi(X) == phi(f(X))
212 if is_MatrixSpace(M
):
214 basis
= list(M
.basis())
216 basis_space
= M
[0].matrix_space()
219 (phi
, phi_inv
) = basis_repr(M
)
221 # Get a basis for the image space. Since phi is an isometry,
222 # it takes one basis to another.
223 image_basis
= [ phi(b
) for b
in basis
]
225 # Now construct the image space itself equipped with our custom basis.
226 W
= VectorSpace(basis_space
.base_ring(), len(basis
))
227 W
= W
.span_of_basis(image_basis
)
229 return matrix
.column( W
.coordinates(phi(L(b
))) for b
in basis
)