Skip to content

Commit f341c79

Browse files
dkarraschKristofferC
authored andcommitted
Make LinearAlgebra.jl independent of SparseArrays.jl
1 parent 8a506f4 commit f341c79

File tree

3 files changed

+236
-46
lines changed

3 files changed

+236
-46
lines changed

src/SparseArrays.jl

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,9 @@ include("linalg.jl")
3838
include("deprecated.jl")
3939

4040

41-
# temporarily moved here and commented out from from base/linalg/diagonal.jl, base/linalg/tridiag.jl
42-
# and base/linalg/bidiag.jl due to their usage of spzeros
43-
similar(B::Bidiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...)
44-
similar(D::Diagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...)
45-
similar(S::SymTridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...)
46-
similar(M::Tridiagonal, ::Type{T}, dims::Union{Dims{1},Dims{2}}) where {T} = spzeros(T, dims...)
47-
4841
zero(a::AbstractSparseArray) = spzeros(eltype(a), size(a)...)
4942

50-
const BiTriSym = Union{Bidiagonal,SymTridiagonal,Tridiagonal}
51-
function *(A::BiTriSym, B::BiTriSym)
52-
TS = promote_op(matprod, eltype(A), eltype(B))
53-
mul!(similar(A, TS, size(A)...), A, B)
54-
end
55-
56-
LinearAlgebra.diagzero(D::Diagonal{<:AbstractSparseMatrix{T}},i,j) where {T} = spzeros(T, size(D.diag[i], 1), size(D.diag[j], 2))
43+
LinearAlgebra.diagzero(D::Diagonal{<:AbstractSparseMatrix{T}},i,j) where {T} =
44+
spzeros(T, size(D.diag[i], 1), size(D.diag[j], 2))
5745

5846
end

src/sparsevector.jl

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import Base: sort, findall, copy!
66
import LinearAlgebra: promote_to_array_type, promote_to_arrays_
7+
using LinearAlgebra: _SpecialArrays, _DenseConcatGroup
78

89
### The SparseVector
910

@@ -1062,30 +1063,16 @@ vcat(X::Union{Vector,SparseVector}...) = vcat(map(sparse, X)...)
10621063

10631064
### Concatenation of un/annotated sparse/special/dense vectors/matrices
10641065

1065-
# TODO: These methods and definitions should be moved to a more appropriate location,
1066-
# particularly some future equivalent of base/linalg/special.jl dedicated to interactions
1067-
# between a broader set of matrix types.
1068-
1069-
# TODO: A definition similar to the third exists in base/linalg/bidiag.jl. These definitions
1070-
# should be consolidated in a more appropriate location, e.g. base/linalg/special.jl.
10711066
const _SparseArrays = Union{SparseVector, AbstractSparseMatrixCSC, Adjoint{<:Any,<:SparseVector}, Transpose{<:Any,<:SparseVector}}
1072-
const _SpecialArrays = Union{Diagonal, Bidiagonal, Tridiagonal, SymTridiagonal}
10731067
const _SparseConcatArrays = Union{_SpecialArrays, _SparseArrays}
10741068

10751069
const _Symmetric_SparseConcatArrays{T,A<:_SparseConcatArrays} = Symmetric{T,A}
10761070
const _Hermitian_SparseConcatArrays{T,A<:_SparseConcatArrays} = Hermitian{T,A}
10771071
const _Triangular_SparseConcatArrays{T,A<:_SparseConcatArrays} = LinearAlgebra.AbstractTriangular{T,A}
10781072
const _Annotated_SparseConcatArrays = Union{_Triangular_SparseConcatArrays, _Symmetric_SparseConcatArrays, _Hermitian_SparseConcatArrays}
1079-
1080-
const _Symmetric_DenseArrays{T,A<:Matrix} = Symmetric{T,A}
1081-
const _Hermitian_DenseArrays{T,A<:Matrix} = Hermitian{T,A}
1082-
const _Triangular_DenseArrays{T,A<:Matrix} = LinearAlgebra.AbstractTriangular{T,A}
1083-
const _Annotated_DenseArrays = Union{_Triangular_DenseArrays, _Symmetric_DenseArrays, _Hermitian_DenseArrays}
1084-
const _Annotated_Typed_DenseArrays{T} = Union{_Triangular_DenseArrays{T}, _Symmetric_DenseArrays{T}, _Hermitian_DenseArrays{T}}
1085-
1086-
const _SparseConcatGroup = Union{Number, Vector, Adjoint{<:Any,<:Vector}, Transpose{<:Any,<:Vector}, Matrix, _SparseConcatArrays, _Annotated_SparseConcatArrays, _Annotated_DenseArrays}
1087-
const _DenseConcatGroup = Union{Number, Vector, Adjoint{<:Any,<:Vector}, Transpose{<:Any,<:Vector}, Matrix, _Annotated_DenseArrays}
1088-
const _TypedDenseConcatGroup{T} = Union{Vector{T}, Adjoint{T,Vector{T}}, Transpose{T,Vector{T}}, Matrix{T}, _Annotated_Typed_DenseArrays{T}}
1073+
# It's important that _SparseConcatGroup is a larger union than _DenseConcatGroup to make
1074+
# sparse cat-methods less specific and to kick in only if there is some sparse array present
1075+
const _SparseConcatGroup = Union{_DenseConcatGroup, _SparseConcatArrays, _Annotated_SparseConcatArrays}
10891076

