From 2ee5664bc615ffd9380e7d0564aad89570e253a3 Mon Sep 17 00:00:00 2001 From: Sacha Verweij Date: Tue, 19 Jul 2016 19:38:18 -0700 Subject: [PATCH] Flesh out `similar` methods operating on `SparseMatrixCSC`s and make them more consistent both among themselves and with other `similar` methods in Base. --- base/sparse/sparsematrix.jl | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index 666e3fd0277bb..0a73e0201cee6 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -249,9 +249,30 @@ function copy!(A::SparseMatrixCSC, B::SparseMatrixCSC) return A end -similar(S::SparseMatrixCSC, Tv::Type=eltype(S)) = SparseMatrixCSC(S.m, S.n, copy(S.colptr), copy(S.rowval), Array{Tv}(length(S.nzval))) -similar{Tv,Ti,TvNew,TiNew}(S::SparseMatrixCSC{Tv,Ti}, ::Type{TvNew}, ::Type{TiNew}) = SparseMatrixCSC(S.m, S.n, convert(Array{TiNew},S.colptr), convert(Array{TiNew}, S.rowval), Array{TvNew}(length(S.nzval))) -@inline similar{Tv}(S::SparseMatrixCSC, ::Type{Tv}, d::Dims) = spzeros(Tv, d...) +# similar with dims specifications only +similar{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, dims::Dims) = similar(S, Tv, Ti, dims...) +similar{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, m::Integer) = similar(S, Tv, Ti, m) +similar{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, m::Integer, n::Integer) = similar(S, Tv, Ti, m, n) +# similar with entry type and dims specifications +similar{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, TvNew::Type, dims::Dims) = similar(S, TvNew, Ti, dims...) +similar{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, TvNew::Type, m::Integer) = similar(S, TvNew, Ti, m) +similar{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, TvNew::Type, m::Integer, n::Integer) = similar(S, TvNew, Ti, m, n) +# similar with entry type, index type, and dims specifications +similar(S::SparseMatrixCSC, TvNew::Type, TiNew::Type, dims::Dims) = similar(S, TvNew, TiNew, dims...) +similar(S::SparseMatrixCSC, TvNew::Type, TiNew::Type, m::Integer) = SparseVector(m, similar(S.rowval, TiNew, 0), similar(S.nzval, TvNew, 0)) +similar(S::SparseMatrixCSC, TvNew::Type, TiNew::Type, m::Integer, n::Integer) = _preservestorage_similar(S, TvNew, TiNew, m, n) +# parent method for similar that only preserves storage (for when new and old dims differ) +function _preservestorage_similar(S::SparseMatrixCSC, TvNew::Type, TiNew::Type, m::Integer, n::Integer) + return SparseMatrixCSC(m, n, ones(TiNew, n+1), similar(S.rowval, TiNew), similar(S.nzval, TvNew)) +end +# similar without specifications or with type specifications only +similar{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, TvNew::Type = Tv, TiNew::Type = Ti) = _preservenzstruc_similar(S, TvNew, TiNew) +# parent method for similar that preserves nonzero structure (for when new and old dims match) +function _preservenzstruc_similar(S::SparseMatrixCSC, TvNew::Type, TiNew::Type) + newcolptr = copy!(similar(S.colptr, TiNew), S.colptr) + newrowval = copy!(similar(S.rowval, TiNew), S.rowval) + return SparseMatrixCSC(S.m, S.n, newcolptr, newrowval, similar(S.nzval, TvNew)) +end function convert{Tv,Ti,TvS,TiS}(::Type{SparseMatrixCSC{Tv,Ti}}, S::SparseMatrixCSC{TvS,TiS}) if Tv == TvS && Ti == TiS