matrix_sparse.hpp

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

HPP
1,692
字号
                non_zeros = size1_ * size2_;            return non_zeros;        }    public:        BOOST_UBLAS_INLINE        void resize (size_type size1, size_type size2, bool preserve = true) {            // FIXME preserve unimplemented            BOOST_UBLAS_CHECK (!preserve, internal_logic ());            size1_ = size1;            size2_ = size2;            data ().clear ();        }        // Reserving        BOOST_UBLAS_INLINE        void reserve (size_type non_zeros, bool preserve = true) {            detail::map_reserve (data (), restrict_capacity (non_zeros));        }        // Element support        BOOST_UBLAS_INLINE        pointer find_element (size_type i, size_type j) {            return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i, j));        }        BOOST_UBLAS_INLINE        const_pointer find_element (size_type i, size_type j) const {            const size_type element = layout_type::element (i, size1_, j, size2_);            const_subiterator_type it (data ().find (element));            if (it == data ().end ())                return 0;            BOOST_UBLAS_CHECK ((*it).first == element, internal_logic ());   // broken map            return &(*it).second;        }        // Element access        BOOST_UBLAS_INLINE        const_reference operator () (size_type i, size_type j) const {            const size_type element = layout_type::element (i, size1_, j, size2_);            const_subiterator_type it (data ().find (element));            if (it == data ().end ())                return zero_;            BOOST_UBLAS_CHECK ((*it).first == element, internal_logic ());   // broken map            return (*it).second;        }        BOOST_UBLAS_INLINE        reference operator () (size_type i, size_type j) {#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE            const size_type element = layout_type::element (i, size1_, j, size2_);            std::pair<subiterator_type, bool> ii (data ().insert (typename array_type::value_type (element, value_type/*zero*/())));            BOOST_UBLAS_CHECK ((ii.first)->first == element, internal_logic ());   // broken map            return (ii.first)->second;#else            return reference (*this, i, j);#endif        }        // Element assingment        BOOST_UBLAS_INLINE        true_reference insert_element (size_type i, size_type j, const_reference t) {            BOOST_UBLAS_CHECK (!find_element (i, j), bad_index ());        // duplicate element            const size_type element = layout_type::element (i, size1_, j, size2_);            std::pair<subiterator_type, bool> ii (data ().insert (typename array_type::value_type (element, t)));            BOOST_UBLAS_CHECK ((ii.first)->first == element, internal_logic ());   // broken map            if (!ii.second)     // existing element                (ii.first)->second = t;            return (ii.first)->second;        }        BOOST_UBLAS_INLINE        void erase_element (size_type i, size_type j) {            subiterator_type it = data ().find (layout_type::element (i, size1_, j, size2_));            if (it == data ().end ())                return;            data ().erase (it);        }                // Zeroing        BOOST_UBLAS_INLINE        void clear () {            data ().clear ();        }        // Assignment        BOOST_UBLAS_INLINE        mapped_matrix &operator = (const mapped_matrix &m) {            if (this != &m) {                size1_ = m.size1_;                size2_ = m.size2_;                data () = m.data ();            }            return *this;        }        template<class C>          // Container assignment without temporary        BOOST_UBLAS_INLINE        mapped_matrix &operator = (const matrix_container<C> &m) {            resize (m ().size1 (), m ().size2 (), false);            assign (m);            return *this;        }        BOOST_UBLAS_INLINE        mapped_matrix &assign_temporary (mapped_matrix &m) {            swap (m);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_matrix &operator = (const matrix_expression<AE> &ae) {            self_type temporary (ae, detail::map_capacity (data ()));            return assign_temporary (temporary);        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_matrix &assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_assign> (*this, ae);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_matrix& operator += (const matrix_expression<AE> &ae) {            self_type temporary (*this + ae, detail::map_capacity (data ()));            return assign_temporary (temporary);        }        template<class C>          // Container assignment without temporary        BOOST_UBLAS_INLINE        mapped_matrix &operator += (const matrix_container<C> &m) {            plus_assign (m);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_matrix &plus_assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_plus_assign> (*this, ae);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_matrix& operator -= (const matrix_expression<AE> &ae) {            self_type temporary (*this - ae, detail::map_capacity (data ()));            return assign_temporary (temporary);        }        template<class C>          // Container assignment without temporary        BOOST_UBLAS_INLINE        mapped_matrix &operator -= (const matrix_container<C> &m) {            minus_assign (m);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_matrix &minus_assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_minus_assign> (*this, ae);            return *this;        }        template<class AT>        BOOST_UBLAS_INLINE        mapped_matrix& operator *= (const AT &at) {            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);            return *this;        }        template<class AT>        BOOST_UBLAS_INLINE        mapped_matrix& operator /= (const AT &at) {            matrix_assign_scalar<scalar_divides_assign> (*this, at);            return *this;        }        // Swapping        BOOST_UBLAS_INLINE        void swap (mapped_matrix &m) {            if (this != &m) {                std::swap (size1_, m.size1_);                std::swap (size2_, m.size2_);                data ().swap (m.data ());            }        }        BOOST_UBLAS_INLINE        friend void swap (mapped_matrix &m1, mapped_matrix &m2) {            m1.swap (m2);        }        // Iterator types    private:        // Use storage iterator        typedef typename A::const_iterator const_subiterator_type;        typedef typename A::iterator subiterator_type;        BOOST_UBLAS_INLINE        true_reference at_element (size_type i, size_type j) {            const size_type element = layout_type::element (i, size1_, j, size2_);            subiterator_type it (data ().find (element));            BOOST_UBLAS_CHECK (it != data ().end(), bad_index ());            BOOST_UBLAS_CHECK ((*it).first == element, internal_logic ());   // broken map            return it->second;        }    public:        class const_iterator1;        class iterator1;        class const_iterator2;        class iterator2;        typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;        typedef reverse_iterator_base1<iterator1> reverse_iterator1;        typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;        typedef reverse_iterator_base2<iterator2> reverse_iterator2;        // Element lookup        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.            const_iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) const {            const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));            const_subiterator_type it_end (data ().end ());            size_type index1 = size_type (-1);            size_type index2 = size_type (-1);            while (rank == 1 && it != it_end) {                index1 = layout_type::index_i ((*it).first, size1_, size2_);                index2 = layout_type::index_j ((*it).first, size1_, size2_);                if (direction > 0) {                    if ((index1 >= i && index2 == j) || (i >= size1_))                        break;                    ++ i;                } else /* if (direction < 0) */ {                    if ((index1 <= i && index2 == j) || (i == 0))                        break;                    -- i;                }                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));            }            if (rank == 1 && index2 != j) {                if (direction > 0)                    i = size1_;                else /* if (direction < 0) */                    i = 0;                rank = 0;            }            return const_iterator1 (*this, rank, i, j, it);        }        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.            iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) {            subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));            subiterator_type it_end (data ().end ());            size_type index1 = size_type (-1);            size_type index2 = size_type (-1);            while (rank == 1 && it != it_end) {                index1 = layout_type::index_i ((*it).first, size1_, size2_);                index2 = layout_type::index_j ((*it).first, size1_, size2_);                if (direction > 0) {                    if ((index1 >= i && index2 == j) || (i >= size1_))                        break;                    ++ i;                } else /* if (direction < 0) */ {                    if ((index1 <= i && index2 == j) || (i == 0))                        break;                    -- i;                }                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));            }            if (rank == 1 && index2 != j) {                if (direction > 0)                    i = size1_;                else /* if (direction < 0) */                    i = 0;                rank = 0;            }            return iterator1 (*this, rank, i, j, it);        }        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.            const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const {            const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));            const_subiterator_type it_end (data ().end ());            size_type index1 = size_type (-1);            size_type index2 = size_type (-1);            while (rank == 1 && it != it_end) {                index1 = layout_type::index_i ((*it).first, size1_, size2_);                index2 = layout_type::index_j ((*it).first, size1_, size2_);                if (direction > 0) {                    if ((index2 >= j && index1 == i) || (j >= size2_))                        break;                    ++ j;                } else /* if (direction < 0) */ {                    if ((index2 <= j && index1 == i) || (j == 0))                        break;                    -- j;                }                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));            }            if (rank == 1 && index1 != i) {                if (direction > 0)                    j = size2_;                else /* if (direction < 0) */                    j = 0;                rank = 0;            }            return const_iterator2 (*this, rank, i, j, it);        }        // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.            iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) {            subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_)));            subiterator_type it_end (data ().end ());            size_type index1 = size_type (-1);            size_type index2 = size_type (-1);            while (rank == 1 && it != it_end) {                index1 = layout_type::index_i ((*it).first, size1_, size2_);                index2 = layout_type::index_j ((*it).first, size1_, size2_);                if (direction > 0) {                    if ((index2 >= j && index1 == i) || (j >= size2_))                        break;                    ++ j;                } else /* if (direction < 0) */ {                    if ((index2 <= j && index1 == i) || (j == 0))                        break;                    -- j;                }                it = data ().lower_bound (layout_type::address (i, size1_, j, size2_));            }            if (rank == 1 && index1 != i) {                if (direction > 0)                    j = size2_;                else /* if (direction < 0) */                    j = 0;                rank = 0;            }            return iterator2 (*this, rank, i, j, it);        }        class const_iterator1:            public container_const_reference<mapped_matrix>,            public bidirectional_iterator_base<sparse_bidirectional_iterator_tag,                                               const_iterator1, value_type> {        public:            typedef typename mapped_matrix::value_type value_type;            typedef typename mapped_matrix::difference_type difference_type;            typedef typename mapped_matrix::const_reference reference;            typedef const typename mapped_matrix::pointer pointer;            typedef const_iterator2 dual_iterator_type;            typedef const_reverse_iterator2 dual_reverse_iterator_type;            // Construction and destruction            BOOST_UBLAS_INLINE            const_iterator1 ():                container_const_reference<self_type> (), rank_ (), i_ (), j_ (), it_ () {}

⌨️ 快捷键说明

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