pub fn numeric<
    Iptr: SpIndex,
    I: SpIndex,
    N: Num + Copy + std::ops::AddAssign,
>(
    a_indptr: &[Iptr],
    a_indices: &[I],
    a_data: &[N],
    b_indptr: &[Iptr],
    b_indices: &[I],
    b_data: &[N],
    c_indptr: &[Iptr],
    c_indices: &[I],
    c_data: &mut [N],
    tmp: &mut [N],
) {
    assert!(a_indptr.len() == c_indptr.len());
    let a_rows = a_indptr.len() - 1;
    let b_rows = b_indptr.len() - 1;
    assert!(b_indices.len() == b_indptr[b_rows].index());
    assert!(b_data.len() == b_indptr[b_rows].index());

    for elt in tmp.iter_mut() {
        *elt = N::zero();
    }
    for a_row in 0..a_rows {
        let a_start = a_indptr[a_row].index();
        let a_stop = a_indptr[a_row + 1].index();
        for a_cur in a_start..a_stop {
            let a_col = a_indices[a_cur].index();
            let a_val = a_data[a_cur];
            let b_row = a_col;
            let b_start = b_indptr[b_row].index();
            let b_stop = b_indptr[b_row + 1].index();
            for b_cur in b_start..b_stop {
                let b_col = b_indices[b_cur].index();
                let b_val = b_data[b_cur];
                tmp[b_col] += a_val * b_val;
            }
        }
        let c_row = a_row;
        let c_start = c_indptr[c_row].index();
        let c_stop = c_indptr[c_row + 1].index();
        for c_cur in c_start..c_stop {
            // Handle split data. On non split data this is a no-op, but on
            // split data this will compute the correct offset.
            let c_cur = c_cur - c_indptr[0].index();
            let c_col = c_indices[c_cur].index();
            c_data[c_cur] = tmp[c_col];
            tmp[c_col] = N::zero();
        }
    }
}
/// Numeric part of the matrix product C = A * B with A, B and C stored in the
/// CSR matrix format.
///
/// This function is low-level, and supports execution on chunks of the
/// rows of C and A. To use the chunks, split the indptrs of A and C and split
/// `c_indices` and `c_data` to only contain the elements referenced in
/// `c_indptr`. This function will take care of using the correct offset
/// inside the sliced indices and data.
///
/// # Panics
///
/// `tmp.len()` should be equal to the maximum dimension of the inputs.
///
/// The matrices should be in proper CSR structure, and their dimensions
/// should be compatible. Failures to do so may result in out of bounds errors
/// (though some cases might go unnoticed).
///
/// The parts for the C matrix should come from the `symbolic` function.
Numeric part of the matrix product C = A * B with A, B and C stored in the
CSR matrix format.

This function is low-level, and supports execution on chunks of the
rows of C and A.
Numeric part of the matrix product C = A * B with A B and C stored in the CSR matrix format . This function is low - level and supports execution on chunks of the rows of C and A .
pub fn numeric<
    Iptr: SpIndex,
    I: SpIndex,
    N: Num + Copy + std::ops::AddAssign,
