Chris@102
|
1 // Copyright (c) 2012 Oswin Krause
|
Chris@102
|
2 // Copyright (c) 2013 Joaquim Duran
|
Chris@102
|
3 //
|
Chris@102
|
4 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@102
|
5 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
7 //
|
Chris@102
|
8
|
Chris@102
|
9 #ifndef BOOST_UBLAS_MATRIX_VECTOR_HPP
|
Chris@102
|
10 #define BOOST_UBLAS_MATRIX_VECTOR_HPP
|
Chris@102
|
11
|
Chris@102
|
12 #include <boost/numeric/ublas/matrix_proxy.hpp>//for matrix_row, matrix_column and matrix_expression
|
Chris@102
|
13 #include <boost/numeric/ublas/vector.hpp>
|
Chris@102
|
14 #include <boost/iterator/iterator_facade.hpp>
|
Chris@102
|
15 #include <boost/range/iterator_range.hpp>
|
Chris@102
|
16 #include <boost/type_traits/is_convertible.hpp>
|
Chris@102
|
17 #include <boost/utility/enable_if.hpp>
|
Chris@102
|
18
|
Chris@102
|
19 namespace boost { namespace numeric { namespace ublas {
|
Chris@102
|
20
|
Chris@102
|
21 namespace detail{
|
Chris@102
|
22
|
Chris@102
|
23 /** \brief Iterator used in the represention of a matrix as a vector of rows or columns
|
Chris@102
|
24 *
|
Chris@102
|
25 * Iterator used in the represention of a matrix as a vector of rows/columns. It refers
|
Chris@102
|
26 * to the i-th element of the matrix, a column or a row depending of Reference type.
|
Chris@102
|
27 *
|
Chris@102
|
28 * The type of Reference should provide a constructor Reference(matrix, i)
|
Chris@102
|
29 *
|
Chris@102
|
30 * This iterator is invalidated when the underlying matrix is resized.
|
Chris@102
|
31 *
|
Chris@102
|
32 * \tparameter Matrix type of matrix that is represented as a vector of row/column
|
Chris@102
|
33 * \tparameter Reference Matrix row or matrix column type.
|
Chris@102
|
34 */
|
Chris@102
|
35 template<class Matrix, class Reference>
|
Chris@102
|
36 class matrix_vector_iterator: public boost::iterator_facade<
|
Chris@102
|
37 matrix_vector_iterator<Matrix,Reference>,
|
Chris@102
|
38 typename vector_temporary_traits<Reference>::type,
|
Chris@102
|
39 boost::random_access_traversal_tag,
|
Chris@102
|
40 Reference
|
Chris@102
|
41 >{
|
Chris@102
|
42 public:
|
Chris@102
|
43 matrix_vector_iterator(){}
|
Chris@102
|
44
|
Chris@102
|
45 ///\brief constructs a matrix_vector_iterator as pointing to the i-th proxy
|
Chris@102
|
46 matrix_vector_iterator(Matrix& matrix, std::size_t position)
|
Chris@102
|
47 : matrix_(&matrix),position_(position) {}
|
Chris@102
|
48
|
Chris@102
|
49 template<class M, class R>
|
Chris@102
|
50 matrix_vector_iterator(matrix_vector_iterator<M,R> const& other)
|
Chris@102
|
51 : matrix_(other.matrix_),position_(other.position_) {}
|
Chris@102
|
52
|
Chris@102
|
53 private:
|
Chris@102
|
54 friend class boost::iterator_core_access;
|
Chris@102
|
55 template <class M,class R> friend class matrix_vector_iterator;
|
Chris@102
|
56
|
Chris@102
|
57 void increment() {
|
Chris@102
|
58 ++position_;
|
Chris@102
|
59 }
|
Chris@102
|
60 void decrement() {
|
Chris@102
|
61 --position_;
|
Chris@102
|
62 }
|
Chris@102
|
63
|
Chris@102
|
64 void advance(std::ptrdiff_t n){
|
Chris@102
|
65 position_ += n;
|
Chris@102
|
66 }
|
Chris@102
|
67
|
Chris@102
|
68 template<class M,class R>
|
Chris@102
|
69 std::ptrdiff_t distance_to(matrix_vector_iterator<M,R> const& other) const{
|
Chris@102
|
70 BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
|
Chris@102
|
71 return (std::ptrdiff_t)other.position_ - (std::ptrdiff_t)position_;
|
Chris@102
|
72 }
|
Chris@102
|
73
|
Chris@102
|
74 template<class M,class R>
|
Chris@102
|
75 bool equal(matrix_vector_iterator<M,R> const& other) const{
|
Chris@102
|
76 BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
|
Chris@102
|
77 return (position_ == other.position_);
|
Chris@102
|
78 }
|
Chris@102
|
79 Reference dereference() const {
|
Chris@102
|
80 return Reference(*matrix_,position_);
|
Chris@102
|
81 }
|
Chris@102
|
82
|
Chris@102
|
83 Matrix* matrix_;//no matrix_closure here to ensure easy usage
|
Chris@102
|
84 std::size_t position_;
|
Chris@102
|
85 };
|
Chris@102
|
86
|
Chris@102
|
87 }
|
Chris@102
|
88
|
Chris@102
|
89 /** \brief Represents a \c Matrix as a vector of rows.
|
Chris@102
|
90 *
|
Chris@102
|
91 * Implements an interface to Matrix that the underlaying matrix is represented as a
|
Chris@102
|
92 * vector of rows.
|
Chris@102
|
93 *
|
Chris@102
|
94 * The vector could be resized which causes the resize of the number of rows of
|
Chris@102
|
95 * the underlaying matrix.
|
Chris@102
|
96 */
|
Chris@102
|
97 template<class Matrix>
|
Chris@102
|
98 class matrix_row_vector {
|
Chris@102
|
99 public:
|
Chris@102
|
100 typedef ublas::matrix_row<Matrix> value_type;
|
Chris@102
|
101 typedef ublas::matrix_row<Matrix> reference;
|
Chris@102
|
102 typedef ublas::matrix_row<Matrix const> const_reference;
|
Chris@102
|
103
|
Chris@102
|
104 typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_row<Matrix> > iterator;
|
Chris@102
|
105 typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_row<Matrix const> const> const_iterator;
|
Chris@102
|
106 typedef boost::reverse_iterator<iterator> reverse_iterator;
|
Chris@102
|
107 typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@102
|
108
|
Chris@102
|
109 typedef typename boost::iterator_difference<iterator>::type difference_type;
|
Chris@102
|
110 typedef typename Matrix::size_type size_type;
|
Chris@102
|
111
|
Chris@102
|
112 matrix_row_vector(Matrix& matrix) :
|
Chris@102
|
113 matrix_(matrix) {
|
Chris@102
|
114 }
|
Chris@102
|
115
|
Chris@102
|
116
|
Chris@102
|
117 iterator begin(){
|
Chris@102
|
118 return iterator(matrix_, 0);
|
Chris@102
|
119 }
|
Chris@102
|
120
|
Chris@102
|
121 const_iterator begin() const {
|
Chris@102
|
122 return const_iterator(matrix_, 0);
|
Chris@102
|
123 }
|
Chris@102
|
124
|
Chris@102
|
125 const_iterator cbegin() const {
|
Chris@102
|
126 return begin();
|
Chris@102
|
127 }
|
Chris@102
|
128
|
Chris@102
|
129 iterator end() {
|
Chris@102
|
130 return iterator(matrix_, matrix_.size1());
|
Chris@102
|
131 }
|
Chris@102
|
132
|
Chris@102
|
133 const_iterator end() const {
|
Chris@102
|
134 return const_iterator(matrix_, matrix_.size1());
|
Chris@102
|
135 }
|
Chris@102
|
136
|
Chris@102
|
137 const_iterator cend() const {
|
Chris@102
|
138 return end();
|
Chris@102
|
139 }
|
Chris@102
|
140
|
Chris@102
|
141 reverse_iterator rbegin() {
|
Chris@102
|
142 return reverse_iterator(end());
|
Chris@102
|
143 }
|
Chris@102
|
144
|
Chris@102
|
145 const_reverse_iterator rbegin() const {
|
Chris@102
|
146 return const_reverse_iterator(end());
|
Chris@102
|
147 }
|
Chris@102
|
148
|
Chris@102
|
149 const_reverse_iterator crbegin() const {
|
Chris@102
|
150 return rbegin();
|
Chris@102
|
151 }
|
Chris@102
|
152
|
Chris@102
|
153 reverse_iterator rend() {
|
Chris@102
|
154 return reverse_iterator(begin());
|
Chris@102
|
155 }
|
Chris@102
|
156
|
Chris@102
|
157 const_reverse_iterator rend() const {
|
Chris@102
|
158 return const_reverse_iterator(begin());
|
Chris@102
|
159 }
|
Chris@102
|
160
|
Chris@102
|
161 const_reverse_iterator crend() const {
|
Chris@102
|
162 return end();
|
Chris@102
|
163 }
|
Chris@102
|
164
|
Chris@102
|
165 value_type operator()(difference_type index) const {
|
Chris@102
|
166 return value_type(matrix_, index);
|
Chris@102
|
167 }
|
Chris@102
|
168
|
Chris@102
|
169 reference operator[](difference_type index){
|
Chris@102
|
170 return reference(matrix_, index);
|
Chris@102
|
171 }
|
Chris@102
|
172
|
Chris@102
|
173 const_reference operator[](difference_type index) const {
|
Chris@102
|
174 return const_reference(matrix_, index);
|
Chris@102
|
175 }
|
Chris@102
|
176
|
Chris@102
|
177 size_type size() const {
|
Chris@102
|
178 return matrix_.size1();
|
Chris@102
|
179 }
|
Chris@102
|
180
|
Chris@102
|
181 void resize(size_type size, bool preserve = true) {
|
Chris@102
|
182 matrix_.resize(size, matrix_.size2(), preserve);
|
Chris@102
|
183 }
|
Chris@102
|
184
|
Chris@102
|
185 private:
|
Chris@102
|
186 Matrix& matrix_;
|
Chris@102
|
187 };
|
Chris@102
|
188
|
Chris@102
|
189
|
Chris@102
|
190 /** \brief Convenience function to create \c matrix_row_vector.
|
Chris@102
|
191 *
|
Chris@102
|
192 * Function to create \c matrix_row_vector objects.
|
Chris@102
|
193 * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring.
|
Chris@102
|
194 * \return Created \c matrix_row_vector object.
|
Chris@102
|
195 *
|
Chris@102
|
196 * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
|
Chris@102
|
197 */
|
Chris@102
|
198 template<class Matrix>
|
Chris@102
|
199 matrix_row_vector<Matrix> make_row_vector(matrix_expression<Matrix>& matrix){
|
Chris@102
|
200 return matrix_row_vector<Matrix>(matrix());
|
Chris@102
|
201 }
|
Chris@102
|
202
|
Chris@102
|
203
|
Chris@102
|
204 /** \brief Convenience function to create \c matrix_row_vector.
|
Chris@102
|
205 *
|
Chris@102
|
206 * Function to create \c matrix_row_vector objects.
|
Chris@102
|
207 * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring.
|
Chris@102
|
208 * \return Created \c matrix_row_vector object.
|
Chris@102
|
209 *
|
Chris@102
|
210 * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
|
Chris@102
|
211 */
|
Chris@102
|
212 template<class Matrix>
|
Chris@102
|
213 matrix_row_vector<Matrix const> make_row_vector(matrix_expression<Matrix> const& matrix){
|
Chris@102
|
214 return matrix_row_vector<Matrix const>(matrix());
|
Chris@102
|
215 }
|
Chris@102
|
216
|
Chris@102
|
217
|
Chris@102
|
218 /** \brief Represents a \c Matrix as a vector of columns.
|
Chris@102
|
219 *
|
Chris@102
|
220 * Implements an interface to Matrix that the underlaying matrix is represented as a
|
Chris@102
|
221 * vector of columns.
|
Chris@102
|
222 *
|
Chris@102
|
223 * The vector could be resized which causes the resize of the number of columns of
|
Chris@102
|
224 * the underlaying matrix.
|
Chris@102
|
225 */
|
Chris@102
|
226 template<class Matrix>
|
Chris@102
|
227 class matrix_column_vector
|
Chris@102
|
228 {
|
Chris@102
|
229 public:
|
Chris@102
|
230 typedef ublas::matrix_column<Matrix> value_type;
|
Chris@102
|
231 typedef ublas::matrix_column<Matrix> reference;
|
Chris@102
|
232 typedef const ublas::matrix_column<Matrix const> const_reference;
|
Chris@102
|
233
|
Chris@102
|
234 typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_column<Matrix> > iterator;
|
Chris@102
|
235 typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_column<Matrix const> const > const_iterator;
|
Chris@102
|
236 typedef boost::reverse_iterator<iterator> reverse_iterator;
|
Chris@102
|
237 typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
|
Chris@102
|
238
|
Chris@102
|
239 typedef typename boost::iterator_difference<iterator>::type difference_type;
|
Chris@102
|
240 typedef typename Matrix::size_type size_type;
|
Chris@102
|
241
|
Chris@102
|
242 matrix_column_vector(Matrix& matrix) :
|
Chris@102
|
243 matrix_(matrix){
|
Chris@102
|
244 }
|
Chris@102
|
245
|
Chris@102
|
246 iterator begin() {
|
Chris@102
|
247 return iterator(matrix_, 0);
|
Chris@102
|
248 }
|
Chris@102
|
249
|
Chris@102
|
250 const_iterator begin() const {
|
Chris@102
|
251 return const_iterator(matrix_, 0);
|
Chris@102
|
252 }
|
Chris@102
|
253
|
Chris@102
|
254 const_iterator cbegin() const {
|
Chris@102
|
255 return begin();
|
Chris@102
|
256 }
|
Chris@102
|
257
|
Chris@102
|
258 iterator end() {
|
Chris@102
|
259 return iterator(matrix_, matrix_.size2());
|
Chris@102
|
260 }
|
Chris@102
|
261
|
Chris@102
|
262 const_iterator end() const {
|
Chris@102
|
263 return const_iterator(matrix_, matrix_.size2());
|
Chris@102
|
264 }
|
Chris@102
|
265
|
Chris@102
|
266 const_iterator cend() const {
|
Chris@102
|
267 return end();
|
Chris@102
|
268 }
|
Chris@102
|
269
|
Chris@102
|
270 reverse_iterator rbegin() {
|
Chris@102
|
271 return reverse_iterator(end());
|
Chris@102
|
272 }
|
Chris@102
|
273
|
Chris@102
|
274 const_reverse_iterator rbegin() const {
|
Chris@102
|
275 return const_reverse_iterator(end());
|
Chris@102
|
276 }
|
Chris@102
|
277
|
Chris@102
|
278 const_reverse_iterator crbegin() const {
|
Chris@102
|
279 return rbegin();
|
Chris@102
|
280 }
|
Chris@102
|
281
|
Chris@102
|
282 reverse_iterator rend() {
|
Chris@102
|
283 return reverse_iterator(begin());
|
Chris@102
|
284 }
|
Chris@102
|
285
|
Chris@102
|
286 const_reverse_iterator rend() const {
|
Chris@102
|
287 return const_reverse_iterator(begin());
|
Chris@102
|
288 }
|
Chris@102
|
289
|
Chris@102
|
290 const_reverse_iterator crend() const {
|
Chris@102
|
291 return rend();
|
Chris@102
|
292 }
|
Chris@102
|
293
|
Chris@102
|
294 value_type operator()(difference_type index) const {
|
Chris@102
|
295 return value_type(matrix_, index);
|
Chris@102
|
296 }
|
Chris@102
|
297
|
Chris@102
|
298 reference operator[](difference_type index) {
|
Chris@102
|
299 return reference(matrix_, index);
|
Chris@102
|
300 }
|
Chris@102
|
301
|
Chris@102
|
302 const_reference operator[](difference_type index) const {
|
Chris@102
|
303 return const_reference(matrix_, index);
|
Chris@102
|
304 }
|
Chris@102
|
305
|
Chris@102
|
306 size_type size() const {
|
Chris@102
|
307 return matrix_.size2();
|
Chris@102
|
308 }
|
Chris@102
|
309
|
Chris@102
|
310 void resize(size_type size, bool preserve = true) {
|
Chris@102
|
311 matrix_.resize(matrix_.size1(), size, preserve);
|
Chris@102
|
312 }
|
Chris@102
|
313
|
Chris@102
|
314 private:
|
Chris@102
|
315 Matrix& matrix_;
|
Chris@102
|
316 };
|
Chris@102
|
317
|
Chris@102
|
318
|
Chris@102
|
319 /** \brief Convenience function to create \c matrix_column_vector.
|
Chris@102
|
320 *
|
Chris@102
|
321 * Function to create \c matrix_column_vector objects.
|
Chris@102
|
322 * \param matrix the \c matrix_expression that generates the matrix that \c matrix_column_vector is referring.
|
Chris@102
|
323 * \return Created \c matrix_column_vector object.
|
Chris@102
|
324 *
|
Chris@102
|
325 * \tparam Matrix the type of matrix that \c matrix_column_vector is referring.
|
Chris@102
|
326 */
|
Chris@102
|
327 template<class Matrix>
|
Chris@102
|
328 matrix_column_vector<Matrix> make_column_vector(matrix_expression<Matrix>& matrix){
|
Chris@102
|
329 return matrix_column_vector<Matrix>(matrix());
|
Chris@102
|
330 }
|
Chris@102
|
331
|
Chris@102
|
332
|
Chris@102
|
333 /** \brief Convenience function to create \c matrix_column_vector.
|
Chris@102
|
334 *
|
Chris@102
|
335 * Function to create \c matrix_column_vector objects.
|
Chris@102
|
336 * \param matrix the \c matrix_expression that generates the matrix that \c matrix_column_vector is referring.
|
Chris@102
|
337 * \return Created \c matrix_column_vector object.
|
Chris@102
|
338 *
|
Chris@102
|
339 * \tparam Matrix the type of matrix that \c matrix_column_vector is referring.
|
Chris@102
|
340 */
|
Chris@102
|
341 template<class Matrix>
|
Chris@102
|
342 matrix_column_vector<Matrix const> make_column_vector(matrix_expression<Matrix> const& matrix){
|
Chris@102
|
343 return matrix_column_vector<Matrix const>(matrix());
|
Chris@102
|
344 }
|
Chris@102
|
345
|
Chris@102
|
346 }}}
|
Chris@102
|
347
|
Chris@102
|
348 #endif
|