sparsemat / sprs

sparse linear algebra library for rust
Apache License 2.0
381 stars 45 forks source link

CsVecBase::to_dense() #257

Closed matzhaugen closed 3 years ago

matzhaugen commented 3 years ago

I was wondering if there is currently a way to get the dense version of a sparse vector, just like the CsMat::to_dense() equivalent. This is to do element-wise multiplication between dense and sparse vectors.

This is for the following use case:

result = ndarray::Zip::from(&mut dense_vector.diag_mut())
                .and(&sparse_vector.diag().to_dense())
                .apply(|a, b| *a -= 1.0 / b);

Or another similar use case

dense_vector.diag_mut() = dense_vector.diag() - 1 / &sparse_vector.diag();

Not sure if the pointers are exactly correct here, but hopefully you get the idea.

mulimoen commented 3 years ago

The idiomatic way would be to use an iterator:

for (i, n) in sparse_diag.iter() {
    dense_vector[i] -= 1.0 / n;
}

There is no current "densifier" of sparse vectors. If we want this implemented should we prefer to return a Vec or ndarray::Array1?

matzhaugen commented 3 years ago

Thanks for the snippet! I see that this is actually a nice one since you don't allocate a dense array. In any case, I'm happy to provide a PR.

It seems like Array1 would be consistent with the previous implementation for CsMat https://github.com/vbarrielle/sprs/blob/master/src/sparse/csmat.rs#L1036

vbarrielle commented 3 years ago

Yes it should be implemented on Array1. The best way to do it if you want to do a PR is to implement it in the src/sparse/to_dense.rs file. It should be possible to extract the method you're interested in from assign_to_dense.

vbarrielle commented 3 years ago

Fixed by #264.