Sparse Matrix Functions
Internal Sparse Matrix Representation
ConleyDynamics.SparseMatrix — Type
SparseMatrix{T}Composite data type for a sparse matrix with entries of type T.
The struct has the following fields:
const nrow::Int: Number of rowsconst ncol::Int: Number of columnsconst char::Int: Characteristic of typeTconst zero::T: Number 0 of typeTconst one::T: Number 1 of typeTentries::Vector{Vector{T}}: Matrix entries corresponding tocolumnscolumns::Vector{Vector{Int}}:columns[k]points to nonzero entries in column krows::Vector{Vector{Int}}:rows[k]points to nonzero entries in the k-th row
Access Functions
ConleyDynamics.sparse_get_entry — Function
sparse_get_entry(matrix::SparseMatrix, ri::Int, ci::Int)Get the sparse matrix entry at location (ri,ci).
Base.getindex — Method
Base.getindex(matrix::SparseMatrix, ri::Int, ci::Int)Get the sparse matrix entry at location (ri,ci).
ConleyDynamics.sparse_set_entry! — Function
sparse_set_entry!(matrix::SparseMatrix, ri::Int, ci::Int, val)Set the sparse matrix entry at location (ri,ci) to val.
sparse_set_entry!(matrix::SparseMatrix{Int}, ri::Int, ci::Int, val)Set the sparse matrix entry at location (ri,ci) to val.
This method assumes that the sparse matrix is over the integers, which means that it is interpreted over a finite field. Thus, the new entry is automatically reduced via modular arithmetic.
Base.setindex! — Method
Base.setindex!(matrix::SparseMatrix, val, ri::Int, ci::Int)Set the sparse matrix entry at location (ri,ci) to val.
ConleyDynamics.sparse_get_column — Function
sparse_get_column(matrix::SparseMatrix, ci::Int)Get the ci-th column of the sparse matrix.
ConleyDynamics.sparse_get_nz_column — Function
sparse_get_nz_column(matrix::SparseMatrix, ci::Int)Get the row indices for the nonzero entries in the ci-th column of the sparse matrix.
ConleyDynamics.sparse_get_nz_row — Function
sparse_get_nz_row(matrix::SparseMatrix, ri::Int)Get the column indices for the nonzero entries in the ri-th row of the sparse matrix.
ConleyDynamics.sparse_minor — Function
smp = sparse_minor(sm::SparseMatrix, rvec::Vector{Int}, cvec::Vector{Int})Create sparse submatrix by specifying the desired row and column indices.
Basic Functions
ConleyDynamics.sparse_size — Function
sparse_size(matrix::SparseMatrix, dim::Int)Number of rows (dim=1) or columns (dim=2) of a sparse matrix.
sparse_size(matrix::SparseMatrix)Return the size of a sparse matrix.
The function returns a tuple which contains the number of rows and the number of columns of the given matrix.
ConleyDynamics.sparse_low — Function
sparse_low(matrix::SparseMatrix, col::Int)Row index of the lowest nonzero matrix entry in column col.
ConleyDynamics.sparse_is_zero — Function
sparse_is_zero(sm::SparseMatrix)Test whether the sparse matrix sm is the zero matrix.
ConleyDynamics.sparse_is_identity — Function
sparse_is_identity(A::SparseMatrix)Test whether the sparse matrix A is the identity matrix.
ConleyDynamics.sparse_is_equal — Function
sparse_is_equal(A::SparseMatrix, B::SparseMatrix)Test whether the sparse matrices A and B are equal.
For equality, the two sparse matrices not only have to have the same size and the same entries, they also have to be of the same type and be defined over the same field.
Base.:(==) — Method
Base.:(==)(A::SparseMatrix,B::SparseMatrix)Test whether the sparse matrices A and B are equal.
For equality, the two sparse matrices not only have to have the same size and the same entries, they also have to be of the same type and be defined over the same field.
ConleyDynamics.sparse_is_rref — Function
sparse_is_rref(A::SparseMatrix)Check whether a matrix is in reduced row Echelon format.
This function determines whether a given matrix is in reduced row Echelon format. It returns the appropriate boolean value.
ConleyDynamics.sparse_is_sut — Function
bool = sparse_is_sut(sm::SparseMatrix)Check whether the sparse matrix is strictly upper triangular.
ConleyDynamics.sparse_fullness — Function
sparse_fullness(sm::SparseMatrix)Return the fullness of the sparse matrix sm, which equals the percentage of nonzero elements.
ConleyDynamics.sparse_sparsity — Function
sparse_sparsity(sm::SparseMatrix)Return the sparsity of the sparse matrix sm, which equals the percentage of zero entries.
ConleyDynamics.sparse_nz_count — Function
sparse_nz_count(sm::SparseMatrix)Return the number of nonzero entries of the sparse matrix sm.
ConleyDynamics.sparse_show — Function
sparse_show(sm::SparseMatrix)Display a sparse matrix in readable format.
This function will print the complete matrix, so be careful with sparse matrices of large size!
sparse_show(sm::SparseMatrix, rlabels::Vector{String}, clabels::Vector{String})Display a sparse matrix in readable format, with labels.
The input parameter clabels contains the labels for the columns, while rlabels give the row labels.
Examples
julia> lc, mvf = example_forman1d();
julia> cm = connection_matrix(lc, mvf, algorithm="DHL");
julia> sparse_show(cm.matrix, cm.labels, cm.labels)
┆ A CD F BF DE
--┆---------------
A┆ . . . . 1
CD┆ . . . . .
F┆ . . . . 1
BF┆ . . . . .
DE┆ . . . . .sparse_show(sm::SparseMatrix, labels::Vector{String})Display a sparse matrix in readable format, with labels.
This function assumes that the matrix is square, and that the labels are the same for rows and columns. They are provided in labels.
sparse_show(cm::ConleyMorseCM)Display the connection matrix with labels.
This function displays the (sparse) connection matrix including its labels. It uses sparse_show(cm.matrix, cm.labels, cm.labels).
Examples
julia> lc, mvf = example_forman1d();
julia> cm = connection_matrix(lc, mvf, algorithm="DHL");
julia> sparse_show(cm)
┆ A CD F BF DE
--┆---------------
A┆ . . . . 1
CD┆ . . . . .
F┆ . . . . 1
BF┆ . . . . .
DE┆ . . . . .Conversion Functions
ConleyDynamics.sparse_from_full — Function
sparse_from_full(matrix::Matrix{Int}; [p::Int=2])Create sparse matrix from full integer matrix. If the optional argument p is specified and positive, then the returned matrix is an integer matrix which is interpreted over GF(p). On the other hand, if p is equal to zero, then the return matrix has rational type.
sparse_from_full(vec::Vector{Int}; [p::Int=2])Create sparse column matrix from a full integer vector. If the optional argument p is specified and positive, then the returned matrix is an integer matrix which is interpreted over GF(p). On the other hand, if p is equal to zero, then the return matrix has rational type.
ConleyDynamics.full_from_sparse — Function
full_from_sparse(sm::SparseMatrix)Create full matrix from sparse matrix.
ConleyDynamics.sparse_from_lists — Function
sparse_from_lists(nr, nc, tchar, tzero, tone, r, c, v)Create sparse matrix from lists describing the entries.
The vectors r, c, and v have to have the same length and the matrix has entry v[k] at (r[k],c[k]). Zero entries will be ignored, and multiple entries for the same matrix position raise an error.
The input arguments have the following meaning:
nr::Int: Number of rowsnc::Int: Number of columnstchar: Field characteristic ifT==Inttzero::T: Number 0 of typeTtone::T: Number 1 of typeTr::Vector{Int}: Vector of row indicesc::Vector{Int}: Vector of column indicesv::Vector{T}: Vector of matrix entries
If tchar>0, then the entries in v are all replaced by their values mod tchar.
ConleyDynamics.lists_from_sparse — Function
nr, nc, tchar, tzero, tone, r, c, v = lists_from_sparse(sm::SparseMatrix)Create list representation from sparse matrix.
The output variables are exactly what is needed to create a sparse matrix object using sparse_from_lists.
Matrix Creation
ConleyDynamics.sparse_identity — Function
sparse_identity(n::Int; p::Int=2)Create a sparse identity matrix with n rows and columns.
The optional argument p specifies the field characteristic. If p=0 then the sparse matrix is over the rationals, while if p>0 is a prime, then the matrix is an integer matrix whose entries are interpreted in GF(p).
ConleyDynamics.sparse_zero — Function
sparse_zero(nr::Int, nc::Int; p::Int=2)Create a sparse zero matrix with nr rows and nc columns.
The optional argument p specifies the field characteristic. If p=0 then the sparse matrix is over the rationals, while if p>0 is a prime, then the matrix is an integer matrix whose entries are interpreted in GF(p).
ConleyDynamics.sparse_diagonal — Function
sparse_diagonal(nr::Int, nc::Int, d::Vector{<:Real};
p::Int=2, offset::Int=0)Create sparse diagonal matrix.
The function creates a sparse matrix with nr rows and nc columns, over a field with characteristic p. Without additional arguments, the matrix has the entries in the vector d along the main diagonal. If the optional argument offset is given and positive, then the diagonal is placed offset positions above the main diagonal, if it is negative, then it indicates how many positions below the diagonal it is placed. The function places as many entries from d as possible, i.e., if the length of d is too short, the remaining diagonal entries are zero, if it is too long, then the later entries are ignored. The function tries to convert the entries in d to the correct format based on p. Errors are raised if this is not possible.
ConleyDynamics.sparse_hcat — Function
sparse_hcat(A::SparseMatrix, B::SparseMatrix)Concatenate two sparse matrices horizontally.
Exceptions are raised if the matrices are not defined over the same field, or if they have different numbers of rows.
sparse_hcat(S1, S2, S3, ...)Concatenate several sparse matrices horizontally.
This method of sparse_hcat allows for any number of arguments. If you want to concatenate a vector vec of sparse matrices, use the call sparse_hcat(vec...).
Exceptions are raised if the matrices are not defined over the same field, or if they have different numbers of rows.
ConleyDynamics.sparse_vcat — Function
sparse_vcat(A::SparseMatrix, B::SparseMatrix)Concatenate two sparse matrices vertically.
Exceptions are raised if the matrices are not defined over the same field, or if they have different numbers of columns.
sparse_vcat(S1, S2, S3, ...)Concatenate several sparse matrices vertically.
This method of sparse_vcat allows for any number of arguments. If you want to concatenate a vector vec of sparse matrices, use the call sparse_vcat(vec...).
Exceptions are raised if the matrices are not defined over the same field, or if they have different numbers of columns.
ConleyDynamics.sparse_hvcat — Function
sparse_hvcat(rblocks::Tuple{Vararg{Int}}, A::SparseMatrix...)Arrange sparse matrices in rectangular form.
The fist argument has to be a tuple which specifies how many blocks have to be combined in each row. This means that the total number of sparse matrices has to be equal to the sum of the entries in rblocks. Exceptions are raised if the dimensions of the matrices are not compatible, or if the matrices are not defined over the same field.
sparse_hvcat(rblocks::Int, A::SparseMatrix...)Arrange sparse matrices in rectangular form.
The fist argument specifies how many blocks are contained in each row. Thus, the number of sparse matrices in Avec has to be divisible by rblocks. Exceptions are raised if the dimensions of the matrices are not compatible, or if the matrices are not defined over the same field.
ConleyDynamics.sparse_hvncat — Function
sparse_hvncat(dims::Tuple{Int,Int}, rowfirst::Bool, A::SparseMatrix...)Arrange sparse matrices in rectangular form.
The function expects dimensions (d1,d2), as well as d1*d2 sparse matrices. The boolean argument rowfirst indicates whether the sparse matrices are arranged row-first or column-first. The matrices are then arranged in an d1 x d2-times rectangular array to create a new sparse matrix. Exceptions are raised if the dimensions of the matrices are not compatible, or if the matrices are not defined over the same field.
ConleyDynamics.sparse_cat — Function
sparse_cat(A::SparseMatrix...; dims=1)Concatenate sparse matrices along a dimension.
The integer dims specifies along which dimension the sparse matrices are combined. In other words, dims=1 reduces to vcat, while dims=2 reduces to hcat. In addition, this function accepts the argument dims=(1,2). In this case, the sparse matrices are placed as blocks along the diagonal of a large sparse block matrix, with all remaining blocks being zero.
Base.hvcat — Method
Base.hvcat(::Tuple{Vararg{Int}}, ::SparseMatrix...)Arrange sparse matrices in rectangular form.
This method allows one to use the shortform [S1 S2; S3 S4 S5] etc for the concatenation, just like in the matrix case. It is based on the function sparse_hvcat. For more information, refer to its documentation. The number of blocks in each row can vary, as long as the dimensions are overall compatible.
Base.hvcat — Method
Base.hvcat(::Int, ::SparseMatrix...)Arrange sparse matrices in rectangular form.
This method allows one to use the shortform [S1 S2; S3 S4] etc for the concatenation, just like in the matrix case. It is based on the function sparse_hvcat. For more information, refer to its documentation.
Base.hvncat — Method
Base.hvncat(::Tuple{Int,Int}, ::Bool, ::SparseMatrix...)Arrange sparse matrices in rectangular form.
This method allows one to use the shortform [S1; S2;; S3; S4] etc for the concatenation, just like in the matrix case. It is based on the function sparse_hvncat. For more information, refer to its documentation. This form does require that the same number of blocks are used in each row and each column. For varying numbers please use the functions hvcat or sparse_hvcat.
Elementary Matrix Operations
ConleyDynamics.sparse_add_column! — Function
sparse_add_column!(matrix::SparseMatrix, ci1::Int, ci2::Int, cn, cd)Replace column[ci1] by column[ci1] + (cn/cd) * column[ci2].
sparse_add_column!(matrix::SparseMatrix{Int}, ci1::Int, ci2::Int,
cn::Int, cd::Int)Replace column[ci1] by column[ci1] + (cn/cd) * column[ci2].
The computation is performed mod p, where the characteristic is taken from matrix.char. An error is thrown if matrix.char==0.
ConleyDynamics.sparse_add_row! — Function
sparse_add_row!(matrix::SparseMatrix, ri1::Int, ri2::Int, cn, cd)Replace row[ri1] by row[ri1] + (cn/cd) * row[ri2].
sparse_add_row!(matrix::SparseMatrix{Int}, ri1::Int, ri2::Int,
cn::Int, cd::Int)Replace row[ri1] by row[ri1] + (cn/cd) * row[ri2].
The computation is performed mod p, where the characteristic is taken from matrix.char. An error is thrown if matrix.char==0.
ConleyDynamics.sparse_rref! — Function
sparse_rref!(A::SparseMatrix)Compute the reduced row Echelon form of the given matrix.
This function computes the reduced row Echelon form of a sparse matrix in place. The input matrix will be altered!
Example
julia> Afull = [1 0 1 2 4 3 2; 3 4 6 2 3 4 2; 2 0 2 4 1 1 1];
julia> A = sparse_from_full(Afull, p=7);
julia> sparse_rref!(A)
julia> sparse_show(A)
1 . 1 2 4 . 3
. 1 6 6 3 . 5
. . . . . 1 2ConleyDynamics.sparse_rref — Function
sparse_rref(A::SparseMatrix)Compute the reduced row Echelon form of the given matrix.
This function computes and returns the reduced row Echelon form of a sparse matrix. The argument A is not altered.
Example
julia> Afull = [1 0 1 2 4 3 2; 3 4 6 2 3 4 2; 2 0 2 4 1 1 1];
julia> A = sparse_from_full(Afull, p=2);
julia> sparse_show(A)
1 . 1 . . 1 .
1 . . . 1 . .
. . . . 1 1 1
julia> sparse_show(sparse_rref(A))
1 . . . . 1 1
. . 1 . . . 1
. . . . 1 1 1ConleyDynamics.sparse_solve — Function
sparse_solve(A::SparseMatrix, b::SparseMatrix)Find a solution of a sparse linear system.
This function computes a solution of the sparse linear system Ax = b. It is expected that A and b are sparse matrices over the same field, and that both have the same number of rows. Usually, this function is used with a column vector b. However, if b is a matrix, then the respective matrix equation is solved. The function returns a particular solution of the system, if one exists. Otherwise it returns nothing.
In order to obtain all solutions of the system, one has to add an arbitrary linear combination of the basis vectors determined via sparse_basis_kernel(A).
Example
julia> Afull = [1 0 1 2 4 3 2; 3 4 6 2 3 4 2; 2 0 2 4 1 1 1];
julia> A = sparse_from_full(Afull, p=7);
julia> bfull = [1 2 5 3; 3 6 6 4; 2 4 2 1];
julia> b = sparse_from_full(bfull, p=7);
julia> sparse_show(A)
1 . 1 2 4 3 2
3 4 6 2 3 4 2
2 . 2 4 1 1 1
julia> sparse_show(b)
1 2 5 3
3 6 6 4
2 4 2 1
julia> x = sparse_solve(A, b);
julia> sparse_show(x)
1 2 3 .
. . 5 .
. . . .
. . . .
. . . .
. . 3 1
. . . .
julia> A*x == b
trueConleyDynamics.sparse_basis_kernel — Function
sparse_basis_kernel(A::SparseMatrix)Compute a kernel basis for a sparse matrix.
This function determines a basis for the kernel of the given matrix A. The result is returned as a vector of sparse matrices. The latter are column vectors which span the kernel.
Example
julia> Afull = [1 0 1 2 4 3 2; 3 4 6 2 3 4 2; 2 0 2 4 1 1 1];
julia> A = sparse_from_full(Afull, p=7);
julia> sparse_rref!(A)
julia> sparse_show(A)
1 . 1 2 4 . 3
. 1 6 6 3 . 5
. . . . . 1 2
julia> kbasis = sparse_basis_kernel(A);
julia> length(kbasis)
4
julia> sparse_show(sparse_transpose(kbasis[1]))
6 1 1 . . . .
julia> sparse_show(sparse_transpose(kbasis[2]))
5 1 . 1 . . .
julia> sparse_show(sparse_transpose(kbasis[3]))
3 4 . . 1 . .
julia> sparse_show(sparse_transpose(kbasis[4]))
4 2 . . . 5 1ConleyDynamics.sparse_basis_range — Function
sparse_basis_range(A::SparseMatrix)Compute a basis for the range of a sparse matrix.
This function determines a basis for the range of the given matrix A. The result is returned as a vector of sparse matrices. The latter are column vectors which span the range, also known as column space.
Example
julia> Afull = [1 0 1 2 4 3 2; 3 4 6 2 3 4 2; 2 0 2 4 1 1 1];
julia> A = sparse_from_full(Afull, p=7);
julia> sparse_show(A)
1 . 1 2 4 3 2
3 4 6 2 3 4 2
2 . 2 4 1 1 1
julia> rbasis = sparse_basis_range(A);
julia> length(rbasis)
3
julia> sparse_show(sparse_transpose(rbasis[1]))
1 3 2
julia> sparse_show(sparse_transpose(rbasis[2]))
. 4 .
julia> sparse_show(sparse_transpose(rbasis[3]))
3 4 1
julia> sparse_show(sparse_rref(A))
1 . 1 2 4 . 3
. 1 6 6 3 . 5
. . . . . 1 2ConleyDynamics.sparse_permute — Function
sparse_permute(sm::SparseMatrix, pr::Vector{Int}, pc::Vector{Int})Create sparse matrix by permuting the row and column indices.
The vector pr describes the row permutation, and pc the column permutation.
ConleyDynamics.sparse_transpose — Function
sparse_transpose(A::SparseMatrix)Create the transpose of a sparse matrix.
This does seem pretty self-explanatory, doesn't it?
Base.adjoint — Method
Base.adjoint(A::SparseMatrix)Create the transpose of a sparse matrix.
This method allows one to use A' for the computation of the transpose matrix.
ConleyDynamics.sparse_inverse — Function
sparse_inverse(matrix::SparseMatrix)Compute the inverse of a sparse matrix.
The function automatically performs the computations over the underlying field of the sparse matrix.
ConleyDynamics.sparse_remove! — Function
sparse_remove!(matrix::SparseMatrix, ri::Int, ci::Int)Remove the sparse matrix entry at location (ri,ci).
ConleyDynamics.sparse_add — Function
sparse_add(A::SparseMatrix, B::SparseMatrix)Add two sparse matrices.
Exceptions are raised if the matrix sum is not defined or the entry types do not match.
ConleyDynamics.sparse_subtract — Function
sparse_subtract(A::SparseMatrix, B::SparseMatrix)Subtract two sparse matrices.
The function returns A - B. Exceptions are raised if the matrix difference is not defined or the entry types do not match.
ConleyDynamics.sparse_multiply — Function
sparse_multiply(A::SparseMatrix, B::SparseMatrix)Multiply two sparse matrices.
Exceptions are raised if the matrix product is not defined or the entry types do not match.
sparse_multiply(alpha::Int, A::SparseMatrix)Multiply a scalar with a sparse matrix.
This method is for finite fields. An exception is raised if the sparse matrix is not defined over a finite field.
sparse_multiply(alpha::Rational{Int}, A::SparseMatrix)Multiply a scalar with a sparse matrix.
This method is for the rational numbers. An exception is raised if the sparse matrix is not defined over field of rationals.
ConleyDynamics.sparse_scale — Function
sparse_scale(sfac, A::SparseMatrix)Scale a sparse matrix by a scalar.
An exception is raised if the entry types do not match.
Sparse Helper Functions
ConleyDynamics.scalar_inverse — Function
scalar_inverse(s, p::Int)Compute the inverse of a scalar.
scalar_inverse(s::Int, p::Int)Compute the inverse of a scalar.
This function computes the inverse in modular arithmetic with base p.
ConleyDynamics.scalar_multiply — Function
scalar_multiply(s1, s2, p::Int)Compute the product of two scalars.
scalar_multiply(s1::Int, s2::Int, p::Int)Compute the product of two scalars.
This function computes the product in modular arithmetic with base p.
ConleyDynamics.scalar_add — Function
scalar_add(s1, s2, p::Int)Compute the sum of two scalars.
scalar_add(s1::Int, s2::Int, p::Int)Compute the sum of two scalars.
This function computes the sum in modular arithmetic with base p.