R’s Matrix
library provides ready access to sparse matrix operations. But the library has one quirk: multiplication by a non-sparse vector (as for multiplying each row of a N
row matrix by a scalar held in a N
entry vector) returns a dense Matrix.
Here’s a neat trick for getting around this specific problem with use of the inline
package.
library(inline)
rcpp.scale.src <- "
int row_idx;
// note the indexing trick: i is valued on 0:[nrow-1]; so no need
// to manipulate it when it's a C index the way required if you weree
// doing this in R.
for(int row=0; row < *nrow; row++) {
row_idx = i[row];
x[row] = x[row] * scale_vec[row_idx];
}"
rcpp.scale.sig <- signature(i="integer", nrow="integer", x="numeric", scale_vec="numeric")
c.scale <- cfunction(sig=rcpp.scale.sig,
body=rcpp.scale.src,
convention=".C"
)
## Assume I have a sparse matrix, sparse.mat,
## where I want to multiply every element
## in each row by the row number
sparse.mat = as(sparse.mat, "dgTMatrix")
scaling.vector = 1:nrow(sparse.mat)
sparse.mat$x = c.scale(sparse.mat@i, length(sparse.mat@i), sparse.mat@x, scaling.vector)$x
Results are fast (as per the documentation for inline
). There’s also no reason this wouldn’t work for column-wise multiplication, too, with j
instead of i
as the index.