p3_matrix/
mul.rs

1use p3_field::{add_scaled_slice_in_place, Field};
2use p3_maybe_rayon::prelude::*;
3
4use crate::dense::RowMajorMatrix;
5use crate::sparse::CsrMatrix;
6use crate::Matrix;
7
8/// Compute `C = A * B`, where `A` in a CSR matrix and `B` is a dense matrix.
9///
10/// # Panics
11/// Panics if dimensions of input matrices don't match.
12pub fn mul_csr_dense<F, B>(a: &CsrMatrix<F>, b: &B) -> RowMajorMatrix<F>
13where
14    F: Field,
15    B: Matrix<F> + Sync,
16{
17    assert_eq!(a.width(), b.height(), "A, B dimensions don't match");
18    let c_width = b.width();
19
20    let c_values = (0..a.height())
21        .into_par_iter()
22        .flat_map(|a_row_idx| {
23            let mut c_row = F::zero_vec(c_width);
24            for &(a_col_idx, a_val) in a.sparse_row(a_row_idx) {
25                add_scaled_slice_in_place(&mut c_row, b.row(a_col_idx), a_val);
26            }
27            c_row
28        })
29        .collect();
30
31    RowMajorMatrix::new(c_values, c_width)
32}