>(
    a_indptr: &[Iptr],
    a_indices: &[I],
    a_data: &[N],
    b_indptr: &[Iptr],
    b_indices: &[I],
    b_data: &[N],
    c_indptr: &[Iptr],
    c_indices: &[I],
    c_data: &mut [N],
    tmp: &mut [N],
) {
    assert!(a_indptr.len() == c_indptr.len());
    let a_rows = a_indptr.len() - 1;
    let b_rows = b_indptr.len() - 1;
    assert!(b_indices.len() == b_indptr[b_rows].index());
    assert!(b_data.len() == b_indptr[b_rows].index());
    for elt in tmp.iter_mut() {
        *elt = N::zero();
    }
    for a_row in 0..a_rows {
        let a_start = a_indptr[a_row].index();
        let a_stop = a_indptr[a_row + 1].index();
        for a_cur in a_start..a_stop {
            let a_col = a_indices[a_cur].index();
            let a_val = a_data[a_cur];
            let b_row = a_col;
            let b_start = b_indptr[b_row].index();
            let b_stop = b_indptr[b_row + 1].index();
            for b_cur in b_start..b_stop {
                let b_col = b_indices[b_cur].index();
                let b_val = b_data[b_cur];
                tmp[b_col] += a_val * b_val;
            }
        }
        let c_row = a_row;
        let c_start = c_indptr[c_row].index();
        let c_stop = c_indptr[c_row + 1].index();
        for c_cur in c_start..c_stop {
            // Handle split data. On non split data this is a no-op, but on
            // split data this will compute the correct offset.
            let c_cur = c_cur - c_indptr[0].index();
            let c_col = c_indices[c_cur].index();
            c_data[c_cur] = tmp[c_col];
            tmp[c_col] = N::zero();
        }
    }
}
pub fn numeric < Iptr : SpIndex , I : SpIndex , N : Num + Copy + std :: ops :: AddAssign , > ( a_indptr : & [ Iptr ] , a_indices : & [ I ] , a_data : & [ N ] , b_indptr : & [ Iptr ] , b_indices : & [ I ] , b_data : & [ N ] , c_indptr : & [ Iptr ] , c_indices : & [ I ] , c_data : & mut [ N ] , tmp : & mut [ N ] , ) { assert ! ( a_indptr len ( ) c_indptr len ( ) ) ; let a_rows = a_indptr . len ( ) - 1 ; let b_rows = b_indptr . len ( ) - 1 ; assert ! ( b_indices len ( ) b_indptr [ b_rows ] index ( ) ) ; assert ! ( b_data len ( ) b_indptr [ b_rows ] index ( ) ) ; for elt in tmp . iter_mut ( ) { * elt = N :: zero ( ) ; } for a_row in 0 .. a_rows { let a_start = a_indptr [ a_row ] . index ( ) ; let a_stop = a_indptr [ a_row + 1 ] . index ( ) ; for a_cur in a_start .. a_stop { let a_col = a_indices [ a_cur ] . index ( ) ; let a_val = a_data [ a_cur ] ; let b_row = a_col ; let b_start = b_indptr [ b_row ] . index ( ) ; let b_stop = b_indptr [ b_row + 1 ] . index ( ) ; for b_cur in b_start .. b_stop { let b_col = b_indices [ b_cur ] . index ( ) ; let b_val = b_data [ b_cur ] ; tmp [ b_col ] += a_val * b_val ; } } let c_row = a_row ; let c_start = c_indptr [ c_row ] . index ( ) ; let c_stop = c_indptr [ c_row + 1 ] . index ( ) ; for c_cur in c_start .. c_stop { // Handle split data. On non split data this is a no-op, but on // split data this will compute the correct offset. let c_cur = c_cur - c_indptr [ 0 ] . index ( ) ; let c_col = c_indices [ c_cur ] . index ( ) ; c_data [ c_cur ] = tmp [ c_col ] ; tmp [ c_col ] = N :: zero ( ) ; } } }
Numeric part of the matrix product C = A * B with A, B and C stored in the
CSR matrix format.
Numeric part of the matrix product C = A * B with A B and C stored in the CSR matrix format .
a_indptr
&[Iptr]
a_indices
&[I]
a_data
&[N]
b_indptr
&[Iptr]
b_indices
&[I]
b_data
&[N]
c_indptr
&[Iptr]
c_indices
&[I]
c_data
&mut [N]
tmp
&mut [N]
a_indptr
&[Iptr]
a_indices
&[I]
a_data
&[N]
b_indptr
&[Iptr]
b_indices
&[I]
b_data
&[N]
c_indptr
&[Iptr]
c_indices
&[I]
c_data
&mut [N]
tmp
&mut [N]
panics
`tmp.len()` should be equal to the maximum dimension of the inputs.

The matrices should be in proper CSR structure, and their dimensions
should be compatible. Failures to do so may result in out of bounds errors
(though some cases might go unnoticed).

The parts for the C matrix should come from the `symbolic` function.
` tmp . len () ` should be equal to the maximum dimension of the inputs . The matrices should be in proper CSR structure and their dimensions should be compatible . Failures to do so may result in out of bounds errors ( though some cases might go unnoticed ) . The parts for the C matrix should come from the ` symbolic ` function .