public static void mult(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC C,
                            @Nullable IGrowArray gw, @Nullable DGrowArray gx )
    {
        double []x = adjust(gx, A.numRows);
        int []w = adjust(gw, A.numRows, A.numRows);

        C.growMaxLength(A.nz_length+B.nz_length,false);
        C.indicesSorted = false;
        C.nz_length = 0;

        // C(i,j) = sum_k A(i,k) * B(k,j)
        int idx0 = B.col_idx[0];
        for (int bj = 1; bj <= B.numCols; bj++) {
            int colB = bj-1;
            int idx1 = B.col_idx[bj];
            C.col_idx[bj] = C.nz_length;

            if( idx0 == idx1 ) {
                continue;
            }

            // C(:,j) = sum_k A(:,k)*B(k,j)
            for (int bi = idx0; bi < idx1; bi++) {
                int rowB = B.nz_rows[bi];
                double valB = B.nz_values[bi];  // B(k,j)  k=rowB j=colB

                multAddColA(A,rowB,valB,C,colB+1,x,w);
            }

            // take the values in the dense vector 'x' and put them into 'C'
            int idxC0 = C.col_idx[colB];
            int idxC1 = C.col_idx[colB+1];

            for (int i = idxC0; i < idxC1; i++) {
                C.nz_values[i] = x[C.nz_rows[i]];
            }

            idx0 = idx1;
        }

    }
public static void mult ( DMatrixSparseCSC A , DMatrixSparseCSC B , DMatrixSparseCSC C , @ Nullable IGrowArray gw , @ Nullable DGrowArray gx ) { double [ ] x = adjust ( gx , A . numRows ) ; int [ ] w = adjust ( gw , A . numRows , A . numRows ) ; C . growMaxLength ( A . nz_length + B . nz_length , false ) ; C . indicesSorted = false ; C . nz_length = 0 ; int idx0 = B . col_idx [ 0 ] ; for ( int bj = 1 ; bj <= B . numCols ; bj ++ ) { int colB = bj - 1 ; int idx1 = B . col_idx [ bj ] ; C . col_idx [ bj ] = C . nz_length ; if ( idx0 == idx1 ) { continue ; } for ( int bi = idx0 ; bi < idx1 ; bi ++ ) { int rowB = B . nz_rows [ bi ] ; double valB = B . nz_values [ bi ] ; multAddColA ( A , rowB , valB , C , colB + 1 , x , w ) ; } int idxC0 = C . col_idx [ colB ] ; int idxC1 = C . col_idx [ colB + 1 ] ; for ( int i = idxC0 ; i < idxC1 ; i ++ ) { C . nz_values [ i ] = x [ C . nz_rows [ i ] ] ; } idx0 = idx1 ; } }
Performs matrix multiplication.  C = A*B

@param A Matrix
@param B Matrix
@param C Storage for results.  Data length is increased if increased if insufficient.
@param gw (Optional) Storage for internal workspace.  Can be null.
@param gx (Optional) Storage for internal workspace.  Can be null.