Last active
January 16, 2019 14:28
Braille plot sparse show
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const BRAILLE = split("⠀⠁⠂⠄⡀⠈⠐⠠⢀", "") .|> s -> Int(s[1]) | |
function show_any_nonzero(S::SparseMatrixCSC; maxw = displaysize(stdout)[2], maxh = displaysize(stdout)[1]-3) | |
h,w = size(S) | |
h > 4maxh && (w = max(1, (w*4maxh+h÷2)÷h); h = 4maxh) | |
w > 2maxw && (h = max(1, (h*2maxw+w÷2)÷w); w = 2maxw) | |
P = fill(BRAILLE[1], (w+3)÷2, (h+3)÷4) | |
P[end, :].=10 | |
@inbounds for c = 0:w-1, r = 0:h-1 | |
_anynz(S, r*S.m÷h+1, c*S.n÷w+1, (r+1)*S.m÷h, (c+1)*S.n÷w) && | |
(P[c÷2+1, r÷4+1] |= BRAILLE[4c&4+r&3+2]) | |
end | |
print(join(Char.(P)) * "nz = $(nnz(S))") | |
end | |
function show_any_nonzero_loop_nz(S::SparseMatrixCSC; maxw = displaysize(stdout)[2], maxh = displaysize(stdout)[1]-3) | |
h,w = size(S) | |
h > 4maxh && (w = max(1, (w*4maxh+h÷2)÷h); h = 4maxh) | |
w > 2maxw && (h = max(1, (h*2maxw+w÷2)÷w); w = 2maxw) | |
P = fill(BRAILLE[1], (w+3)÷2, (h+3)÷4) | |
P[end, :].=10 | |
@inbounds for c = 1:S.n | |
for k in nzrange(S, c) | |
x = (c-1)*w÷S.n | |
y = (S.rowval[k]-1)*h÷S.m | |
P[1+x÷2,1+y÷4] |= BRAILLE[4x&4+y&3+2] | |
end | |
end | |
print(join(Char.(P)) * "nz = $(nnz(S))") | |
end | |
function show_above_median_nonzero(S::SparseMatrixCSC; maxw = displaysize(stdout)[2], maxh = displaysize(stdout)[1]-3) | |
h,w = size(S) | |
h > 4maxh && (w = max(1, (w*4maxh+h÷2)÷h); h = 4maxh) | |
w > 2maxw && (h = max(1, (h*2maxw+w÷2)÷w); w = 2maxw) | |
P = fill(BRAILLE[1], (w+3)÷2, (h+3)÷4) | |
P[end, :].=10 | |
med = mediancount(S, h, w) | |
@inbounds for c = 0:w-1, r = 0:h-1 | |
_gtnz(S, r*S.m÷h+1, c*S.n÷w+1, (r+1)*S.m÷h, (c+1)*S.n÷w, med) && | |
(P[c÷2+1, r÷4+1] |= BRAILLE[4c&4+r&3+2]) | |
end | |
print(join(Char.(P)) * "nz = $(nnz(S))") | |
end | |
function mediancount(S::SparseMatrixCSC, h, w) | |
counts = Vector{Int}(undef, w*h) | |
@inbounds for c = 0:w-1, r = 0:h-1 | |
counts[r*w+c+1] = _count(S, r*S.m÷h+1, c*S.n÷w+1, (r+1)*S.m÷h, (c+1)*S.n÷w) | |
end | |
trunc(Int, median!(counts)) | |
end | |
function _anynz(S::SparseMatrixCSC, r1, c1, r2, c2) | |
@inbounds for c = c1:c2 | |
k = searchsortedfirst(S.rowval, r1, S.colptr[c], S.colptr[c+1]-1, Base.Order.Forward) | |
k != S.colptr[c+1] && S.rowval[k] ≤ r2 && return true | |
end | |
false | |
end | |
function _gtnz(S::SparseMatrixCSC, r1, c1, r2, c2, m) | |
count = 0 | |
@inbounds for c = c1:c2 | |
for k = searchsortedfirst(S.rowval, r1, S.colptr[c], S.colptr[c+1]-1, Base.Order.Forward):S.colptr[c+1]-1 | |
S.rowval[k] > r2 && break | |
(count += 1) > m && return true | |
end | |
end | |
false | |
end | |
function _count(S::SparseMatrixCSC, r1, c1, r2, c2) | |
count = 0 | |
@inbounds for c = c1:c2 | |
for k = searchsortedfirst(S.rowval, r1, S.colptr[c], S.colptr[c+1]-1, Base.Order.Forward):S.colptr[c+1]-1 | |
S.rowval[k] > r2 && break | |
count += 1 | |
end | |
end | |
count | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For the
loop_nz
variant you may putx =
outside the inner loop.Also counting non-zeros into a preallocated
bucket = zeros(Int, h, w)
and writing the characters separately shaves of a bit (trading a small amount of memory though).That is especially performant in the
median
variant, where the median can now be calculated using the bucket counts instead of the whole matrix.