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