x
Yes
No
Do you want to visit DriveHQ English website?
首页
产品服务
价格
免费试用
下载客户端
关于我们
云文件服务
|
云备份服务
|
FTP服务
|
企业邮箱服务
|
网站托管
|
客户端软件
云文件服务
云备份服务
FTP服务
企业级邮箱服务
网站托管
客户端软件
functional.hpp - Hosted on DriveHQ Cloud IT Platform
返回上层目录
上传
下载
共享
发布
新建文件夹
新建文件
复制
剪切
删除
粘贴
评论
升级服务
路径: \\game3dprogramming\materials\GameFactory\GameFactoryDemo\references\boost_1_35_0\boost\numeric\ublas\functional.hpp
旋转
特效
属性
历史版本
// // Copyright (c) 2000-2002 // Joerg Walter, Mathias Koch // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // The authors gratefully acknowledge the support of // GeNeSys mbH & Co. KG in producing this work. // #ifndef _BOOST_UBLAS_FUNCTIONAL_ #define _BOOST_UBLAS_FUNCTIONAL_ #include
#include
#ifdef BOOST_UBLAS_USE_DUFF_DEVICE #include
#endif #ifdef BOOST_UBLAS_USE_SIMD #include
#else namespace boost { namespace numeric { namespace ublas { namespace raw { }}}} #endif #ifdef BOOST_UBLAS_HAVE_BINDINGS #include
#include
#include
#include
#endif #include
namespace boost { namespace numeric { namespace ublas { // Scalar functors // Unary template
struct scalar_unary_functor { typedef T value_type; typedef typename type_traits
::const_reference argument_type; typedef typename type_traits
::value_type result_type; }; template
struct scalar_identity: public scalar_unary_functor
{ typedef typename scalar_unary_functor
::argument_type argument_type; typedef typename scalar_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return t; } }; template
struct scalar_negate: public scalar_unary_functor
{ typedef typename scalar_unary_functor
::argument_type argument_type; typedef typename scalar_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return - t; } }; template
struct scalar_conj: public scalar_unary_functor
{ typedef typename scalar_unary_functor
::value_type value_type; typedef typename scalar_unary_functor
::argument_type argument_type; typedef typename scalar_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return type_traits
::conj (t); } }; // Unary returning real template
struct scalar_real_unary_functor { typedef T value_type; typedef typename type_traits
::const_reference argument_type; typedef typename type_traits
::real_type result_type; }; template
struct scalar_real: public scalar_real_unary_functor
{ typedef typename scalar_real_unary_functor
::value_type value_type; typedef typename scalar_real_unary_functor
::argument_type argument_type; typedef typename scalar_real_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return type_traits
::real (t); } }; template
struct scalar_imag: public scalar_real_unary_functor
{ typedef typename scalar_real_unary_functor
::value_type value_type; typedef typename scalar_real_unary_functor
::argument_type argument_type; typedef typename scalar_real_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return type_traits
::imag (t); } }; // Binary template
struct scalar_binary_functor { typedef typename type_traits
::const_reference argument1_type; typedef typename type_traits
::const_reference argument2_type; typedef typename promote_traits
::promote_type result_type; }; template
struct scalar_plus: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 + t2; } }; template
struct scalar_minus: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 - t2; } }; template
struct scalar_multiplies: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 * t2; } }; template
struct scalar_divides: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 / t2; } }; template
struct scalar_binary_assign_functor { // ISSUE Remove reference to avoid reference to reference problems typedef typename type_traits
::type>::reference argument1_type; typedef typename type_traits
::const_reference argument2_type; }; struct assign_tag {}; struct computed_assign_tag {}; template
struct scalar_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) static const bool computed ; #else static const bool computed = false ; #endif static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 = t2; } template
struct rebind { typedef scalar_assign
other; }; }; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) template
const bool scalar_assign
::computed = false; #endif template
struct scalar_plus_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) static const bool computed ; #else static const bool computed = true ; #endif static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 += t2; } template
struct rebind { typedef scalar_plus_assign
other; }; }; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) template
const bool scalar_plus_assign
::computed = true; #endif template
struct scalar_minus_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) static const bool computed ; #else static const bool computed = true ; #endif static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 -= t2; } template
struct rebind { typedef scalar_minus_assign
other; }; }; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) template
const bool scalar_minus_assign
::computed = true; #endif template
struct scalar_multiplies_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; static const bool computed = true; static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 *= t2; } template
struct rebind { typedef scalar_multiplies_assign
other; }; }; template
struct scalar_divides_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; static const bool computed ; static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 /= t2; } template
struct rebind { typedef scalar_divides_assign
other; }; }; template
const bool scalar_divides_assign
::computed = true; template
struct scalar_binary_swap_functor { typedef typename type_traits
::type>::reference argument1_type; typedef typename type_traits
::type>::reference argument2_type; }; template
struct scalar_swap: public scalar_binary_swap_functor
{ typedef typename scalar_binary_swap_functor
::argument1_type argument1_type; typedef typename scalar_binary_swap_functor
::argument2_type argument2_type; static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { std::swap (t1, t2); } template
struct rebind { typedef scalar_swap
other; }; }; // Vector functors // Unary returning scalar template
struct vector_scalar_unary_functor { typedef typename V::value_type value_type; typedef typename V::value_type result_type; }; template
struct vector_sum: public vector_scalar_unary_functor
{ typedef typename vector_scalar_unary_functor
::value_type value_type; typedef typename vector_scalar_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { result_type t = result_type (0); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) t += e () (i); return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { result_type t = result_type (0); while (-- size >= 0) t += *it, ++ it; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { result_type t = result_type (0); while (it != it_end) t += *it, ++ it; return t; } }; // Unary returning real scalar template
struct vector_scalar_real_unary_functor { typedef typename V::value_type value_type; typedef typename type_traits
::real_type real_type; typedef real_type result_type; }; template
struct vector_norm_1: public vector_scalar_real_unary_functor
{ typedef typename vector_scalar_real_unary_functor
::value_type value_type; typedef typename vector_scalar_real_unary_functor
::real_type real_type; typedef typename vector_scalar_real_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::type_abs (e () (i))); t += u; } return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_1 (*it)); t += u; ++ it; } return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_1 (*it)); t += u; ++ it; } return t; } }; template
struct vector_norm_2: public vector_scalar_real_unary_functor
{ typedef typename vector_scalar_real_unary_functor
::value_type value_type; typedef typename vector_scalar_real_unary_functor
::real_type real_type; typedef typename vector_scalar_real_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_2 (e () (i))); t += u * u; } return type_traits
::type_sqrt (t); #else real_type scale = real_type (); real_type sum_squares (1); size_type size (e ().size ()); for (size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_2 (e () (i))); if (scale < u) { real_type v (scale / u); sum_squares = sum_squares * v * v + real_type (1); scale = u; } else { real_type v (u / scale); sum_squares += v * v; } } return scale * type_traits
::type_sqrt (sum_squares); #endif } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_2 (*it)); t += u * u; ++ it; } return type_traits
::type_sqrt (t); #else real_type scale = real_type (); real_type sum_squares (1); while (-- size >= 0) { real_type u (type_traits
::norm_2 (*it)); if (scale < u) { real_type v (scale / u); sum_squares = sum_squares * v * v + real_type (1); scale = u; } else { real_type v (u / scale); sum_squares += v * v; } ++ it; } return scale * type_traits
::type_sqrt (sum_squares); #endif } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_2 (*it)); t += u * u; ++ it; } return type_traits
::type_sqrt (t); #else real_type scale = real_type (); real_type sum_squares (1); while (it != it_end) { real_type u (type_traits
::norm_2 (*it)); if (scale < u) { real_type v (scale / u); sum_squares = sum_squares * v * v + real_type (1); scale = u; } else { real_type v (u / scale); sum_squares += v * v; } ++ it; } return scale * type_traits
::type_sqrt (sum_squares); #endif } }; template
struct vector_norm_inf: public vector_scalar_real_unary_functor
{ typedef typename vector_scalar_real_unary_functor
::value_type value_type; typedef typename vector_scalar_real_unary_functor
::real_type real_type; typedef typename vector_scalar_real_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_inf (e () (i))); if (u > t) t = u; } return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_inf (*it)); if (u > t) t = u; ++ it; } return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_inf (*it)); if (u > t) t = u; ++ it; } return t; } }; // Unary returning index template
struct vector_scalar_index_unary_functor { typedef typename V::value_type value_type; typedef typename type_traits
::real_type real_type; typedef typename V::size_type result_type; }; template
struct vector_index_norm_inf: public vector_scalar_index_unary_functor
{ typedef typename vector_scalar_index_unary_functor
::value_type value_type; typedef typename vector_scalar_index_unary_functor
::real_type real_type; typedef typename vector_scalar_index_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_inf (e () (i))); if (u > t) { i_norm_inf = i; t = u; } } return i_norm_inf; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_inf (*it)); if (u > t) { i_norm_inf = it.index (); t = u; } ++ it; } return i_norm_inf; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_inf (*it)); if (u > t) { i_norm_inf = it.index (); t = u; } ++ it; } return i_norm_inf; } }; // Binary returning scalar template
struct vector_scalar_binary_functor { typedef TV value_type; typedef TV result_type; }; template
struct vector_inner_prod: public vector_scalar_binary_functor
{ typedef typename vector_scalar_binary_functor
::value_type value_type; typedef typename vector_scalar_binary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_container
&c1, const vector_container
&c2) { #ifdef BOOST_UBLAS_USE_SIMD using namespace raw; typedef typename C1::size_type vector_size_type; vector_size_type size (BOOST_UBLAS_SAME (c1 ().size (), c2 ().size ())); const typename V1::value_type *data1 = data_const (c1 ()); const typename V1::value_type *data2 = data_const (c2 ()); vector_size_type s1 = stride (c1 ()); vector_size_type s2 = stride (c2 ()); result_type t = result_type (0); if (s1 == 1 && s2 == 1) { for (vector_size_type i = 0; i < size; ++ i) t += data1 [i] * data2 [i]; } else if (s2 == 1) { for (vector_size_type i = 0, i1 = 0; i < size; ++ i, i1 += s1) t += data1 [i1] * data2 [i]; } else if (s1 == 1) { for (vector_size_type i = 0, i2 = 0; i < size; ++ i, i2 += s2) t += data1 [i] * data2 [i2]; } else { for (vector_size_type i = 0, i1 = 0, i2 = 0; i < size; ++ i, i1 += s1, i2 += s2) t += data1 [i1] * data2 [i2]; } return t; #elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 (), c2 ()); #else return apply (static_cast
> (c1), static_cast
> (c2)); #endif } template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e1, const vector_expression
&e2) { typedef typename E1::size_type vector_size_type; vector_size_type size (BOOST_UBLAS_SAME (e1 ().size (), e2 ().size ())); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (vector_size_type i = 0; i < size; ++ i) t += e1 () (i) * e2 () (i); #else vector_size_type i (0); DD (size, 4, r, (t += e1 () (i) * e2 () (i), ++ i)); #endif return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; #else DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2)); #endif return t; } // Packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); typedef typename I1::difference_type vector_difference_type; vector_difference_type it1_size (it1_end - it1); vector_difference_type it2_size (it2_end - it2); vector_difference_type diff (0); if (it1_size > 0 && it2_size > 0) diff = it2.index () - it1.index (); if (diff != 0) { vector_difference_type size = (std::min) (diff, it1_size); if (size > 0) { it1 += size; it1_size -= size; diff -= size; } size = (std::min) (- diff, it2_size); if (size > 0) { it2 += size; it2_size -= size; diff += size; } } vector_difference_type size ((std::min) (it1_size, it2_size)); while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { while (true) { if (it1.index () == it2.index ()) { t += *it1 * *it2, ++ it1, ++ it2; if (it1 == it1_end || it2 == it2_end) break; } else if (it1.index () < it2.index ()) { increment (it1, it1_end, it2.index () - it1.index ()); if (it1 == it1_end) break; } else if (it1.index () > it2.index ()) { increment (it2, it2_end, it1.index () - it2.index ()); if (it2 == it2_end) break; } } } return t; } }; // Matrix functors // Binary returning vector template
struct matrix_vector_binary_functor { typedef typename M1::size_type size_type; typedef typename M1::difference_type difference_type; typedef TV value_type; typedef TV result_type; }; template
struct matrix_vector_prod1: public matrix_vector_binary_functor
{ typedef typename matrix_vector_binary_functor
::size_type size_type; typedef typename matrix_vector_binary_functor
::difference_type difference_type; typedef typename matrix_vector_binary_functor
::value_type value_type; typedef typename matrix_vector_binary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const matrix_container
&c1, const vector_container
&c2, size_type i) { #ifdef BOOST_UBLAS_USE_SIMD using namespace raw; size_type size = BOOST_UBLAS_SAME (c1 ().size2 (), c2 ().size ()); const typename M1::value_type *data1 = data_const (c1 ()) + i * stride1 (c1 ()); const typename M2::value_type *data2 = data_const (c2 ()); size_type s1 = stride2 (c1 ()); size_type s2 = stride (c2 ()); result_type t = result_type (0); if (s1 == 1 && s2 == 1) { for (size_type j = 0; j < size; ++ j) t += data1 [j] * data2 [j]; } else if (s2 == 1) { for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1) t += data1 [j1] * data2 [j]; } else if (s1 == 1) { for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2) t += data1 [j] * data2 [j2]; } else { for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2) t += data1 [j1] * data2 [j2]; } return t; #elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 ().row (i), c2 ()); #else return apply (static_cast
> (c1), static_cast
> (c2, i)); #endif } template
static BOOST_UBLAS_INLINE result_type apply (const matrix_expression
&e1, const vector_expression
&e2, size_type i) { size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ()); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type j = 0; j < size; ++ j) t += e1 () (i, j) * e2 () (j); #else size_type j (0); DD (size, 4, r, (t += e1 () (i, j) * e2 () (j), ++ j)); #endif return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; #else DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2)); #endif return t; } // Packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); difference_type diff (0); if (it1_size > 0 && it2_size > 0) diff = it2.index () - it1.index2 (); if (diff != 0) { difference_type size = (std::min) (diff, it1_size); if (size > 0) { it1 += size; it1_size -= size; diff -= size; } size = (std::min) (- diff, it2_size); if (size > 0) { it2 += size; it2_size -= size; diff += size; } } difference_type size ((std::min) (it1_size, it2_size)); while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index2 (), it2_index = it2.index (); while (true) { difference_type compare = it1_index - it2_index; if (compare == 0) { t += *it1 * *it2, ++ it1, ++ it2; if (it1 != it1_end && it2 != it2_end) { it1_index = it1.index2 (); it2_index = it2.index (); } else break; } else if (compare < 0) { increment (it1, it1_end, - compare); if (it1 != it1_end) it1_index = it1.index2 (); else break; } else if (compare > 0) { increment (it2, it2_end, compare); if (it2 != it2_end) it2_index = it2.index (); else break; } } } return t; } // Sparse packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) { result_type t = result_type (0); while (it1 != it1_end) { t += *it1 * it2 () (it1.index2 ()); ++ it1; } return t; } // Packed sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); while (it2 != it2_end) { t += it1 () (it1.index1 (), it2.index ()) * *it2; ++ it2; } return t; } // Another dispatcher template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { typedef typename I1::iterator_category iterator1_category; typedef typename I2::iterator_category iterator2_category; return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); } }; template
struct matrix_vector_prod2: public matrix_vector_binary_functor
{ typedef typename matrix_vector_binary_functor
::size_type size_type; typedef typename matrix_vector_binary_functor
::difference_type difference_type; typedef typename matrix_vector_binary_functor
::value_type value_type; typedef typename matrix_vector_binary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_container
&c1, const matrix_container
&c2, size_type i) { #ifdef BOOST_UBLAS_USE_SIMD using namespace raw; size_type size = BOOST_UBLAS_SAME (c1 ().size (), c2 ().size1 ()); const typename M1::value_type *data1 = data_const (c1 ()); const typename M2::value_type *data2 = data_const (c2 ()) + i * stride2 (c2 ()); size_type s1 = stride (c1 ()); size_type s2 = stride1 (c2 ()); result_type t = result_type (0); if (s1 == 1 && s2 == 1) { for (size_type j = 0; j < size; ++ j) t += data1 [j] * data2 [j]; } else if (s2 == 1) { for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1) t += data1 [j1] * data2 [j]; } else if (s1 == 1) { for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2) t += data1 [j] * data2 [j2]; } else { for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2) t += data1 [j1] * data2 [j2]; } return t; #elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 (), c2 ().column (i)); #else return apply (static_cast
> (c1), static_cast
> (c2, i)); #endif } template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e1, const matrix_expression
&e2, size_type i) { size_type size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ()); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type j = 0; j < size; ++ j) t += e1 () (j) * e2 () (j, i); #else size_type j (0); DD (size, 4, r, (t += e1 () (j) * e2 () (j, i), ++ j)); #endif return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; #else DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2)); #endif return t; } // Packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); difference_type diff (0); if (it1_size > 0 && it2_size > 0) diff = it2.index1 () - it1.index (); if (diff != 0) { difference_type size = (std::min) (diff, it1_size); if (size > 0) { it1 += size; it1_size -= size; diff -= size; } size = (std::min) (- diff, it2_size); if (size > 0) { it2 += size; it2_size -= size; diff += size; } } difference_type size ((std::min) (it1_size, it2_size)); while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index (), it2_index = it2.index1 (); while (true) { difference_type compare = it1_index - it2_index; if (compare == 0) { t += *it1 * *it2, ++ it1, ++ it2; if (it1 != it1_end && it2 != it2_end) { it1_index = it1.index (); it2_index = it2.index1 (); } else break; } else if (compare < 0) { increment (it1, it1_end, - compare); if (it1 != it1_end) it1_index = it1.index (); else break; } else if (compare > 0) { increment (it2, it2_end, compare); if (it2 != it2_end) it2_index = it2.index1 (); else break; } } } return t; } // Packed sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); while (it2 != it2_end) { t += it1 () (it2.index1 ()) * *it2; ++ it2; } return t; } // Sparse packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) { result_type t = result_type (0); while (it1 != it1_end) { t += *it1 * it2 () (it1.index (), it2.index2 ()); ++ it1; } return t; } // Another dispatcher template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { typedef typename I1::iterator_category iterator1_category; typedef typename I2::iterator_category iterator2_category; return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); } }; // Binary returning matrix template
struct matrix_matrix_binary_functor { typedef typename M1::size_type size_type; typedef typename M1::difference_type difference_type; typedef TV value_type; typedef TV result_type; }; template
struct matrix_matrix_prod: public matrix_matrix_binary_functor
{ typedef typename matrix_matrix_binary_functor