// Copyright (c) 2012 // Oswin Krause // // 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_RANGE_HPP #define BOOST_UBLAS_MATRIX_VECTOR_RANGE_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 scond 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 range of row vectors. template class matrix_row_range : public boost::iterator_range > >{ private: typedef detail::matrix_vector_iterator > iterator_type; typedef boost::iterator_range base_type; public: matrix_row_range(Matrix& matrix) :base_type(iterator_type(matrix,0),iterator_type(matrix,matrix.size1())){} }; ///\brief convenience function to create matrix_row_ranges. template matrix_row_range make_row_range(matrix_expression& matrix){ return matrix_row_range(matrix()); } ///\brief convenience function to create matrix_row_ranges. template matrix_row_range make_row_range(matrix_expression const& matrix){ return matrix_row_range(matrix()); } ///\brief Represents a Matrix as range of column vectors. template class matrix_column_range : public boost::iterator_range > >{ private: typedef detail::matrix_vector_iterator > iterator_type; typedef boost::iterator_range base_type; public: matrix_column_range(Matrix& matrix) :base_type(iterator_type(matrix,0),iterator_type(matrix,matrix.size2())){} }; ///\brief convenience function to create matrix_row_ranges. template matrix_column_range make_column_range(matrix_expression& matrix){ return matrix_column_range(matrix()); } ///\brief convenience function to create matrix_row_ranges. template matrix_column_range make_column_range(matrix_expression const& matrix){ return matrix_column_range(matrix()); } }}} #endif