Skip to content

Commit 4243b96

Browse files
committed
fix related issues, add tests
1 parent 7792727 commit 4243b96

6 files changed

Lines changed: 88 additions & 46 deletions

File tree

docs/src/index.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,11 @@ julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];
113113
114114
julia> S = sparse(I,J,V)
115115
5×18 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
116-
⎡⠀⠈⠀⠀⠀⠀⠀⠀⢀⎤
117-
⎣⠀⠀⠀⠂⡀⠀⠀⠀⠀⎦
116+
⋅ ⋅ ⋅ 1 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
117+
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
118+
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ -5
119+
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 2 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
120+
⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 3 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅
118121
119122
julia> R = sparsevec(I,V)
120123
5-element SparseVector{Int64, Int64} with 4 stored entries:

src/linalg.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,19 +2094,19 @@ julia> A[4:4:8] .= 1;
20942094
20952095
julia> A
20962096
3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
2097-
1.0 ⋅
2098-
⋅ 1.0
2099-
⋅ ⋅
2097+
1.0 ⋅
2098+
⋅ 1.0
2099+
⋅ ⋅
21002100
21012101
julia> C = spzeros(3,3);
21022102
21032103
julia> C[2:4:6] .= 2;
21042104
21052105
julia> C
21062106
3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
2107-
⋅ ⋅
2108-
2.0 ⋅
2109-
⋅ 2.0
2107+
⋅ ⋅ ⋅
2108+
2.0 ⋅ ⋅
2109+
⋅ 2.0 ⋅
21102110
21112111
julia> SparseArrays.mergeinds!(C, A)
21122112
3×3 SparseMatrixCSC{Float64, Int64} with 4 stored entries:

