Matrix Spaces

You can create any space \(\text{Mat}_{n\times m}(R)\) of either dense or sparse matrices with given number of rows and columns over any commutative or noncommutative ring.

EXAMPLES:

sage: MS = MatrixSpace(QQ,6,6,sparse=True); MS
Full MatrixSpace of 6 by 6 sparse matrices over Rational Field
sage: MS.base_ring()
Rational Field
sage: MS = MatrixSpace(ZZ,3,5,sparse=False); MS
Full MatrixSpace of 3 by 5 dense matrices over Integer Ring
class sage.matrix.matrix_space.MatrixSpace(base_ring, nrows, ncols, sparse, implementation)

Bases: sage.structure.unique_representation.UniqueRepresentation, sage.structure.parent.Parent

The space of matrices of given size and base ring

EXAMPLES:

Some examples of square 2 by 2 rational matrices:

sage: MS = MatrixSpace(QQ, 2)
sage: MS.dimension()
4
sage: MS.dims()
(2, 2)
sage: B = MS.basis()
sage: list(B)
[
[1 0]  [0 1]  [0 0]  [0 0]
[0 0], [0 0], [1 0], [0 1]
]
sage: B[0,0]
[1 0]
[0 0]
sage: B[0,1]
[0 1]
[0 0]
sage: B[1,0]
[0 0]
[1 0]
sage: B[1,1]
[0 0]
[0 1]
sage: A = MS.matrix([1,2,3,4])
sage: A
[1 2]
[3 4]

The above matrix A can be multiplied by a 2 by 3 integer matrix:

sage: MS2 = MatrixSpace(ZZ, 2, 3)
sage: B = MS2.matrix([1,2,3,4,5,6])
sage: A * B
[ 9 12 15]
[19 26 33]

Check categories:

sage: MatrixSpace(ZZ,10,5)
Full MatrixSpace of 10 by 5 dense matrices over Integer Ring
sage: MatrixSpace(ZZ,10,5).category()
Category of infinite enumerated finite dimensional modules with basis over
 (euclidean domains and infinite enumerated sets and metric spaces)
sage: MatrixSpace(ZZ,10,10).category()
Category of infinite enumerated finite dimensional algebras with basis over
 (euclidean domains and infinite enumerated sets and metric spaces)
sage: MatrixSpace(QQ,10).category()
Category of infinite finite dimensional algebras with basis over
 (number fields and quotient fields and metric spaces)
base_extend(R)

Return base extension of this matrix space to R.

INPUT:

  • R - ring

OUTPUT: a matrix space

EXAMPLES:

sage: Mat(ZZ,3,5).base_extend(QQ)
Full MatrixSpace of 3 by 5 dense matrices over Rational Field
sage: Mat(QQ,3,5).base_extend(GF(7))
Traceback (most recent call last):
...
TypeError: no base extension defined
basis()

Return a basis for this matrix space.

Warning

This will of course compute every generator of this matrix space. So for large dimensions, this could take a long time, waste a massive amount of memory (for dense matrices), and is likely not very useful. Don’t use this on large matrix spaces.

EXAMPLES:

sage: list(Mat(ZZ,2,2).basis())
[
[1 0]  [0 1]  [0 0]  [0 0]
[0 0], [0 0], [1 0], [0 1]
]
cached_method(f, name=None, key=None, do_pickle=None)

A decorator for cached methods.

EXAMPLES:

In the following examples, one can see how a cached method works in application. Below, we demonstrate what is done behind the scenes:

sage: class C:
....:     @cached_method
....:     def __hash__(self):
....:         print("compute hash")
....:         return int(5)
....:     @cached_method
....:     def f(self, x):
....:         print("computing cached method")
....:         return x*2
sage: c = C()
sage: type(C.__hash__)
<type 'sage.misc.cachefunc.CachedMethodCallerNoArgs'>
sage: hash(c)
compute hash
5

When calling a cached method for the second time with the same arguments, the value is gotten from the cache, so that a new computation is not needed:

sage: hash(c)
5
sage: c.f(4)
computing cached method
8
sage: c.f(4) is c.f(4)
True

Different instances have distinct caches:

sage: d = C()
sage: d.f(4) is c.f(4)
computing cached method
False
sage: d.f.clear_cache()
sage: c.f(4)
8
sage: d.f(4)
computing cached method
8

Using cached methods for the hash and other special methods was implemented in trac ticket #12601, by means of CachedSpecialMethod. We show that it is used behind the scenes:

