]>
gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/matrix_algebra.py
a695b0b7919edfb243cd96fd2592aa2f9fa916df
1 from sage
.misc
.table
import table
2 from sage
.categories
.magmatic_algebras
import MagmaticAlgebras
3 from sage
.misc
.cachefunc
import cached_method
4 from sage
.combinat
.free_module
import CombinatorialFreeModule
5 from sage
.modules
.with_basis
.indexed_element
import IndexedFreeModuleElement
7 class MatrixAlgebraElement(IndexedFreeModuleElement
):
9 return self
.parent().nrows()
17 sage: from mjo.matrix_algebra import MatrixAlgebra
21 sage: M = MatrixAlgebra(QQbar,RDF,2)
22 sage: A = M.monomial((0,0,1)) + 4*M.monomial((0,1,1))
33 zero
= self
.parent().entry_algebra().zero()
34 l
= [[zero
for j
in range(self
.ncols())] for i
in range(self
.nrows())]
35 for (k
,v
) in self
.monomial_coefficients().items():
42 Display this matrix as a table.
44 The SageMath Matrix class representation is not easily reusable,
45 but using a table fakes it.
49 sage: from mjo.matrix_algebra import MatrixAlgebra
53 sage: MatrixAlgebra(ZZ,ZZ,2).one()
61 return table(self
.rows(), frame
=True)._repr
_()
66 Return one long list of this matrix's entries.
70 sage: from mjo.matrix_algebra import MatrixAlgebra
74 sage: MatrixAlgebra(ZZ,ZZ,2).one().list()
78 return sum( self
.rows(), [] )
81 def __getitem__(self
, indices
):
86 sage: from mjo.matrix_algebra import MatrixAlgebra
90 sage: M = MatrixAlgebra(ZZ,ZZ,2).one()
102 return self
.rows()[i
][j
]
106 Return the sum of this matrix's diagonal entries.
110 sage: from mjo.matrix_algebra import MatrixAlgebra
114 The trace (being a sum of entries) belongs to the same algebra
115 as those entries, and NOT the scalar ring::
117 sage: entries = MatrixSpace(ZZ,2)
119 sage: M = MatrixAlgebra(entries, scalars, 2)
120 sage: M.one().trace()
125 zero
= self
.parent().entry_algebra().zero()
126 return sum( (self
[i
,i
] for i
in range(self
.nrows())), zero
)
128 def matrix_space(self
):
133 sage: from mjo.matrix_algebra import MatrixAlgebra
137 sage: set_random_seed()
138 sage: entries = QuaternionAlgebra(QQ,-1,-1)
139 sage: M = MatrixAlgebra(entries, QQ, 3)
140 sage: M.random_element().matrix_space() == M
146 # onlt valid in HurwitzMatrixAlgebra subclass
147 # def is_hermitian(self):
152 # sage: from mjo.octonions import OctonionMatrixAlgebra
156 # sage: MS = OctonionMatrixAlgebra(3)
157 # sage: MS.one().is_hermitian()
161 # return all( self[i,j] == self[j,i].conjugate()
162 # for i in range(self.nrows())
163 # for j in range(self.ncols()) )
166 class MatrixAlgebra(CombinatorialFreeModule
):
168 An algebra of ``n``-by-``n`` matrices over an arbitrary scalar
169 ring whose entries come from a magmatic algebra that need not
170 be the same as the scalars.
172 The usual matrix spaces in SageMath don't support separate spaces
173 for the entries and the scalars; in particular they assume that
174 the entries come from a commutative and associative ring. This
175 is problematic in several interesting matrix algebras, like those
176 where the entries are quaternions or octonions.
178 Element
= MatrixAlgebraElement
180 def __init__(self
, entry_algebra
, scalars
, n
, prefix
="A", **kwargs
):
182 category
= MagmaticAlgebras(scalars
).FiniteDimensional()
183 category
= category
.WithBasis()
185 if "Unital" in entry_algebra
.category().axioms():
186 category
= category
.Unital()
187 if "Associative" in entry_algebra
.category().axioms():
188 category
= category
.Associative()
192 # Since the scalar ring is real but the entries are not,
193 # sticking a "1" in each position doesn't give us a basis for
194 # the space. We actually need to stick each of e0, e1, ... (a
195 # basis for the entry algebra itself) into each position.
196 from sage
.sets
.finite_enumerated_set
import FiniteEnumeratedSet
197 from sage
.categories
.sets_cat
import cartesian_product
199 I
= FiniteEnumeratedSet(range(n
))
200 J
= FiniteEnumeratedSet(range(n
))
201 self
._entry
_algebra
= entry_algebra
202 entry_basis
= entry_algebra
.gens()
204 basis_indices
= cartesian_product([I
,J
,entry_basis
])
205 super().__init
__(scalars
,
212 return ("Module of %d by %d matrices with entries in %s"
213 " over the scalar ring %s" %
216 self
.entry_algebra(),
219 def entry_algebra(self
):
221 Return the algebra that our elements' entries come from.
223 return self
._entry
_algebra
229 def product_on_basis(self
, mon1
, mon2
):
233 return self
.monomial((i
,l
,oct1
*oct2
))
241 sage: from mjo.matrix_algebra import MatrixAlgebra
244 return sum( (self
.monomial((i
,i
,self
.entry_algebra().one()))
245 for i
in range(self
.nrows()) ),
248 def from_list(self
, entries
):
250 Construct an element of this algebra from a list of lists of
255 sage: from mjo.matrix_algebra import MatrixAlgebra
261 ncols
= len(entries
[0])
263 if (not all( len(r
) == ncols
for r
in entries
)) or (ncols
!= nrows
):
264 raise ValueError("list must be square")
267 # We have to pass through vectors to convert from the
268 # given entry algebra to ours. Otherwise we can fail
269 # to convert an element of (for example) Octonions(QQ)
271 return self
.entry_algebra().from_vector(e_ij
.to_vector())
273 return sum( (self
.monomial( (i
,j
, convert(entries
[i
][j
])) )
274 for i
in range(nrows
)
275 for j
in range(ncols
) ),