matrix_sparse.hpp

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

HPP
1,692
字号
            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();        }        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector (size_type size1, size_type size2, size_type non_zeros = 0):            matrix_container<self_type> (),            size1_ (size1), size2_ (size2), data_ () {            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();        }        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector (const mapped_vector_of_mapped_vector &m):            matrix_container<self_type> (),            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector (const matrix_expression<AE> &ae, size_type non_zeros = 0):            matrix_container<self_type> (),            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ () {            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();            matrix_assign<scalar_assign> (*this, ae);        }        // Accessors        BOOST_UBLAS_INLINE        size_type size1 () const {            return size1_;        }        BOOST_UBLAS_INLINE        size_type size2 () const {            return size2_;        }        BOOST_UBLAS_INLINE        size_type nnz_capacity () const {            size_type non_zeros = 0;            for (vector_const_subiterator_type itv = data_ ().begin (); itv != data_ ().end (); ++ itv)                non_zeros += detail::map_capacity (*itv);            return non_zeros;        }        BOOST_UBLAS_INLINE        size_type nnz () const {            size_type filled = 0;            for (vector_const_subiterator_type itv = data_ ().begin (); itv != data_ ().end (); ++ itv)                filled += (*itv).size ();            return filled;        }        // Storage accessors        BOOST_UBLAS_INLINE        const_array_type &data () const {            return data_;        }        BOOST_UBLAS_INLINE        array_type &data () {            return data_;        }        // Resizing        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 ();            data () [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();        }        // 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 element1 = layout_type::index_M (i, j);            const size_type element2 = layout_type::index_m (i, j);            vector_const_subiterator_type itv (data ().find (element1));            if (itv == data ().end ())                return 0;            BOOST_UBLAS_CHECK ((*itv).first == element1, internal_logic ());   // broken map            const_subiterator_type it ((*itv).second.find (element2));            if (it == (*itv).second.end ())                return 0;            BOOST_UBLAS_CHECK ((*it).first == element2, 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 element1 = layout_type::index_M (i, j);            const size_type element2 = layout_type::index_m (i, j);            vector_const_subiterator_type itv (data ().find (element1));            if (itv == data ().end ())                return zero_;            BOOST_UBLAS_CHECK ((*itv).first == element1, internal_logic ());   // broken map            const_subiterator_type it ((*itv).second.find (element2));            if (it == (*itv).second.end ())                return zero_;            BOOST_UBLAS_CHECK ((*itv).first == element1, 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 element1 = layout_type::index_M (i, j);            const size_type element2 = layout_type::index_m (i, j);            vector_data_value_type& vd (data () [element1]);            std::pair<subiterator_type, bool> ii (vd.insert (typename array_type::value_type::second_type::value_type (element2, value_type/*zero*/())));            BOOST_UBLAS_CHECK ((ii.first)->first == element2, internal_logic ());   // broken map            return (ii.first)->second;#else            return reference (*this, i, j);#endif        }        // Element assignment        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 element1 = layout_type::index_M (i, j);            const size_type element2 = layout_type::index_m (i, j);            vector_data_value_type& vd (data () [element1]);            std::pair<subiterator_type, bool> ii (vd.insert (typename vector_data_value_type::value_type (element2, t)));            BOOST_UBLAS_CHECK ((ii.first)->first == element2, 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) {            vector_subiterator_type itv (data ().find (layout_type::index_M (i, j)));            if (itv == data ().end ())                return;            subiterator_type it ((*itv).second.find (layout_type::index_m (i, j)));            if (it == (*itv).second.end ())                return;            (*itv).second.erase (it);        }                // Zeroing        BOOST_UBLAS_INLINE        void clear () {            data ().clear ();            data_ [layout_type::size_M (size1_, size2_)] = vector_data_value_type ();        }        // Assignment        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &operator = (const mapped_vector_of_mapped_vector &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_vector_of_mapped_vector &operator = (const matrix_container<C> &m) {            resize (m ().size1 (), m ().size2 ());            assign (m);            return *this;        }        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &assign_temporary (mapped_vector_of_mapped_vector &m) {            swap (m);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &operator = (const matrix_expression<AE> &ae) {            self_type temporary (ae);            return assign_temporary (temporary);        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_assign> (*this, ae);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector& operator += (const matrix_expression<AE> &ae) {            self_type temporary (*this + ae);            return assign_temporary (temporary);        }        template<class C>          // Container assignment without temporary        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &operator += (const matrix_container<C> &m) {            plus_assign (m);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &plus_assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_plus_assign> (*this, ae);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector& operator -= (const matrix_expression<AE> &ae) {            self_type temporary (*this - ae);            return assign_temporary (temporary);        }        template<class C>          // Container assignment without temporary        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &operator -= (const matrix_container<C> &m) {            minus_assign (m);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector &minus_assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_minus_assign> (*this, ae);            return *this;        }        template<class AT>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector& operator *= (const AT &at) {            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);            return *this;        }        template<class AT>        BOOST_UBLAS_INLINE        mapped_vector_of_mapped_vector& operator /= (const AT &at) {            matrix_assign_scalar<scalar_divides_assign> (*this, at);            return *this;        }        // Swapping        BOOST_UBLAS_INLINE        void swap (mapped_vector_of_mapped_vector &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_vector_of_mapped_vector &m1, mapped_vector_of_mapped_vector &m2) {            m1.swap (m2);        }        // Iterator types    private:        // Use storage iterators        typedef typename A::const_iterator vector_const_subiterator_type;        typedef typename A::iterator vector_subiterator_type;        typedef typename A::value_type::second_type::const_iterator const_subiterator_type;        typedef typename A::value_type::second_type::iterator subiterator_type;        BOOST_UBLAS_INLINE        true_reference at_element (size_type i, size_type j) {            const size_type element1 = layout_type::index_M (i, j);            const size_type element2 = layout_type::index_m (i, j);            vector_subiterator_type itv (data ().find (element1));            BOOST_UBLAS_CHECK (itv != data ().end(), bad_index ());            BOOST_UBLAS_CHECK ((*itv).first == element1, internal_logic ());   // broken map            subiterator_type it ((*itv).second.find (element2));            BOOST_UBLAS_CHECK (it != (*itv).second.end (), bad_index ());            BOOST_UBLAS_CHECK ((*it).first == element2, 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 {            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());            for (;;) {                vector_const_subiterator_type itv (data ().lower_bound (layout_type::index_M (i, j)));                vector_const_subiterator_type itv_end (data ().end ());                if (itv == itv_end)                    return const_iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ());                const_subiterator_type it ((*itv).second.lower_bound (layout_type::index_m (i, j)));                const_subiterator_type it_end ((*itv).second.end ());                if (rank == 0) {                    // advance to the first available major index                    size_type M = itv->first;                    size_type m;                    if (it != it_end) {                         m = it->first;                     } else {                        m = layout_type::size_m(size1_, size2_);                    }                    size_type first_i = layout_type::index_M(M,m);                    return const_iterator1 (*this, rank, first_i, j, itv, it);                }                if (it != it_end && (*it).first == layout_type::index_m (i, j))                    return const_iterator1 (*this, rank, i, j, itv, it);                if (direction > 0) {                    if (layout_type::fast_i ()) {                        if (it == it_end)                            return const_iterator1 (*this, rank, i, j, itv, it);                        i = (*it).first;                    } else {                        if (i >= size1_)                            return const_iterator1 (*this, rank, i, j, itv, it);                        ++ i;                    }                } else /* if (direction < 0)  */ {                    if (layout_type::fast_i ()) {                        if (it == (*itv).second.begin ())                            return const_iterator1 (*this, rank, i, j, itv, it);                        -- it;                        i = (*it).first;                    } else {                        if (i == 0)                            return const_iterator1 (*this, rank, i, j, itv, it);                        -- i;                    }                }            }        }        // 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) {            BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ());            for (;;) {                vector_subiterator_type itv (data ().lower_bound (layout_type::index_M (i, j)));                vector_subiterator_type itv_end (data ().end ());                if (itv == itv_end)                    return iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ());                subiterator_type it ((*itv).second.lower_bound (layout_type::index

⌨️ 快捷键说明

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