The cvxopt.base module includes a few arithmetic functions that extend functions from cvxopt.blas to sparse matrices. These functions are faster than the corresponding operations implemented using the overloaded arithmetic described in section 6.3. They also work in-place, i.e., they modify their arguments without creating new objects.
gemv(A, x, y[, trans=’N’[, alpha=1.0[, beta=0.0]]])
Matrix-vector product with a general dense or sparse matrix:
If A is a dense matrix, this is identical to blas.gemv(). If A is sparse, the result is the same as when blas.gemv() is called with matrix(A) as argument, however, without explicitly converting A to dense.
symv(A, x, y[, uplo=’L’[, alpha=1.0[, beta=0.0]]])
Matrix-vector product with a dense or sparse real symmetric matrix:
If A is a dense matrix, this is identical to blas.symv(). If A is sparse, the result is the same as when blas.symv() is called with matrix(A) as argument, however, without explicitly converting A to dense.
gemm(A, B, C[, transA=’N’[, transB=’N’[, alpha=1.0[, beta=0.0[, partial=False]]]]])
Matrix-matrix product of two general sparse or dense matrices:
where
If A, B and C are dense matrices, this is identical to blas.gemm(), described in section 3.4, and the argument partial is ignored.
If A and/or B are sparse and C is dense, the result is the same as when blas.gemm() is called with matrix(A) and matrix(B) as arguments, without explicitly converting A and B to dense. The argument partial is ignored.
If C is a sparse matrix, the matrix-matrix product in the definition of blas.gemm() is computed, but as a sparse matrix. If partial is False, the result is stored in C, and the sparsity pattern of C is modified if necessary. If partial is True, the operation only updates the nonzero elements in C, even if the sparsity pattern of C differs from that of the matrix product.
syrk(A, C[, uplo=’L’[, trans=’N’[, alpha=1.0[, beta=0.0[, partial=False]]]]])
Rank-k update of a sparse or dense real or complex symmetric matrix:
If A and C are dense, this is identical to blas.syrk(), described in section 3.4, and the argument partial is ignored.
If A is sparse and C is dense, the result is the same as when blas.syrk() is called with matrix(A) as argument, without explicitly converting A to dense. The argument partial is ignored.
If C is sparse, the product in the definition of blas.syrk() is computed, but as a sparse matrix. If partial is False, the result is stored in C, and the sparsity pattern of C is modified if necessary. If partial is True, the operation only updates the nonzero elements in C, even if the sparsity pattern of C differs from that of the matrix product.
In the following example, we first compute
>>> from cvxopt.base import spmatrix, gemm
>>> A = spmatrix(1, [1,3,0,2,1], [0,0,1,1,2]) >>> B = spmatrix([2,2,-1,3,2], [1,3,0,2,1], [0,0,1,1,2]) >>> C = spmatrix([], [], [], size=(3,3)) >>> gemm(A, B, C, transA=’T’) >>> print C [ 4.00e+00 0 2.00e+00] [ 0 2.00e+00 0 ] [ 2.00e+00 0 2.00e+00] |
Now suppose we want to replace C with
The new matrix has the same sparsity pattern as C, so we can use gemm() with the partial=True option. This saves time in large sparse matrix multiplications when the sparsity pattern of the result is known beforehand.
>>> D = spmatrix([3,4,1,1,-2], [1,3,0,2,1], [0,0,1,1,2])
>>> gemm(A, D, C, transA=’T’, partial=True) >>> print C [ 7.00e+00 0 -2.00e+00] [ 0 2.00e+00 0 ] [ 3.00e+00 0 -2.00e+00] |