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 + -
显示快捷键?