matrix arithmetic

faer matrices implement most of the arithmetic operators, so two matrices can be added simply by writing &a + &b, the result of the expression is a faer::Mat, which allows simple chaining of operations (e.g. (&a + 3.0 * &b) * &c), although at the cost of allocating temporary matrices.

temporary allocations can be avoided by using the zip! api:

use faer::{Mat, zip, unzip};

let A = Mat::<f64>::zeros(4, 3);
let B = Mat::<f64>::zeros(4, 3);
let mut C = Mat::<f64>::zeros(4, 3);

// sums `A` and `B` and stores the result in `C`.
zip!(&mut C, &A, &B).for_each(|unzip!(c, a, b)| *c = *a + *b);

// sums `A`, `B` and `C` into a new matrix `D`.
let D = zip!(&mut C, &A, &B).map(|unzip!(c, a, b)| *a + *b + *c);

for matrix multiplication, the non-allocating api in-place is provided in the faer::linalg::matmul module.

use faer::{Mat, Par, Accum};
use faer::linalg::matmul::matmul;
use reborrow::*;

let A = Mat::<f64>::zeros(4, 3);
let B = Mat::<f64>::zeros(3, 5);

let mut C = Mat::<f64>::zeros(4, 5);

// Computes `3.0 * &A * &A` and stores the result in `C`.
matmul(C.rb_mut(), Accum::Replace, A.rb(), B.rb(), 3.0, Par::Seq);

// Computes `3.0 * &A * &B + &C` and stores the result in `C`.
matmul(C.rb_mut(), Accum::Add, A.rb(), B.rb(), 3.0, Par::Seq);