matrix_assign.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,356 行 · 第 1/5 页

HPP
1,356
字号
    // Explicitly iterating column major    template<template <class T1, class T2> class F, class M, class E>    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {        typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;        typedef typename M::difference_type difference_type;        difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));        difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));        typename M::iterator2 it2 (m.begin2 ());        BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());        typename E::const_iterator2 it2e (e ().begin2 ());        BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());        while (-- size2 >= 0) {#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION            typename M::iterator1 it1 (it2.begin ());            typename E::const_iterator1 it1e (it2e.begin ());#else            typename M::iterator1 it1 (begin (it2, iterator2_tag ()));            typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));#endif            BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());            BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());            difference_type temp_size1 (size1);#ifndef BOOST_UBLAS_USE_DUFF_DEVICE            while (-- temp_size1 >= 0)                functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;#else            DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));#endif            ++ it2, ++ it2e;        }    }    // Explicitly indexing row major    template<template <class T1, class T2> class F, class M, class E>    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {        typedef F<typename M::reference, typename E::value_type> functor_type;        typedef typename M::size_type size_type;        size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));        size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));        for (size_type i = 0; i < size1; ++ i) {#ifndef BOOST_UBLAS_USE_DUFF_DEVICE            for (size_type j = 0; j < size2; ++ j)                functor_type::apply (m (i, j), e () (i, j));#else            size_type j (0);            DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));#endif        }    }    // Explicitly indexing column major    template<template <class T1, class T2> class F, class M, class E>    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {        typedef F<typename M::reference, typename E::value_type> functor_type;        typedef typename M::size_type size_type;        size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));        size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));        for (size_type j = 0; j < size2; ++ j) {#ifndef BOOST_UBLAS_USE_DUFF_DEVICE            for (size_type i = 0; i < size1; ++ i)                functor_type::apply (m (i, j), e () (i, j));#else            size_type i (0);            DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));#endif        }    }    // Dense (proxy) case    template<template <class T1, class T2> class F, class R, class M, class E, class C>    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {        // R unnecessary, make_conformant not required        typedef C orientation_category;#ifdef BOOST_UBLAS_USE_INDEXING        indexing_matrix_assign<F> (m, e, orientation_category ());#elif BOOST_UBLAS_USE_ITERATING        iterating_matrix_assign<F> (m, e, orientation_category ());#else        typedef typename M::difference_type difference_type;        size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));        size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));        if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&            size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)            iterating_matrix_assign<F> (m, e, orientation_category ());        else            indexing_matrix_assign<F> (m, e, orientation_category ());#endif    }    // Packed (proxy) row major case    template<template <class T1, class T2> class F, class R, class M, class E>    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {        typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;        // R unnecessary, make_conformant not required        typedef typename M::difference_type difference_type;        typedef typename M::value_type value_type;        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());#if BOOST_UBLAS_TYPE_CHECK        matrix<value_type, row_major> cm (m.size1 (), m.size2 ());        indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());        indexing_matrix_assign<F> (cm, e, row_major_tag ());#endif        typename M::iterator1 it1 (m.begin1 ());        typename M::iterator1 it1_end (m.end1 ());        typename E::const_iterator1 it1e (e ().begin1 ());        typename E::const_iterator1 it1e_end (e ().end1 ());        difference_type it1_size (it1_end - it1);        difference_type it1e_size (it1e_end - it1e);        difference_type diff1 (0);        if (it1_size > 0 && it1e_size > 0)            diff1 = it1.index1 () - it1e.index1 ();        if (diff1 != 0) {            difference_type size1 = (std::min) (diff1, it1e_size);            if (size1 > 0) {                it1e += size1;                it1e_size -= size1;                diff1 -= size1;            }            size1 = (std::min) (- diff1, it1_size);            if (size1 > 0) {                it1_size -= size1;                if (!functor_type::computed) {                    while (-- size1 >= 0) { // zeroing#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION                        typename M::iterator2 it2 (it1.begin ());                        typename M::iterator2 it2_end (it1.end ());#else                        typename M::iterator2 it2 (begin (it1, iterator1_tag ()));                        typename M::iterator2 it2_end (end (it1, iterator1_tag ()));#endif                        difference_type size2 (it2_end - it2);                        while (-- size2 >= 0)                            functor_type::apply (*it2, value_type/*zero*/()), ++ it2;                        ++ it1;                    }                } else {                    it1 += size1;                }                diff1 += size1;            }        }        difference_type size1 ((std::min) (it1_size, it1e_size));        it1_size -= size1;        it1e_size -= size1;        while (-- size1 >= 0) {#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION            typename M::iterator2 it2 (it1.begin ());            typename M::iterator2 it2_end (it1.end ());            typename E::const_iterator2 it2e (it1e.begin ());            typename E::const_iterator2 it2e_end (it1e.end ());#else            typename M::iterator2 it2 (begin (it1, iterator1_tag ()));            typename M::iterator2 it2_end (end (it1, iterator1_tag ()));            typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));            typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));#endif            difference_type it2_size (it2_end - it2);            difference_type it2e_size (it2e_end - it2e);            difference_type diff2 (0);            if (it2_size > 0 && it2e_size > 0) {                diff2 = it2.index2 () - it2e.index2 ();                difference_type size2 = (std::min) (diff2, it2e_size);                if (size2 > 0) {                    it2e += size2;                    it2e_size -= size2;                    diff2 -= size2;                }                size2 = (std::min) (- diff2, it2_size);                if (size2 > 0) {                    it2_size -= size2;                    if (!functor_type::computed) {                        while (-- size2 >= 0)   // zeroing                            functor_type::apply (*it2, value_type/*zero*/()), ++ it2;                    } else {                        it2 += size2;                    }                    diff2 += size2;                }            }            difference_type size2 ((std::min) (it2_size, it2e_size));            it2_size -= size2;            it2e_size -= size2;            while (-- size2 >= 0)                functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;            size2 = it2_size;            if (!functor_type::computed) {                while (-- size2 >= 0)   // zeroing                    functor_type::apply (*it2, value_type/*zero*/()), ++ it2;            } else {                it2 += size2;            }            ++ it1, ++ it1e;        }        size1 = it1_size;        if (!functor_type::computed) {            while (-- size1 >= 0) { // zeroing#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION                typename M::iterator2 it2 (it1.begin ());                typename M::iterator2 it2_end (it1.end ());#else                typename M::iterator2 it2 (begin (it1, iterator1_tag ()));                typename M::iterator2 it2_end (end (it1, iterator1_tag ()));#endif                difference_type size2 (it2_end - it2);                while (-- size2 >= 0)                    functor_type::apply (*it2, value_type/*zero*/()), ++ it2;                ++ it1;            }        } else {            it1 += size1;        }#if BOOST_UBLAS_TYPE_CHECK        if (! disable_type_check<bool>::value)            BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());#endif    }    // Packed (proxy) column major case    template<template <class T1, class T2> class F, class R, class M, class E>    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.    void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {        typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;        // R unnecessary, make_conformant not required        typedef typename M::difference_type difference_type;        typedef typename M::value_type value_type;        BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());        BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());#if BOOST_UBLAS_TYPE_CHECK        matrix<value_type, column_major> cm (m.size1 (), m.size2 ());        indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());        indexing_matrix_assign<F> (cm, e, column_major_tag ());#endif        typename M::iterator2 it2 (m.begin2 ());        typename M::iterator2 it2_end (m.end2 ());        typename E::const_iterator2 it2e (e ().begin2 ());        typename E::const_iterator2 it2e_end (e ().end2 ());        difference_type it2_size (it2_end - it2);        difference_type it2e_size (it2e_end - it2e);        difference_type diff2 (0);        if (it2_size > 0 && it2e_size > 0)            diff2 = it2.index2 () - it2e.index2 ();        if (diff2 != 0) {            difference_type size2 = (std::min) (diff2, it2e_size);            if (size2 > 0) {                it2e += size2;                it2e_size -= size2;                diff2 -= size2;            }            size2 = (std::min) (- diff2, it2_size);            if (size2 > 0) {                it2_size -= size2;                if (!functor_type::computed) {                    while (-- size2 >= 0) { // zeroing#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION                        typename M::iterator1 it1 (it2.begin ());                        typename M::iterator1 it1_end (it2.end ());#else                        typename M::iterator1 it1 (begin (it2, iterator2_tag ()));                        typename M::iterator1 it1_end (end (it2, iterator2_tag ()));#endif                        difference_type size1 (it1_end - it1);                        while (-- size1 >= 0)                            functor_type::apply (*it1, value_type/*zero*/()), ++ it1;                        ++ it2;                    }                } else {                    it2 += size2;                }                diff2 += size2;            }

⌨️ 快捷键说明

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