// Copyright (c) 2012 Oswin Krause // Copyright (c) 2013 Joaquim Duran // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // #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 used in the represention of a matrix as a vector of rows or columns * * Iterator used in the represention of a matrix as a vector of rows/columns. It refers * to the i-th element of the matrix, a column or a row depending of Reference type. * * The type of Reference should provide a constructor Reference(matrix, i) * * This iterator is invalidated when the underlying matrix is resized. * * \tparameter Matrix type of matrix that is represented as a vector of row/column * \tparameter Reference Matrix row or matrix column type. */ template class 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 \c Matrix as a vector of rows. * * Implements an interface to Matrix that the underlaying matrix is represented as a * vector of rows. * * The vector could be resized which causes the resize of the number of rows of * the underlaying matrix. */ 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) : matrix_(matrix) { } iterator begin(){ return iterator(matrix_, 0); } const_iterator begin() const { return const_iterator(matrix_, 0); } const_iterator cbegin() const { return begin(); } iterator end() { return iterator(matrix_, matrix_.size1()); } const_iterator end() const { return const_iterator(matrix_, matrix_.size1()); } const_iterator cend() const { return end(); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator crbegin() const { return rbegin(); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } const_reverse_iterator crend() const { return end(); } value_type operator()(difference_type index) const { return value_type(matrix_, index); } reference operator[](difference_type index){ return reference(matrix_, index); } const_reference operator[](difference_type index) const { return const_reference(matrix_, index); } size_type size() const { return matrix_.size1(); } void resize(size_type size, bool preserve = true) { matrix_.resize(size, matrix_.size2(), preserve); } private: Matrix& matrix_; }; /** \brief Convenience function to create \c matrix_row_vector. * * Function to create \c matrix_row_vector objects. * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring. * \return Created \c matrix_row_vector object. * * \tparam Matrix the type of matrix that \c matrix_row_vector is referring. */ template matrix_row_vector make_row_vector(matrix_expression& matrix){ return matrix_row_vector(matrix()); } /** \brief Convenience function to create \c matrix_row_vector. * * Function to create \c matrix_row_vector objects. * \param matrix the \c matrix_expression that generates the matrix that \c matrix_row_vector is referring. * \return Created \c matrix_row_vector object. * * \tparam Matrix the type of matrix that \c matrix_row_vector is referring. */ template matrix_row_vector make_row_vector(matrix_expression const& matrix){ return matrix_row_vector(matrix()); } /** \brief Represents a \c Matrix as a vector of columns. * * Implements an interface to Matrix that the underlaying matrix is represented as a * vector of columns. * * The vector could be resized which causes the resize of the number of columns of * the underlaying matrix. */ 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) : matrix_(matrix){ } iterator begin() { return iterator(matrix_, 0); } const_iterator begin() const { return const_iterator(matrix_, 0); } const_iterator cbegin() const { return begin(); } iterator end() { return iterator(matrix_, matrix_.size2()); } const_iterator end() const { return const_iterator(matrix_, matrix_.size2()); } const_iterator cend() const { return end(); } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator crbegin() const { return rbegin(); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } const_reverse_iterator crend() const { return rend(); } value_type operator()(difference_type index) const { return value_type(matrix_, index); } reference operator[](difference_type index) { return reference(matrix_, index); } const_reference operator[](difference_type index) const { return const_reference(matrix_, index); } size_type size() const { return matrix_.size2(); } void resize(size_type size, bool preserve = true) { matrix_.resize(matrix_.size1(), size, preserve); } private: Matrix& matrix_; }; /** \brief Convenience function to create \c matrix_column_vector. * * Function to create \c matrix_column_vector objects. * \param matrix the \c matrix_expression that generates the matrix that \c matrix_column_vector is referring. * \return Created \c matrix_column_vector object. * * \tparam Matrix the type of matrix that \c matrix_column_vector is referring. */ template matrix_column_vector make_column_vector(matrix_expression& matrix){ return matrix_column_vector(matrix()); } /** \brief Convenience function to create \c matrix_column_vector. * * Function to create \c matrix_column_vector objects. * \param matrix the \c matrix_expression that generates the matrix that \c matrix_column_vector is referring. * \return Created \c matrix_column_vector object. * * \tparam Matrix the type of matrix that \c matrix_column_vector is referring. */ template matrix_column_vector make_column_vector(matrix_expression const& matrix){ return matrix_column_vector(matrix()); } }}} #endif