functional.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,692 行 · 第 1/5 页
HPP
1,692 行
#elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 (), c2 ());#else return apply (static_cast<const vector_expression<C1> > (c1), static_cast<const vector_expression<C2> > (c2));#endif } template<class E1, class E2> static BOOST_UBLAS_INLINE result_type apply (const vector_expression<E1> &e1, const vector_expression<E2> &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<class D, class I1, class I2> 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<class I1, class I2> 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<class I1, class I2> 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<class M1, class M2, class TV> 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<class M1, class M2, class TV> struct matrix_vector_prod1: public matrix_vector_binary_functor<M1, M2, TV> { typedef typename matrix_vector_binary_functor<M1, M2, TV>::size_type size_type; typedef typename matrix_vector_binary_functor<M1, M2, TV>::difference_type difference_type; typedef typename matrix_vector_binary_functor<M1, M2, TV>::value_type value_type; typedef typename matrix_vector_binary_functor<M1, M2, TV>::result_type result_type; template<class C1, class C2> static BOOST_UBLAS_INLINE result_type apply (const matrix_container<C1> &c1, const vector_container<C2> &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<const matrix_expression<C1> > (c1), static_cast<const vector_expression<C2> > (c2, i));#endif } template<class E1, class E2> static BOOST_UBLAS_INLINE result_type apply (const matrix_expression<E1> &e1, const vector_expression<E2> &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<class I1, class I2> 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<class I1, class I2> 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<class I1, class I2> 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<class I1, class I2> 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<class I1, class I2> 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<class I1, class I2> 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<class M1, class M2, class TV> struct matrix_vector_prod2: public matrix_vector_binary_functor<M1, M2, TV> { typedef typename matrix_vector_binary_functor<M1, M2, TV>::size_type size_type; typedef typename matrix_vector_binary_functor<M1, M2, TV>::difference_type difference_type; typedef typename matrix_vector_binary_functor<M1, M2, TV>::value_type value_type; typedef typename matrix_vector_binary_functor<M1, M2, TV>::result_type result_type; template<class C1, class C2> static BOOST_UBLAS_INLINE result_type apply (const vector_container<C1> &c1, const matrix_container<C2> &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<const vector_expression<C1> > (c1), static_cast<const matrix_expression<C2> > (c2, i));#endif } template<class E1, class E2> static BOOST_UBLAS_INLINE result_type apply (const vector_expression<E1> &e1, const matrix_expression<E2> &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<class I1, class I2> 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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?