10901077
# Concatenations involving un/annotated sparse/special matrices/vectors should yield sparse arrays
10911078
_makesparse(x::Number) = x
@@ -1123,23 +1110,8 @@ _hvcat_rows(::Tuple{}, X::_SparseConcatGroup...) = ()
11231110

11241111
# make sure UniformScaling objects are converted to sparse matrices for concatenation
11251112
promote_to_array_type(A::Tuple{Vararg{Union{_SparseConcatGroup,UniformScaling}}}) = SparseMatrixCSC
1126-
promote_to_array_type(A::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = Matrix
11271113
promote_to_arrays_(n::Int, ::Type{SparseMatrixCSC}, J::UniformScaling) = sparse(J, n, n)
11281114

1129-
# Concatenations strictly involving un/annotated dense matrices/vectors should yield dense arrays
1130-
Base._cat(dims, xs::_DenseConcatGroup...) = Base.cat_t(promote_eltype(xs...), xs...; dims=dims)
1131-
vcat(A::Vector...) = Base.typed_vcat(promote_eltype(A...), A...)
1132-
vcat(A::_DenseConcatGroup...) = Base.typed_vcat(promote_eltype(A...), A...)
1133-
hcat(A::Vector...) = Base.typed_hcat(promote_eltype(A...), A...)
1134-
hcat(A::_DenseConcatGroup...) = Base.typed_hcat(promote_eltype(A...), A...)
1135-
hvcat(rows::Tuple{Vararg{Int}}, xs::_DenseConcatGroup...) = Base.typed_hvcat(promote_eltype(xs...), rows, xs...)
1136-
# For performance, specially handle the case where the matrices/vectors have homogeneous eltype
1137-
Base._cat(dims, xs::_TypedDenseConcatGroup{T}...) where {T} = Base.cat_t(T, xs...; dims=dims)
1138-
vcat(A::_TypedDenseConcatGroup{T}...) where {T} = Base.typed_vcat(T, A...)
1139-
hcat(A::_TypedDenseConcatGroup{T}...) where {T} = Base.typed_hcat(T, A...)
1140-
hvcat(rows::Tuple{Vararg{Int}}, xs::_TypedDenseConcatGroup{T}...) where {T} = Base.typed_hvcat(T, rows, xs...)
1141-
1142-
11431115
### math functions
11441116

11451117
### Unary Map

test/sparse.jl

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ end
132132
# constructor methods well-exercised by the immediately preceding testset
133133
@test sparse(2I, 3, 4)::SparseMatrixCSC{Int,Int} == Matrix(2I, 3, 4)
134134
@test sparse(2I, (3, 4))::SparseMatrixCSC{Int,Int} == Matrix(2I, 3, 4)
135+
@test sparse(3I, 4, 5) == sparse(1:4, 1:4, 3, 4, 5)
136+
@test sparse(3I, 5, 4) == sparse(1:4, 1:4, 3, 5, 4)
135137
end
136138

137139
se33 = SparseMatrixCSC{Float64}(I, 3, 3)
@@ -154,6 +156,33 @@ do33 = fill(1.,3)
154156
@test_throws DimensionMismatch map(|, sqrboolmat, colboolmat)
155157
@test_throws DimensionMismatch map(xor, sqrboolmat, colboolmat)
156158
end
159+
160+
# ascertain inference friendliness, ref. https://github.com/JuliaLang/julia/pull/25083#issuecomment-353031641
161+
sparsevec = SparseVector([1.0, 2.0, 3.0])
162+
@test map(-, Adjoint(sparsevec), Adjoint(sparsevec)) isa Adjoint{Float64,SparseVector{Float64,Int}}
163+
@test map(-, Transpose(sparsevec), Transpose(sparsevec)) isa Transpose{Float64,SparseVector{Float64,Int}}
164+
@test broadcast(-, Adjoint(sparsevec), Adjoint(sparsevec)) isa Adjoint{Float64,SparseVector{Float64,Int}}
165+
@test broadcast(-, Transpose(sparsevec), Transpose(sparsevec)) isa Transpose{Float64,SparseVector{Float64,Int}}
166+
@test broadcast(+, Adjoint(sparsevec), 1.0, Adjoint(sparsevec)) isa Adjoint{Float64,SparseVector{Float64,Int}}
167+
@test broadcast(+, Transpose(sparsevec), 1.0, Transpose(sparsevec)) isa Transpose{Float64,SparseVector{Float64,Int}}
168+
169+
@testset "binary ops with matrices" begin
170+
λ = complex(randn(),randn())
171+
J = UniformScaling(λ)
172+
B = bitrand(2, 2)
173+
@test B + I == B + Matrix(I, size(B))
174+
@test I + B == B + Matrix(I, size(B))
175+
AA = randn(2, 2)
176+
for SS in (sprandn(3,3, 0.5), sparse(Int(1)I, 3, 3))
177+
for S in (SS, view(SS, 1:3, 1:3))
178+
@test @inferred(I*S) !== S # Don't alias
179+
@test @inferred(S*I) !== S # Don't alias
180+
181+
@test @inferred(S*J) == S*λ
182+
@test @inferred(J*S) == S*λ
183+
end
184+
end
185+
end
157186
end
158187

159188
@testset "Issue #30006" begin
@@ -194,6 +223,14 @@ end
194223
@test nnz(blockdiag()) == 0
195224
end
196225

226+
@testset "Diagonal of sparse matrices" begin
227+
s = sparse([1 2; 3 4])
228+
D = Diagonal([s, s])
229+
@test D[1, 1] == s
230+
@test D[1, 2] == zero(s)
231+
@test isa(D[2, 1], SparseMatrixCSC)
232+
end
233+
197234
@testset "concatenation promotion" begin
198235
sz41_f32 = spzeros(Float32, 4, 1)
199236
se33_i32 = sparse(Int32(1)I, 3, 3)
@@ -213,6 +250,141 @@ end
213250
@test [a[1:2,1:2] a[1:2,3:4]; a[3:5,1] [a[3:4,2:4]; a[5:5,2:4]]] == a
214251
end
215252
end
253+
254+
# should all yield sparse arrays
255+
@testset "concatenations of combinations of special and other matrix types" begin
256+
N = 4
257+
diagmat = Diagonal(1:N)
258+
bidiagmat = Bidiagonal(1:N, 1:(N-1), :U)
259+
tridiagmat = Tridiagonal(1:(N-1), 1:N, 1:(N-1))
260+
symtridiagmat = SymTridiagonal(1:N, 1:(N-1))
261+
specialmats = (diagmat, bidiagmat, tridiagmat, symtridiagmat)
262+
# Test concatenating pairwise combinations of special matrices with sparse matrices,
263+
# dense matrices, or dense vectors
264+
spmat = spdiagm(0 => fill(1., N))
265+
spvec = sparse(fill(1., N))
266+
for specialmat in specialmats
267+
# --> Tests applicable only to pairs of matrices
268+
@test issparse(vcat(specialmat, spmat))
269+
@test issparse(vcat(spmat, specialmat))
270+
# --> Tests applicable also to pairs including vectors
271+
for specialmat in specialmats, othermatorvec in (spmat, spvec)
272+
@test issparse(hcat(specialmat, othermatorvec))
273+
@test issparse(hcat(othermatorvec, specialmat))
274+
@test issparse(hvcat((2,), specialmat, othermatorvec))
275+
@test issparse(hvcat((2,), othermatorvec, specialmat))
276+
@test issparse(cat(specialmat, othermatorvec; dims=(1,2)))
277+
@test issparse(cat(othermatorvec, specialmat; dims=(1,2)))
278+
end
279+
end
280+
end
281+
282+
# Test that concatenations of annotated sparse/special matrix types with other matrix
283+
# types yield sparse arrays, and that the code which effects that does not make concatenations
284+
# strictly involving un/annotated dense matrices yield sparse arrays
285+
@testset "concatenations of annotated types" begin
286+
N = 4
287+
# The tested annotation types
288+
testfull = Bool(parse(Int,(get(ENV, "JULIA_TESTFULL", "0"))))
289+
utriannotations = (UpperTriangular, UnitUpperTriangular)
290+
ltriannotations = (LowerTriangular, UnitLowerTriangular)
291+
triannotations = (utriannotations..., ltriannotations...)
292+
symannotations = (Symmetric, Hermitian)
293+
annotations = testfull ? (triannotations..., symannotations...) : (LowerTriangular, Symmetric)
294+
# Concatenations involving these types, un/annotated, should yield sparse arrays
295+
spvec = spzeros(N)
296+
spmat = sparse(1.0I, N, N)
297+
diagmat = Diagonal(1:N)
298+
bidiagmat = Bidiagonal(1:N, 1:(N-1), :U)
299+
tridiagmat = Tridiagonal(1:(N-1), 1:N, 1:(N-1))
300+
symtridiagmat = SymTridiagonal(1:N, 1:(N-1))
301+
sparseconcatmats = testfull ? (spmat, diagmat, bidiagmat, tridiagmat, symtridiagmat) : (spmat, diagmat)
302+
# Concatenations involving strictly these types, un/annotated, should yield dense arrays
303+
densevec = fill(1., N)
304+
densemat = fill(1., N, N)
305+
# Annotated collections
306+
annodmats = [annot(densemat) for annot in annotations]
307+
annospcmats = [annot(spmat) for annot in annotations]
308+
# Test that concatenations of pairwise combinations of annotated sparse/special
309+
# yield sparse matrices
310+
for annospcmata in annospcmats, annospcmatb in annospcmats
311+
@test issparse(vcat(annospcmata, annospcmatb))
312+
@test issparse(hcat(annospcmata, annospcmatb))
313+
@test issparse(hvcat((2,), annospcmata, annospcmatb))
314+
@test issparse(cat(annospcmata, annospcmatb; dims=(1,2)))
315+
end
316+
# Test that concatenations of pairwise combinations of annotated sparse/special
317+
# matrices and other matrix/vector types yield sparse matrices
318+
for annospcmat in annospcmats
319+
# --> Tests applicable to pairs including only matrices
320+
for othermat in (densemat, annodmats..., sparseconcatmats...)
321+
@test issparse(vcat(annospcmat, othermat))
322+
@test issparse(vcat(othermat, annospcmat))
323+
end
324+
# --> Tests applicable to pairs including other vectors or matrices
325+
for other in (spvec, densevec, densemat, annodmats..., sparseconcatmats...)
326+
@test issparse(hcat(annospcmat, other))
327+
@test issparse(hcat(other, annospcmat))
328+
@test issparse(hvcat((2,), annospcmat, other))
329+
@test issparse(hvcat((2,), other, annospcmat))
330+
@test issparse(cat(annospcmat, other; dims=(1,2)))
331+
@test issparse(cat(other, annospcmat; dims=(1,2)))
332+
end
333+
end
334+
# The preceding tests should cover multi-way combinations of those types, but for good
335+
# measure test a few multi-way combinations involving those types
336+
@test issparse(vcat(spmat, densemat, annospcmats[1], annodmats[2]))
337+
@test issparse(vcat(densemat, spmat, annodmats[1], annospcmats[2]))
338+
@test issparse(hcat(spvec, annodmats[1], annospcmats[1], densevec, diagmat))
339+
@test issparse(hcat(annodmats[2], annospcmats[2], spvec, densevec, diagmat))
340+
@test issparse(hvcat((5,), diagmat, densevec, spvec, annodmats[1], annospcmats[1]))
341+
@test issparse(hvcat((5,), spvec, annodmats[2], diagmat, densevec, annospcmats[2]))
342+
@test issparse(cat(annodmats[1], diagmat, annospcmats[2], densevec, spvec; dims=(1,2)))
343+
@test issparse(cat(spvec, diagmat, densevec, annospcmats[1], annodmats[2]; dims=(1,2)))
344+
end
345+
346+
@testset "hcat and vcat involving UniformScaling" begin
347+
@test_throws ArgumentError hcat(I)
348+
@test_throws ArgumentError [I I]
349+
@test_throws ArgumentError vcat(I)
350+
@test_throws ArgumentError [I; I]
351+
@test_throws ArgumentError [I I; I]
352+
353+
A = SparseMatrixCSC(rand(3,4))
354+
B = SparseMatrixCSC(rand(3,3))
355+
C = SparseMatrixCSC(rand(0,3))
356+
D = SparseMatrixCSC(rand(2,0))
357+
E = SparseMatrixCSC(rand(1,3))
358+
F = SparseMatrixCSC(rand(3,1))
359+
α = rand()
360+
@test (hcat(A, 2I))::SparseMatrixCSC == hcat(A, Matrix(2I, 3, 3))
361+
@test (hcat(E, α))::SparseMatrixCSC == hcat(E, [α])
362+
@test (hcat(E, α, 2I))::SparseMatrixCSC == hcat(E, [α], fill(2, 1, 1))
363+
@test (vcat(A, 2I))::SparseMatrixCSC == vcat(A, Matrix(2I, 4, 4))
364+
@test (vcat(F, α))::SparseMatrixCSC == vcat(F, [α])
365+
@test (vcat(F, α, 2I))::SparseMatrixCSC == vcat(F, [α], fill(2, 1, 1))
366+
@test (hcat(C, 2I))::SparseMatrixCSC == C
367+
@test_throws DimensionMismatch hcat(C, α)
368+
@test (vcat(D, 2I))::SparseMatrixCSC == D
369+
@test_throws DimensionMismatch vcat(D, α)
370+
@test (hcat(I, 3I, A, 2I))::SparseMatrixCSC == hcat(Matrix(I, 3, 3), Matrix(3I, 3, 3), A, Matrix(2I, 3, 3))
371+
@test (vcat(I, 3I, A, 2I))::SparseMatrixCSC == vcat(Matrix(I, 4, 4), Matrix(3I, 4, 4), A, Matrix(2I, 4, 4))
372+
@test (hvcat((2,1,2), B, 2I, I, 3I, 4I))::SparseMatrixCSC ==
373+
hvcat((2,1,2), B, Matrix(2I, 3, 3), Matrix(I, 6, 6), Matrix(3I, 3, 3), Matrix(4I, 3, 3))
374+
@test hvcat((3,1), C, C, I, 3I)::SparseMatrixCSC == hvcat((2,1), C, C, Matrix(3I, 6,6))
375+
@test hvcat((2,2,2), I, 2I, 3I, 4I, C, C)::SparseMatrixCSC ==
376+
hvcat((2,2,2), Matrix(I, 3, 3), Matrix(2I, 3,3 ), Matrix(3I, 3,3), Matrix(4I, 3,3), C, C)
377+
@test hvcat((2,2,4), C, C, I, 2I, 3I, 4I, 5I, D)::SparseMatrixCSC ==
378+
hvcat((2,2,4), C, C, Matrix(I, 3, 3), Matrix(2I,3,3),
379+
Matrix(3I, 2, 2), Matrix(4I, 2, 2), Matrix(5I,2,2), D)
380+
@test (hvcat((2,3,2), B, 2I, C, C, I, 3I, 4I))::SparseMatrixCSC ==
381+
hvcat((2,2,2), B, Matrix(2I, 3, 3), C, C, Matrix(3I, 3, 3), Matrix(4I, 3, 3))
382+
@test hvcat((3,2,1), C, C, I, B ,3I, 2I)::SparseMatrixCSC ==
383+
hvcat((2,2,1), C, C, B, Matrix(3I,3,3), Matrix(2I,6,6))
384+
@test (hvcat((1,2), A, E, α))::SparseMatrixCSC == hvcat((1,2), A, E, [α]) == hvcat((1,2), A, E, α*I)
385+
@test (hvcat((2,2), α, E, F, 3I))::SparseMatrixCSC == hvcat((2,2), [α], E, F, Matrix(3I, 3, 3))
386+
@test (hvcat((2,2), 3I, F, E, α))::SparseMatrixCSC == hvcat((2,2), Matrix(3I, 3, 3), F, E, [α])
387+
end
216388
end
217389

218390
let
@@ -2023,6 +2195,31 @@ end
20232195
@test_throws LinearAlgebra.SingularException UpperTriangular(A)\b
20242196
end
20252197

2198+
@testset "Diagonal linear solve" begin
2199+
n = 12
2200+
for relty in (Float32, Float64), elty in (relty, Complex{relty})
2201+
dd=convert(Vector{elty}, randn(n))
2202+
if elty <: Complex
2203+
dd+=im*convert(Vector{elty}, randn(n))
2204+
end
2205+
D = Diagonal(dd)
2206+
b = rand(elty, n, n)
2207+
b = sparse(b)
2208+
@test ldiv!(D, copy(b)) Array(D)\Array(b)
2209+
@test_throws SingularException ldiv!(Diagonal(zeros(elty, n)), copy(b))
2210+
b = rand(elty, n+1, n+1)
2211+
b = sparse(b)
2212+
@test_throws DimensionMismatch ldiv!(D, copy(b))
2213+
b = view(rand(elty, n+1), Vector(1:n+1))
2214+
@test_throws DimensionMismatch ldiv!(D, b)
2215+
for b in (sparse(rand(elty,n,n)), sparse(rand(elty,n)))
2216+
@test lmul!(copy(D), copy(b)) Array(D)*Array(b)
2217+
@test lmul!(transpose(copy(D)), copy(b)) transpose(Array(D))*Array(b)
2218+
@test lmul!(adjoint(copy(D)), copy(b)) Array(D)'*Array(b)
2219+
end
2220+
end
2221+
end
2222+
20262223
@testset "issue described in https://groups.google.com/forum/#!topic/julia-dev/QT7qpIpgOaA" begin
20272224
@test sparse([1,1], [1,1], [true, true]) == sparse([1,1], [1,1], [true, true], 1, 1) == fill(true, 1, 1)
20282225
@test sparsevec([1,1], [true, true]) == sparsevec([1,1], [true, true], 1) == fill(true, 1)
@@ -2211,6 +2408,13 @@ end
22112408
@test_throws BoundsError setindex!(A, [4.0, 5.0, 6.0], 3, 4)
22122409
end
22132410

2411+
@testset "issue #29644" begin
2412+
F = lu(Tridiagonal(sparse(1.0I, 3, 3)))
2413+
@test F.L == Matrix(I, 3, 3)
2414+
@test startswith(sprint(show, MIME("text/plain"), F),
2415+
"$(LinearAlgebra.LU){Float64, $(LinearAlgebra.Tridiagonal){Float64, SparseArrays.SparseVector")
2416+
end
2417+
22142418
@testset "isstored" begin
22152419
m = 5
22162420
n = 4
@@ -2466,6 +2670,32 @@ end
24662670
@test similar(A, Float32, Int8, 6) == similar(A, Float32, Int8, (6,))
24672671
end
24682672

2673+
@testset "similar should preserve underlying storage type and uplo flag" begin
2674+
m, n = 4, 3
2675+
sparsemat = sprand(m, m, 0.5)
2676+
for SymType in (Symmetric, Hermitian)
2677+
symsparsemat = SymType(sparsemat)
2678+
@test isa(similar(symsparsemat), typeof(symsparsemat))
2679+
@test similar(symsparsemat).uplo == symsparsemat.uplo
2680+
@test isa(similar(symsparsemat, Float32), SymType{Float32,<:SparseMatrixCSC{Float32}})
2681+
@test similar(symsparsemat, Float32).uplo == symsparsemat.uplo
2682+
@test isa(similar(symsparsemat, (n, n)), typeof(sparsemat))
2683+
@test isa(similar(symsparsemat, Float32, (n, n)), SparseMatrixCSC{Float32})
2684+
end
2685+
end
2686+
2687+
@testset "similar should preserve underlying storage type" begin
2688+
local m, n = 4, 3
2689+
sparsemat = sprand(m, m, 0.5)
2690+
for TriType in (UpperTriangular, LowerTriangular, UnitUpperTriangular, UnitLowerTriangular)
2691+
trisparsemat = TriType(sparsemat)
2692+
@test isa(similar(trisparsemat), typeof(trisparsemat))
2693+
@test isa(similar(trisparsemat, Float32), TriType{Float32,<:SparseMatrixCSC{Float32}})
2694+
@test isa(similar(trisparsemat, (n, n)), typeof(sparsemat))
2695+
@test isa(similar(trisparsemat, Float32, (n, n)), SparseMatrixCSC{Float32})
2696+
end
2697+
end
2698+
24692699
@testset "count specializations" begin
24702700
# count should throw for sparse arrays for which zero(eltype) does not exist
24712701
@test_throws MethodError count(SparseMatrixCSC(2, 2, Int[1, 2, 3], Int[1, 2], Any[true, true]))

0 commit comments

Comments
 (0)