matrix_vector.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  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. BOOST_UBLAS_INLINE
  41. matrix_vector_iterator(Matrix& matrix, std::size_t position)
  42. : matrix_(&matrix),position_(position) {}
  43. template<class M, class R>
  44. BOOST_UBLAS_INLINE
  45. matrix_vector_iterator(matrix_vector_iterator<M,R> const& other)
  46. : matrix_(other.matrix_),position_(other.position_) {}
  47. private:
  48. friend class boost::iterator_core_access;
  49. template <class M,class R> friend class matrix_vector_iterator;
  50. BOOST_UBLAS_INLINE
  51. void increment() {
  52. ++position_;
  53. }
  54. BOOST_UBLAS_INLINE
  55. void decrement() {
  56. --position_;
  57. }
  58. BOOST_UBLAS_INLINE
  59. void advance(std::ptrdiff_t n){
  60. position_ += n;
  61. }
  62. template<class M,class R>
  63. BOOST_UBLAS_INLINE
  64. std::ptrdiff_t distance_to(matrix_vector_iterator<M,R> const& other) const{
  65. BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
  66. return (std::ptrdiff_t)other.position_ - (std::ptrdiff_t)position_;
  67. }
  68. template<class M,class R>
  69. BOOST_UBLAS_INLINE
  70. bool equal(matrix_vector_iterator<M,R> const& other) const{
  71. BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
  72. return (position_ == other.position_);
  73. }
  74. BOOST_UBLAS_INLINE
  75. Reference dereference() const {
  76. return Reference(*matrix_,position_);
  77. }
  78. Matrix* matrix_;//no matrix_closure here to ensure easy usage
  79. std::size_t position_;
  80. };
  81. }
  82. /** \brief Represents a \c Matrix as a vector of rows.
  83. *
  84. * Implements an interface to Matrix that the underlaying matrix is represented as a
  85. * vector of rows.
  86. *
  87. * The vector could be resized which causes the resize of the number of rows of
  88. * the underlaying matrix.
  89. */
  90. template<class Matrix>
  91. class matrix_row_vector {
  92. public:
  93. typedef ublas::matrix_row<Matrix> value_type;
  94. typedef ublas::matrix_row<Matrix> reference;
  95. typedef ublas::matrix_row<Matrix const> const_reference;
  96. typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_row<Matrix> > iterator;
  97. typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_row<Matrix const> const> const_iterator;
  98. typedef boost::reverse_iterator<iterator> reverse_iterator;
  99. typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
  100. typedef typename boost::iterator_difference<iterator>::type difference_type;
  101. typedef typename Matrix::size_type size_type;
  102. BOOST_UBLAS_INLINE
  103. explicit matrix_row_vector(Matrix& matrix) :
  104. matrix_(&matrix) {
  105. }
  106. BOOST_UBLAS_INLINE
  107. iterator begin(){
  108. return iterator(*matrix_, 0);
  109. }
  110. BOOST_UBLAS_INLINE
  111. const_iterator begin() const {
  112. return const_iterator(*matrix_, 0);
  113. }
  114. BOOST_UBLAS_INLINE
  115. const_iterator cbegin() const {
  116. return begin();
  117. }
  118. BOOST_UBLAS_INLINE
  119. iterator end() {
  120. return iterator(*matrix_, matrix_->size1());
  121. }
  122. BOOST_UBLAS_INLINE
  123. const_iterator end() const {
  124. return const_iterator(*matrix_, matrix_->size1());
  125. }
  126. BOOST_UBLAS_INLINE
  127. const_iterator cend() const {
  128. return end();
  129. }
  130. BOOST_UBLAS_INLINE
  131. reverse_iterator rbegin() {
  132. return reverse_iterator(end());
  133. }
  134. BOOST_UBLAS_INLINE
  135. const_reverse_iterator rbegin() const {
  136. return const_reverse_iterator(end());
  137. }
  138. BOOST_UBLAS_INLINE
  139. const_reverse_iterator crbegin() const {
  140. return rbegin();
  141. }
  142. BOOST_UBLAS_INLINE
  143. reverse_iterator rend() {
  144. return reverse_iterator(begin());
  145. }
  146. BOOST_UBLAS_INLINE
  147. const_reverse_iterator rend() const {
  148. return const_reverse_iterator(begin());
  149. }
  150. BOOST_UBLAS_INLINE
  151. const_reverse_iterator crend() const {
  152. return end();
  153. }
  154. BOOST_UBLAS_INLINE
  155. value_type operator()(size_type index) {
  156. return value_type(*matrix_, index);
  157. }
  158. BOOST_UBLAS_INLINE
  159. value_type operator()(size_type index) const {
  160. return value_type(*matrix_, index);
  161. }
  162. BOOST_UBLAS_INLINE
  163. reference operator[](size_type index){
  164. return (*this) (index);
  165. }
  166. BOOST_UBLAS_INLINE
  167. const_reference operator[](size_type index) const {
  168. return (*this) (index);
  169. }
  170. BOOST_UBLAS_INLINE
  171. size_type size() const {
  172. return matrix_->size1();
  173. }
  174. BOOST_UBLAS_INLINE
  175. void resize(size_type size, bool preserve = true) {
  176. matrix_->resize(size, matrix_->size2(), preserve);
  177. }
  178. private:
  179. Matrix* matrix_;
  180. };
  181. /** \brief Convenience function to create \c matrix_row_vector.
  182. *
  183. * Function to create \c matrix_row_vector objects.
  184. * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring.
  185. * \return Created \c matrix_row_vector object.
  186. *
  187. * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
  188. */
  189. template<class Matrix>
  190. BOOST_UBLAS_INLINE
  191. matrix_row_vector<Matrix> make_row_vector(matrix_expression<Matrix>& matrix){
  192. return matrix_row_vector<Matrix>(matrix());
  193. }
  194. /** \brief Convenience function to create \c matrix_row_vector.
  195. *
  196. * Function to create \c matrix_row_vector objects.
  197. * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring.
  198. * \return Created \c matrix_row_vector object.
  199. *
  200. * \tparam Matrix the type of matrix that \c matrix_row_vector is referring.
  201. */
  202. template<class Matrix>
  203. BOOST_UBLAS_INLINE
  204. matrix_row_vector<Matrix const> make_row_vector(matrix_expression<Matrix> const& matrix){
  205. return matrix_row_vector<Matrix const>(matrix());
  206. }
  207. /** \brief Represents a \c Matrix as a vector of columns.
  208. *
  209. * Implements an interface to Matrix that the underlaying matrix is represented as a
  210. * vector of columns.
  211. *
  212. * The vector could be resized which causes the resize of the number of columns of
  213. * the underlaying matrix.
  214. */
  215. template<class Matrix>
  216. class matrix_column_vector {
  217. public:
  218. typedef ublas::matrix_column<Matrix> value_type;
  219. typedef ublas::matrix_column<Matrix> reference;
  220. typedef const ublas::matrix_column<Matrix const> const_reference;
  221. typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_column<Matrix> > iterator;
  222. typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_column<Matrix const> const > const_iterator;
  223. typedef boost::reverse_iterator<iterator> reverse_iterator;
  224. typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
  225. typedef typename boost::iterator_difference<iterator>::type difference_type;
  226. typedef typename Matrix::size_type size_type;
  227. BOOST_UBLAS_INLINE
  228. explicit matrix_column_vector(Matrix& matrix) :
  229. matrix_(&matrix){
  230. }
  231. BOOST_UBLAS_INLINE
  232. iterator begin() {
  233. return iterator(*matrix_, 0);
  234. }
  235. BOOST_UBLAS_INLINE
  236. const_iterator begin() const {
  237. return const_iterator(*matrix_, 0);
  238. }
  239. BOOST_UBLAS_INLINE
  240. const_iterator cbegin() const {
  241. return begin();
  242. }
  243. BOOST_UBLAS_INLINE
  244. iterator end() {
  245. return iterator(*matrix_, matrix_->size2());
  246. }
  247. BOOST_UBLAS_INLINE
  248. const_iterator end() const {
  249. return const_iterator(*matrix_, matrix_->size2());
  250. }
  251. BOOST_UBLAS_INLINE
  252. const_iterator cend() const {
  253. return end();
  254. }
  255. BOOST_UBLAS_INLINE
  256. reverse_iterator rbegin() {
  257. return reverse_iterator(end());
  258. }
  259. BOOST_UBLAS_INLINE
  260. const_reverse_iterator rbegin() const {
  261. return const_reverse_iterator(end());
  262. }
  263. BOOST_UBLAS_INLINE
  264. const_reverse_iterator crbegin() const {
  265. return rbegin();
  266. }
  267. BOOST_UBLAS_INLINE
  268. reverse_iterator rend() {
  269. return reverse_iterator(begin());
  270. }
  271. BOOST_UBLAS_INLINE
  272. const_reverse_iterator rend() const {
  273. return const_reverse_iterator(begin());
  274. }
  275. BOOST_UBLAS_INLINE
  276. const_reverse_iterator crend() const {
  277. return rend();
  278. }
  279. BOOST_UBLAS_INLINE
  280. value_type operator()(size_type index) {
  281. return value_type(*matrix_, index);
  282. }
  283. BOOST_UBLAS_INLINE
  284. value_type operator()(size_type index) const {
  285. return value_type(*matrix_, index);
  286. }
  287. BOOST_UBLAS_INLINE
  288. reference operator[](size_type index) {
  289. return (*this) (index);
  290. }
  291. BOOST_UBLAS_INLINE
  292. const_reference operator[](size_type index) const {
  293. return (*this) (index);
  294. }
  295. BOOST_UBLAS_INLINE
  296. size_type size() const {
  297. return matrix_->size2();
  298. }
  299. BOOST_UBLAS_INLINE
  300. void resize(size_type size, bool preserve = true) {
  301. matrix_->resize(matrix_->size1(), size, preserve);
  302. }
  303. private:
  304. Matrix* matrix_;
  305. };
  306. /** \brief Convenience function to create \c matrix_column_vector.
  307. *
  308. * Function to create \c matrix_column_vector objects.
  309. * \param matrix the \c matrix_expression that generates the matrix that \c matrix_column_vector is referring.
  310. * \return Created \c matrix_column_vector object.
  311. *
  312. * \tparam Matrix the type of matrix that \c matrix_column_vector is referring.
  313. */
  314. template<class Matrix>
  315. BOOST_UBLAS_INLINE
  316. matrix_column_vector<Matrix> make_column_vector(matrix_expression<Matrix>& matrix){
  317. return matrix_column_vector<Matrix>(matrix());
  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. BOOST_UBLAS_INLINE
  329. matrix_column_vector<Matrix const> make_column_vector(matrix_expression<Matrix> const& matrix){
  330. return matrix_column_vector<Matrix const>(matrix());
  331. }
  332. }}}
  333. #endif