matrix_sparse.hpp

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

HPP
1,692
字号
////  Copyright (c) 2000-2007//  Joerg Walter, Mathias Koch, Gunter Winkler////  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_MATRIX_SPARSE_#define _BOOST_UBLAS_MATRIX_SPARSE_#include <boost/numeric/ublas/vector_sparse.hpp>#include <boost/numeric/ublas/matrix_expression.hpp>#include <boost/numeric/ublas/detail/matrix_assign.hpp>#if BOOST_UBLAS_TYPE_CHECK#include <boost/numeric/ublas/matrix.hpp>#endif// Iterators based on ideas of Jeremy Sieknamespace boost { namespace numeric { namespace ublas {#ifdef BOOST_UBLAS_STRICT_MATRIX_SPARSE    template<class M>    class sparse_matrix_element:       public container_reference<M> {    public:        typedef M matrix_type;        typedef typename M::size_type size_type;        typedef typename M::value_type value_type;        typedef const value_type &const_reference;        typedef value_type *pointer;        typedef const value_type *const_pointer;    private:        // Proxied element operations        void get_d () const {            const_pointer p = (*this) ().find_element (i_, j_);            if (p)                d_ = *p;            else                d_ = value_type/*zero*/();        }        void set (const value_type &s) const {            pointer p = (*this) ().find_element (i_, j_);            if (!p)                (*this) ().insert_element (i_, j_, s);            else                *p = s;        }            public:        // Construction and destruction        BOOST_UBLAS_INLINE        sparse_matrix_element (matrix_type &m, size_type i, size_type j):            container_reference<matrix_type> (m), i_ (i), j_ (j) {        }        BOOST_UBLAS_INLINE        sparse_matrix_element (const sparse_matrix_element &p):            container_reference<matrix_type> (p), i_ (p.i_), j_ (p.j_) {}        BOOST_UBLAS_INLINE        ~sparse_matrix_element () {        }        // Assignment        BOOST_UBLAS_INLINE        sparse_matrix_element &operator = (const sparse_matrix_element &p) {            // Overide the implict copy assignment            p.get_d ();            set (p.d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_matrix_element &operator = (const D &d) {            set (d);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_matrix_element &operator += (const D &d) {            get_d ();            d_ += d;            set (d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_matrix_element &operator -= (const D &d) {            get_d ();            d_ -= d;            set (d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_matrix_element &operator *= (const D &d) {            get_d ();            d_ *= d;            set (d_);            return *this;        }        template<class D>        BOOST_UBLAS_INLINE        sparse_matrix_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_, j_);            if (!p)                return (*this) ().insert_element (i_, j_, value_type/*zero*/());            else                return *p;        }    private:        size_type i_;        size_type j_;        mutable value_type d_;    };    /*     * Generalise explicit reference access     */    namespace detail {        template <class V>        struct element_reference<sparse_matrix_element<V> > {            typedef typename V::value_type& reference;            static reference get_reference (const sparse_matrix_element<V>& sve)            {                return sve.ref ();            }        };    }    template<class M>    struct type_traits<sparse_matrix_element<M> > {        typedef typename M::value_type element_type;        typedef type_traits<sparse_matrix_element<M> > self_type;        typedef typename type_traits<element_type>::value_type value_type;        typedef typename type_traits<element_type>::const_reference const_reference;        typedef sparse_matrix_element<M> 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 M1, class T2>    struct promote_traits<sparse_matrix_element<M1>, T2> {        typedef typename promote_traits<typename sparse_matrix_element<M1>::value_type, T2>::promote_type promote_type;    };    template<class T1, class M2>    struct promote_traits<T1, sparse_matrix_element<M2> > {        typedef typename promote_traits<T1, typename sparse_matrix_element<M2>::value_type>::promote_type promote_type;    };    template<class M1, class M2>    struct promote_traits<sparse_matrix_element<M1>, sparse_matrix_element<M2> > {        typedef typename promote_traits<typename sparse_matrix_element<M1>::value_type,                                        typename sparse_matrix_element<M2>::value_type>::promote_type promote_type;    };#endif    // Index map based sparse matrix class    template<class T, class L, class A>    class mapped_matrix:        public matrix_container<mapped_matrix<T, L, A> > {        typedef T &true_reference;        typedef T *pointer;        typedef const T * const_pointer;        typedef L layout_type;        typedef mapped_matrix<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 A array_type;        typedef const T &const_reference;#ifndef BOOST_UBLAS_STRICT_MATRIX_SPARSE        typedef typename detail::map_traits<A, T>::reference reference;#else        typedef sparse_matrix_element<self_type> reference;#endif        typedef const matrix_reference<const self_type> const_closure_type;        typedef matrix_reference<self_type> closure_type;        typedef mapped_vector<T, A> 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        mapped_matrix ():            matrix_container<self_type> (),            size1_ (0), size2_ (0), data_ () {}        BOOST_UBLAS_INLINE        mapped_matrix (size_type size1, size_type size2, size_type non_zeros = 0):            matrix_container<self_type> (),            size1_ (size1), size2_ (size2), data_ () {            detail::map_reserve (data (), restrict_capacity (non_zeros));        }        BOOST_UBLAS_INLINE        mapped_matrix (const mapped_matrix &m):            matrix_container<self_type> (),            size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {}        template<class AE>        BOOST_UBLAS_INLINE        mapped_matrix (const matrix_expression<AE> &ae, size_type non_zeros = 0):            matrix_container<self_type> (),            size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ () {            detail::map_reserve (data (), restrict_capacity (non_zeros));            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 {            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 {            // Guarding against overflow - thanks to Alexei Novakov for the hint.            // non_zeros = (std::min) (non_zeros, size1_ * size2_);            if (size1_ > 0 && non_zeros / size1_ >= size2_)

⌨️ 快捷键说明

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