Hi, I’m looking to initialize a block-sparse matrix (conceptually sparse - it is fine that it will end up storing the 0s in memory). However, I am not sure which is the most idiomatic way to do that. Of course I could start from primitives again and use from_fn
, but that’s awkward. My attempt was as follows:
use nalgebra as na;
fn main() {
let expected = na::DMatrix::from_row_slice(4, 4, &[
1., 2., 0., 0.,
3., 4., 0., 0.,
0., 0., 1., 2.,
0., 0., 3., 4.,
]);
let block = na::DMatrix::from_row_slice(2, 2, &[
1., 2.,
3., 4.
]);
let mut bsparse = na::DMatrix::zeros(4, 4);
//bsparse.index_mut((..2, ..2)); // this is not an invalid expression
//*bsparse.index_mut((..2, ..2)) = block; // <very_complicated_type> cannot be dereferenced
bsparse.index_mut((..2, ..2)) = block;
bsparse.index_mut((2.., 2..)) = block;
println!("{}\n{}", bsparse, expected);
assert_eq!(bsparse, expected);
}
However it produces two kinds of errors:
bsparse.index_mut((..2, ..2)) = block;
^^^^^ expected struct `nalgebra::base::matrix_slice::SliceStorageMut`, found struct `nalgebra::base::vec_storage::VecStorage`
which suggests that in order to assign to a mutable slice I need to also construct a slice, not just an owned matrix. Normally I would try to dereference the mutable borrow when assigning, but I am being told that the type returned by index_mut
does not support dereferencing.
error[E0614]: type `nalgebra::base::matrix::Matrix<_, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::Dynamic, nalgebra::base::matrix_slice::SliceStorageMut<'_, _, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::U1, nalgebra::base::dimension::Dynamic>>` cannot be dereferenced
I can resolve the type mismatch error by matching the exact type on both sides
bsparse.index_mut((..2, ..2)) = block.index_mut((.., ..))
which shuts the compiler up in this regard, as little sense as this incantation makes. However, at all times there is another error
bsparse.index_mut((..2, ..2)) = block;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ left-hand of expression not valid
which is slightly surprising me, since removing the = block;
part results in an expression which compiles (although it does nothing).
I would be grateful for both explanation how to best form block-sparse matrices (in numpy I could use stack/concatenate functions for instance, but I couldn’t find those in nalgebra) and how I would go about getting my current approach to work.