p3_matrix/
mul.rs

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