1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
|
// 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 <boost/numeric/ublas/matrix_proxy.hpp>//for matrix_row, matrix_column and matrix_expression
#include <boost/numeric/ublas/vector.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
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, class Reference>
class matrix_vector_iterator: public boost::iterator_facade<
matrix_vector_iterator<Matrix,Reference>,
typename vector_temporary_traits<Reference>::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<class M, class R>
matrix_vector_iterator(matrix_vector_iterator<M,R> const& other)
: matrix_(other.matrix_),position_(other.position_) {}
private:
friend class boost::iterator_core_access;
template <class M,class R> friend class matrix_vector_iterator;
void increment() {
++position_;
}
void decrement() {
--position_;
}
void advance(std::ptrdiff_t n){
position_ += n;
}
template<class M,class R>
std::ptrdiff_t distance_to(matrix_vector_iterator<M,R> const& other) const{
BOOST_UBLAS_CHECK (matrix_ == other.matrix_, external_logic ());
return (std::ptrdiff_t)other.position_ - (std::ptrdiff_t)position_;
}
template<class M,class R>
bool equal(matrix_vector_iterator<M,R> 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>
class matrix_row_vector {
public:
typedef ublas::matrix_row<Matrix> value_type;
typedef ublas::matrix_row<Matrix> reference;
typedef ublas::matrix_row<Matrix const> const_reference;
typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_row<Matrix> > iterator;
typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_row<Matrix const> const> const_iterator;
typedef boost::reverse_iterator<iterator> reverse_iterator;
typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
typedef typename boost::iterator_difference<iterator>::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<class Matrix>
matrix_row_vector<Matrix> make_row_vector(matrix_expression<Matrix>& matrix){
return matrix_row_vector<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<class Matrix>
matrix_row_vector<Matrix const> make_row_vector(matrix_expression<Matrix> const& matrix){
return matrix_row_vector<Matrix const>(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>
class matrix_column_vector
{
public:
typedef ublas::matrix_column<Matrix> value_type;
typedef ublas::matrix_column<Matrix> reference;
typedef const ublas::matrix_column<Matrix const> const_reference;
typedef ublas::detail::matrix_vector_iterator<Matrix, ublas::matrix_column<Matrix> > iterator;
typedef ublas::detail::matrix_vector_iterator<Matrix const, ublas::matrix_column<Matrix const> const > const_iterator;
typedef boost::reverse_iterator<iterator> reverse_iterator;
typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
typedef typename boost::iterator_difference<iterator>::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<class Matrix>
matrix_column_vector<Matrix> make_column_vector(matrix_expression<Matrix>& matrix){
return matrix_column_vector<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<class Matrix>
matrix_column_vector<Matrix const> make_column_vector(matrix_expression<Matrix> const& matrix){
return matrix_column_vector<Matrix const>(matrix());
}
}}}
#endif
|