Chris@16: // Chris@16: // Copyright (c) 2009 Chris@16: // Gunter Winkler Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // Chris@16: Chris@16: #ifndef _BOOST_UBLAS_SPARSE_VIEW_ Chris@16: #define _BOOST_UBLAS_SPARSE_VIEW_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #if BOOST_UBLAS_TYPE_CHECK Chris@16: #include Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: Chris@16: namespace boost { namespace numeric { namespace ublas { Chris@16: Chris@16: // view a chunk of memory as ublas array Chris@16: Chris@16: template < class T > Chris@16: class c_array_view Chris@16: : public storage_array< c_array_view > { Chris@16: private: Chris@16: typedef c_array_view self_type; Chris@16: typedef T * pointer; Chris@16: Chris@16: public: Chris@16: // TODO: think about a const pointer Chris@16: typedef const pointer array_type; Chris@16: Chris@16: typedef std::size_t size_type; Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: Chris@16: typedef T value_type; Chris@16: typedef const T &const_reference; Chris@16: typedef const T *const_pointer; Chris@16: Chris@16: typedef const_pointer const_iterator; Chris@16: typedef std::reverse_iterator const_reverse_iterator; Chris@16: Chris@16: // Chris@16: // typedefs required by vector concept Chris@16: // Chris@16: Chris@16: typedef dense_tag storage_category; Chris@16: typedef const vector_reference const_closure_type; Chris@16: Chris@16: c_array_view(size_type size, array_type data) : Chris@16: size_(size), data_(data) Chris@16: {} Chris@16: Chris@16: ~c_array_view() Chris@16: {} Chris@16: Chris@16: // Chris@16: // immutable methods of container concept Chris@16: // Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: size_type size () const { Chris@16: return size_; Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reference operator [] (size_type i) const { Chris@16: BOOST_UBLAS_CHECK (i < size_, bad_index ()); Chris@16: return data_ [i]; Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator begin () const { Chris@16: return data_; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_iterator end () const { Chris@16: return data_ + size_; Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rbegin () const { Chris@16: return const_reverse_iterator (end ()); Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: const_reverse_iterator rend () const { Chris@16: return const_reverse_iterator (begin ()); Chris@16: } Chris@16: Chris@16: private: Chris@16: size_type size_; Chris@16: array_type data_; Chris@16: }; Chris@16: Chris@16: Chris@16: /** \brief Present existing arrays as compressed array based Chris@16: * sparse matrix. Chris@16: * This class provides CRS / CCS storage layout. Chris@16: * Chris@16: * see also http://www.netlib.org/utk/papers/templates/node90.html Chris@16: * Chris@16: * \param L layout type, either row_major or column_major Chris@16: * \param IB index base, use 0 for C indexing and 1 for Chris@16: * FORTRAN indexing of the internal index arrays. This Chris@16: * does not affect the operator()(int,int) where the first Chris@16: * row/column has always index 0. Chris@16: * \param IA index array type, e.g., int[] Chris@16: * \param TA value array type, e.g., double[] Chris@16: */ Chris@16: template Chris@16: class compressed_matrix_view: Chris@16: public matrix_expression > { Chris@16: Chris@16: public: Chris@16: typedef typename vector_view_traits::value_type value_type; Chris@16: Chris@16: private: Chris@16: typedef value_type &true_reference; Chris@16: typedef value_type *pointer; Chris@16: typedef const value_type *const_pointer; Chris@16: typedef L layout_type; Chris@16: typedef compressed_matrix_view self_type; Chris@16: Chris@16: public: Chris@16: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS Chris@16: using matrix_expression::operator (); Chris@16: #endif Chris@16: // ISSUE require type consistency check Chris@16: // is_convertable (IA::size_type, TA::size_type) Chris@16: typedef typename boost::remove_cv::value_type>::type index_type; Chris@16: // for compatibility, should be removed some day ... Chris@16: typedef index_type size_type; Chris@16: // size_type for the data arrays. Chris@16: typedef typename vector_view_traits::size_type array_size_type; Chris@16: typedef typename vector_view_traits::difference_type difference_type; Chris@16: typedef const value_type & const_reference; Chris@16: Chris@16: // do NOT define reference type, because class is read only Chris@16: // typedef value_type & reference; Chris@16: Chris@16: typedef IA rowptr_array_type; Chris@16: typedef JA index_array_type; Chris@16: typedef TA value_array_type; Chris@16: typedef const matrix_reference const_closure_type; Chris@16: typedef matrix_reference closure_type; Chris@16: Chris@16: // FIXME: define a corresponding temporary type Chris@16: // typedef compressed_vector vector_temporary_type; Chris@16: Chris@16: // FIXME: define a corresponding temporary type Chris@16: // typedef self_type matrix_temporary_type; Chris@16: Chris@16: typedef sparse_tag storage_category; Chris@16: typedef typename L::orientation_category orientation_category; Chris@16: Chris@16: // Chris@16: // private types for internal use Chris@16: // Chris@16: Chris@16: private: Chris@16: typedef typename vector_view_traits::const_iterator const_subiterator_type; Chris@16: Chris@16: // Chris@16: // Construction and destruction Chris@16: // Chris@16: private: Chris@16: /// private default constructor because data must be filled by caller Chris@16: BOOST_UBLAS_INLINE Chris@16: compressed_matrix_view () { } Chris@16: Chris@16: public: Chris@16: BOOST_UBLAS_INLINE Chris@16: compressed_matrix_view (index_type n_rows, index_type n_cols, array_size_type nnz Chris@16: , const rowptr_array_type & iptr Chris@16: , const index_array_type & jptr Chris@16: , const value_array_type & values): Chris@16: matrix_expression (), Chris@16: size1_ (n_rows), size2_ (n_cols), Chris@16: nnz_ (nnz), Chris@16: index1_data_ (iptr), Chris@16: index2_data_ (jptr), Chris@16: value_data_ (values) { Chris@16: storage_invariants (); Chris@16: } Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: compressed_matrix_view(const compressed_matrix_view& o) : Chris@101: size1_(o.size1_), size2_(o.size2_), Chris@101: nnz_(o.nnz_), Chris@101: index1_data_(o.index1_data_), Chris@101: index2_data_(o.index2_data_), Chris@101: value_data_(o.value_data_) Chris@16: {} Chris@16: Chris@16: // Chris@16: // implement immutable iterator types Chris@16: // Chris@16: Chris@16: class const_iterator1 {}; Chris@16: class const_iterator2 {}; Chris@16: Chris@16: typedef reverse_iterator_base1 const_reverse_iterator1; Chris@16: typedef reverse_iterator_base2 const_reverse_iterator2; Chris@16: Chris@16: // Chris@16: // implement all read only methods for the matrix expression concept Chris@16: // Chris@16: Chris@16: //! return the number of rows Chris@16: index_type size1() const { Chris@16: return size1_; Chris@16: } Chris@16: Chris@16: //! return the number of columns Chris@16: index_type size2() const { Chris@16: return size2_; Chris@16: } Chris@16: Chris@16: //! return value at position (i,j) Chris@16: value_type operator()(index_type i, index_type j) const { Chris@16: const_pointer p = find_element(i,j); Chris@16: if (!p) { Chris@16: return zero_; Chris@16: } else { Chris@16: return *p; Chris@16: } Chris@16: } Chris@16: Chris@16: Chris@16: private: Chris@16: // Chris@16: // private helper functions Chris@16: // Chris@16: Chris@16: const_pointer find_element (index_type i, index_type j) const { Chris@16: index_type element1 (layout_type::index_M (i, j)); Chris@16: index_type element2 (layout_type::index_m (i, j)); Chris@16: Chris@16: const array_size_type itv = zero_based( index1_data_[element1] ); Chris@16: const array_size_type itv_next = zero_based( index1_data_[element1+1] ); Chris@16: Chris@16: const_subiterator_type it_start = boost::next(vector_view_traits::begin(index2_data_),itv); Chris@16: const_subiterator_type it_end = boost::next(vector_view_traits::begin(index2_data_),itv_next); Chris@16: const_subiterator_type it = find_index_in_row(it_start, it_end, element2) ; Chris@16: Chris@16: if (it == it_end || *it != k_based (element2)) Chris@16: return 0; Chris@16: return &value_data_ [it - vector_view_traits::begin(index2_data_)]; Chris@16: } Chris@16: Chris@16: const_subiterator_type find_index_in_row(const_subiterator_type it_start Chris@16: , const_subiterator_type it_end Chris@16: , index_type index) const { Chris@16: return std::lower_bound( it_start Chris@16: , it_end Chris@16: , k_based (index) ); Chris@16: } Chris@16: Chris@16: Chris@16: private: Chris@16: void storage_invariants () const { Chris@16: BOOST_UBLAS_CHECK (index1_data_ [layout_type::size_M (size1_, size2_)] == k_based (nnz_), external_logic ()); Chris@16: } Chris@16: Chris@16: index_type size1_; Chris@16: index_type size2_; Chris@16: Chris@16: array_size_type nnz_; Chris@16: Chris@16: const rowptr_array_type & index1_data_; Chris@16: const index_array_type & index2_data_; Chris@16: const value_array_type & value_data_; Chris@16: Chris@16: static const value_type zero_; Chris@16: Chris@16: BOOST_UBLAS_INLINE Chris@16: static index_type zero_based (index_type k_based_index) { Chris@16: return k_based_index - IB; Chris@16: } Chris@16: BOOST_UBLAS_INLINE Chris@16: static index_type k_based (index_type zero_based_index) { Chris@16: return zero_based_index + IB; Chris@16: } Chris@16: Chris@16: friend class iterator1; Chris@16: friend class iterator2; Chris@16: friend class const_iterator1; Chris@16: friend class const_iterator2; Chris@16: }; Chris@16: Chris@16: template Chris@16: const typename compressed_matrix_view::value_type Chris@16: compressed_matrix_view::zero_ = value_type/*zero*/(); Chris@16: Chris@16: Chris@16: template Chris@16: compressed_matrix_view Chris@16: make_compressed_matrix_view(typename vector_view_traits::value_type n_rows Chris@16: , typename vector_view_traits::value_type n_cols Chris@16: , typename vector_view_traits::size_type nnz Chris@16: , const IA & ia Chris@16: , const JA & ja Chris@16: , const TA & ta) { Chris@16: Chris@16: return compressed_matrix_view(n_rows, n_cols, nnz, ia, ja, ta); Chris@16: Chris@16: } Chris@16: Chris@16: }}} Chris@16: Chris@16: #endif