Ticket #7411: matrix_vector_range.hpp

File matrix_vector_range.hpp, 4.3 KB (added by Gunter, 10 years ago)

class matrix_vector_iterator

Line 
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
18namespace boost { namespace numeric { namespace ublas {
19
20namespace 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.
27template<class Matrix, class Reference>
28struct 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>{
34public:
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
45private:
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.
82template<class Matrix>
83class matrix_row_range
84: public boost::iterator_range<detail::matrix_vector_iterator<Matrix,matrix_row<Matrix> > >{
85private:
86 typedef detail::matrix_vector_iterator<Matrix,matrix_row<Matrix> > iterator_type;
87 typedef boost::iterator_range<iterator_type> base_type;
88public:
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.
94template<class Matrix>
95matrix_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.
100template<class Matrix>
101matrix_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.
106template<class Matrix >
107class matrix_column_range
108: public boost::iterator_range<detail::matrix_vector_iterator<Matrix,matrix_column<Matrix> > >{
109private:
110 typedef detail::matrix_vector_iterator<Matrix,matrix_column<Matrix> > iterator_type;
111 typedef boost::iterator_range<iterator_type> base_type;
112public:
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.
118template<class Matrix>
119matrix_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.
124template<class Matrix>
125matrix_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