#ifndef BOOST_UBLAS_MATRIX_VECTOR_HPP #define BOOST_UBLAS_MATRIX_VECTOR_HPP #include //for matrix_row, matrix_column and matrix_expression #include #include #include #include #include namespace boost { namespace numeric { namespace ublas { namespace detail{ /// \brief Iterator which represents a matrix as a range of row/column-vectors /// /// The second argument is the reference to a matrix_row/matrix_column. /// Whatever type used, it must offer a constructor Reference(sequence,i) /// which constructs a reference to the i-th proxy-element /// This iterator is invalidated when the underlying matrix is resized. template struct matrix_vector_iterator: public boost::iterator_facade< matrix_vector_iterator, typename vector_temporary_traits::type, boost::random_access_traversal_tag, Reference >{ public: matrix_vector_iterator(){} ///\brief constructs a matrix_vector_iterator as pointing to the i-th proxy matrix_vector_iterator(Matrix& matrix, std::size_t position) : matrix_(&matrix),position_(position) {} template matrix_vector_iterator(matrix_vector_iterator const& other) : matrix_(other.matrix_),position_(other.position_) {} private: friend class boost::iterator_core_access; template friend class matrix_vector_iterator; void increment() { ++position_; } void decrement() { --position_; } void advance(std::ptrdiff_t n){ position_ += n; } template std::ptrdiff_t distance_to(matrix_vector_iterator const& other) const{ BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ()); return (std::ptrdiff_t)other.position_ - (std::ptrdiff_t)position_; } template bool equal(matrix_vector_iterator const& other) const{ BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ()); return (position_ == other.position_); } Reference dereference() const { return Reference(*matrix_,position_); } Matrix* matrix_;//no matrix_closure here to ensure easy usage std::size_t position_; }; } ///\brief Represents a Matrix as a vector of rows. template class matrix_row_vector { public: typedef ublas::matrix_row value_type; typedef ublas::matrix_row reference; typedef ublas::matrix_row const_reference; typedef ublas::detail::matrix_vector_iterator > iterator; typedef ublas::detail::matrix_vector_iterator const> const_iterator; typedef boost::reverse_iterator reverse_iterator; typedef boost::reverse_iterator const_reverse_iterator; typedef typename boost::iterator_difference::type difference_type; typedef typename Matrix::size_type size_type; matrix_row_vector(Matrix& matrix) : m_matrix(matrix) { } iterator begin(){ return iterator(m_matrix, 0); } const_iterator begin() const { return const_iterator(m_matrix, 0); } iterator end() { return iterator(m_matrix, m_matrix.size1()); } const_iterator end() const { return const_iterator(m_matrix, m_matrix.size1()); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } value_type operator()(difference_type index) const { return value_type(m_matrix, index); } reference operator[](difference_type index){ return reference(m_matrix, index); } const_reference operator[](difference_type index) const { return const_reference(m_matrix, index); } size_type size() const { return m_matrix.size1(); } void resize(size_type size, bool preserve = true) { m_matrix.resize(size, m_matrix.size2(), preserve); } private: Matrix& m_matrix; }; ///\brief convenience function to create matrix_row_vector. template matrix_row_vector make_row_vector(matrix_expression& matrix){ return matrix_row_vector(matrix()); } ///\brief convenience function to create matrix_row_vector. template matrix_row_vector make_row_vector(matrix_expression const& matrix){ return matrix_row_vector(matrix()); } ///\brief Represents a Matrix as a vector of rows. template class matrix_column_vector { public: typedef ublas::matrix_column value_type; typedef ublas::matrix_column reference; typedef const ublas::matrix_column const_reference; typedef ublas::detail::matrix_vector_iterator > iterator; typedef ublas::detail::matrix_vector_iterator const > const_iterator; typedef boost::reverse_iterator reverse_iterator; typedef boost::reverse_iterator const_reverse_iterator; typedef typename boost::iterator_difference::type difference_type; typedef typename Matrix::size_type size_type; matrix_column_vector(Matrix& matrix) : m_matrix(matrix){ } iterator begin() { return iterator(m_matrix, 0); } const_iterator begin() const { return const_iterator(m_matrix, 0); } iterator end() { return iterator(m_matrix, m_matrix.size2()); } const_iterator end() const { return const_iterator(m_matrix, m_matrix.size2()); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } value_type operator()(difference_type index) const { return value_type(m_matrix, index); } reference operator[](difference_type index) { return reference(m_matrix, index); } const_reference operator[](difference_type index) const { return const_reference(m_matrix, index); } size_type size() const { return m_matrix.size2(); } void resize(size_type size, bool preserve = true) { m_matrix.resize(m_matrix.size1(), size, preserve); } private: Matrix& m_matrix; }; ///\brief convenience function to create matrix_column_vector. template matrix_column_vector make_column_vector(matrix_expression& matrix){ return matrix_column_vector(matrix()); } ///\brief convenience function to create matrix_column_vector. template matrix_column_vector make_column_vector(matrix_expression const& matrix){ return matrix_column_vector(matrix()); } }}} #endif