functional.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 1,668 行 · 第 1/5 页

HPP
1,668
字号
                    t += data1 [i1] * data2 [i2];            }            return t;#else            return boost::numeric::bindings::atlas::dot (e1 (), e2 ());#endif        }        template<class E1, class E2>        static BOOST_UBLAS_INLINE        result_type apply (const vector_expression<E1> &e1,                                 const vector_expression<E2> &e2,                                 abstract_tag) {            size_type size (BOOST_UBLAS_SAME (e1 ().size (), e2 ().size ()));            result_type t = result_type (0);#ifndef BOOST_UBLAS_USE_DUFF_DEVICE            for (size_type i = 0; i < size; ++ i)                t += e1 () (i) * e2 () (i);#else            size_type i (0);            DD (size, 4, r, (t += e1 () (i) * e2 () (i), ++ i));#endif            return t;        }        template<class E1, class E2>        static BOOST_UBLAS_INLINE        result_type apply (const vector_expression<E1> &e1,                                 const vector_expression<E2> &e2) {#ifdef BOOST_UBLAS_USE_SIMD            typedef typename boost::mpl::if_<                boost::mpl::and_<boost::is_same<typename E1::simd_category, concrete_tag>,                                 boost::is_same<typename E2::simd_category, concrete_tag> >,                    concrete_tag,                    abstract_tag>::type simd_category;#else            typedef abstract_tag simd_category;#endif            return apply (e1, e2, simd_category ());        }        // 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.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) {            result_type t = result_type (0);            if (it1 != it1_end && it2 != it2_end) {                size_type it1_index = it1.index (), 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.index ();                            it2_index = it2.index ();                        } 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.index ();                        else                            break;                    }                }            }            return t;        }    };    // Matrix functors    // Binary returning vector    template<class T1, class T2, class TR>    struct matrix_vector_binary_functor {        typedef std::size_t size_type;        typedef std::ptrdiff_t difference_type;        typedef TR value_type;        typedef TR result_type;    };    template<class T1, class T2, class TR>    struct matrix_vector_prod1:        public matrix_vector_binary_functor<T1, T2, TR> {        typedef typename matrix_vector_binary_functor<T1, T2, TR>::size_type size_type;        typedef typename matrix_vector_binary_functor<T1, T2, TR>::difference_type difference_type;        typedef typename matrix_vector_binary_functor<T1, T2, TR>::value_type value_type;        typedef typename matrix_vector_binary_functor<T1, T2, TR>::result_type result_type;        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, concrete_tag) {#ifndef BOOST_UBLAS_HAVE_BINDINGS            using namespace raw;            size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ());            const T1 *data1 = data_const (e1 ()) + i * stride1 (e1 ());            const T2 *data2 = data_const (e2 ());            size_type s1 = stride2 (e1 ());            size_type s2 = stride (e2 ());            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;#else            return boost::numeric::bindings::atlas::dot (e1 ().row (i), e2 ());#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, abstract_tag) {            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;        }        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) {#ifdef BOOST_UBLAS_USE_SIMD            typedef typename boost::mpl::if_<                boost::mpl::and_<boost::is_same<typename E1::simd_category, concrete_tag>,                                 boost::is_same<typename E2::simd_category, concrete_tag> >,                    concrete_tag,                    abstract_tag>::type simd_category;#else            typedef abstract_tag simd_category;#endif            return apply (e1, e2, i, simd_category ());        }        // 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 T1, class T2, class TR>    struct matrix_vector_prod2:        public matrix_vector_binary_functor<T1, T2, TR> {        typedef typename matrix_vector_binary_functor<T1, T2, TR>::size_type size_type;        typedef typename matrix_vector_binary_functor<T1, T2, TR>::difference_type difference_type;        typedef typename matrix_vector_binary_functor<T1, T2, TR>::value_type value_type;        typedef typename matrix_vector_binary_functor<T1, T2, TR>::result_type result_type;        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, concrete_tag) {#ifndef BOOST_UBLAS_HAVE_BINDINGS            using namespace raw;            size_type size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ());            const T1 *data1 = data_const (e1 ());            const T2 *data2 = data_const (e2 ()) + i * stride2 (e2 ());            size_type s1 = stride (e1 ());            size_type s2 = stride1 (e2 ());            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)

⌨️ 快捷键说明

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