Nalgebra: best practice to assign a Matrix to a part (submatrix) of an existing Matrix

Hi, All,
I'm using nalgebra DMatrix and want to assign a smaller dimension matrix y_1 to an equal-dimensional part (submatrix) of an existing matrix y. Maybe I missed the right section of the nalgebra documentation, but I can't find a better solution. The view_mut() method does not manipulate the matrix in-place and can't be used as the LHS in assignment operations. I can use fill_with() method for element-wise operations to do the job, but it is quite tedious and inefficient. I'm expecting an assignment statement like the view_mut() method:

y.view_in_place_mut((0,0), (m, n)) = y_1;

or

y.set_submatrix((0,0), (m, n), y_1);

where y_1 is an m*n matrix. Appreciate the assistance!

Sean Nie

I cannot tel you what the best way is. What I can tell you is that Nalgebra is unfortunately very cumbersome in dealing with manipulating matrices (like what you are attempting to do). Depending on your code, using ndarray instead may be option, which of course has other limitations but excels in slicing matrices.

Thank you. Maybe ndarray and ndarray-linalg together are more suitable.

It is an unfortunate fact that the Rust ecosystem is split between these two crates (ndarray vs nalgebra). I personally prefer nalgebra when I’m exclusively doing linear algebra operations, e.g. matrix decomposition and friends. For everything else, I stick to ndarray.

Thanks. The ndarray-linalg also supports matrix decomposition via lapack. It seems that the crate can do everything that nalgebra can, except that nalgebra is natively implemented by Rust. Is there any advantage of using nalgebra over ndarray-linalg for matrix decomposition like QR, LU, Eigenvalue, etc? Appreciate your assistance.

I haven't used ndarray-linalg to be honest. Several years ago, I faced the decision of implementing something with either nalgebra or ndarray. At the time, nalgebra was the clear winner; it just felt more ergonomic for simple stuff (matrix-vector multiplication, inversion, SVD, take a row/column, etc.) and compile-time dimension check is also nice. However, soon enough I ran into the nalgebra limitations: it was a pain to write a submatrix (just as you discovered), and although the documentation claim that it works in no_std environments (using nightly), I couldn't make it work (I can confirm from personal experience that ndarray does work on no-std, in case that is important to you). So, I have mixed feelings towards nalgebra.
In the end, at some point you might need to learn both crates: the Rust ecosystem seems to be equally split between nalgebra and ndarray. Fortunately, transforming arrays between them is straightforward using nshare.

Thank you so much for your valuable comments!

I have a similar problem and was able to sorta solve it with Nalgebra's Matrix::add_to function. Here is an example:

use nalgebra::DMatrix;
use nalgebra::Matrix2;
use nalgebra::dmatrix;

pub fn main() {
    let mut m = DMatrix::zeros(10,10);
    let mut v = m.view_mut((3,3), (2,2));
    let addend = dmatrix![1,2;3,4];
    Matrix2::zeros().add_to(&addend, &mut v);
    println!("{m}");
}

Rust Playground

I don't like it, and I am open to suggestions for a better solution.

1 Like