extendr_api::prelude::modules::core::mul

Function matmul

pub fn matmul<E, LhsE, RhsE>(
    acc: impl As2DMut<E>,
    lhs: impl As2D<LhsE>,
    rhs: impl As2D<RhsE>,
    alpha: Option<E>,
    beta: E,
    parallelism: Parallelism<'_>,
)
where E: ComplexField, LhsE: Conjugate<Canonical = E>, RhsE: Conjugate<Canonical = E>,
Expand description

Computes the matrix product [alpha * acc] + beta * lhs * rhs and stores the result in acc.

Performs the operation:

  • acc = beta * lhs * rhs if alpha is None (in this case, the preexisting values in acc are not read, so it is allowed to be a view over uninitialized values if E: Copy),
  • acc = alpha * acc + beta * lhs * rhs if alpha is Some(_),

§Panics

Panics if the matrix dimensions are not compatible for matrix multiplication.
i.e.

  • acc.nrows() == lhs.nrows()
  • acc.ncols() == rhs.ncols()
  • lhs.ncols() == rhs.nrows()

§Example

use faer::{linalg::matmul::matmul, mat, unzipped, zipped, Mat, Parallelism};

let lhs = mat![[0.0, 2.0], [1.0, 3.0]];
let rhs = mat![[4.0, 6.0], [5.0, 7.0]];

let mut acc = Mat::<f64>::zeros(2, 2);
let target = mat![
    [
        2.5 * (lhs.read(0, 0) * rhs.read(0, 0) + lhs.read(0, 1) * rhs.read(1, 0)),
        2.5 * (lhs.read(0, 0) * rhs.read(0, 1) + lhs.read(0, 1) * rhs.read(1, 1)),
    ],
    [
        2.5 * (lhs.read(1, 0) * rhs.read(0, 0) + lhs.read(1, 1) * rhs.read(1, 0)),
        2.5 * (lhs.read(1, 0) * rhs.read(0, 1) + lhs.read(1, 1) * rhs.read(1, 1)),
    ],
];

matmul(
    acc.as_mut(),
    lhs.as_ref(),
    rhs.as_ref(),
    None,
    2.5,
    Parallelism::None,
);

zipped!(acc.as_ref(), target.as_ref())
    .for_each(|unzipped!(acc, target)| assert!((acc.read() - target.read()).abs() < 1e-10));