sage: cached_method(c.__hash__)
<sage.misc.cachefunc.CachedSpecialMethod object at ...>
sage: cached_method(c.f)
<sage.misc.cachefunc.CachedMethod object at ...>

The parameter do_pickle can be used if the contents of the cache should be stored in a pickle of the cached method. This can be dangerous with special methods such as __hash__:

sage: class C:
....:     @cached_method(do_pickle=True)
....:     def __hash__(self):
....:         return id(self)

sage: import __main__
sage: __main__.C = C
sage: c = C()
sage: hash(c) # random output
sage: d = loads(dumps(c))
sage: hash(d) == hash(c)
True

However, the contents of a method’s cache are not pickled unless do_pickle is set:

sage: class C:
....:     @cached_method
....:     def __hash__(self):
....:         return id(self)

sage: __main__.C = C
sage: c = C()
sage: hash(c) # random output
sage: d = loads(dumps(c))
sage: hash(d) == hash(c)
False
cardinality()

Return the number of elements in self.

EXAMPLES:

sage: MatrixSpace(GF(3), 2, 3).cardinality()
729
sage: MatrixSpace(ZZ, 2).cardinality()
+Infinity
sage: MatrixSpace(ZZ, 0, 3).cardinality()
1
change_ring(R)

Return matrix space over R with otherwise same parameters as self.

INPUT:

  • R - ring

OUTPUT: a matrix space

EXAMPLES:

sage: Mat(QQ,3,5).change_ring(GF(7))
Full MatrixSpace of 3 by 5 dense matrices over Finite Field of size 7
characteristic()

Return the characteristic.

EXAMPLES:

sage: MatrixSpace(ZZ, 2).characteristic()
0
sage: MatrixSpace(GF(9), 0).characteristic()
3
column_space()

Return the module spanned by all columns of matrices in this matrix space. This is a free module of rank the number of columns. It will be sparse or dense as this matrix space is sparse or dense.

EXAMPLES:

sage: M = Mat(GF(9,'a'),20,5,sparse=True); M.column_space()
Sparse vector space of dimension 20 over Finite Field in a of size 3^2
construction()

EXAMPLES:

sage: A = matrix(ZZ, 2, [1..4], sparse=True)
sage: A.parent().construction()
(MatrixFunctor, Integer Ring)
sage: A.parent().construction()[0](QQ['x'])
Full MatrixSpace of 2 by 2 sparse matrices over Univariate Polynomial Ring in x over Rational Field
sage: parent(A/2)
Full MatrixSpace of 2 by 2 sparse matrices over Rational Field
dimension()

Return (m rows) * (n cols) of self as Integer.

EXAMPLES:

sage: MS = MatrixSpace(ZZ,4,6)
sage: u = MS.dimension()
sage: u - 24 == 0
True
dims()

Return (m row, n col) representation of self dimension.

EXAMPLES:

sage: MS = MatrixSpace(ZZ,4,6)
sage: MS.dims()
(4, 6)
gen(n)

Return the n-th generator of this matrix space.

This does not compute all basis matrices, so it is reasonably intelligent.

EXAMPLES:

sage: M = Mat(GF(7),10000,5); M.ngens()
50000
sage: a = M.10
sage: a[:4]
[0 0 0 0 0]
[0 0 0 0 0]
[1 0 0 0 0]
[0 0 0 0 0]
identity_matrix()

Return the identity matrix in self.

self must be a space of square matrices. The returned matrix is immutable. Please use copy if you want a modified copy.

EXAMPLES:

sage: MS1 = MatrixSpace(ZZ,4)
sage: MS2 = MatrixSpace(QQ,3,4)
sage: I = MS1.identity_matrix()
sage: I
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
sage: Er = MS2.identity_matrix()
Traceback (most recent call last):
...
TypeError: identity matrix must be square
is_dense()

Return whether matrices in self are dense.

EXAMPLES:

sage: Mat(RDF,2,3).is_sparse()
False
sage: Mat(RR,123456,22,sparse=True).is_sparse()
True
is_finite()

Return whether this matrix space is finite.

EXAMPLES:

sage: MatrixSpace(GF(101), 10000).is_finite()
True
sage: MatrixSpace(QQ, 2).is_finite()
False
is_sparse()

Return whether matrices in self are sparse.

EXAMPLES:

