1 // Copyright (c) 2012 Oswin Krause
2 // Copyright (c) 2013 Joaquim Duran
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)
9 #ifndef BOOST_UBLAS_MATRIX_VECTOR_HPP
10 #define BOOST_UBLAS_MATRIX_VECTOR_HPP
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>
19 namespace boost { namespace numeric { namespace ublas {
23 /** \brief Iterator used in the represention of a matrix as a vector of rows or columns
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.
28 * The type of Reference should provide a constructor Reference(matrix, i)
30 * This iterator is invalidated when the underlying matrix is resized.
32 * \tparameter Matrix type of matrix that is represented as a vector of row/column
33 * \tparameter Reference Matrix row or matrix column type.
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,
43 matrix_vector_iterator(){}
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) {}
49 template<class M, class R>
50 matrix_vector_iterator(matrix_vector_iterator<M,R> const& other)
51 : matrix_(other.matrix_),position_(other.position_) {}
54 friend class boost::iterator_core_access;
55 template <class M,class R> friend class matrix_vector_iterator;
64 void advance(std::ptrdiff_t n){
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_;
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_);
79 Reference dereference() const {
80 return Reference(*matrix_,position_);
83 Matrix* matrix_;//no matrix_closure here to ensure easy usage
84 std::size_t position_;
89 /** \brief Represents a \c Matrix as a vector of rows.
91 * Implements an interface to Matrix that the underlaying matrix is represented as a
94 * The vector could be resized which causes the resize of the number of rows of
95 * the underlaying matrix.
97 template<class Matrix>
98 class matrix_row_vector {
100 typedef ublas::matrix_row<Matrix> value_type;
101 typedef ublas::matrix_row<Matrix> reference;
102 typedef ublas::matrix_row<Matrix const> const_reference;
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;
109 typedef typename boost::iterator_difference<iterator>::type difference_type;
110 typedef typename Matrix::size_type size_type;
112 matrix_row_vector(Matrix& matrix) :
118 return iterator(matrix_, 0);
121 const_iterator begin() const {
122 return const_iterator(matrix_, 0);
125 const_iterator cbegin() const {
130 return iterator(matrix_, matrix_.size1());
133 const_iterator end() const {
134 return const_iterator(matrix_, matrix_.size1());
137 const_iterator cend() const {
141 reverse_iterator rbegin() {
142 return reverse_iterator(end());
145 const_reverse_iterator rbegin() const {
146 return const_reverse_iterator(end());
149 const_reverse_iterator crbegin() const {
153 reverse_iterator rend() {
154 return reverse_iterator(begin());
157 const_reverse_iterator rend() const {
158 return const_reverse_iterator(begin());
161 const_reverse_iterator crend() const {
165 value_type operator()(difference_type index) const {
166 return value_type(matrix_, index);
169 reference operator[](difference_type index){
170 return reference(matrix_, index);
173 const_reference operator[](difference_type index) const {
174 return const_reference(matrix_, index);
177 size_type size() const {
178 return matrix_.size1();
181 void resize(size_type size, bool preserve = true) {
182 matrix_.resize(size, matrix_.size2(), preserve);
190 /** \brief Convenience function to create \c matrix_row_vector.
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.
196 * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
198 template<class Matrix>
199 matrix_row_vector<Matrix> make_row_vector(matrix_expression<Matrix>& matrix){
200 return matrix_row_vector<Matrix>(matrix());
204 /** \brief Convenience function to create \c matrix_row_vector.
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.
210 * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
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());
218 /** \brief Represents a \c Matrix as a vector of columns.
220 * Implements an interface to Matrix that the underlaying matrix is represented as a
223 * The vector could be resized which causes the resize of the number of columns of
224 * the underlaying matrix.
226 template<class Matrix>
227 class matrix_column_vector
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;
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;
239 typedef typename boost::iterator_difference<iterator>::type difference_type;
240 typedef typename Matrix::size_type size_type;
242 matrix_column_vector(Matrix& matrix) :
247 return iterator(matrix_, 0);
250 const_iterator begin() const {
251 return const_iterator(matrix_, 0);
254 const_iterator cbegin() const {
259 return iterator(matrix_, matrix_.size2());
262 const_iterator end() const {
263 return const_iterator(matrix_, matrix_.size2());
266 const_iterator cend() const {
270 reverse_iterator rbegin() {
271 return reverse_iterator(end());
274 const_reverse_iterator rbegin() const {
275 return const_reverse_iterator(end());
278 const_reverse_iterator crbegin() const {
282 reverse_iterator rend() {
283 return reverse_iterator(begin());
286 const_reverse_iterator rend() const {
287 return const_reverse_iterator(begin());
290 const_reverse_iterator crend() const {
294 value_type operator()(difference_type index) const {
295 return value_type(matrix_, index);
298 reference operator[](difference_type index) {
299 return reference(matrix_, index);
302 const_reference operator[](difference_type index) const {
303 return const_reference(matrix_, index);
306 size_type size() const {
307 return matrix_.size2();
310 void resize(size_type size, bool preserve = true) {
311 matrix_.resize(matrix_.size1(), size, preserve);
319 /** \brief Convenience function to create \c matrix_column_vector.
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.
325 * \tparam Matrix the type of matrix that \c matrix_column_vector is referring.
327 template<class Matrix>
328 matrix_column_vector<Matrix> make_column_vector(matrix_expression<Matrix>& matrix){
329 return matrix_column_vector<Matrix>(matrix());
333 /** \brief Convenience function to create \c matrix_column_vector.
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.
339 * \tparam Matrix the type of matrix that \c matrix_column_vector is referring.
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());