📄 matrix_sparse.hpp
字号:
data_ [functor_type::size1 (size1_, size2_)] = vector_data_value_type (); } BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector (size_type size1, size_type size2, size_type non_zeros = 0): matrix_expression<self_type> (), size1_ (size1), size2_ (size2), non_zeros_ (non_zeros), data_ () { data_ [functor_type::size1 (size1_, size2_)] = vector_data_value_type (); } BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector (const sparse_vector_of_sparse_vector &m): matrix_expression<self_type> (), size1_ (m.size1_), size2_ (m.size2_), non_zeros_ (m.non_zeros_), data_ (m.data_) {} template<class AE> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector (const matrix_expression<AE> &ae, size_type non_zeros = 0): matrix_expression<self_type> (), size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), non_zeros_ (non_zeros), data_ () { data_ [functor_type::size1 (size1_, size2_)] = vector_data_value_type (); matrix_assign (scalar_assign<true_reference, BOOST_UBLAS_TYPENAME AE::value_type> (), *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 non_zeros () const { size_type non_zeros = 0; for (vector_const_iterator_type itv = data_ ().begin (); itv != data_ ().end (); ++ itv) non_zeros += detail::map_capacity (*itv); return non_zeros; } 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 () [functor_type::size1 (size1_, size2_)] = vector_data_value_type (); } // Proxy support#ifdef BOOST_UBLAS_STRICT_MATRIX_SPARSE BOOST_UBLAS_INLINE pointer find_element (size_type i, size_type j) { vector_iterator_type itv (data ().find (functor_type::element1 (i, size1_, j, size2_))); if (itv == data ().end () || (*itv).first != functor_type::element1 (i, size1_, j, size2_)) return 0; iterator_type it ((*itv).second.find (functor_type::element2 (i, size1_, j, size2_))); if (it == (*itv).second.end () || (*it).first != functor_type::element2 (i, size1_, j, size2_)) return 0; return &(*it).second; }#endif // Element access BOOST_UBLAS_INLINE const_reference at_element (size_type i, size_type j) const { vector_const_iterator_type itv (data ().find (functor_type::element1 (i, size1_, j, size2_))); if (itv == data ().end () || (*itv).first != functor_type::element1 (i, size1_, j, size2_)) return zero_; const_iterator_type it ((*itv).second.find (functor_type::element2 (i, size1_, j, size2_))); if (it == (*itv).second.end () || (*it).first != functor_type::element2 (i, size1_, j, size2_)) return zero_; return (*it).second; } BOOST_UBLAS_INLINE true_reference at_element (size_type i, size_type j) { return data () [functor_type::element1 (i, size1_, j, size2_)] [functor_type::element2 (i, size1_, j, size2_)]; } BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return at_element (i, j); } 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 sparse_vector_of_sparse_vector &operator = (const sparse_vector_of_sparse_vector &m) { if (this != &m) { size1_ = m.size1_; size2_ = m.size2_; non_zeros_ = m.non_zeros_; data () = m.data (); } return *this; } BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector &assign_temporary (sparse_vector_of_sparse_vector &m) { swap (m); return *this; } template<class AE> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector &operator = (const matrix_expression<AE> &ae) { // return assign (self_type (ae, non_zeros_)); self_type temporary (ae, non_zeros_); return assign_temporary (temporary); } template<class AE> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector &assign (const matrix_expression<AE> &ae) { matrix_assign (scalar_assign<true_reference, BOOST_UBLAS_TYPENAME AE::value_type> (), *this, ae); return *this; } template<class AE> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector& operator += (const matrix_expression<AE> &ae) { // return assign (self_type (*this + ae, non_zeros_)); self_type temporary (*this + ae, non_zeros_); return assign_temporary (temporary); } template<class AE> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector &plus_assign (const matrix_expression<AE> &ae) { matrix_assign (scalar_plus_assign<true_reference, BOOST_UBLAS_TYPENAME AE::value_type> (), *this, ae); return *this; } template<class AE> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector& operator -= (const matrix_expression<AE> &ae) { // return assign (self_type (*this - ae, non_zeros_)); self_type temporary (*this - ae, non_zeros_); return assign_temporary (temporary); } template<class AE> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector &minus_assign (const matrix_expression<AE> &ae) { matrix_assign (scalar_minus_assign<true_reference, BOOST_UBLAS_TYPENAME AE::value_type> (), *this, ae); return *this; } template<class AT> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector& operator *= (const AT &at) { matrix_assign_scalar (scalar_multiplies_assign<true_reference, AT> (), *this, at); return *this; } template<class AT> BOOST_UBLAS_INLINE sparse_vector_of_sparse_vector& operator /= (const AT &at) { matrix_assign_scalar (scalar_divides_assign<true_reference, AT> (), *this, at); return *this; } // Swapping BOOST_UBLAS_INLINE void swap (sparse_vector_of_sparse_vector &m) { if (this != &m) { std::swap (size1_, m.size1_); std::swap (size2_, m.size2_); std::swap (non_zeros_, m.non_zeros_); data ().swap (m.data ()); } }#ifndef BOOST_UBLAS_NO_MEMBER_FRIENDS BOOST_UBLAS_INLINE friend void swap (sparse_vector_of_sparse_vector &m1, sparse_vector_of_sparse_vector &m2) { m1.swap (m2); }#endif // Element insertion and erasure BOOST_UBLAS_INLINE void insert (size_type i, size_type j, const_reference t) { vector_iterator_type itv (data ().find (functor_type::element1 (i, size1_, j, size2_))); if (itv == data ().end ()) itv = data ().insert (data ().end (), BOOST_UBLAS_TYPENAME array_type::value_type (functor_type::element1 (i, size1_, j, size2_), vector_data_value_type ())); BOOST_UBLAS_CHECK ((*itv).second.find (functor_type::element2 (i, size1_, j, size2_)) == (*itv).second.end (), bad_index ()); (*itv).second.insert ((*itv).second.end (), BOOST_UBLAS_TYPENAME array_type::value_type::second_type::value_type (functor_type::element2 (i, size1_, j, size2_), t)); } BOOST_UBLAS_INLINE void erase (size_type i, size_type j) { vector_iterator_type itv (data ().find (functor_type::element1 (i, size1_, j, size2_))); if (itv == data ().end ()) return; iterator_type it ((*itv).second.find (functor_type::element2 (i, size1_, j, size2_))); if (it == (*itv).second.end ()) return; (*itv).second.erase (it); } BOOST_UBLAS_INLINE void clear () { data ().clear (); data_ [functor_type::size1 (size1_, size2_)] = vector_data_value_type (); } // Iterator types private: // Use storage iterators typedef typename A::const_iterator vector_const_iterator_type; typedef typename A::iterator vector_iterator_type; typedef typename A::value_type::second_type::const_iterator const_iterator_type; typedef typename A::value_type::second_type::iterator iterator_type; public: class const_iterator1; class iterator1; class const_iterator2; class iterator2;#ifdef BOOST_MSVC_STD_ITERATOR typedef reverse_iterator_base1<const_iterator1, value_type, const_reference> const_reverse_iterator1; typedef reverse_iterator_base1<iterator1, value_type, reference> reverse_iterator1; typedef reverse_iterator_base2<const_iterator2, value_type, const_reference> const_reverse_iterator2; typedef reverse_iterator_base2<iterator2, value_type, reference> reverse_iterator2;#else 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;#endif // Element lookup // This function seems to be big. So we do not let the compiler inline it. // BOOST_UBLAS_INLINE 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_iterator_type itv (data ().lower_bound (functor_type::address1 (i, size1_, j, size2_))); vector_const_iterator_type itv_end (data ().end ()); if (itv == itv_end) return const_iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ()); const_iterator_type it ((*itv).second.lower_bound (functor_type::address2 (i, size1_, j, size2_))); const_iterator_type it_end ((*itv).second.end ()); if (rank == 0) return const_iterator1 (*this, rank, i, j, itv, it); if (it != it_end && (*it).first == functor_type::address2 (i, size1_, j, size2_)) return const_iterator1 (*this, rank, i, j, itv, it); if (direction > 0) { if (functor_type::fast1 ()) { 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 (functor_type::fast1 ()) { 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; } } } } // This function seems to be big. So we do not let the compiler inline it. // BOOST_UBLAS_INLINE iterator1 find1 (int rank, size_type i, size_type j, int direction = 1) { BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ()); for (;;) { vector_iterator_type itv (data ().lower_bound (functor_type::address1 (i, size1_, j, size2_))); vector_iterator_type itv_end (data ().end ()); if (itv == itv_end) return iterator1 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ()); iterator_type it ((*itv).second.lower_bound (functor_type::address2 (i, size1_, j, size2_))); iterator_type it_end ((*itv).second.end ()); if (rank == 0) return iterator1 (*this, rank, i, j, itv, it); if (it != it_end && (*it).first == functor_type::address2 (i, size1_, j, size2_)) return iterator1 (*this, rank, i, j, itv, it); if (direction > 0) { if (functor_type::fast1 ()) { if (it == it_end) return iterator1 (*this, rank, i, j, itv, it); i = (*it).first; } else { if (i >= size1_) return iterator1 (*this, rank, i, j, itv, it); ++ i; } } else /* if (direction < 0) */ { if (functor_type::fast1 ()) { if (it == (*itv).second.begin ()) return iterator1 (*this, rank, i, j, itv, it); -- it; i = (*it).first; } else { if (i == 0) return iterator1 (*this, rank, i, j, itv, it); -- i; } } } } // This function seems to be big. So we do not let the compiler inline it. // BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j, int direction = 1) const { BOOST_UBLAS_CHECK (data ().begin () != data ().end (), internal_logic ()); for (;;) { vector_const_iterator_type itv (data ().lower_bound (functor_type::address1 (i, size1_, j, size2_))); vector_const_iterator_type itv_end (data ().end ()); if (itv == itv_end) return const_iterator2 (*this, rank, i, j, itv_end, (*(-- itv)).second.end ()); const_iterator_type it ((*itv).second.lower_bound (functor_type::address2 (i, size1_, j, size2_))); const_iterator_type it_end ((*itv).second.end ()); if (rank == 0) return c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -