Base class for sparse matrices
Bases: sage.matrix.matrix.Matrix
The initialization routine of the Matrix base class ensures that it sets the attributes self._parent, self._base_ring, self._nrows, self._ncols. It sets the latter ones by accessing the relevant information on parent, which is often slower than what a more specific subclass can do.
Subclasses of Matrix can safely skip calling Matrix.__init__ provided they take care of initializing these attributes themselves.
The private attributes self._is_immutable and self._cache are implicitly initialized to valid values upon memory allocation.
EXAMPLES:
sage: import sage.matrix.matrix0
sage: A = sage.matrix.matrix0.Matrix(MatrixSpace(QQ,2))
sage: type(A)
<type 'sage.matrix.matrix0.Matrix'>
Apply the given map phi (an arbitrary Python function or callable object) to this matrix. If R is not given, automatically determine the base ring of the resulting matrix.
OUTPUT: a matrix over R
EXAMPLES:
sage: m = matrix(ZZ, 10000, {(1,2): 17}, sparse=True)
sage: k.<a> = GF(9)
sage: f = lambda x: k(x)
sage: n = m.apply_map(f)
sage: n.parent()
Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field in a of size 3^2
sage: n[1,2]
2
An example where the codomain is explicitly specified.
sage: n = m.apply_map(lambda x:x%3, GF(3))
sage: n.parent()
Full MatrixSpace of 10000 by 10000 sparse matrices over Finite Field of size 3
sage: n[1,2]
2
If we didn’t specify the codomain, the resulting matrix in the above case ends up over ZZ again:
sage: n = m.apply_map(lambda x:x%3)
sage: n.parent()
Full MatrixSpace of 10000 by 10000 sparse matrices over Integer Ring
sage: n[1,2]
2
If self is subdivided, the result will be as well:
sage: m = matrix(2, 2, [0, 0, 3, 0])
sage: m.subdivide(None, 1); m
[0|0]
[3|0]
sage: m.apply_map(lambda x: x*x)
[0|0]
[9|0]
If the map sends zero to a non-zero value, then it may be useful to get the result as a dense matrix.
sage: m = matrix(ZZ, 3, 3, [0] * 7 + [1,2], sparse=True); m
[0 0 0]
[0 0 0]
[0 1 2]
sage: parent(m)
Full MatrixSpace of 3 by 3 sparse matrices over Integer Ring
sage: n = m.apply_map(lambda x: x+polygen(QQ), sparse=False); n
[ x x x]
[ x x x]
[ x x + 1 x + 2]
sage: parent(n)
Full MatrixSpace of 3 by 3 dense matrices over Univariate Polynomial Ring in x over Rational Field
TESTS:
sage: m = matrix([], sparse=True)
sage: m.apply_map(lambda x: x*x) == m
True
sage: m.apply_map(lambda x: x*x, sparse=False).parent()
Full MatrixSpace of 0 by 0 dense matrices over Integer Ring
Check that we don’t unnecessarily apply phi to 0 in the sparse case:
sage: m = matrix(QQ, 2, 2, range(1, 5), sparse=True)
sage: m.apply_map(lambda x: 1/x)
[ 1 1/2]
[1/3 1/4]
Test subdivisions when phi maps 0 to non-zero:
sage: m = matrix(2, 2, [0, 0, 3, 0])
sage: m.subdivide(None, 1); m
[0|0]
[3|0]
sage: m.apply_map(lambda x: x+1)
[1|1]
[4|1]
Apply the morphism phi to the coefficients of this sparse matrix.
The resulting matrix is over the codomain of phi.
INPUT:
OUTPUT: a matrix over the codomain of phi
EXAMPLES:
sage: m = matrix(ZZ, 3, range(9), sparse=True)
sage: phi = ZZ.hom(GF(5))
sage: m.apply_morphism(phi)
[0 1 2]
[3 4 0]
[1 2 3]
sage: m.apply_morphism(phi).parent()
Full MatrixSpace of 3 by 3 sparse matrices over Finite Field of size 5
Return the augmented matrix of the form:
[self | right].
EXAMPLES:
sage: M = MatrixSpace(QQ, 2, 2, sparse=True)
sage: A = M([1,2, 3,4])
sage: A
[1 2]
[3 4]
sage: N = MatrixSpace(QQ, 2, 1, sparse=True)
sage: B = N([9,8])
sage: B
[9]
[8]
sage: A.augment(B)
[1 2 9]
[3 4 8]
sage: B.augment(A)
[9 1 2]
[8 3 4]
A vector may be augmented to a matrix.
sage: A = matrix(QQ, 3, 4, range(12), sparse=True)
sage: v = vector(QQ, 3, range(3), sparse=True)
sage: A.augment(v)
[ 0 1 2 3 0]
[ 4 5 6 7 1]
[ 8 9 10 11 2]
The subdivide option will add a natural subdivision between self and right. For more details about how subdivisions are managed when augmenting, see sage.matrix.matrix1.Matrix.augment().
sage: A = matrix(QQ, 3, 5, range(15), sparse=True)
sage: B = matrix(QQ, 3, 3, range(9), sparse=True)
sage: A.augment(B, subdivide=True)
[ 0 1 2 3 4| 0 1 2]
[ 5 6 7 8 9| 3 4 5]
[10 11 12 13 14| 6 7 8]
TESTS:
Verify that Trac #12689 is fixed:
sage: A = identity_matrix(QQ, 2, sparse=True)
sage: B = identity_matrix(ZZ, 2, sparse=True)
sage: A.augment(B)
[1 0 1 0]
[0 1 0 1]
Return the matrix obtained by coercing the entries of this matrix into the given ring.
Always returns a copy (unless self is immutable, in which case returns self).
EXAMPLES:
sage: A = matrix(QQ[‘x,y’], 2, [0,-1,2*x,-2], sparse=True); A [ 0 -1] [2*x -2] sage: A.change_ring(QQ[‘x,y,z’]) [ 0 -1] [2*x -2]
Subdivisions are preserved when changing rings:
sage: A.subdivide([2],[]); A
[ 0 -1]
[2*x -2]
[-------]
sage: A.change_ring(RR['x,y'])
[ 0 -1.00000000000000]
[2.00000000000000*x -2.00000000000000]
[-------------------------------------]
Return the characteristic polynomial of this matrix.
Note - the generic sparse charpoly implementation in Sage is to just compute the charpoly of the corresponding dense matrix, so this could use a lot of memory. In particular, for this matrix, the charpoly will be computed using a dense algorithm.
EXAMPLES:
sage: A = matrix(ZZ, 4, range(16), sparse=True)
sage: A.charpoly()
x^4 - 30*x^3 - 80*x^2
sage: A.charpoly('y')
y^4 - 30*y^3 - 80*y^2
sage: A.charpoly()
x^4 - 30*x^3 - 80*x^2
Return the density of the matrix.
By density we understand the ratio of the number of nonzero positions and the self.nrows() * self.ncols(), i.e. the number of possible nonzero positions.
EXAMPLES:
sage: a = matrix([[],[],[],[]], sparse=True); a.density()
0
sage: a = matrix(5000,5000,{(1,2): 1}); a.density()
1/25000000
Return the determinant of this matrix.
Note
the generic sparse determinant implementation in Sage is to just compute the determinant of the corresponding dense matrix, so this could use a lot of memory. In particular, for this matrix, the determinant will be computed using a dense algorithm.
EXAMPLES:
sage: A = matrix(ZZ, 4, range(16), sparse=True)
sage: B = A + identity_matrix(ZZ, 4, sparse=True)
sage: B.det()
-49
Return the matrix constructed from self from the given rows and columns.
EXAMPLES:
sage: M = MatrixSpace(Integers(8),3,3, sparse=True)
sage: A = M(range(9)); A
[0 1 2]
[3 4 5]
[6 7 0]
sage: A.matrix_from_rows_and_columns([1], [0,2])
[3 5]
sage: A.matrix_from_rows_and_columns([1,2], [1,2])
[4 5]
[7 0]
Note that row and column indices can be reordered or repeated:
sage: A.matrix_from_rows_and_columns([2,1], [2,1])
[0 7]
[5 4]
For example here we take from row 1 columns 2 then 0 twice, and do this 3 times.
sage: A.matrix_from_rows_and_columns([1,1,1],[2,0,0])
[5 3 3]
[5 3 3]
[5 3 3]
We can efficiently extract large submatrices:
sage: A = random_matrix(ZZ, 100000, density=.00005, sparse=True) # long time (4s on sage.math, 2012)
sage: B = A[50000:,:50000] # long time
sage: len(B.nonzero_positions()) # long time
17550 # 32-bit
125449 # 64-bit
We must pass in a list of indices:
sage: A=random_matrix(ZZ,100,density=.02,sparse=True)
sage: A.matrix_from_rows_and_columns(1,[2,3])
Traceback (most recent call last):
...
TypeError: rows must be a list of integers
sage: A.matrix_from_rows_and_columns([1,2],3)
Traceback (most recent call last):
...
TypeError: columns must be a list of integers
AUTHORS:
Stack self on top of bottom.
[ self ] [ bottom ]
EXAMPLES:
sage: M = Matrix(QQ, 2, 3, range(6), sparse=True)
sage: N = Matrix(QQ, 1, 3, [10,11,12], sparse=True)
sage: M.stack(N)
[ 0 1 2]
[ 3 4 5]
[10 11 12]
A vector may be stacked below a matrix.
sage: A = matrix(QQ, 2, 5, range(10), sparse=True)
sage: v = vector(QQ, 5, range(5), sparse=True)
sage: A.stack(v)
[0 1 2 3 4]
[5 6 7 8 9]
[0 1 2 3 4]
The subdivide option will add a natural subdivision between self and other. For more details about how subdivisions are managed when stacking, see sage.matrix.matrix1.Matrix.stack().
sage: A = matrix(ZZ, 3, 4, range(12), sparse=True)
sage: B = matrix(ZZ, 2, 4, range(8), sparse=True)
sage: A.stack(B, subdivide=True)
[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[-----------]
[ 0 1 2 3]
[ 4 5 6 7]
Returns the transpose of self, without changing self.
EXAMPLES: We create a matrix, compute its transpose, and note that the original matrix is not changed.
sage: M = MatrixSpace(QQ, 2, sparse=True)
sage: A = M([1,2,3,4])
sage: B = A.transpose()
sage: print B
[1 3]
[2 4]
sage: print A
[1 2]
[3 4]
.T is a convenient shortcut for the transpose:
sage: A.T
[1 3]
[2 4]