Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:01

0001 //
0002 //  Copyright (c) 2009
0003 //  Gunter Winkler
0004 //
0005 //  Distributed under the Boost Software License, Version 1.0. (See
0006 //  accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 //
0010 
0011 #ifndef _BOOST_UBLAS_SPARSE_VIEW_
0012 #define _BOOST_UBLAS_SPARSE_VIEW_
0013 
0014 #include <boost/numeric/ublas/matrix_expression.hpp>
0015 #include <boost/numeric/ublas/detail/matrix_assign.hpp>
0016 #if BOOST_UBLAS_TYPE_CHECK
0017 #include <boost/numeric/ublas/matrix.hpp>
0018 #endif
0019 
0020 #include <boost/next_prior.hpp>
0021 #include <boost/type_traits/remove_cv.hpp>
0022 #include <boost/numeric/ublas/storage.hpp>
0023 
0024 namespace boost { namespace numeric { namespace ublas {
0025 
0026     // view a chunk of memory as ublas array
0027 
0028     template < class T >
0029     class c_array_view
0030         : public storage_array< c_array_view<T> > {
0031     private:
0032         typedef c_array_view<T> self_type;
0033         typedef T * pointer;
0034 
0035     public:
0036         // TODO: think about a const pointer
0037         typedef const pointer array_type;
0038 
0039         typedef std::size_t size_type;
0040         typedef std::ptrdiff_t difference_type;
0041 
0042         typedef T value_type;
0043         typedef const T  &const_reference;
0044         typedef const T  *const_pointer;
0045 
0046         typedef const_pointer const_iterator;
0047         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0048 
0049         //
0050         // typedefs required by vector concept
0051         //
0052 
0053         typedef dense_tag  storage_category;
0054         typedef const vector_reference<const self_type>    const_closure_type;
0055 
0056         c_array_view(size_type size, array_type data) :
0057             size_(size), data_(data)
0058         {}
0059 
0060         ~c_array_view()
0061         {}
0062 
0063         //
0064         // immutable methods of container concept
0065         //
0066 
0067         BOOST_UBLAS_INLINE
0068         size_type size () const {
0069             return size_;
0070         }
0071 
0072         BOOST_UBLAS_INLINE
0073         const_reference operator [] (size_type i) const {
0074             BOOST_UBLAS_CHECK (i < size_, bad_index ());
0075             return data_ [i];
0076         }
0077 
0078         BOOST_UBLAS_INLINE
0079         const_iterator begin () const {
0080             return data_;
0081         }
0082         BOOST_UBLAS_INLINE
0083         const_iterator end () const {
0084             return data_ + size_;
0085         }
0086 
0087         BOOST_UBLAS_INLINE
0088         const_reverse_iterator rbegin () const {
0089             return const_reverse_iterator (end ());
0090         }
0091         BOOST_UBLAS_INLINE
0092         const_reverse_iterator rend () const {
0093             return const_reverse_iterator (begin ());
0094         }
0095 
0096     private:
0097         size_type  size_;
0098         array_type data_;
0099     };
0100 
0101 
0102     /** \brief Present existing arrays as compressed array based
0103      *  sparse matrix.
0104      *  This class provides CRS / CCS storage layout.
0105      *
0106      *  see also http://www.netlib.org/utk/papers/templates/node90.html
0107      *
0108      *       \param L layout type, either row_major or column_major
0109      *       \param IB index base, use 0 for C indexing and 1 for
0110      *       FORTRAN indexing of the internal index arrays. This
0111      *       does not affect the operator()(int,int) where the first
0112      *       row/column has always index 0.
0113      *       \param IA index array type, e.g., int[]
0114      *       \param TA value array type, e.g., double[]
0115      */
0116     template<class L, std::size_t IB, class IA, class JA, class TA>
0117     class compressed_matrix_view:
0118         public matrix_expression<compressed_matrix_view<L, IB, IA, JA, TA> > {
0119 
0120     public:
0121         typedef typename vector_view_traits<TA>::value_type value_type;
0122 
0123     private:
0124         typedef value_type &true_reference;
0125         typedef value_type *pointer;
0126         typedef const value_type *const_pointer;
0127         typedef L layout_type;
0128         typedef compressed_matrix_view<L, IB, IA, JA, TA> self_type;
0129 
0130     public:
0131 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0132         using matrix_expression<self_type>::operator ();
0133 #endif
0134         // ISSUE require type consistency check
0135         // is_convertable (IA::size_type, TA::size_type)
0136         typedef typename boost::remove_cv<typename vector_view_traits<JA>::value_type>::type index_type;
0137         // for compatibility, should be removed some day ...
0138         typedef index_type size_type;
0139         // size_type for the data arrays.
0140         typedef typename vector_view_traits<JA>::size_type array_size_type;
0141         typedef typename vector_view_traits<JA>::difference_type difference_type;
0142         typedef const value_type & const_reference;
0143 
0144         // do NOT define reference type, because class is read only
0145         // typedef value_type & reference;
0146 
0147         typedef IA rowptr_array_type;
0148         typedef JA index_array_type;
0149         typedef TA value_array_type;
0150         typedef const matrix_reference<const self_type> const_closure_type;
0151         typedef matrix_reference<self_type> closure_type;
0152 
0153         // FIXME: define a corresponding temporary type
0154         // typedef compressed_vector<T, IB, IA, TA> vector_temporary_type;
0155 
0156         // FIXME: define a corresponding temporary type
0157         // typedef self_type matrix_temporary_type;
0158 
0159         typedef sparse_tag storage_category;
0160         typedef typename L::orientation_category orientation_category;
0161 
0162         //
0163         // private types for internal use
0164         //
0165 
0166     private:
0167         typedef typename vector_view_traits<index_array_type>::const_iterator const_subiterator_type;
0168 
0169         //
0170         // Construction and destruction
0171         //
0172     private:
0173         /// private default constructor because data must be filled by caller
0174         BOOST_UBLAS_INLINE
0175         compressed_matrix_view () { }
0176 
0177     public:
0178         BOOST_UBLAS_INLINE
0179         compressed_matrix_view (index_type n_rows, index_type n_cols, array_size_type nnz
0180                                 , const rowptr_array_type & iptr
0181                                 , const index_array_type & jptr
0182                                 , const value_array_type & values):
0183             matrix_expression<self_type> (),
0184             size1_ (n_rows), size2_ (n_cols), 
0185             nnz_ (nnz),
0186             index1_data_ (iptr), 
0187             index2_data_ (jptr), 
0188             value_data_ (values) {
0189             storage_invariants ();
0190         }
0191 
0192         BOOST_UBLAS_INLINE
0193         compressed_matrix_view(const compressed_matrix_view& o) :
0194             size1_(o.size1_), size2_(o.size2_),
0195             nnz_(o.nnz_),
0196             index1_data_(o.index1_data_),
0197             index2_data_(o.index2_data_),
0198             value_data_(o.value_data_)
0199         {}
0200 
0201         //
0202         // implement immutable iterator types
0203         //
0204 
0205         class const_iterator1 {};
0206         class const_iterator2 {};
0207 
0208         typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
0209         typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
0210 
0211         //
0212         // implement all read only methods for the matrix expression concept
0213         // 
0214 
0215         //! return the number of rows 
0216         index_type size1() const {
0217             return size1_;
0218         }
0219 
0220         //! return the number of columns
0221         index_type size2() const {
0222             return size2_;
0223         }
0224 
0225         //! return value at position (i,j)
0226         value_type operator()(index_type i, index_type j) const {
0227             const_pointer p = find_element(i,j);
0228             if (!p) {
0229                 return zero_;
0230             } else {
0231                 return *p;
0232             }
0233         }
0234         
0235 
0236     private:
0237         //
0238         // private helper functions
0239         //
0240 
0241         const_pointer find_element (index_type i, index_type j) const {
0242             index_type element1 (layout_type::index_M (i, j));
0243             index_type element2 (layout_type::index_m (i, j));
0244 
0245             const array_size_type itv      = zero_based( index1_data_[element1] );
0246             const array_size_type itv_next = zero_based( index1_data_[element1+1] );
0247 
0248             const_subiterator_type it_start = boost::next(vector_view_traits<index_array_type>::begin(index2_data_),itv);
0249             const_subiterator_type it_end = boost::next(vector_view_traits<index_array_type>::begin(index2_data_),itv_next);
0250             const_subiterator_type it = find_index_in_row(it_start, it_end, element2) ;
0251             
0252             if (it == it_end || *it != k_based (element2))
0253                 return 0;
0254             return &value_data_ [it - vector_view_traits<index_array_type>::begin(index2_data_)];
0255         }
0256 
0257         const_subiterator_type find_index_in_row(const_subiterator_type it_start
0258                                                  , const_subiterator_type it_end
0259                                                  , index_type index) const {
0260             return std::lower_bound( it_start
0261                                      , it_end
0262                                      , k_based (index) );
0263         }
0264 
0265 
0266     private:
0267         void storage_invariants () const {
0268             BOOST_UBLAS_CHECK (index1_data_ [layout_type::size_M (size1_, size2_)] == k_based (nnz_), external_logic ());
0269         }
0270         
0271         index_type size1_;
0272         index_type size2_;
0273 
0274         array_size_type nnz_;
0275 
0276         const rowptr_array_type & index1_data_;
0277         const index_array_type & index2_data_;
0278         const value_array_type & value_data_;
0279 
0280         static const value_type zero_;
0281 
0282         BOOST_UBLAS_INLINE
0283         static index_type zero_based (index_type k_based_index) {
0284             return k_based_index - IB;
0285         }
0286         BOOST_UBLAS_INLINE
0287         static index_type k_based (index_type zero_based_index) {
0288             return zero_based_index + IB;
0289         }
0290 
0291         friend class iterator1;
0292         friend class iterator2;
0293         friend class const_iterator1;
0294         friend class const_iterator2;
0295     };
0296 
0297     template<class L, std::size_t IB, class IA, class JA, class TA  >
0298     const typename compressed_matrix_view<L,IB,IA,JA,TA>::value_type 
0299     compressed_matrix_view<L,IB,IA,JA,TA>::zero_ = value_type/*zero*/();
0300 
0301 
0302     template<class L, std::size_t IB, class IA, class JA, class TA  >
0303     compressed_matrix_view<L,IB,IA,JA,TA>
0304     make_compressed_matrix_view(typename vector_view_traits<JA>::value_type n_rows
0305                                 , typename vector_view_traits<JA>::value_type n_cols
0306                                 , typename vector_view_traits<JA>::size_type nnz
0307                                 , const IA & ia
0308                                 , const JA & ja
0309                                 , const TA & ta) {
0310 
0311         return compressed_matrix_view<L,IB,IA,JA,TA>(n_rows, n_cols, nnz, ia, ja, ta);
0312 
0313     }
0314 
0315 }}}
0316 
0317 #endif