Skip to content

Commit 1539390

Browse files
authored
Generic path in ldiv! for Diagonal (#1261)
The performance improvement in `ldiv!` is best seen using `SparseArrays`, as this seems to lack a specialized `ldiv!` method currently: ```julia julia> D = Diagonal(rand(3000)); julia> S = sprand(size(D,1), 0.01); julia> @Btime ldiv!($D, $S); 29.620 μs (0 allocations: 0 bytes) # master 15.388 μs (22 allocations: 154.47 KiB) # This PR ``` This is because the broadcasting method is taken. Unfortunately, in this example, the in-place broadcasting for a sparse array is allocating, but this should be allocation-free in general.
1 parent 4635c5e commit 1539390

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/diagonal.jl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,10 +612,10 @@ function _rdiv!(B::AbstractVecOrMat, A::AbstractVecOrMat, D::Diagonal)
612612
if (k = length(dd)) != n
613613
throw(DimensionMismatch(lazy"left hand side has $n columns but D is $k by $k"))
614614
end
615-
@inbounds for j in 1:n
615+
@inbounds for j in axes(A,2)
616616
ddj = dd[j]
617617
iszero(ddj) && throw(SingularException(j))
618-
for i in 1:m
618+
for i in axes(A,1)
619619
B[i, j] = A[i, j] / ddj
620620
end
621621
end
@@ -640,7 +640,17 @@ function ldiv!(B::AbstractVecOrMat, D::Diagonal, A::AbstractVecOrMat)
640640
(m, n) == (m′, n′) || throw(DimensionMismatch(lazy"expect output to be $m by $n, but got $m′ by $n′"))
641641
j = findfirst(iszero, D.diag)
642642
isnothing(j) || throw(SingularException(j))
643-
@inbounds for j = 1:n, i = 1:m
643+
_ldiv_Diagonal_loop!(B, D, A)
644+
B
645+
end
646+
function _ldiv_Diagonal_loop!(B::AbstractVecOrMat, D::Diagonal, A::AbstractVecOrMat)
647+
dd = D.diag
648+
@. B = dd \ A
649+
B
650+
end
651+
function _ldiv_Diagonal_loop!(B::StridedVecOrMat, D::Diagonal, A::StridedVecOrMat)
652+
dd = D.diag
653+
@inbounds for j in axes(A,2), i in axes(A,1)
644654
B[i, j] = dd[i] \ A[i, j]
645655
end
646656
B

0 commit comments

Comments
 (0)