inline void smat_smat_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign, 
			   tag::col_major,  // orientation a 
			   tag::row_major)  // orientation b
{
    if (Assign::init_to_zero) set_to_zero(c);
    
    // Average numbers of non-zeros per row
    double ava= double(a.nnz()) / num_rows(a), avb= double(b.nnz()) / num_rows(b); 

    // Define Updater type corresponding to assign mode
    typedef typename Collection<MatrixC>::value_type                            c_value_type;
    typedef typename operations::update_assign_mode<Assign, c_value_type>::type Updater;

    // Reserve 20% over the average's product for entries in c
    matrix::inserter<MatrixC, Updater>     ins(c, int( ava * avb * 1.2 ));

    typename traits::row<MatrixA>::type             row_a(a); 
    typename traits::col<MatrixA>::type             col_a(a); 
    typename traits::const_value<MatrixA>::type     value_a(a); 

    typename traits::row<MatrixB>::type             row_b(b); 
    typename traits::col<MatrixB>::type             col_b(b); 
    typename traits::const_value<MatrixB>::type     value_b(b); 

    typedef typename traits::range_generator<tag::col, MatrixA>::type  a_cursor_type;
    a_cursor_type a_cursor = begin<tag::col>(a), a_cend = end<tag::col>(a); 

    typedef typename traits::range_generator<tag::row, MatrixB>::type  b_cursor_type;
    b_cursor_type b_cursor = begin<tag::row>(b);

    for (unsigned ca= 0; a_cursor != a_cend; ++ca, ++a_cursor, ++b_cursor) {

	// Iterate over non-zeros of A's column
	typedef typename traits::range_generator<tag::nz, a_cursor_type>::type ia_cursor_type;
	for (ia_cursor_type ia_cursor = begin<tag::nz>(a_cursor), ia_cend = end<tag::nz>(a_cursor); 
	     ia_cursor != ia_cend; ++ia_cursor) 
        {
	    typename Collection<MatrixA>::size_type     ra= row_a(*ia_cursor);   // row of non-zero
	    typename Collection<MatrixA>::value_type    va= value_a(*ia_cursor); // value of non-zero

	    // Iterate over non-zeros of B's row 
	    typedef typename traits::range_generator<tag::nz, b_cursor_type>::type ib_cursor_type;
	    for (ib_cursor_type ib_cursor = begin<tag::nz>(b_cursor), ib_cend = end<tag::nz>(b_cursor); 
		 ib_cursor != ib_cend; ++ib_cursor) 
            {
		typename Collection<MatrixB>::size_type     cb= col_b(*ib_cursor);   // column of non-zero
		typename Collection<MatrixB>::value_type    vb= value_b(*ib_cursor); // value of non-zero
		ins(ra, cb) << va * vb;		
	    }
	}
    }
}
Ejemplo n.º 2
0
inline void smat_smat_mult(const MatrixA& A, const MatrixB& B, MatrixC& C, Assign, 
			   tag::col_major,  // orientation A 
			   tag::row_major)  // orientation B
{
    if (Assign::init_to_zero) set_to_zero(C);
    
    // Average numbers of non-zeros per row
    double ava= double(A.nnz()) / num_rows(A), avb= double(B.nnz()) / num_rows(B); 

    // Define Updater type corresponding to assign mode
    typedef typename Collection<MatrixC>::value_type                            C_value_type;
    typedef typename operations::update_assign_mode<Assign, C_value_type>::type Updater;

    // Reserve 20% over the average's product for entries in C
    matrix::inserter<MatrixC, Updater>     ins(C, int( ava * avb * 1.2 ));

    typename traits::row<MatrixA>::type             row_A(A); 
    typename traits::col<MatrixA>::type             col_A(A); 
    typename traits::const_value<MatrixA>::type     value_A(A); 

    typename traits::row<MatrixB>::type             row_B(B); 
    typename traits::col<MatrixB>::type             col_B(B); 
    typename traits::const_value<MatrixB>::type     value_B(B); 

    typedef typename traits::range_generator<tag::col, MatrixA>::type  A_cursor_type;
    A_cursor_type A_cursor = begin<tag::col>(A), A_cend = end<tag::col>(A); 

    typedef typename traits::range_generator<tag::row, MatrixB>::type  B_cursor_type;
    B_cursor_type B_cursor = begin<tag::row>(B);

    for (unsigned ca= 0; A_cursor != A_cend; ++ca, ++A_cursor, ++B_cursor) {

	// Iterate over non-zeros of A's column
	typedef typename traits::range_generator<tag::nz, A_cursor_type>::type ia_cursor_type;
	for (ia_cursor_type ia_cursor = begin<tag::nz>(A_cursor), ia_cend = end<tag::nz>(A_cursor); 
	     ia_cursor != ia_cend; ++ia_cursor) 
        {
	    typename Collection<MatrixA>::size_type     ra= row_A(*ia_cursor);   // row of non-zero
	    typename Collection<MatrixA>::value_type    va= value_A(*ia_cursor); // value of non-zero

	    // Iterate over non-zeros of B's row 
	    typedef typename traits::range_generator<tag::nz, B_cursor_type>::type ib_cursor_type;
	    for (ib_cursor_type ib_cursor = begin<tag::nz>(B_cursor), ib_cend = end<tag::nz>(B_cursor); 
		 ib_cursor != ib_cend; ++ib_cursor) 
            {
		typename Collection<MatrixB>::size_type     cb= col_B(*ib_cursor);   // column of non-zero
		typename Collection<MatrixB>::value_type    vb= value_B(*ib_cursor); // value of non-zero
		ins(ra, cb) << va * vb;		
	    }
	}
    }
}
Ejemplo n.º 3
0
inline void smat_smat_mult(const MatrixA& A, const MatrixB& B, MatrixC& C, Assign, 
			   tag::row_major,  // orientation A 
			   tag::row_major)  // orientation B
{
    if (Assign::init_to_zero) set_to_zero(C);
    
    // Average numbers of non-zeros per row
    double ava= num_cols(A) ? double(A.nnz()) / num_cols(A) : 0, 
	   avb= num_rows(B) ? double(B.nnz()) / num_rows(B) : 0; 

    // Define Updater type corresponding to assign mode
    typedef typename Collection<MatrixC>::value_type                            C_value_type;
    typedef typename operations::update_assign_mode<Assign, C_value_type>::type Updater;

    // Reserve 20% over the average's product for entries in C
    matrix::inserter<MatrixC, Updater>     ins(C, int( ava * avb * 1.4 ));

    typename traits::row<MatrixA>::type             row_A(A); 
    typename traits::col<MatrixA>::type             col_A(A); 
    typename traits::const_value<MatrixA>::type     value_A(A); 

    typename traits::col<MatrixB>::type             col_B(B); 
    typename traits::const_value<MatrixB>::type     value_B(B); 

    typedef typename traits::range_generator<tag::row, MatrixA>::type  cursor_type;
    cursor_type cursor = begin<tag::row>(A), cend = end<tag::row>(A); 
    for (unsigned ra= 0; cursor != cend; ++ra, ++cursor) {
	// Iterate over non-zeros of each row of A
	typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type;
	for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) {
	    typename Collection<MatrixA>::size_type     ca= col_A(*icursor);   // column of non-zero
	    typename Collection<MatrixA>::value_type    va= value_A(*icursor); // value of non-zero
 
	    // Get cursor corresponding to row 'ca' in matrix B
	    typedef typename traits::range_generator<tag::row, MatrixB>::type  B_cursor_type;
	    B_cursor_type B_cursor = begin<tag::row>(B);
	    B_cursor+= ca;

	    // Iterate over non-zeros of this row 
	    typedef typename traits::range_generator<tag::nz, B_cursor_type>::type ib_cursor_type;
	    for (ib_cursor_type ib_cursor = begin<tag::nz>(B_cursor), ib_cend = end<tag::nz>(B_cursor); 
		 ib_cursor != ib_cend; ++ib_cursor) {
		typename Collection<MatrixB>::size_type     cb= col_B(*ib_cursor);   // column of non-zero
		typename Collection<MatrixB>::value_type    vb= value_B(*ib_cursor); // value of non-zero
		ins(ra, cb) << va * vb;		
	    }
	}
    }
}