1 | // Copyright (c) 2012
|
---|
2 | // Oswin Krause
|
---|
3 | //
|
---|
4 | // Distributed under the Boost Software License, Version 1.0. (See
|
---|
5 | // accompanying file LICENSE_1_0.txt or copy at
|
---|
6 | // http://www.boost.org/LICENSE_1_0.txt)
|
---|
7 | //
|
---|
8 | #ifndef BOOST_UBLAS_MATRIX_VECTOR_RANGE_HPP
|
---|
9 | #define BOOST_UBLAS_MATRIX_VECTOR_RANGE_HPP
|
---|
10 |
|
---|
11 | #include <boost/numeric/ublas/matrix_proxy.hpp>//for matrix_row, matrix_column and matrix_expression
|
---|
12 | #include <boost/numeric/ublas/vector.hpp>
|
---|
13 | #include <boost/iterator/iterator_facade.hpp>
|
---|
14 | #include <boost/range/iterator_range.hpp>
|
---|
15 | #include <boost/type_traits/is_convertible.hpp>
|
---|
16 | #include <boost/utility/enable_if.hpp>
|
---|
17 |
|
---|
18 | namespace boost { namespace numeric { namespace ublas {
|
---|
19 |
|
---|
20 | namespace detail{
|
---|
21 | /// \brief Iterator which represents a matrix as a range of row/column-vectors
|
---|
22 | ///
|
---|
23 | /// The scond argument is the reference to a matrix_row/matrix_column.
|
---|
24 | /// Whatever type used, it must offer a constructor Reference(sequence,i)
|
---|
25 | /// which constructs a reference to the i-th proxy-element
|
---|
26 | /// This iterator is invalidated when the underlying matrix is resized.
|
---|
27 | template<class Matrix, class Reference>
|
---|
28 | struct matrix_vector_iterator: public boost::iterator_facade<
|
---|
29 | matrix_vector_iterator<Matrix,Reference>,
|
---|
30 | typename vector_temporary_traits<Reference>::type,
|
---|
31 | boost::random_access_traversal_tag,
|
---|
32 | Reference
|
---|
33 | >{
|
---|
34 | public:
|
---|
35 | matrix_vector_iterator(){}
|
---|
36 |
|
---|
37 | ///\brief constructs a matrix_vector_iterator as pointing to the i-th proxy
|
---|
38 | matrix_vector_iterator(Matrix& matrix, std::size_t position)
|
---|
39 | : matrix_(&matrix),position_(position) {}
|
---|
40 |
|
---|
41 | template<class M, class R>
|
---|
42 | matrix_vector_iterator(matrix_vector_iterator<M,R> const& other)
|
---|
43 | : matrix_(other.matrix_),position_(other.position_) {}
|
---|
44 |
|
---|
45 | private:
|
---|
46 | friend class boost::iterator_core_access;
|
---|
47 | template <class M,class R> friend class matrix_vector_iterator;
|
---|
48 |
|
---|
49 | void increment() {
|
---|
50 | ++position_;
|
---|
51 | }
|
---|
52 | void decrement() {
|
---|
53 | --position_;
|
---|
54 | }
|
---|
55 |
|
---|
56 | void advance(std::ptrdiff_t n){
|
---|
57 | position_ += n;
|
---|
58 | }
|
---|
59 |
|
---|
60 | template<class M,class R>
|
---|
61 | std::ptrdiff_t distance_to(matrix_vector_iterator<M,R> const& other) const{
|
---|
62 | BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
|
---|
63 | return (std::ptrdiff_t)other.position_ - (std::ptrdiff_t)position_;
|
---|
64 | }
|
---|
65 |
|
---|
66 | template<class M,class R>
|
---|
67 | bool equal(matrix_vector_iterator<M,R> const& other) const{
|
---|
68 | BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
|
---|
69 | return (position_ == other.position_);
|
---|
70 | }
|
---|
71 | Reference dereference() const {
|
---|
72 | return Reference(*matrix_,position_);
|
---|
73 | }
|
---|
74 |
|
---|
75 | Matrix* matrix_;//no matrix_closure here to ensure easy usage
|
---|
76 | std::size_t position_;
|
---|
77 | };
|
---|
78 |
|
---|
79 | }
|
---|
80 |
|
---|
81 | ///\brief Represents a Matrix as range of row vectors.
|
---|
82 | template<class Matrix>
|
---|
83 | class matrix_row_range
|
---|
84 | : public boost::iterator_range<detail::matrix_vector_iterator<Matrix,matrix_row<Matrix> > >{
|
---|
85 | private:
|
---|
86 | typedef detail::matrix_vector_iterator<Matrix,matrix_row<Matrix> > iterator_type;
|
---|
87 | typedef boost::iterator_range<iterator_type> base_type;
|
---|
88 | public:
|
---|
89 | matrix_row_range(Matrix& matrix)
|
---|
90 | :base_type(iterator_type(matrix,0),iterator_type(matrix,matrix.size1())){}
|
---|
91 | };
|
---|
92 |
|
---|
93 | ///\brief convenience function to create matrix_row_ranges.
|
---|
94 | template<class Matrix>
|
---|
95 | matrix_row_range<Matrix> make_row_range(matrix_expression<Matrix>& matrix){
|
---|
96 | return matrix_row_range<Matrix>(matrix());
|
---|
97 | }
|
---|
98 |
|
---|
99 | ///\brief convenience function to create matrix_row_ranges.
|
---|
100 | template<class Matrix>
|
---|
101 | matrix_row_range<Matrix const> make_row_range(matrix_expression<Matrix> const& matrix){
|
---|
102 | return matrix_row_range<Matrix const>(matrix());
|
---|
103 | }
|
---|
104 |
|
---|
105 | ///\brief Represents a Matrix as range of column vectors.
|
---|
106 | template<class Matrix >
|
---|
107 | class matrix_column_range
|
---|
108 | : public boost::iterator_range<detail::matrix_vector_iterator<Matrix,matrix_column<Matrix> > >{
|
---|
109 | private:
|
---|
110 | typedef detail::matrix_vector_iterator<Matrix,matrix_column<Matrix> > iterator_type;
|
---|
111 | typedef boost::iterator_range<iterator_type> base_type;
|
---|
112 | public:
|
---|
113 | matrix_column_range(Matrix& matrix)
|
---|
114 | :base_type(iterator_type(matrix,0),iterator_type(matrix,matrix.size2())){}
|
---|
115 | };
|
---|
116 |
|
---|
117 | ///\brief convenience function to create matrix_row_ranges.
|
---|
118 | template<class Matrix>
|
---|
119 | matrix_column_range<Matrix> make_column_range(matrix_expression<Matrix>& matrix){
|
---|
120 | return matrix_column_range<Matrix>(matrix());
|
---|
121 | }
|
---|
122 |
|
---|
123 | ///\brief convenience function to create matrix_row_ranges.
|
---|
124 | template<class Matrix>
|
---|
125 | matrix_column_range<Matrix const> make_column_range(matrix_expression<Matrix> const& matrix){
|
---|
126 | return matrix_column_range<Matrix const>(matrix());
|
---|
127 | }
|
---|
128 |
|
---|
129 | }}}
|
---|
130 | #endif
|
---|