vector_sparse.hpp

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

HPP
1,787
字号
////  Copyright (c) 2000-2002//  Joerg Walter, Mathias Koch////  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_SPARSE_#define _BOOST_UBLAS_VECTOR_SPARSE_#include <boost/numeric/ublas/storage_sparse.hpp>#include <boost/numeric/ublas/vector_expression.hpp>#include <boost/numeric/ublas/detail/vector_assign.hpp>#if BOOST_UBLAS_TYPE_CHECK#include <boost/numeric/ublas/vector.hpp>#endif// Iterators based on ideas of Jeremy Sieknamespace boost { namespace numeric { namespace ublas {#ifdef BOOST_UBLAS_STRICT_VECTOR_SPARSE    template<class V>    class sparse_vector_element:       public container_reference<V> {    public:        typedef V vector_type;        typedef typename V::size_type size_type;        typedef typename V::value_type value_type;        typedef const value_type &const_reference;        typedef value_type *pointer;    private:        // Proxied element operations        void get_d () const {            pointer p = (*this) ().find_element (i_);            if (p)                d_ = *p;            else                d_ = value_type/*zero*/();        }        void set (const value_type &s) const {            pointer p = (*this) ().find_element (i_);            if (!p)                (*this) ().insert_element (i_, s);            else                *p = s;        }            public:           // Construction and destruction        sparse_vector_element (vector_type &v, size_type i):            container_reference<vector_type> (v), i_ (i) {        }        BOOST_UBLAS_INLINE        sparse_vector_element (const sparse_vector_element &p):            container_reference<vector_type> (p), i_ (p.i_) {}        BOOST_UBLAS_INLINE        ~sparse_vector_element () {        }        // Assignment        BOOST_UBLAS_INLINE        sparse_vector_element &operator = (const sparse_vector_element &p) {            // Overide the implict copy assignment            p.get_d ();            set (p.d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_vector_element &operator = (const D &d) {            set (d);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_vector_element &operator += (const D &d) {            get_d ();            d_ += d;            set (d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_vector_element &operator -= (const D &d) {            get_d ();            d_ -= d;            set (d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_vector_element &operator *= (const D &d) {            get_d ();            d_ *= d;            set (d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_vector_element &operator /= (const D &d) {            get_d ();            d_ /= d;            set (d_);            return *this;        }        // Comparison        template<class D>        BOOST_UBLAS_INLINE        bool operator == (const D &d) const {            get_d ();            return d_ == d;        }        template<class D>        BOOST_UBLAS_INLINE        bool operator != (const D &d) const {            get_d ();            return d_ != d;        }        // Conversion - weak link in proxy as d_ is not a perfect alias for the element        BOOST_UBLAS_INLINE        operator const_reference () const {            get_d ();            return d_;        }        // Conversion to reference - may be invalidated        BOOST_UBLAS_INLINE        value_type& ref () const {            const pointer p = (*this) ().find_element (i_);            if (!p)                return (*this) ().insert_element (i_, value_type/*zero*/());            else                return *p;        }    private:        size_type i_;        mutable value_type d_;    };    /*     * Generalise explicit reference access     */    namespace detail {        template <class R>        struct element_reference {            typedef R& reference;            static reference get_reference (reference r)            {                return r;            }        };        template <class V>        struct element_reference<sparse_vector_element<V> > {            typedef typename V::value_type& reference;            static reference get_reference (const sparse_vector_element<V>& sve)            {                return sve.ref ();            }        };    }    template <class VER>    typename detail::element_reference<VER>::reference ref (VER& ver) {        return detail::element_reference<VER>::get_reference (ver);    }    template <class VER>    typename detail::element_reference<VER>::reference ref (const VER& ver) {        return detail::element_reference<VER>::get_reference (ver);    }    template<class V>    struct type_traits<sparse_vector_element<V> > {        typedef typename V::value_type element_type;        typedef type_traits<sparse_vector_element<V> > self_type;        typedef typename type_traits<element_type>::value_type value_type;        typedef typename type_traits<element_type>::const_reference const_reference;        typedef sparse_vector_element<V> reference;        typedef typename type_traits<element_type>::real_type real_type;        typedef typename type_traits<element_type>::precision_type precision_type;        static const unsigned plus_complexity = type_traits<element_type>::plus_complexity;        static const unsigned multiplies_complexity = type_traits<element_type>::multiplies_complexity;        static        BOOST_UBLAS_INLINE        real_type real (const_reference t) {            return type_traits<element_type>::real (t);        }        static        BOOST_UBLAS_INLINE        real_type imag (const_reference t) {            return type_traits<element_type>::imag (t);        }        static        BOOST_UBLAS_INLINE        value_type conj (const_reference t) {            return type_traits<element_type>::conj (t);        }        static        BOOST_UBLAS_INLINE        real_type type_abs (const_reference t) {            return type_traits<element_type>::type_abs (t);        }        static        BOOST_UBLAS_INLINE        value_type type_sqrt (const_reference t) {            return type_traits<element_type>::type_sqrt (t);        }        static        BOOST_UBLAS_INLINE        real_type norm_1 (const_reference t) {            return type_traits<element_type>::norm_1 (t);        }        static        BOOST_UBLAS_INLINE        real_type norm_2 (const_reference t) {            return type_traits<element_type>::norm_2 (t);        }        static        BOOST_UBLAS_INLINE        real_type norm_inf (const_reference t) {            return type_traits<element_type>::norm_inf (t);        }        static        BOOST_UBLAS_INLINE        bool equals (const_reference t1, const_reference t2) {            return type_traits<element_type>::equals (t1, t2);        }    };    template<class V1, class T2>    struct promote_traits<sparse_vector_element<V1>, T2> {        typedef typename promote_traits<typename sparse_vector_element<V1>::value_type, T2>::promote_type promote_type;    };    template<class T1, class V2>    struct promote_traits<T1, sparse_vector_element<V2> > {        typedef typename promote_traits<T1, typename sparse_vector_element<V2>::value_type>::promote_type promote_type;    };    template<class V1, class V2>    struct promote_traits<sparse_vector_element<V1>, sparse_vector_element<V2> > {        typedef typename promote_traits<typename sparse_vector_element<V1>::value_type,                                        typename sparse_vector_element<V2>::value_type>::promote_type promote_type;    };#endif    // Index map based sparse vector class    template<class T, class A>    class mapped_vector:        public vector_container<mapped_vector<T, A> > {        typedef T &true_reference;        typedef T *pointer;        typedef const T *const_pointer;        typedef mapped_vector<T, A> self_type;    public:#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS        using vector_container<self_type>::operator ();#endif        typedef typename A::size_type size_type;        typedef typename A::difference_type difference_type;        typedef T value_type;        typedef A array_type;        typedef const value_type &const_reference;#ifndef BOOST_UBLAS_STRICT_VECTOR_SPARSE        typedef typename detail::map_traits<A,T>::reference reference;#else        typedef sparse_vector_element<self_type> reference;#endif        typedef const vector_reference<const self_type> const_closure_type;        typedef vector_reference<self_type> closure_type;        typedef self_type vector_temporary_type;        typedef sparse_tag storage_category;        // Construction and destruction        BOOST_UBLAS_INLINE        mapped_vector ():            vector_container<self_type> (),            size_ (0), data_ () {}        BOOST_UBLAS_INLINE        mapped_vector (size_type size, size_type non_zeros = 0):            vector_container<self_type> (),            size_ (size), data_ () {            detail::map_reserve (data(), restrict_capacity (non_zeros));        }        BOOST_UBLAS_INLINE        mapped_vector (const mapped_vector &v):            vector_container<self_type> (),            size_ (v.size_), data_ (v.data_) {}        template<class AE>        BOOST_UBLAS_INLINE        mapped_vector (const vector_expression<AE> &ae, size_type non_zeros = 0):            vector_container<self_type> (),            size_ (ae ().size ()), data_ () {            detail::map_reserve (data(), restrict_capacity (non_zeros));            vector_assign<scalar_assign> (*this, ae);        }        // Accessors        BOOST_UBLAS_INLINE        size_type size () const {            return size_;        }        BOOST_UBLAS_INLINE        size_type nnz_capacity () const {            return detail::map_capacity (data ());        }        BOOST_UBLAS_INLINE        size_type nnz () const {            return data (). size ();        }        // Storage accessors        BOOST_UBLAS_INLINE        const array_type &data () const {            return data_;        }        BOOST_UBLAS_INLINE        array_type &data () {            return data_;        }        // Resizing    private:        BOOST_UBLAS_INLINE        size_type restrict_capacity (size_type non_zeros) const {            non_zeros = (std::min) (non_zeros, size_);            return non_zeros;        }    public:        BOOST_UBLAS_INLINE        void resize (size_type size, bool preserve = true) {            size_ = size;            if (preserve) {                data ().erase (data ().lower_bound(size_), data ().end());            }            else {                data ().clear ();            }        }        // Reserving

⌨️ 快捷键说明

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