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