src/solvers/spqr.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ Q factor:
192192
4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}
193193
R factor:
194194
2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
195-
-1.41421 ⋅
196-
-1.41421
195+
-1.41421
196+
-1.41421
197197
Row permutation:
198198
4-element Vector{Int64}:
199199
1
@@ -471,10 +471,10 @@ when the problem is underdetermined.
471471
```jldoctest
472472
julia> A = sparse([1,2,4], [1,1,1], [1.0,1.0,1.0], 4, 2)
473473
4×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
474-
1.0
475-
1.0
476-
477-
1.0
474+
1.0 ⋅
475+
1.0 ⋅
476+
⋅ ⋅
477+
1.0 ⋅
478478
479479
julia> qr(A)\\fill(1.0, 4)
480480
2-element Vector{Float64}:

src/sparsematrix.jl

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,6 @@ function Base.show(io::IO, ::MIME"text/plain", S::AbstractSparseMatrixCSCInclAdj
352352

353353
screen = displaysize(io)
354354
get(io, :limit, false) && screen[1] <= 4 && return print(io, ": …")
355-
println(io, ":")
356355

357356
show_circular(io, S) && return
358357
io = IOContext(io, :compact=>true, :typeinfo=>eltype(S), :SHOWN_SET=>S)
@@ -433,7 +432,7 @@ function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjoi
433432
# `scaleHeight` and `scaleWidth` accordingly. Note that each available
434433
# character can contain up to 4 braille dots in its height (⡇) and up to
435434
# 2 braille dots in its width (⠉).
436-
if get(io, :limit, true) && (m > 4maxHeight || n > 2maxWidth)
435+
if get(io, :limit, false) && (m > 4maxHeight || n > 2maxWidth)
437436
s = min(2maxWidth / n, 4maxHeight / m)
438437
scaleHeight = floor(Int, s * m)
439438
scaleWidth = floor(Int, s * n)
@@ -521,6 +520,8 @@ function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAn
521520
colwidths = [max.((0, 0), align[findall(==(col), cols)]...) for col in axes(S,2)]
522521
displaysize(io)[2] < sum(sum.(colwidths) .+ 2) && return _show_with_braille_patterns(io, S)
523522

523+
println(io, ":")
524+
524525
try
525526
zero(eltype(S))
526527
catch
@@ -535,12 +536,26 @@ function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAn
535536
if isempty(index) # no value here, print an aligned dot
536537
l, r = cld(l+r-1, 2) + 1, div(l+r-1, 2) + 1
537538
print(io, " "^l * "" * (col==axes(S,2)[end] ? "" : " "^r))
538-
else
539+
else try # print the element with 1 space of buffer on each side
539540
l, r = (l+1, r+1) .- align[index[]]
540541
print(io, " "^l)
541542
isassigned(vals, index[]) ? show(io, vals[index[]]) : print(io, "#undef")
542543
col == axes(S,2)[end] || print(io, " "^r)
543-
end
544+
catch # if there's 2+ entries, index[] errors. default to summing
545+
# entries, but print red to warn user that something's wrong
546+
elm = any(!isassigned(vals, ind) for ind in index) ? "#undef" :
547+
try repr(sum(vals[index]); context=:compact=>true) catch e "#NaN" end
548+
549+
if length(elm) <= l+r # give up on alignment, center item in the column
550+
l, r = cld(l+r-length(elm), 2) + 1, div(l+r-length(elm), 2) + 1
551+
else # len of new item does not fit in column
552+
elm = ""^(l+r)
553+
l, r = 1, 1
554+
end
555+
556+
printstyled(io, " "^l, elm, color=:red)
557+
col == axes(S,2)[end] || print(io, " "^r)
558+
end end
544559
end
545560
row == axes(S,1)[end] || println(io)
546561
end
@@ -688,7 +703,7 @@ function _sparse_copyto!(dest::AbstractMatrix, src::AbstractSparseMatrixCSC)
688703
@inbounds for col in axes(src, 2), ptr in nzrange(src, col)
689704
row = rowvals(src)[ptr]
690705
val = nonzeros(src)[ptr]
691-
dest[isrc[row, col]] = val
706+
dest[isrc[row, col]] += val
692707
end
693708
return dest
694709
end
@@ -712,7 +727,7 @@ function copyto!(dest::AbstractMatrix, Rdest::CartesianIndices{2},
712727
if row in rows
713728
val = nonzeros(src′)[ptr]
714729
I = Rdest[lin[row, col]]
715-
dest[I] = val
730+
dest[I] += val
716731
end
717732
end
718733
return dest
@@ -737,7 +752,7 @@ function Base.copyto!(A::Array{T}, S::SparseMatrixCSC{<:Number}) where {T<:Numbe
737752
for i in nzrange(S, col)
738753
row = rowval[i]
739754
val = nzval[i]
740-
A[linear_index_col0+row] = val
755+
A[linear_index_col0+row] += val
741756
end
742757
linear_index_col0 += num_rows
743758
end
@@ -1962,9 +1977,9 @@ julia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])
19621977
19631978
julia> dropzeros(A)
19641979
3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
1965-
1.0
1966-
1967-
1.0
1980+
1.0
1981+
1982+
1.0
19681983
```
19691984
"""
19701985
dropzeros(A::AbstractSparseMatrixCSC) = dropzeros!(copy(A))
@@ -2134,7 +2149,7 @@ argument specifies a random number generator, see [Random Numbers](@ref).
21342149
```jldoctest; setup = :(using Random; Random.seed!(0))
21352150
julia> sprandn(2, 2, 0.75)
21362151
2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
2137-
-1.20577 ⋅
2152+
-1.20577
21382153
0.311817 -0.234641
21392154
```
21402155
"""
@@ -2161,9 +2176,9 @@ specified.
21612176
```jldoctest
21622177
julia> spzeros(3, 3)
21632178
3×3 SparseMatrixCSC{Float64, Int64} with 0 stored entries:
2164-
2165-
2166-
2179+
2180+
2181+
21672182
21682183
julia> spzeros(Float32, 4)
21692184
4-element SparseVector{Float32, Int64} with 0 stored entries

test/issues.jl

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,14 +758,14 @@ let
758758
B = similar(A, T12960)
759759
@test repr(B) == "sparse([1, 2, 3], [1, 2, 3], $T12960[#undef, #undef, #undef], 3, 3)"
760760
@test occursin(
761-
"\n #undef \n #undef \n #undef",
761+
" #undef ⋅ \n ⋅ #undef \n #undef",
762762
repr(MIME("text/plain"), B),
763763
)
764764

765765
B[1,2] = T12960()
766766
@test repr(B) == "sparse([1, 1, 2, 3], [1, 2, 2, 3], $T12960[#undef, $T12960(), #undef, #undef], 3, 3)"
767767
@test occursin(
768-
"\n #undef T12960() \n #undef \n #undef",
768+
"\n #undef T12960() \n ⋅ #undef \n #undef",
769769
repr(MIME("text/plain"), B),
770770
)
771771
end
@@ -805,13 +805,37 @@ end
805805
7 16 4])
806806
end
807807

808+
@testset "Issue #512" begin # suppresses but does not fix the error mentioned
809+
x = sparse([1, 1, 3], [1, 4, 3], [20, 0, [2]])
810+
@test_warn "WARNING: could not find generic zero" repr(MIME("text/plain"), x)
811+
x = sparse([1, 100, 3], [1, 4, 300], [20, 0, [2]])
812+
@test_warn "WARNING: could not find generic zero" repr(MIME("text/plain"), x)
813+
814+
@test_broken repr(MIME("text/plain"), transpose(x'))
815+
end
816+
808817
@testset "Issue #574" begin
809818
a = spzeros(Float32, Int16, 2, 3)
810819
v = spzeros(Float32, Int16, 2)
811820
@test eltype(rowvals(zero(a))) <: Int16
812821
@test eltype(rowvals(zero(v))) <: Int16
813822
end
814823

824+
@testset "Issue #618" begin
825+
x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [1.0, 1.0, 1.0, 1.0])
826+
@test contains(repr(MIME"text/plain"(), x), "2.0")
827+
x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [7.0, 7.0, 1.0, 1.0])
828+
@test contains(repr(MIME"text/plain"(), x), "▒▒▒")
829+
x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [7.0, 'o', 1.0, 1.0])
830+
@test contains(repr(MIME"text/plain"(), x), "#NaN")
831+
v = similar(Any[1, 2, 3, 4]); v[2:4] = [1.0, 1.0, 1.0]
832+
x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], v)
833+
@test contains(repr(MIME"text/plain"(), x), "#undef")
834+
835+
x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [1, 1, 1, 1])
836+
@test 2 == Matrix(x)[1,1]
837+
end
838+
815839
end # SparseTestsBase
816840

817841
end # module

test/sparsematrix_constructors_indexing.jl

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,9 +1514,9 @@ end
15141514
A = spzeros(Float32, Int64, 2, 2)
15151515
for (transform, showstring) in zip(
15161516
(identity, adjoint, transpose), (
1517-
"2×2 $SparseMatrixCSC{Float32, Int64} with 0 stored entries:\n \n ",
1518-
"2×2 $Adjoint{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n \n ",
1519-
"2×2 $Transpose{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n \n ",
1517+
"2×2 $SparseMatrixCSC{Float32, Int64} with 0 stored entries:\n\n",
1518+
"2×2 $Adjoint{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n\n",
1519+
"2×2 $Transpose{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n\n",
15201520
))
15211521
show(io, MIME"text/plain"(), transform(A))
15221522
@test String(take!(io)) == showstring
@@ -1538,7 +1538,7 @@ end
15381538
show(io, MIME"text/plain"(), transform(A))
15391539
@test String(take!(io)) == showstring
15401540
_show_with_braille_patterns(convert(IOContext, io), transform(A))
1541-
@test String(take!(io)) == braille
1541+
@test contains(String(take!(io)), braille)
15421542
end
15431543

15441544
# every 1-dot braille pattern
@@ -1559,7 +1559,7 @@ end
15591559
for transform in (identity, adjoint, transpose)
15601560
expected = "" * Char(10240)^2 * "\n" * Char(10240)^2 * ""
15611561
_show_with_braille_patterns(convert(IOContext, io), transform(A))
1562-
@test String(take!(io)) == expected
1562+
@test contains(String(take!(io)), expected)
15631563
end
15641564

15651565
A = sparse(Int64[1, 2, 4, 2, 3], Int64[1, 1, 1, 2, 2], Int64[1, 1, 1, 1, 1], 4, 2)
@@ -1578,7 +1578,7 @@ end
15781578
show(io, MIME"text/plain"(), transform(A))
15791579
@test String(take!(io)) == showstring
15801580
_show_with_braille_patterns(convert(IOContext, io), transform(A))
1581-
@test String(take!(io)) == braille
1581+
@test contains(String(take!(io)), braille)
15821582
end
15831583

15841584
A = sparse(Int64[1, 3, 2, 4], Int64[1, 1, 2, 2], Int64[1, 1, 1, 1], 7, 3)
@@ -1597,7 +1597,7 @@ end
15971597
show(io, MIME"text/plain"(), transform(A))
15981598
@test String(take!(io)) == showstring
15991599
_show_with_braille_patterns(convert(IOContext, io), transform(A))
1600-
@test String(take!(io)) == braille
1600+
@test contains(String(take!(io)), braille)
16011601
end
16021602

16031603
A = sparse(Int64[1:10;], Int64[1:10;], fill(Float64(1), 10))
@@ -1606,7 +1606,7 @@ end
16061606
"⎣⠀⠀⠀⠀⠑⎦"
16071607
for transform in (identity, adjoint, transpose)
16081608
_show_with_braille_patterns(convert(IOContext, io), transform(A))
1609-
@test String(take!(io)) == brailleString
1609+
@test contains(String(take!(io)), brailleString)
16101610
end
16111611

16121612
# Issue #30589
@@ -1622,22 +1622,22 @@ end
16221622
# vertical scaling
16231623
ioc = IOContext(io, :displaysize => (5, 80), :limit => true)
16241624
_show_with_braille_patterns(ioc, _filled_sparse(10, 10))
1625-
@test String(take!(io)) == "⎡⣿⣿⎤\n" *
1626-
"⎣⣿⣿⎦"
1625+
@test contains(String(take!(io)), "⎡⣿⣿⎤\n" *
1626+
"⎣⣿⣿⎦")
16271627

16281628
_show_with_braille_patterns(ioc, _filled_sparse(20, 10))
1629-
@test String(take!(io)) == "⎡⣿⣿⎤\n" *
1630-
"⎣⣿⣿⎦"
1629+
@test contains(String(take!(io)), "⎡⣿⣿⎤\n" *
1630+
"⎣⣿⣿⎦")
16311631

16321632
# horizontal scaling
16331633
ioc = IOContext(io, :displaysize => (80, 4), :limit => true)
16341634
_show_with_braille_patterns(ioc, _filled_sparse(8, 8))
1635-
@test String(take!(io)) == "⎡⣿⣿⎤\n" *
1636-
"⎣⣿⣿⎦"
1635+
@test contains(String(take!(io)), "⎡⣿⣿⎤\n" *
1636+
"⎣⣿⣿⎦")
16371637

16381638
_show_with_braille_patterns(ioc, _filled_sparse(8, 16))
1639-
@test String(take!(io)) == "⎡⣿⣿⎤\n" *
1640-
"⎣⣿⣿⎦"
1639+
@test contains(String(take!(io)), "⎡⣿⣿⎤\n" *
1640+
"⎣⣿⣿⎦")
16411641

16421642
# respect IOContext while displaying J
16431643
I, J, V = shuffle(1:50), shuffle(1:50), [1:50;]

0 commit comments

Comments
 (0)