smat_smat_mult.hpp

来自「矩阵运算源码最新版本」· HPP 代码 · 共 191 行

HPP
191
字号
// Software License for MTL// // Copyright (c) 2007 The Trustees of Indiana University. All rights reserved.// Authors: Peter Gottschling and Andrew Lumsdaine// // This file is part of the Matrix Template Library// // See also license.mtl.txt in the distribution.#ifndef MTL_SMAT_SMAT_MULT_INCLUDE#define MTL_SMAT_SMAT_MULT_INCLUDE#include <boost/numeric/mtl/mtl_fwd.hpp>#include <boost/numeric/mtl/matrix/compressed2D.hpp>#include <boost/numeric/mtl/matrix/parameter.hpp>#include <boost/numeric/mtl/utility/tag.hpp>#include <boost/numeric/mtl/operation/mult_assign_mode.hpp>namespace mtl {template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>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= 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::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;			    }	}    }}template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>inline void smat_smat_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign, 			   tag::col_major,  // orientation a 			   tag::col_major)  // orientation b{    if (Assign::init_to_zero) set_to_zero(c);        // Average numbers of non-zeros per column    double ava= double(a.nnz()) / num_cols(a), avb= double(b.nnz()) / num_cols(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, MatrixB>::type  cursor_type;    cursor_type cursor = begin<tag::col>(b), cend = end<tag::col>(b);     for (unsigned cb= 0; cursor != cend; ++cb, ++cursor) {	// Iterate over non-zeros of each column of B	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<MatrixB>::size_type     rb= row_b(*icursor);   // row of non-zero	    typename Collection<MatrixB>::value_type    vb= value_b(*icursor); // value of non-zero 	    // Get cursor corresponding to column 'rb' in matrix A	    typedef typename traits::range_generator<tag::col, MatrixA>::type  a_cursor_type;	    a_cursor_type a_cursor = begin<tag::col>(a);	    a_cursor+= rb;	    // Iterate over non-zeros of this 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		ins(ra, cb) << va * vb;			    }	}    }}template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>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;			    }	}    }}template <typename MatrixA, typename MatrixB, typename MatrixC, typename Assign>inline void smat_smat_mult(const MatrixA& a, const MatrixB& b, MatrixC& c, Assign, 			   tag::row_major,  // orientation a 			   tag::col_major)  // orientation b{    // Copy B into a row-major matrix    compressed2D<typename Collection<MatrixB>::value_type, matrix::parameters<> > b_copy(b);    smat_smat_mult(a, b_copy, c, Assign(), tag::row_major(), tag::row_major());}} // namespace mtl#endif // MTL_SMAT_SMAT_MULT_INCLUDE

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?