matrix_sparse.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,692 行 · 第 1/5 页
HPP
1,692 行
non_zeros = size1_ * size2_; return non_zeros; } public: 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 (); } // Reserving BOOST_UBLAS_INLINE void reserve (size_type non_zeros, bool preserve = true) { detail::map_reserve (data (), restrict_capacity (non_zeros)); } // 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 element = layout_type::element (i, size1_, j, size2_); const_subiterator_type it (data ().find (element)); if (it == data ().end ()) return 0; BOOST_UBLAS_CHECK ((*it).first == element, 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 element = layout_type::element (i, size1_, j, size2_); const_subiterator_type it (data ().find (element)); if (it == data ().end ()) return zero_; BOOST_UBLAS_CHECK ((*it).first == element, 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 element = layout_type::element (i, size1_, j, size2_); std::pair<subiterator_type, bool> ii (data ().insert (typename array_type::value_type (element, value_type/*zero*/()))); BOOST_UBLAS_CHECK ((ii.first)->first == element, internal_logic ()); // broken map return (ii.first)->second;#else return reference (*this, i, j);#endif } // Element assingment 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 element = layout_type::element (i, size1_, j, size2_); std::pair<subiterator_type, bool> ii (data ().insert (typename array_type::value_type (element, t))); BOOST_UBLAS_CHECK ((ii.first)->first == element, 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) { subiterator_type it = data ().find (layout_type::element (i, size1_, j, size2_)); if (it == data ().end ()) return; data ().erase (it); } // Zeroing BOOST_UBLAS_INLINE void clear () { data ().clear (); } // Assignment BOOST_UBLAS_INLINE mapped_matrix &operator = (const mapped_matrix &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_matrix &operator = (const matrix_container<C> &m) { resize (m ().size1 (), m ().size2 (), false); assign (m); return *this; } BOOST_UBLAS_INLINE mapped_matrix &assign_temporary (mapped_matrix &m) { swap (m); return *this; } template<class AE> BOOST_UBLAS_INLINE mapped_matrix &operator = (const matrix_expression<AE> &ae) { self_type temporary (ae, detail::map_capacity (data ())); return assign_temporary (temporary); } template<class AE> BOOST_UBLAS_INLINE mapped_matrix &assign (const matrix_expression<AE> &ae) { matrix_assign<scalar_assign> (*this, ae); return *this; } template<class AE> BOOST_UBLAS_INLINE mapped_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae, detail::map_capacity (data ())); return assign_temporary (temporary); } template<class C> // Container assignment without temporary BOOST_UBLAS_INLINE mapped_matrix &operator += (const matrix_container<C> &m) { plus_assign (m); return *this; } template<class AE> BOOST_UBLAS_INLINE mapped_matrix &plus_assign (const matrix_expression<AE> &ae) { matrix_assign<scalar_plus_assign> (*this, ae); return *this; } template<class AE> BOOST_UBLAS_INLINE mapped_matrix& operator -= (const matrix_expression<AE> &ae) { self_type temporary (*this - ae, detail::map_capacity (data ())); return assign_temporary (temporary); } template<class C> // Container assignment without temporary BOOST_UBLAS_INLINE mapped_matrix &operator -= (const matrix_container<C> &m) { minus_assign (m); return *this; } template<class AE> BOOST_UBLAS_INLINE mapped_matrix &minus_assign (const matrix_expression<AE> &ae) { matrix_assign<scalar_minus_assign> (*this, ae); return *this; } template<class AT> BOOST_UBLAS_INLINE mapped_matrix& operator *= (const AT &at) { matrix_assign_scalar<scalar_multiplies_assign> (*this, at); return *this; } template<class AT> BOOST_UBLAS_INLINE mapped_matrix& operator /= (const AT &at) { matrix_assign_scalar<scalar_divides_assign> (*this, at); return *this; } // Swapping BOOST_UBLAS_INLINE void swap (mapped_matrix &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_matrix &m1, mapped_matrix &m2) { m1.swap (m2); } // Iterator types private: // Use storage iterator typedef typename A::const_iterator const_subiterator_type; typedef typename A::iterator subiterator_type; BOOST_UBLAS_INLINE true_reference at_element (size_type i, size_type j) { const size_type element = layout_type::element (i, size1_, j, size2_); subiterator_type it (data ().find (element)); BOOST_UBLAS_CHECK (it != data ().end(), bad_index ()); BOOST_UBLAS_CHECK ((*it).first == element, 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 { const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_))); const_subiterator_type it_end (data ().end ()); size_type index1 = size_type (-1); size_type index2 = size_type (-1); while (rank == 1 && it != it_end) { index1 = layout_type::index_i ((*it).first, size1_, size2_); index2 = layout_type::index_j ((*it).first, size1_, size2_); if (direction > 0) { if ((index1 >= i && index2 == j) || (i >= size1_)) break; ++ i; } else /* if (direction < 0) */ { if ((index1 <= i && index2 == j) || (i == 0)) break; -- i; } it = data ().lower_bound (layout_type::address (i, size1_, j, size2_)); } if (rank == 1 && index2 != j) { if (direction > 0) i = size1_; else /* if (direction < 0) */ i = 0; rank = 0; } return const_iterator1 (*this, rank, i, j, it); } // 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) { subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_))); subiterator_type it_end (data ().end ()); size_type index1 = size_type (-1); size_type index2 = size_type (-1); while (rank == 1 && it != it_end) { index1 = layout_type::index_i ((*it).first, size1_, size2_); index2 = layout_type::index_j ((*it).first, size1_, size2_); if (direction > 0) { if ((index1 >= i && index2 == j) || (i >= size1_)) break; ++ i; } else /* if (direction < 0) */ { if ((index1 <= i && index2 == j) || (i == 0)) break; -- i; } it = data ().lower_bound (layout_type::address (i, size1_, j, size2_)); } if (rank == 1 && index2 != j) { if (direction > 0) i = size1_; else /* if (direction < 0) */ i = 0; rank = 0; } return iterator1 (*this, rank, i, j, it); } // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const { const_subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_))); const_subiterator_type it_end (data ().end ()); size_type index1 = size_type (-1); size_type index2 = size_type (-1); while (rank == 1 && it != it_end) { index1 = layout_type::index_i ((*it).first, size1_, size2_); index2 = layout_type::index_j ((*it).first, size1_, size2_); if (direction > 0) { if ((index2 >= j && index1 == i) || (j >= size2_)) break; ++ j; } else /* if (direction < 0) */ { if ((index2 <= j && index1 == i) || (j == 0)) break; -- j; } it = data ().lower_bound (layout_type::address (i, size1_, j, size2_)); } if (rank == 1 && index1 != i) { if (direction > 0) j = size2_; else /* if (direction < 0) */ j = 0; rank = 0; } return const_iterator2 (*this, rank, i, j, it); } // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) { subiterator_type it (data ().lower_bound (layout_type::address (i, size1_, j, size2_))); subiterator_type it_end (data ().end ()); size_type index1 = size_type (-1); size_type index2 = size_type (-1); while (rank == 1 && it != it_end) { index1 = layout_type::index_i ((*it).first, size1_, size2_); index2 = layout_type::index_j ((*it).first, size1_, size2_); if (direction > 0) { if ((index2 >= j && index1 == i) || (j >= size2_)) break; ++ j; } else /* if (direction < 0) */ { if ((index2 <= j && index1 == i) || (j == 0)) break; -- j; } it = data ().lower_bound (layout_type::address (i, size1_, j, size2_)); } if (rank == 1 && index1 != i) { if (direction > 0) j = size2_; else /* if (direction < 0) */ j = 0; rank = 0; } return iterator2 (*this, rank, i, j, it); } class const_iterator1: public container_const_reference<mapped_matrix>, public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, const_iterator1, value_type> { public: typedef typename mapped_matrix::value_type value_type; typedef typename mapped_matrix::difference_type difference_type; typedef typename mapped_matrix::const_reference reference; typedef const typename mapped_matrix::pointer pointer; typedef const_iterator2 dual_iterator_type; typedef const_reverse_iterator2 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference<self_type> (), rank_ (), i_ (), j_ (), it_ () {}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?