sage: Mat(GF(2011),10000).is_sparse()
False
sage: Mat(GF(2011),10000,sparse=True).is_sparse()
True
matrix(x=None, **kwds)

Create a matrix in self.

INPUT:

  • x – data to construct a new matrix from. See matrix()
  • coerce – (default: True) if False, assume without checking that the values in x lie in the base ring

OUTPUT:

  • a matrix in self.

EXAMPLES:

sage: M = MatrixSpace(ZZ, 2)
sage: M.matrix([[1,0],[0,-1]])
[ 1  0]
[ 0 -1]
sage: M.matrix([1,0,0,-1])
[ 1  0]
[ 0 -1]
sage: M.matrix([1,2,3,4])
[1 2]
[3 4]

Note that the last “flip” cannot be performed if x is a matrix, no matter what is rows (it used to be possible but was fixed by trac ticket #10793):

sage: projection = matrix(ZZ,[[1,0,0],[0,1,0]])
sage: projection
[1 0 0]
[0 1 0]
sage: projection.parent()
Full MatrixSpace of 2 by 3 dense matrices over Integer Ring
sage: M = MatrixSpace(ZZ, 3 , 2)
sage: M
Full MatrixSpace of 3 by 2 dense matrices over Integer Ring
sage: M(projection)
Traceback (most recent call last):
...
ValueError: inconsistent number of rows: should be 3 but got 2

If you really want to make from a matrix another matrix of different dimensions, use either transpose method or explicit conversion to a list:

sage: M(projection.list())
[1 0]
[0 0]
[1 0]
matrix_space(nrows=None, ncols=None, sparse=False)

Return the matrix space with given number of rows, columns and sparcity over the same base ring as self, and defaults the same as self.

EXAMPLES:

sage: M = Mat(GF(7),100,200)
sage: M.matrix_space(5000)
Full MatrixSpace of 5000 by 200 dense matrices over Finite Field of size 7
sage: M.matrix_space(ncols=5000)
Full MatrixSpace of 100 by 5000 dense matrices over Finite Field of size 7
sage: M.matrix_space(sparse=True)
Full MatrixSpace of 100 by 200 sparse matrices over Finite Field of size 7
ncols()

Return the number of columns of matrices in this space.

EXAMPLES:

sage: M = Mat(ZZ['x'],200000,500000,sparse=True)
sage: M.ncols()
500000
ngens()

Return the number of generators of this matrix space.

This is the number of entries in the matrices in this space.

EXAMPLES:

sage: M = Mat(GF(7),100,200); M.ngens()
20000
nrows()

Return the number of rows of matrices in this space.

EXAMPLES:

sage: M = Mat(ZZ,200000,500000)
sage: M.nrows()
200000
one()

Return the identity matrix in self.

self must be a space of square matrices. The returned matrix is immutable. Please use copy if you want a modified copy.

EXAMPLES:

sage: MS1 = MatrixSpace(ZZ,4)
sage: MS2 = MatrixSpace(QQ,3,4)
sage: I = MS1.identity_matrix()
sage: I
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
sage: Er = MS2.identity_matrix()
Traceback (most recent call last):
...
TypeError: identity matrix must be square
random_element(density=None, *args, **kwds)

Return a random element from this matrix space.

INPUT:

  • density - float or None (default: None); rough measure of the proportion of nonzero entries in the random matrix; if set to None, all entries of the matrix are randomized, allowing for any element of the underlying ring, but if set to a float, a proportion of entries is selected and randomized to non-zero elements of the ring
  • *args, **kwds - remaining parameters, which may be passed to the random_element function of the base ring. (“may be”, since this function calls the randomize function on the zero matrix, which need not call the random_element function of the base ring at all in general.)

OUTPUT:

  • Matrix

Note

This method will randomize a proportion of roughly density entries in a newly allocated zero matrix.

By default, if the user sets the value of density explicitly, this method will enforce that these entries are set to non-zero values. However, if the test for equality with zero in the base ring is too expensive, the user can override this behaviour by passing the argument nonzero=False to this method.

Otherwise, if the user does not set the value of density, the default value is taken to be 1, and the option nonzero=False is passed to the randomize method.

EXAMPLES:

sage: Mat(ZZ,2,5).random_element()
[ -8   2   0   0   1]
[ -1   2   1 -95  -1]
sage: Mat(QQ,2,5).random_element(density=0.5)
[  2   0   0   0   1]
[  0   0   0 1/2   0]
sage: Mat(QQ,3,sparse=True).random_element()
[  -1  1/3    1]
[   0   -1    0]
[  -1    1 -1/4]
sage: Mat(GF(9,'a'),3,sparse=True).random_element()
[      1       2       1]
[  a + 2     2*a       2]
[      2 2*a + 2       1]
row_space()

Return the module spanned by all rows of matrices in this matrix space. This is a free module of rank the number of rows. It will be sparse or dense as this matrix space is sparse or dense.

EXAMPLES:

sage: M = Mat(ZZ,20,5,sparse=False); M.row_space()
Ambient free module of rank 5 over the principal ideal domain Integer Ring
some_elements()

Return some elements of this matrix space.

See TestSuite for a typical use case.

OUTPUT:

An iterator.

EXAMPLES:

sage: M = MatrixSpace(ZZ, 2, 2)
sage: tuple(M.some_elements())
(
[ 0  1]  [1 0]  [0 1]  [0 0]  [0 0]
[-1  2], [0 0], [0 0], [1 0], [0 1]
)
sage: M = MatrixSpace(QQ, 2, 3)
sage: tuple(M.some_elements())
(
[ 1/2 -1/2    2]  [1 0 0]  [0 1 0]  [0 0 1]  [0 0 0]  [0 0 0]  [0 0 0]
[  -2    0    1], [0 0 0], [0 0 0], [0 0 0], [1 0 0], [0 1 0], [0 0 1]
)
sage: M = MatrixSpace(SR, 2, 2)
sage: tuple(M.some_elements())
(
[some_variable some_variable]  [1 0]  [0 1]  [0 0]  [0 0]
[some_variable some_variable], [0 0], [0 0], [1 0], [0 1]
)
transposed()

The transposed matrix space, having the same base ring and sparseness, but number of columns and rows is swapped.

EXAMPLES:

sage: MS = MatrixSpace(GF(3), 7, 10)
sage: MS.transposed
Full MatrixSpace of 10 by 7 dense matrices over Finite Field of size 3
sage: MS = MatrixSpace(GF(3), 7, 7)
sage: MS.transposed is MS
True

sage: M = MatrixSpace(ZZ, 2, 3)
sage: M.transposed
Full MatrixSpace of 3 by 2 dense matrices over Integer Ring
zero()

Return the zero matrix in self.

self must be a space of square matrices. The returned matrix is immutable. Please use copy if you want a modified copy.

EXAMPLES:

sage: z = MatrixSpace(GF(7),2,4).zero_matrix(); z
[0 0 0 0]
[0 0 0 0]
sage: z.is_mutable()
False
zero_matrix()

Return the zero matrix in self.

self must be a space of square matrices. The returned matrix is immutable. Please use copy if you want a modified copy.

EXAMPLES:

sage: z = MatrixSpace(GF(7),2,4).zero_matrix(); z
[0 0 0 0]
[0 0 0 0]
sage: z.is_mutable()
False
sage.matrix.matrix_space.dict_to_list(entries, nrows, ncols)

Given a dictionary of coordinate tuples, return the list given by reading off the nrows*ncols matrix in row order.

EXAMPLES:

sage: from sage.matrix.matrix_space import dict_to_list
sage: d = {}
sage: d[(0,0)] = 1
sage: d[(1,1)] = 2
sage: dict_to_list(d, 2, 2)
[1, 0, 0, 2]
sage: dict_to_list(d, 2, 3)
[1, 0, 0, 0, 2, 0]
sage.matrix.matrix_space.get_matrix_class(R, nrows, ncols, sparse, implementation)

Return a matrix class according to the input.

Note

This returns the base class without the category.

INPUT:

  • R – a base ring
  • nrows – number of rows
  • ncols – number of columns
  • sparse – (boolean) whether the matrix class should be sparse
  • implementation – (None or string or a matrix class) a possible implementation. See the documentation of the constructor of MatrixSpace.

EXAMPLES:

sage: from sage.matrix.matrix_space import get_matrix_class

sage: get_matrix_class(ZZ, 4, 5, False, None)
<type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'>
sage: get_matrix_class(ZZ, 4, 5, True, None)
<type 'sage.matrix.matrix_integer_sparse.Matrix_integer_sparse'>

sage: get_matrix_class(ZZ, 3, 3, False, 'flint')
<type 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'>
sage: get_matrix_class(ZZ, 3, 3, False, 'gap')
<type 'sage.matrix.matrix_gap.Matrix_gap'>
sage: get_matrix_class(ZZ, 3, 3, False, 'generic')
<type 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>

sage: get_matrix_class(GF(2), 2, 2, False, 'm4ri')
<type 'sage.matrix.matrix_mod2_dense.Matrix_mod2_dense'>
sage: get_matrix_class(GF(4), 2, 2, False, 'm4ri')
<type 'sage.matrix.matrix_gf2e_dense.Matrix_gf2e_dense'>
sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-float')
<type 'sage.matrix.matrix_modn_dense_float.Matrix_modn_dense_float'>
sage: get_matrix_class(GF(7), 2, 2, False, 'linbox-double')
<type 'sage.matrix.matrix_modn_dense_double.Matrix_modn_dense_double'>

sage: get_matrix_class(RDF, 2, 2, False, 'numpy')
<type 'sage.matrix.matrix_real_double_dense.Matrix_real_double_dense'>
sage: get_matrix_class(CDF, 2, 3, False, 'numpy')
<type 'sage.matrix.matrix_complex_double_dense.Matrix_complex_double_dense'>

sage: get_matrix_class(ZZ, 3, 5, False, 'crazy_matrix')
Traceback (most recent call last):
...
ValueError: unknown matrix implementation 'crazy_matrix' over Integer Ring
sage: get_matrix_class(GF(3), 2, 2, False, 'm4ri')
Traceback (most recent call last):
...
ValueError: m4ri matrices are only available in characteristic 2
sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-float')
Traceback (most recent call last):
...
ValueError: linbox-float can only deal with order < 256
sage: get_matrix_class(Zmod(2**30), 2, 2, False, 'linbox-double')
Traceback (most recent call last):
...
ValueError: linbox-double can only deal with order < 8388608

sage: type(matrix(SR, 2, 2, 0))
<type 'sage.matrix.matrix_symbolic_dense.Matrix_symbolic_dense'>
sage: type(matrix(GF(7), 2, range(4)))
<type 'sage.matrix.matrix_modn_dense_float.Matrix_modn_dense_float'>
sage: type(matrix(GF(16007), 2, range(4)))
<type 'sage.matrix.matrix_modn_dense_double.Matrix_modn_dense_double'>
sage: type(matrix(CBF, 2, range(4)))
<type 'sage.matrix.matrix_complex_ball_dense.Matrix_complex_ball_dense'>
sage: type(matrix(GF(2), 2, range(4)))
<type 'sage.matrix.matrix_mod2_dense.Matrix_mod2_dense'>
sage: type(matrix(GF(64,'z'), 2, range(4)))
<type 'sage.matrix.matrix_gf2e_dense.Matrix_gf2e_dense'>
sage: type(matrix(GF(125,'z'), 2, range(4)))     # optional: meataxe
<type 'sage.matrix.matrix_gfpn_dense.Matrix_gfpn_dense'>
sage.matrix.matrix_space.is_MatrixSpace(x)

Return whether self is an instance of MatrixSpace.

EXAMPLES:

sage: from sage.matrix.matrix_space import is_MatrixSpace
sage: MS = MatrixSpace(QQ,2)
sage: A = MS.random_element()
sage: is_MatrixSpace(MS)
True
sage: is_MatrixSpace(A)
False
sage: is_MatrixSpace(5)
False
sage.matrix.matrix_space.test_trivial_matrices_inverse(ring, sparse=True, implementation=None, checkrank=True)

Tests inversion, determinant and is_invertible for trivial matrices.

This function is a helper to check that the inversion of trivial matrices (of size 0x0, nx0, 0xn or 1x1) is handled consistently by the various implementation of matrices. The coherency is checked through a bunch of assertions. If an inconsistency is found, an AssertionError is raised which should make clear what is the problem.

INPUT:

  • ring - a ring
  • sparse - a boolean
  • checkrank - a boolean

OUTPUT:

  • nothing if everything is correct, otherwise raise an AssertionError
The methods determinant, is_invertible, rank and inverse are checked for
  • the 0x0 empty identity matrix
  • the 0x3 and 3x0 matrices
  • the 1x1 null matrix [0]
  • the 1x1 identity matrix [1]

If checkrank is False then the rank is not checked. This is used the check matrix over ring where echelon form is not implemented.

Todo

This must be adapted to category check framework when ready (see trac ticket #5274).