I need to scale a sparse matrix row-wise and column-wise. That is
S[i,j] = r[i] * A[i,j] * c[j]
If I write it the way you’d see it in a math book,
S = spdiagm(r) * A * spdiagm(c)
the expression takes 8x times more than the MATLAB
S = r .* A .* c.'
And if I attempt the above in Julia, it either runs forever, or runs out of memory …
Obviously, S
has the same non-zero pattern as A
and one can restrict the indices i
and j
accordingly, so somewhere between the Broadcast and the SparseArrays the ball is lost… Where do I go to get this scaling to run efficiently and competitively?
Here is a MWE to play with
using LinearAlgebra, SparseArrays, BenchmarkTools
n = 10_000_000
A = sprand(n,n,2/n)
r = rand(n,1); c = rand(n,1)
S = r .* A .* c' # ERROR: OutOfMemoryError()
@benchmark $S = spdiagm($(vec(r))) * $A * spdiagm($(vec(c)))
While in MATLAB
>> A = sprand(10e6,10e6,2/10e6);
>> r = rand(10e6,1);
>> c = rand(10e6,1);
>> timeit (@() r .* A .* c.')
ans =
0.2720
which is 8.5 times faster than the Julia benchmark code above