matrix_vector.hpp 10.0 KB

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