vector_of_vector.hpp

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

HPP
1,259
字号
////  Copyright (c) 2003//  Gunter Winkler, Joerg Walter////  Distributed under the Boost Software License, Version 1.0. (See//  accompanying file LICENSE_1_0.txt or copy at//  http://www.boost.org/LICENSE_1_0.txt)////  The authors gratefully acknowledge the support of//  GeNeSys mbH & Co. KG in producing this work.//#ifndef _BOOST_UBLAS_VECTOR_OF_VECTOR_#define _BOOST_UBLAS_VECTOR_OF_VECTOR_#include <boost/type_traits.hpp>#include <boost/numeric/ublas/storage_sparse.hpp>#include <boost/numeric/ublas/matrix_sparse.hpp>// Iterators based on ideas of Jeremy Sieknamespace boost { namespace numeric { namespace ublas {    // uBLAS sparse vector based sparse matrix class    // FIXME outer vector can be sparse type but it is completely filled    template<class T, class L, class A>    class generalized_vector_of_vector:        public matrix_container<generalized_vector_of_vector<T, L, A> > {        typedef T &true_reference;        typedef T *pointer;        typedef const T *const_pointer;        typedef L layout_type;        typedef generalized_vector_of_vector<T, L, A> self_type;    public:#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS        using matrix_container<self_type>::operator ();#endif        typedef typename A::size_type size_type;        typedef typename A::difference_type difference_type;        typedef T value_type;        typedef const T &const_reference;#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE        typedef T &reference;#else        typedef sparse_matrix_element<self_type> reference;#endif        typedef A array_type;        typedef const matrix_reference<const self_type> const_closure_type;        typedef matrix_reference<self_type> closure_type;        typedef typename A::value_type vector_data_value_type;        typedef vector_data_value_type vector_temporary_type;        typedef self_type matrix_temporary_type;        typedef sparse_tag storage_category;        typedef typename L::orientation_category orientation_category;        // Construction and destruction        BOOST_UBLAS_INLINE        generalized_vector_of_vector ():            matrix_container<self_type> (),            size1_ (0), size2_ (0), data_ (1) {            const size_type sizeM = layout_type::size_M (size1_, size2_);             // create size1+1 empty vector elements            data_.insert_element (sizeM, vector_data_value_type ());            storage_invariants ();        }        BOOST_UBLAS_INLINE        generalized_vector_of_vector (size_type size1, size_type size2, size_type non_zeros = 0):            matrix_container<self_type> (),            size1_ (size1), size2_ (size2), data_ (layout_type::size_M (size1_, size2_) + 1) {            const size_type sizeM = layout_type::size_M (size1_, size2_);            const size_type sizem = layout_type::size_m (size1_, size2_);            for (size_type i = 0; i < sizeM; ++ i) // create size1 vector elements                data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);            data_.insert_element (sizeM, vector_data_value_type ());            storage_invariants ();        }        BOOST_UBLAS_INLINE        generalized_vector_of_vector (const generalized_vector_of_vector &m):            matrix_container<self_type> (),            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {            storage_invariants ();        }        template<class AE>        BOOST_UBLAS_INLINE        generalized_vector_of_vector (const matrix_expression<AE> &ae, size_type non_zeros = 0):            matrix_container<self_type> (),            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) {            const size_type sizeM = layout_type::size_M (size1_, size2_);            const size_type sizem = layout_type::size_m (size1_, size2_);            for (size_type i = 0; i < sizeM; ++ i) // create size1 vector elements                data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);            data_.insert_element (sizeM, vector_data_value_type ());            storage_invariants ();            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 (const_vectoriterator_type itv = data_.begin (); itv != data_.end (); ++ itv)                non_zeros += (*itv).nnz_capacity ();            return non_zeros;        }        BOOST_UBLAS_INLINE        size_type nnz () const {            size_type non_zeros = 0;            for (const_vectoriterator_type itv = data_.begin (); itv != data_.end (); ++ itv)                non_zeros += (*itv).nnz ();            return non_zeros;        }        // 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) {            const size_type oldM = layout_type::size_M (size1_, size2_);            size1_ = size1;            size2_ = size2;            const size_type sizeM = layout_type::size_M (size1_, size2_);            const size_type sizem = layout_type::size_m (size1_, size2_);            data ().resize (sizeM + 1, preserve);            if (preserve) {                for (size_type i = 0; (i <= oldM) && (i < sizeM); ++ i)                    ref (data () [i]).resize (sizem, preserve);                for (size_type i = oldM+1; i < sizeM; ++ i) // create new vector elements                    data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);                if (sizeM > oldM) {                    data_.insert_element (sizeM, vector_data_value_type ());                } else {                    ref (data () [sizeM]).resize (0, false);                }            } else {                for (size_type i = 0; i < sizeM; ++ i)                     data_.insert_element (i, vector_data_value_type ()) .resize (sizem, false);                data_.insert_element (sizeM, vector_data_value_type ());            }            storage_invariants ();        }        // 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 elementM = layout_type::index_M (i, j);            const size_type elementm = layout_type::index_m (i, j);            // optimise: check the storage_type and index directly if element always exists            if (boost::is_convertible<typename array_type::storage_category, packed_tag>::value) {                return & (data () [elementM] [elementm]);            }            else {                const typename array_type::value_type *pv = data ().find_element (elementM);                if (!pv)                    return 0;                return pv->find_element (elementm);            }        }        // Element access        BOOST_UBLAS_INLINE        const_reference operator () (size_type i, size_type j) const {            const_pointer p = find_element (i, j);            // optimise: check the storage_type and index directly if element always exists            if (boost::is_convertible<typename array_type::storage_category, packed_tag>::value) {                BOOST_UBLAS_CHECK (p, internal_logic () );                return *p;            }            else {                if (p)                    return *p;                else                    return zero_;            }        }        BOOST_UBLAS_INLINE        reference operator () (size_type i, size_type j) {#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE            return at_element (i, j);#else            return reference (*this, i, j);#endif        }        // Assignment        BOOST_UBLAS_INLINE        generalized_vector_of_vector &operator = (const generalized_vector_of_vector &m) {            if (this != &m) {                size1_ = m.size1_;                size2_ = m.size2_;                data () = m.data ();            }            storage_invariants ();            return *this;        }        BOOST_UBLAS_INLINE        generalized_vector_of_vector &assign_temporary (generalized_vector_of_vector &m) {            swap (m);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        generalized_vector_of_vector &operator = (const matrix_expression<AE> &ae) {            self_type temporary (ae);            return assign_temporary (temporary);        }        template<class AE>        BOOST_UBLAS_INLINE        generalized_vector_of_vector &assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_assign> (*this, ae);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        generalized_vector_of_vector& operator += (const matrix_expression<AE> &ae) {            self_type temporary (*this + ae);            return assign_temporary (temporary);        }        template<class AE>        BOOST_UBLAS_INLINE        generalized_vector_of_vector &plus_assign (const matrix_expression<AE> &ae) {             matrix_assign<scalar_plus_assign> (*this, ae);            return *this;        }        template<class AE>        BOOST_UBLAS_INLINE        generalized_vector_of_vector& operator -= (const matrix_expression<AE> &ae) {            self_type temporary (*this - ae);            return assign_temporary (temporary);        }        template<class AE>        BOOST_UBLAS_INLINE        generalized_vector_of_vector &minus_assign (const matrix_expression<AE> &ae) {            matrix_assign<scalar_minus_assign> (*this, ae);            return *this;        }        template<class AT>        BOOST_UBLAS_INLINE        generalized_vector_of_vector& operator *= (const AT &at) {            matrix_assign_scalar<scalar_multiplies_assign> (*this, at);            return *this;        }        template<class AT>        BOOST_UBLAS_INLINE        generalized_vector_of_vector& operator /= (const AT &at) {            matrix_assign_scalar<scalar_divides_assign> (*this, at);            return *this;        }        // Swapping        BOOST_UBLAS_INLINE        void swap (generalized_vector_of_vector &m) {            if (this != &m) {                std::swap (size1_, m.size1_);                std::swap (size2_, m.size2_);                data ().swap (m.data ());            }            storage_invariants ();        }        BOOST_UBLAS_INLINE        friend void swap (generalized_vector_of_vector &m1, generalized_vector_of_vector &m2) {            m1.swap (m2);        }        // Sorting        void sort () {            vectoriterator_type itv (data ().begin ());            vectoriterator_type itv_end (data ().end ());            while (itv != itv_end) {                (*itv).sort ();                ++ itv;            }        }        // Element insertion and erasure        BOOST_UBLAS_INLINE        true_reference insert_element (size_type i, size_type j, const_reference t) {            const size_type elementM = layout_type::index_M (i, j);            const size_type elementm = layout_type::index_m (i, j);            vector_data_value_type& vd (ref (data () [elementM]));            storage_invariants ();            return vd.insert_element (elementm, t);        }        BOOST_UBLAS_INLINE        void append_element (size_type i, size_type j, const_reference t) {            const size_type elementM = layout_type::index_M (i, j);            const size_type elementm = layout_type::index_m (i, j);            vector_data_value_type& vd (ref (data () [elementM]));            storage_invariants ();            return vd.append_element (elementm, t);        }        BOOST_UBLAS_INLINE        void erase_element (size_type i, size_type j) {            vectoriterator_type itv (data ().find (layout_type::index_M (i, j)));

⌨️ 快捷键说明

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