functional.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,692 行 · 第 1/5 页
HPP
1,692 行
} // 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.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<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.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<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 () (it2.index1 ()) * *it2; ++ it2; } 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.index (), it2.index2 ()); ++ it1; } 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 ()); } }; // Binary returning matrix template<class M1, class M2, class TV> 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<class M1, class M2, class TV> struct matrix_matrix_prod: public matrix_matrix_binary_functor<M1, M2, TV> { typedef typename matrix_matrix_binary_functor<M1, M2, TV>::size_type size_type; typedef typename matrix_matrix_binary_functor<M1, M2, TV>::difference_type difference_type; typedef typename matrix_matrix_binary_functor<M1, M2, TV>::value_type value_type; typedef typename matrix_matrix_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 matrix_container<C2> &c2, size_type i, size_type j) {#ifdef BOOST_UBLAS_USE_SIMD using namespace raw; size_type size = BOOST_UBLAS_SAME (c1 ().size2 (), c2 ().sizc1 ()); const typename M1::value_type *data1 = data_const (c1 ()) + i * stride1 (c1 ()); const typename M2::value_type *data2 = data_const (c2 ()) + j * stride2 (c2 ()); size_type s1 = stride2 (c1 ()); size_type s2 = stride1 (c2 ()); result_type t = result_type (0); if (s1 == 1 && s2 == 1) { for (size_type k = 0; k < size; ++ k) t += data1 [k] * data2 [k]; } else if (s2 == 1) { for (size_type k = 0, k1 = 0; k < size; ++ k, k1 += s1) t += data1 [k1] * data2 [k]; } else if (s1 == 1) { for (size_type k = 0, k2 = 0; k < size; ++ k, k2 += s2) t += data1 [k] * data2 [k2]; } else { for (size_type k = 0, k1 = 0, k2 = 0; k < size; ++ k, k1 += s1, k2 += s2) t += data1 [k1] * data2 [k2]; } return t;#elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 ().row (i), c2 ().column (j));#else return apply (static_cast<const matrix_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 matrix_expression<E1> &e1, const matrix_expression<E2> &e2, size_type i, size_type j) { size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ()); result_type t = result_type (0);#ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type k = 0; k < size; ++ k) t += e1 () (i, k) * e2 () (k, j);#else size_type k (0); DD (size, 4, r, (t += e1 () (i, k) * e2 () (k, j), ++ k));#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, packed_random_access_iterator_tag) { 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.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) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index2 (), it2_index = it2.index1 (); while (true) { difference_type compare = difference_type (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.index1 (); } 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.index1 (); else break; } } } return t; } }; // Unary returning scalar norm template<class M> struct matrix_scalar_real_unary_functor { typedef typename M::value_type value_type; typedef typename type_traits<value_type>::real_type real_type; typedef real_type result_type; }; template<class M> struct matrix_norm_1: public matrix_scalar_real_unary_functor<M> { typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type; typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type; typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type; template<class E> static BOOST_UBLAS_INLINE result_type apply (const matrix_expression<E> &e) { real_type t = real_type (); typedef typename E::size_type matrix_size_type; matrix_size_type size2 (e ().size2 ()); for (matrix_size_type j = 0; j < size2; ++ j) { real_type u = real_type (); matrix_size_type size1 (e ().size1 ()); for (matrix_size_type i = 0; i < size1; ++ i) { real_type v (type_traits<value_type>::norm_1 (e () (i, j))); u += v; } if (u > t) t = u; } return t; } }; template<class M> struct matrix_norm_frobenius: public matrix_scalar_real_unary_functor<M> { typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type; typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type; typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type; template<class E> static BOOST_UBLAS_INLINE result_type apply (const matrix_expression<E> &e) { real_type t = real_type (); typedef typename E::size_type matrix_size_type; matrix_size_type size1 (e ().size1 ()); for (matrix_size_type i = 0; i < size1; ++ i) { matrix_size_type size2 (e ().size2 ()); for (matrix_size_type j = 0; j < size2; ++ j) { real_type u (type_traits<value_type>::norm_2 (e () (i, j))); t += u * u; } } return type_traits<real_type>::type_sqrt (t); } }; template<class M> struct matrix_norm_inf: public matrix_scalar_real_unary_functor<M> { typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type; typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type; typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type; template<class E> static BOOST_UBLAS_INLINE result_type apply (const matrix_expression<E> &e) { real_type t = real_type (); typedef typename E::size_type matrix_size_type; matrix_size_type size1 (e ().size1 ()); for (matrix_size_type i = 0; i < size1; ++ i) { real_type u = real_type (); matrix_size_type size2 (e ().size2 ()); for (matrix_size_type j = 0; j < size2; ++ j) { real_type v (type_traits<value_type>::norm_inf (e () (i, j))); u += v; } if (u > t) t = u; } return t; } }; // This functor defines storage layout and it's properties // matrix (i,j) -> storage [i * size_i + j] template <class Z, class D> struct basic_row_major { typedef Z size_type; typedef D difference_type; typedef row_major_tag orientation_category; static BOOST_UBLAS_INLINE size_type storage_size (size_type size_i, size_type size_j) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?