annotate DEPENDENCIES/generic/include/boost/numeric/ublas/banded.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //
Chris@101 2 // Copyright (c) 2000-2013
Chris@101 3 // Joerg Walter, Mathias Koch, Athanasios Iliopoulos
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // The authors gratefully acknowledge the support of
Chris@16 10 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 11 //
Chris@16 12
Chris@16 13 #ifndef _BOOST_UBLAS_BANDED_
Chris@16 14 #define _BOOST_UBLAS_BANDED_
Chris@16 15
Chris@16 16 #include <boost/numeric/ublas/matrix.hpp>
Chris@16 17 #include <boost/numeric/ublas/detail/temporary.hpp>
Chris@16 18
Chris@16 19 // Iterators based on ideas of Jeremy Siek
Chris@16 20
Chris@16 21 namespace boost { namespace numeric { namespace ublas {
Chris@16 22
Chris@101 23
Chris@101 24 namespace hidden {
Chris@101 25
Chris@101 26
Chris@101 27
Chris@101 28 /** \brief A helper for band_matrix indexing.
Chris@101 29 *
Chris@101 30 * The indexing happens as per the netlib description: http://www.netlib.org/lapack/lug/node124.html.
Chris@101 31 * In the case of a row_major matrix a different approach is followed;
Chris@101 32 */
Chris@101 33 template <class LayoutType>
Chris@101 34 class banded_indexing { };
Chris@101 35
Chris@101 36 /** \brief A helper for indexing column major banded matrices.
Chris@101 37 *
Chris@101 38 */
Chris@101 39 template <>
Chris@101 40 class banded_indexing<column_major_tag> {
Chris@101 41 public:
Chris@101 42
Chris@101 43 template <class T>
Chris@101 44 BOOST_UBLAS_INLINE static T size(T /*size1*/, T size2) {
Chris@101 45 return size2;
Chris@101 46 }
Chris@101 47
Chris@101 48 // template <class T>
Chris@101 49 // BOOST_UBLAS_INLINE static bool valid_index(T size1, T /*size2*/, T lower, T upper, T i, T j) {
Chris@101 50 // return (upper+i >= j) && i <= std::min(size1 - 1, j + lower); // upper + i is used by get_index. Maybe find a way to consolidate the operations to increase performance
Chris@101 51 // }
Chris@101 52
Chris@101 53 template <class T>
Chris@101 54 BOOST_UBLAS_INLINE static T get_index(T /*size1*/, T size2, T lower, T upper, T i, T j) {
Chris@101 55 return column_major::element (upper + i - j, lower + 1 + upper, j, size2);
Chris@101 56 }
Chris@101 57 };
Chris@101 58
Chris@101 59 /** \brief A helper for indexing row major banded matrices.
Chris@101 60 *
Chris@101 61 */
Chris@101 62 template <>
Chris@101 63 class banded_indexing<row_major_tag> {
Chris@101 64 public:
Chris@101 65
Chris@101 66 template <class T>
Chris@101 67 BOOST_UBLAS_INLINE static T size(T size1, T /*size2*/) {
Chris@101 68 return size1;
Chris@101 69 }
Chris@101 70
Chris@101 71 // template <class T>
Chris@101 72 // BOOST_UBLAS_INLINE static bool valid_index(T /*size1*/, T size2, T lower, T upper, T i, T j) {
Chris@101 73 // return (lower+j >= i) && j <= std::min(size2 - 1, i + upper); // lower + j is used by get_index. Maybe find a way to consolidate the operations to increase performance
Chris@101 74 // }
Chris@101 75
Chris@101 76 template <class T>
Chris@101 77 BOOST_UBLAS_INLINE static T get_index(T size1, T /*size2*/, T lower, T upper, T i, T j) {
Chris@101 78 return row_major::element (i, size1, lower + j - i, lower + 1 + upper);
Chris@101 79 }
Chris@101 80 };
Chris@101 81
Chris@101 82 }
Chris@101 83
Chris@16 84 /** \brief A banded matrix of values of type \c T.
Chris@16 85 *
Chris@16 86 * For a \f$(mxn)\f$-dimensional banded matrix with \f$l\f$ lower and \f$u\f$ upper diagonals and
Chris@16 87 * \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$, if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$.
Chris@16 88 * The default storage for banded matrices is packed. Orientation and storage can also be specified.
Chris@16 89 * Default is \c row_major and and unbounded_array. It is \b not required by the storage to initialize
Chris@16 90 * elements of the matrix.
Chris@16 91 *
Chris@16 92 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 93 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
Chris@16 94 * \tparam A the type of Storage array. Default is \c unbounded_array
Chris@16 95 */
Chris@16 96 template<class T, class L, class A>
Chris@16 97 class banded_matrix:
Chris@16 98 public matrix_container<banded_matrix<T, L, A> > {
Chris@16 99
Chris@16 100 typedef T *pointer;
Chris@16 101 typedef L layout_type;
Chris@16 102 typedef banded_matrix<T, L, A> self_type;
Chris@101 103
Chris@101 104
Chris@101 105
Chris@16 106 public:
Chris@16 107 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 108 using matrix_container<self_type>::operator ();
Chris@16 109 #endif
Chris@16 110 typedef typename A::size_type size_type;
Chris@16 111 typedef typename A::difference_type difference_type;
Chris@16 112 typedef T value_type;
Chris@16 113 typedef const T &const_reference;
Chris@16 114 typedef T &reference;
Chris@16 115 typedef A array_type;
Chris@16 116 typedef const matrix_reference<const self_type> const_closure_type;
Chris@16 117 typedef matrix_reference<self_type> closure_type;
Chris@16 118 typedef vector<T, A> vector_temporary_type;
Chris@16 119 typedef matrix<T, L, A> matrix_temporary_type; // general sub-matrix
Chris@16 120 typedef packed_tag storage_category;
Chris@16 121 typedef typename L::orientation_category orientation_category;
Chris@16 122
Chris@101 123 private:
Chris@101 124 public:
Chris@101 125
Chris@16 126 // Construction and destruction
Chris@16 127 BOOST_UBLAS_INLINE
Chris@16 128 banded_matrix ():
Chris@16 129 matrix_container<self_type> (),
Chris@16 130 size1_ (0), size2_ (0),
Chris@16 131 lower_ (0), upper_ (0), data_ (0) {}
Chris@16 132 BOOST_UBLAS_INLINE
Chris@16 133 banded_matrix (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0):
Chris@16 134 matrix_container<self_type> (),
Chris@16 135 size1_ (size1), size2_ (size2),
Chris@101 136 lower_ (lower), upper_ (upper),
Chris@101 137 #if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
Chris@101 138 data_ ((std::max) (size1, size2) * (lower + 1 + upper))
Chris@101 139 #else
Chris@101 140 data_ ( hidden::banded_indexing<orientation_category>::size(size1, size2) * (lower + 1 + upper)) // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
Chris@101 141 #endif
Chris@101 142 {
Chris@16 143 }
Chris@16 144 BOOST_UBLAS_INLINE
Chris@16 145 banded_matrix (size_type size1, size_type size2, size_type lower, size_type upper, const array_type &data):
Chris@16 146 matrix_container<self_type> (),
Chris@16 147 size1_ (size1), size2_ (size2),
Chris@16 148 lower_ (lower), upper_ (upper), data_ (data) {}
Chris@16 149 BOOST_UBLAS_INLINE
Chris@16 150 banded_matrix (const banded_matrix &m):
Chris@16 151 matrix_container<self_type> (),
Chris@16 152 size1_ (m.size1_), size2_ (m.size2_),
Chris@16 153 lower_ (m.lower_), upper_ (m.upper_), data_ (m.data_) {}
Chris@16 154 template<class AE>
Chris@16 155 BOOST_UBLAS_INLINE
Chris@16 156 banded_matrix (const matrix_expression<AE> &ae, size_type lower = 0, size_type upper = 0):
Chris@16 157 matrix_container<self_type> (),
Chris@16 158 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()),
Chris@16 159 lower_ (lower), upper_ (upper),
Chris@101 160 #if defined(BOOST_UBLAS_OWN_BANDED) || (BOOST_UBLAS_LEGACY_BANDED)
Chris@101 161 data_ ((std::max) (size1_, size2_) * (lower_ + 1 + upper_))
Chris@101 162 #else
Chris@101 163 data_ ( hidden::banded_indexing<orientation_category>::size(size1_, size2_) * (lower_ + 1 + upper_)) // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
Chris@101 164 #endif
Chris@101 165 {
Chris@16 166 matrix_assign<scalar_assign> (*this, ae);
Chris@16 167 }
Chris@16 168
Chris@16 169 // Accessors
Chris@16 170 BOOST_UBLAS_INLINE
Chris@16 171 size_type size1 () const {
Chris@16 172 return size1_;
Chris@16 173 }
Chris@16 174 BOOST_UBLAS_INLINE
Chris@16 175 size_type size2 () const {
Chris@16 176 return size2_;
Chris@16 177 }
Chris@16 178 BOOST_UBLAS_INLINE
Chris@16 179 size_type lower () const {
Chris@16 180 return lower_;
Chris@16 181 }
Chris@16 182 BOOST_UBLAS_INLINE
Chris@16 183 size_type upper () const {
Chris@16 184 return upper_;
Chris@16 185 }
Chris@16 186
Chris@16 187 // Storage accessors
Chris@16 188 BOOST_UBLAS_INLINE
Chris@16 189 const array_type &data () const {
Chris@16 190 return data_;
Chris@16 191 }
Chris@16 192 BOOST_UBLAS_INLINE
Chris@16 193 array_type &data () {
Chris@16 194 return data_;
Chris@16 195 }
Chris@16 196
Chris@101 197 #if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
Chris@101 198 BOOST_UBLAS_INLINE
Chris@101 199 bool is_element_in_band(size_type i, size_type j) const{
Chris@101 200 //return (upper_+i >= j) && i <= std::min(size1() - 1, j + lower_); // We don't need to check if i is outside because it is checked anyway in the accessors.
Chris@101 201 return (upper_+i >= j) && i <= ( j + lower_); // Essentially this band has "infinite" positive dimensions
Chris@101 202 }
Chris@101 203 #endif
Chris@16 204 // Resizing
Chris@16 205 BOOST_UBLAS_INLINE
Chris@16 206 void resize (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0, bool preserve = true) {
Chris@16 207 if (preserve) {
Chris@16 208 self_type temporary (size1, size2, lower, upper);
Chris@16 209 detail::matrix_resize_preserve<layout_type> (*this, temporary);
Chris@16 210 }
Chris@16 211 else {
Chris@16 212 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper));
Chris@16 213 size1_ = size1;
Chris@16 214 size2_ = size2;
Chris@16 215 lower_ = lower;
Chris@16 216 upper_ = upper;
Chris@16 217 }
Chris@16 218 }
Chris@16 219
Chris@16 220 BOOST_UBLAS_INLINE
Chris@16 221 void resize_packed_preserve (size_type size1, size_type size2, size_type lower = 0, size_type upper = 0) {
Chris@16 222 size1_ = size1;
Chris@16 223 size2_ = size2;
Chris@16 224 lower_ = lower;
Chris@16 225 upper_ = upper;
Chris@16 226 data ().resize ((std::max) (size1, size2) * (lower + 1 + upper), value_type ());
Chris@16 227 }
Chris@16 228
Chris@16 229 // Element access
Chris@16 230 BOOST_UBLAS_INLINE
Chris@16 231 const_reference operator () (size_type i, size_type j) const {
Chris@16 232 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
Chris@16 233 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
Chris@16 234 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 235 const size_type k = (std::max) (i, j);
Chris@16 236 const size_type l = lower_ + j - i;
Chris@101 237 if (k < (std::max) (size1_, size2_) && // TODO: probably use BOOST_UBLAS_CHECK here instead of if
Chris@16 238 l < lower_ + 1 + upper_)
Chris@16 239 return data () [layout_type::element (k, (std::max) (size1_, size2_),
Chris@16 240 l, lower_ + 1 + upper_)];
Chris@101 241 #elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
Chris@16 242 const size_type k = j;
Chris@16 243 const size_type l = upper_ + i - j;
Chris@16 244 if (k < size2_ &&
Chris@16 245 l < lower_ + 1 + upper_)
Chris@16 246 return data () [layout_type::element (k, size2_,
Chris@16 247 l, lower_ + 1 + upper_)];
Chris@101 248 #else // New default
Chris@101 249 // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
Chris@101 250 if ( is_element_in_band( i, j) ) {
Chris@101 251 return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
Chris@101 252 }
Chris@16 253 #endif
Chris@16 254 return zero_;
Chris@16 255 }
Chris@101 256
Chris@16 257 BOOST_UBLAS_INLINE
Chris@16 258 reference at_element (size_type i, size_type j) {
Chris@16 259 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
Chris@16 260 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
Chris@16 261 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 262 const size_type k = (std::max) (i, j);
Chris@101 263 const size_type l = lower_ + j - i; // TODO: Don't we need an if or BOOST_UBLAS_CHECK HERE?
Chris@16 264 return data () [layout_type::element (k, (std::max) (size1_, size2_),
Chris@16 265 l, lower_ + 1 + upper_)];
Chris@101 266 #elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
Chris@16 267 const size_type k = j;
Chris@16 268 const size_type l = upper_ + i - j;
Chris@101 269 if (! (k < size2_ &&
Chris@101 270 l < lower_ + 1 + upper_) ) {
Chris@101 271 bad_index ().raise ();
Chris@101 272 // NEVER reached
Chris@101 273 }
Chris@16 274 return data () [layout_type::element (k, size2_,
Chris@101 275 l, lower_ + 1 + upper_)];
Chris@101 276 #else
Chris@101 277 // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
Chris@101 278 BOOST_UBLAS_CHECK(is_element_in_band( i, j) , bad_index());
Chris@101 279 return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
Chris@16 280 #endif
Chris@16 281 }
Chris@16 282 BOOST_UBLAS_INLINE
Chris@16 283 reference operator () (size_type i, size_type j) {
Chris@16 284 BOOST_UBLAS_CHECK (i < size1_, bad_index ());
Chris@16 285 BOOST_UBLAS_CHECK (j < size2_, bad_index ());
Chris@16 286 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 287 const size_type k = (std::max) (i, j);
Chris@16 288 const size_type l = lower_ + j - i;
Chris@101 289 if (! (k < (std::max) (size1_, size2_) && // TODO: probably use BOOST_UBLAS_CHECK here instead of if
Chris@16 290 l < lower_ + 1 + upper_) ) {
Chris@16 291 bad_index ().raise ();
Chris@16 292 // NEVER reached
Chris@16 293 }
Chris@16 294 return data () [layout_type::element (k, (std::max) (size1_, size2_),
Chris@16 295 l, lower_ + 1 + upper_)];
Chris@101 296 #elif BOOST_UBLAS_LEGACY_BANDED // Prior to version: TODO: add version this is actually incorporated in
Chris@16 297 const size_type k = j;
Chris@16 298 const size_type l = upper_ + i - j;
Chris@16 299 if (! (k < size2_ &&
Chris@16 300 l < lower_ + 1 + upper_) ) {
Chris@16 301 bad_index ().raise ();
Chris@16 302 // NEVER reached
Chris@16 303 }
Chris@16 304 return data () [layout_type::element (k, size2_,
Chris@16 305 l, lower_ + 1 + upper_)];
Chris@101 306 #else
Chris@101 307 // This is the netlib layout as described here: http://www.netlib.org/lapack/lug/node124.html
Chris@101 308 BOOST_UBLAS_CHECK( is_element_in_band( i, j) , bad_index());
Chris@101 309 return data () [hidden::banded_indexing<orientation_category>::get_index(size1_, size2_, lower_, upper_, i, j)];
Chris@16 310 #endif
Chris@101 311
Chris@16 312 }
Chris@16 313
Chris@16 314 // Element assignment
Chris@16 315 BOOST_UBLAS_INLINE
Chris@16 316 reference insert_element (size_type i, size_type j, const_reference t) {
Chris@16 317 return (operator () (i, j) = t);
Chris@16 318 }
Chris@16 319 BOOST_UBLAS_INLINE
Chris@16 320 void erase_element (size_type i, size_type j) {
Chris@16 321 operator () (i, j) = value_type/*zero*/();
Chris@16 322 }
Chris@16 323
Chris@16 324 // Zeroing
Chris@16 325 BOOST_UBLAS_INLINE
Chris@16 326 void clear () {
Chris@16 327 std::fill (data ().begin (), data ().end (), value_type/*zero*/());
Chris@16 328 }
Chris@16 329
Chris@16 330 // Assignment
Chris@16 331 BOOST_UBLAS_INLINE
Chris@16 332 banded_matrix &operator = (const banded_matrix &m) {
Chris@16 333 size1_ = m.size1_;
Chris@16 334 size2_ = m.size2_;
Chris@16 335 lower_ = m.lower_;
Chris@16 336 upper_ = m.upper_;
Chris@16 337 data () = m.data ();
Chris@16 338 return *this;
Chris@16 339 }
Chris@16 340 BOOST_UBLAS_INLINE
Chris@16 341 banded_matrix &assign_temporary (banded_matrix &m) {
Chris@16 342 swap (m);
Chris@16 343 return *this;
Chris@16 344 }
Chris@16 345 template<class AE>
Chris@16 346 BOOST_UBLAS_INLINE
Chris@16 347 banded_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 348 self_type temporary (ae, lower_, upper_);
Chris@16 349 return assign_temporary (temporary);
Chris@16 350 }
Chris@16 351 template<class AE>
Chris@16 352 BOOST_UBLAS_INLINE
Chris@16 353 banded_matrix &assign (const matrix_expression<AE> &ae) {
Chris@16 354 matrix_assign<scalar_assign> (*this, ae);
Chris@16 355 return *this;
Chris@16 356 }
Chris@16 357 template<class AE>
Chris@16 358 BOOST_UBLAS_INLINE
Chris@16 359 banded_matrix& operator += (const matrix_expression<AE> &ae) {
Chris@16 360 self_type temporary (*this + ae, lower_, upper_);
Chris@16 361 return assign_temporary (temporary);
Chris@16 362 }
Chris@16 363 template<class AE>
Chris@16 364 BOOST_UBLAS_INLINE
Chris@16 365 banded_matrix &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 366 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 367 return *this;
Chris@16 368 }
Chris@16 369 template<class AE>
Chris@16 370 BOOST_UBLAS_INLINE
Chris@16 371 banded_matrix& operator -= (const matrix_expression<AE> &ae) {
Chris@16 372 self_type temporary (*this - ae, lower_, upper_);
Chris@16 373 return assign_temporary (temporary);
Chris@16 374 }
Chris@16 375 template<class AE>
Chris@16 376 BOOST_UBLAS_INLINE
Chris@16 377 banded_matrix &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 378 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 379 return *this;
Chris@16 380 }
Chris@16 381 template<class AT>
Chris@16 382 BOOST_UBLAS_INLINE
Chris@16 383 banded_matrix& operator *= (const AT &at) {
Chris@16 384 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 385 return *this;
Chris@16 386 }
Chris@16 387 template<class AT>
Chris@16 388 BOOST_UBLAS_INLINE
Chris@16 389 banded_matrix& operator /= (const AT &at) {
Chris@16 390 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 391 return *this;
Chris@16 392 }
Chris@16 393
Chris@16 394 // Swapping
Chris@16 395 BOOST_UBLAS_INLINE
Chris@16 396 void swap (banded_matrix &m) {
Chris@16 397 if (this != &m) {
Chris@16 398 std::swap (size1_, m.size1_);
Chris@16 399 std::swap (size2_, m.size2_);
Chris@16 400 std::swap (lower_, m.lower_);
Chris@16 401 std::swap (upper_, m.upper_);
Chris@16 402 data ().swap (m.data ());
Chris@16 403 }
Chris@16 404 }
Chris@16 405 BOOST_UBLAS_INLINE
Chris@16 406 friend void swap (banded_matrix &m1, banded_matrix &m2) {
Chris@16 407 m1.swap (m2);
Chris@16 408 }
Chris@16 409
Chris@16 410 // Iterator types
Chris@16 411 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 412 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
Chris@16 413 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
Chris@16 414 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
Chris@16 415 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
Chris@16 416 #else
Chris@16 417 class const_iterator1;
Chris@16 418 class iterator1;
Chris@16 419 class const_iterator2;
Chris@16 420 class iterator2;
Chris@16 421 #endif
Chris@16 422 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 423 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 424 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 425 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 426
Chris@16 427 // Element lookup
Chris@16 428 BOOST_UBLAS_INLINE
Chris@16 429 const_iterator1 find1 (int rank, size_type i, size_type j) const {
Chris@16 430 if (rank == 1) {
Chris@16 431 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
Chris@16 432 i = (std::max) (i, lower_i);
Chris@16 433 size_type upper_i = (std::min) (j + 1 + lower_, size1_);
Chris@16 434 i = (std::min) (i, upper_i);
Chris@16 435 }
Chris@16 436 return const_iterator1 (*this, i, j);
Chris@16 437 }
Chris@16 438 BOOST_UBLAS_INLINE
Chris@16 439 iterator1 find1 (int rank, size_type i, size_type j) {
Chris@16 440 if (rank == 1) {
Chris@16 441 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
Chris@16 442 i = (std::max) (i, lower_i);
Chris@16 443 size_type upper_i = (std::min) (j + 1 + lower_, size1_);
Chris@16 444 i = (std::min) (i, upper_i);
Chris@16 445 }
Chris@16 446 return iterator1 (*this, i, j);
Chris@16 447 }
Chris@16 448 BOOST_UBLAS_INLINE
Chris@16 449 const_iterator2 find2 (int rank, size_type i, size_type j) const {
Chris@16 450 if (rank == 1) {
Chris@16 451 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
Chris@16 452 j = (std::max) (j, lower_j);
Chris@16 453 size_type upper_j = (std::min) (i + 1 + upper_, size2_);
Chris@16 454 j = (std::min) (j, upper_j);
Chris@16 455 }
Chris@16 456 return const_iterator2 (*this, i, j);
Chris@16 457 }
Chris@16 458 BOOST_UBLAS_INLINE
Chris@16 459 iterator2 find2 (int rank, size_type i, size_type j) {
Chris@16 460 if (rank == 1) {
Chris@16 461 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
Chris@16 462 j = (std::max) (j, lower_j);
Chris@16 463 size_type upper_j = (std::min) (i + 1 + upper_, size2_);
Chris@16 464 j = (std::min) (j, upper_j);
Chris@16 465 }
Chris@16 466 return iterator2 (*this, i, j);
Chris@16 467 }
Chris@16 468
Chris@16 469 // Iterators simply are indices.
Chris@16 470
Chris@16 471 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 472 class const_iterator1:
Chris@16 473 public container_const_reference<banded_matrix>,
Chris@16 474 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 475 const_iterator1, value_type> {
Chris@16 476 public:
Chris@16 477 typedef typename banded_matrix::value_type value_type;
Chris@16 478 typedef typename banded_matrix::difference_type difference_type;
Chris@16 479 typedef typename banded_matrix::const_reference reference;
Chris@16 480 typedef const typename banded_matrix::pointer pointer;
Chris@16 481
Chris@16 482 typedef const_iterator2 dual_iterator_type;
Chris@16 483 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 484
Chris@16 485 // Construction and destruction
Chris@16 486 BOOST_UBLAS_INLINE
Chris@16 487 const_iterator1 ():
Chris@16 488 container_const_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 489 BOOST_UBLAS_INLINE
Chris@16 490 const_iterator1 (const self_type &m, size_type it1, size_type it2):
Chris@16 491 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 492 BOOST_UBLAS_INLINE
Chris@16 493 const_iterator1 (const iterator1 &it):
Chris@16 494 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
Chris@16 495
Chris@16 496 // Arithmetic
Chris@16 497 BOOST_UBLAS_INLINE
Chris@16 498 const_iterator1 &operator ++ () {
Chris@16 499 ++ it1_;
Chris@16 500 return *this;
Chris@16 501 }
Chris@16 502 BOOST_UBLAS_INLINE
Chris@16 503 const_iterator1 &operator -- () {
Chris@16 504 -- it1_;
Chris@16 505 return *this;
Chris@16 506 }
Chris@16 507 BOOST_UBLAS_INLINE
Chris@16 508 const_iterator1 &operator += (difference_type n) {
Chris@16 509 it1_ += n;
Chris@16 510 return *this;
Chris@16 511 }
Chris@16 512 BOOST_UBLAS_INLINE
Chris@16 513 const_iterator1 &operator -= (difference_type n) {
Chris@16 514 it1_ -= n;
Chris@16 515 return *this;
Chris@16 516 }
Chris@16 517 BOOST_UBLAS_INLINE
Chris@16 518 difference_type operator - (const const_iterator1 &it) const {
Chris@16 519 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 520 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 521 return it1_ - it.it1_;
Chris@16 522 }
Chris@16 523
Chris@16 524 // Dereference
Chris@16 525 BOOST_UBLAS_INLINE
Chris@16 526 const_reference operator * () const {
Chris@16 527 return (*this) () (it1_, it2_);
Chris@16 528 }
Chris@16 529 BOOST_UBLAS_INLINE
Chris@16 530 const_reference operator [] (difference_type n) const {
Chris@16 531 return *(*this + n);
Chris@16 532 }
Chris@16 533
Chris@16 534 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 535 BOOST_UBLAS_INLINE
Chris@16 536 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 537 typename self_type::
Chris@16 538 #endif
Chris@16 539 const_iterator2 begin () const {
Chris@16 540 return (*this) ().find2 (1, it1_, 0);
Chris@16 541 }
Chris@16 542 BOOST_UBLAS_INLINE
Chris@16 543 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 544 typename self_type::
Chris@16 545 #endif
Chris@101 546 const_iterator2 cbegin () const {
Chris@101 547 return begin ();
Chris@101 548 }
Chris@101 549 BOOST_UBLAS_INLINE
Chris@101 550 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 551 typename self_type::
Chris@101 552 #endif
Chris@16 553 const_iterator2 end () const {
Chris@16 554 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
Chris@16 555 }
Chris@16 556 BOOST_UBLAS_INLINE
Chris@16 557 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 558 typename self_type::
Chris@16 559 #endif
Chris@101 560 const_iterator2 cend () const {
Chris@101 561 return end ();
Chris@101 562 }
Chris@101 563 BOOST_UBLAS_INLINE
Chris@101 564 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 565 typename self_type::
Chris@101 566 #endif
Chris@16 567 const_reverse_iterator2 rbegin () const {
Chris@16 568 return const_reverse_iterator2 (end ());
Chris@16 569 }
Chris@16 570 BOOST_UBLAS_INLINE
Chris@16 571 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 572 typename self_type::
Chris@16 573 #endif
Chris@101 574 const_reverse_iterator2 crbegin () const {
Chris@101 575 return rbegin ();
Chris@101 576 }
Chris@101 577 BOOST_UBLAS_INLINE
Chris@101 578 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 579 typename self_type::
Chris@101 580 #endif
Chris@16 581 const_reverse_iterator2 rend () const {
Chris@16 582 return const_reverse_iterator2 (begin ());
Chris@16 583 }
Chris@101 584 BOOST_UBLAS_INLINE
Chris@101 585 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 586 typename self_type::
Chris@101 587 #endif
Chris@101 588 const_reverse_iterator2 crend () const {
Chris@101 589 return rend ();
Chris@101 590 }
Chris@16 591 #endif
Chris@16 592
Chris@16 593 // Indices
Chris@16 594 BOOST_UBLAS_INLINE
Chris@16 595 size_type index1 () const {
Chris@16 596 return it1_;
Chris@16 597 }
Chris@16 598 BOOST_UBLAS_INLINE
Chris@16 599 size_type index2 () const {
Chris@16 600 return it2_;
Chris@16 601 }
Chris@16 602
Chris@16 603 // Assignment
Chris@16 604 BOOST_UBLAS_INLINE
Chris@16 605 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 606 container_const_reference<self_type>::assign (&it ());
Chris@16 607 it1_ = it.it1_;
Chris@16 608 it2_ = it.it2_;
Chris@16 609 return *this;
Chris@16 610 }
Chris@16 611
Chris@16 612 // Comparison
Chris@16 613 BOOST_UBLAS_INLINE
Chris@16 614 bool operator == (const const_iterator1 &it) const {
Chris@16 615 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 616 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 617 return it1_ == it.it1_;
Chris@16 618 }
Chris@16 619 BOOST_UBLAS_INLINE
Chris@16 620 bool operator < (const const_iterator1 &it) const {
Chris@16 621 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 622 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 623 return it1_ < it.it1_;
Chris@16 624 }
Chris@16 625
Chris@16 626 private:
Chris@16 627 size_type it1_;
Chris@16 628 size_type it2_;
Chris@16 629 };
Chris@16 630 #endif
Chris@16 631
Chris@16 632 BOOST_UBLAS_INLINE
Chris@16 633 const_iterator1 begin1 () const {
Chris@16 634 return find1 (0, 0, 0);
Chris@16 635 }
Chris@16 636 BOOST_UBLAS_INLINE
Chris@101 637 const_iterator1 cbegin1 () const {
Chris@101 638 return begin1 ();
Chris@101 639 }
Chris@101 640 BOOST_UBLAS_INLINE
Chris@16 641 const_iterator1 end1 () const {
Chris@16 642 return find1 (0, size1_, 0);
Chris@16 643 }
Chris@101 644 BOOST_UBLAS_INLINE
Chris@101 645 const_iterator1 cend1 () const {
Chris@101 646 return end1 ();
Chris@101 647 }
Chris@16 648
Chris@16 649 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 650 class iterator1:
Chris@16 651 public container_reference<banded_matrix>,
Chris@16 652 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 653 iterator1, value_type> {
Chris@16 654 public:
Chris@16 655 typedef typename banded_matrix::value_type value_type;
Chris@16 656 typedef typename banded_matrix::difference_type difference_type;
Chris@16 657 typedef typename banded_matrix::reference reference;
Chris@16 658 typedef typename banded_matrix::pointer pointer;
Chris@16 659
Chris@16 660 typedef iterator2 dual_iterator_type;
Chris@16 661 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 662
Chris@16 663 // Construction and destruction
Chris@16 664 BOOST_UBLAS_INLINE
Chris@16 665 iterator1 ():
Chris@16 666 container_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 667 BOOST_UBLAS_INLINE
Chris@16 668 iterator1 (self_type &m, size_type it1, size_type it2):
Chris@16 669 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 670
Chris@16 671 // Arithmetic
Chris@16 672 BOOST_UBLAS_INLINE
Chris@16 673 iterator1 &operator ++ () {
Chris@16 674 ++ it1_;
Chris@16 675 return *this;
Chris@16 676 }
Chris@16 677 BOOST_UBLAS_INLINE
Chris@16 678 iterator1 &operator -- () {
Chris@16 679 -- it1_;
Chris@16 680 return *this;
Chris@16 681 }
Chris@16 682 BOOST_UBLAS_INLINE
Chris@16 683 iterator1 &operator += (difference_type n) {
Chris@16 684 it1_ += n;
Chris@16 685 return *this;
Chris@16 686 }
Chris@16 687 BOOST_UBLAS_INLINE
Chris@16 688 iterator1 &operator -= (difference_type n) {
Chris@16 689 it1_ -= n;
Chris@16 690 return *this;
Chris@16 691 }
Chris@16 692 BOOST_UBLAS_INLINE
Chris@16 693 difference_type operator - (const iterator1 &it) const {
Chris@16 694 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 695 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 696 return it1_ - it.it1_;
Chris@16 697 }
Chris@16 698
Chris@16 699 // Dereference
Chris@16 700 BOOST_UBLAS_INLINE
Chris@16 701 reference operator * () const {
Chris@16 702 return (*this) ().at_element (it1_, it2_);
Chris@16 703 }
Chris@16 704 BOOST_UBLAS_INLINE
Chris@16 705 reference operator [] (difference_type n) const {
Chris@16 706 return *(*this + n);
Chris@16 707 }
Chris@16 708
Chris@16 709 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 710 BOOST_UBLAS_INLINE
Chris@16 711 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 712 typename self_type::
Chris@16 713 #endif
Chris@16 714 iterator2 begin () const {
Chris@16 715 return (*this) ().find2 (1, it1_, 0);
Chris@16 716 }
Chris@16 717 BOOST_UBLAS_INLINE
Chris@16 718 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 719 typename self_type::
Chris@16 720 #endif
Chris@16 721 iterator2 end () const {
Chris@16 722 return (*this) ().find2 (1, it1_, (*this) ().size2 ());
Chris@16 723 }
Chris@101 724
Chris@16 725 BOOST_UBLAS_INLINE
Chris@16 726 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 727 typename self_type::
Chris@16 728 #endif
Chris@16 729 reverse_iterator2 rbegin () const {
Chris@16 730 return reverse_iterator2 (end ());
Chris@16 731 }
Chris@16 732 BOOST_UBLAS_INLINE
Chris@16 733 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 734 typename self_type::
Chris@16 735 #endif
Chris@16 736 reverse_iterator2 rend () const {
Chris@16 737 return reverse_iterator2 (begin ());
Chris@16 738 }
Chris@16 739 #endif
Chris@16 740
Chris@16 741 // Indices
Chris@16 742 BOOST_UBLAS_INLINE
Chris@16 743 size_type index1 () const {
Chris@16 744 return it1_;
Chris@16 745 }
Chris@16 746 BOOST_UBLAS_INLINE
Chris@16 747 size_type index2 () const {
Chris@16 748 return it2_;
Chris@16 749 }
Chris@16 750
Chris@16 751 // Assignment
Chris@16 752 BOOST_UBLAS_INLINE
Chris@16 753 iterator1 &operator = (const iterator1 &it) {
Chris@16 754 container_reference<self_type>::assign (&it ());
Chris@16 755 it1_ = it.it1_;
Chris@16 756 it2_ = it.it2_;
Chris@16 757 return *this;
Chris@16 758 }
Chris@16 759
Chris@16 760 // Comparison
Chris@16 761 BOOST_UBLAS_INLINE
Chris@16 762 bool operator == (const iterator1 &it) const {
Chris@16 763 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 764 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 765 return it1_ == it.it1_;
Chris@16 766 }
Chris@16 767 BOOST_UBLAS_INLINE
Chris@16 768 bool operator < (const iterator1 &it) const {
Chris@16 769 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 770 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 771 return it1_ < it.it1_;
Chris@16 772 }
Chris@16 773
Chris@16 774 private:
Chris@16 775 size_type it1_;
Chris@16 776 size_type it2_;
Chris@16 777
Chris@16 778 friend class const_iterator1;
Chris@16 779 };
Chris@16 780 #endif
Chris@16 781
Chris@16 782 BOOST_UBLAS_INLINE
Chris@16 783 iterator1 begin1 () {
Chris@16 784 return find1 (0, 0, 0);
Chris@16 785 }
Chris@16 786 BOOST_UBLAS_INLINE
Chris@16 787 iterator1 end1 () {
Chris@16 788 return find1 (0, size1_, 0);
Chris@16 789 }
Chris@16 790
Chris@16 791 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 792 class const_iterator2:
Chris@16 793 public container_const_reference<banded_matrix>,
Chris@16 794 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 795 const_iterator2, value_type> {
Chris@16 796 public:
Chris@16 797 typedef typename banded_matrix::value_type value_type;
Chris@16 798 typedef typename banded_matrix::difference_type difference_type;
Chris@16 799 typedef typename banded_matrix::const_reference reference;
Chris@16 800 typedef const typename banded_matrix::pointer pointer;
Chris@16 801
Chris@16 802 typedef const_iterator1 dual_iterator_type;
Chris@16 803 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 804
Chris@16 805 // Construction and destruction
Chris@16 806 BOOST_UBLAS_INLINE
Chris@16 807 const_iterator2 ():
Chris@16 808 container_const_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 809 BOOST_UBLAS_INLINE
Chris@16 810 const_iterator2 (const self_type &m, size_type it1, size_type it2):
Chris@16 811 container_const_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 812 BOOST_UBLAS_INLINE
Chris@16 813 const_iterator2 (const iterator2 &it):
Chris@16 814 container_const_reference<self_type> (it ()), it1_ (it.it1_), it2_ (it.it2_) {}
Chris@16 815
Chris@16 816 // Arithmetic
Chris@16 817 BOOST_UBLAS_INLINE
Chris@16 818 const_iterator2 &operator ++ () {
Chris@16 819 ++ it2_;
Chris@16 820 return *this;
Chris@16 821 }
Chris@16 822 BOOST_UBLAS_INLINE
Chris@16 823 const_iterator2 &operator -- () {
Chris@16 824 -- it2_;
Chris@16 825 return *this;
Chris@16 826 }
Chris@16 827 BOOST_UBLAS_INLINE
Chris@16 828 const_iterator2 &operator += (difference_type n) {
Chris@16 829 it2_ += n;
Chris@16 830 return *this;
Chris@16 831 }
Chris@16 832 BOOST_UBLAS_INLINE
Chris@16 833 const_iterator2 &operator -= (difference_type n) {
Chris@16 834 it2_ -= n;
Chris@16 835 return *this;
Chris@16 836 }
Chris@16 837 BOOST_UBLAS_INLINE
Chris@16 838 difference_type operator - (const const_iterator2 &it) const {
Chris@16 839 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 840 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 841 return it2_ - it.it2_;
Chris@16 842 }
Chris@16 843
Chris@16 844 // Dereference
Chris@16 845 BOOST_UBLAS_INLINE
Chris@16 846 const_reference operator * () const {
Chris@16 847 return (*this) () (it1_, it2_);
Chris@16 848 }
Chris@16 849 BOOST_UBLAS_INLINE
Chris@16 850 const_reference operator [] (difference_type n) const {
Chris@16 851 return *(*this + n);
Chris@16 852 }
Chris@16 853
Chris@16 854 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 855 BOOST_UBLAS_INLINE
Chris@16 856 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 857 typename self_type::
Chris@16 858 #endif
Chris@16 859 const_iterator1 begin () const {
Chris@16 860 return (*this) ().find1 (1, 0, it2_);
Chris@16 861 }
Chris@16 862 BOOST_UBLAS_INLINE
Chris@16 863 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 864 typename self_type::
Chris@16 865 #endif
Chris@101 866 const_iterator1 cbegin () const {
Chris@101 867 return begin ();
Chris@101 868 }
Chris@101 869 BOOST_UBLAS_INLINE
Chris@101 870 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 871 typename self_type::
Chris@101 872 #endif
Chris@16 873 const_iterator1 end () const {
Chris@16 874 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
Chris@16 875 }
Chris@16 876 BOOST_UBLAS_INLINE
Chris@16 877 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 878 typename self_type::
Chris@16 879 #endif
Chris@101 880 const_iterator1 cend () const {
Chris@101 881 return end();
Chris@101 882 }
Chris@101 883
Chris@101 884 BOOST_UBLAS_INLINE
Chris@101 885 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 886 typename self_type::
Chris@101 887 #endif
Chris@16 888 const_reverse_iterator1 rbegin () const {
Chris@16 889 return const_reverse_iterator1 (end ());
Chris@16 890 }
Chris@16 891 BOOST_UBLAS_INLINE
Chris@16 892 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 893 typename self_type::
Chris@16 894 #endif
Chris@101 895 const_reverse_iterator1 crbegin () const {
Chris@101 896 return rbegin ();
Chris@101 897 }
Chris@101 898 BOOST_UBLAS_INLINE
Chris@101 899 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 900 typename self_type::
Chris@101 901 #endif
Chris@16 902 const_reverse_iterator1 rend () const {
Chris@16 903 return const_reverse_iterator1 (begin ());
Chris@16 904 }
Chris@101 905 BOOST_UBLAS_INLINE
Chris@101 906 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 907 typename self_type::
Chris@101 908 #endif
Chris@101 909 const_reverse_iterator1 crend () const {
Chris@101 910 return rend ();
Chris@101 911 }
Chris@16 912 #endif
Chris@16 913
Chris@16 914 // Indices
Chris@16 915 BOOST_UBLAS_INLINE
Chris@16 916 size_type index1 () const {
Chris@16 917 return it1_;
Chris@16 918 }
Chris@16 919 BOOST_UBLAS_INLINE
Chris@16 920 size_type index2 () const {
Chris@16 921 return it2_;
Chris@16 922 }
Chris@16 923
Chris@16 924 // Assignment
Chris@16 925 BOOST_UBLAS_INLINE
Chris@16 926 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 927 container_const_reference<self_type>::assign (&it ());
Chris@16 928 it1_ = it.it1_;
Chris@16 929 it2_ = it.it2_;
Chris@16 930 return *this;
Chris@16 931 }
Chris@16 932
Chris@16 933 // Comparison
Chris@16 934 BOOST_UBLAS_INLINE
Chris@16 935 bool operator == (const const_iterator2 &it) const {
Chris@16 936 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 937 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 938 return it2_ == it.it2_;
Chris@16 939 }
Chris@16 940 BOOST_UBLAS_INLINE
Chris@16 941 bool operator < (const const_iterator2 &it) const {
Chris@16 942 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 943 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 944 return it2_ < it.it2_;
Chris@16 945 }
Chris@16 946
Chris@16 947 private:
Chris@16 948 size_type it1_;
Chris@16 949 size_type it2_;
Chris@16 950 };
Chris@16 951 #endif
Chris@16 952
Chris@16 953 BOOST_UBLAS_INLINE
Chris@16 954 const_iterator2 begin2 () const {
Chris@16 955 return find2 (0, 0, 0);
Chris@16 956 }
Chris@16 957 BOOST_UBLAS_INLINE
Chris@101 958 const_iterator2 cbegin2 () const {
Chris@101 959 return begin2 ();
Chris@101 960 }
Chris@101 961 BOOST_UBLAS_INLINE
Chris@16 962 const_iterator2 end2 () const {
Chris@16 963 return find2 (0, 0, size2_);
Chris@16 964 }
Chris@101 965 BOOST_UBLAS_INLINE
Chris@101 966 const_iterator2 cend2 () const {
Chris@101 967 return end2 ();
Chris@101 968 }
Chris@16 969
Chris@16 970 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 971 class iterator2:
Chris@16 972 public container_reference<banded_matrix>,
Chris@16 973 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 974 iterator2, value_type> {
Chris@16 975 public:
Chris@16 976 typedef typename banded_matrix::value_type value_type;
Chris@16 977 typedef typename banded_matrix::difference_type difference_type;
Chris@16 978 typedef typename banded_matrix::reference reference;
Chris@16 979 typedef typename banded_matrix::pointer pointer;
Chris@16 980
Chris@16 981 typedef iterator1 dual_iterator_type;
Chris@16 982 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 983
Chris@16 984 // Construction and destruction
Chris@16 985 BOOST_UBLAS_INLINE
Chris@16 986 iterator2 ():
Chris@16 987 container_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 988 BOOST_UBLAS_INLINE
Chris@16 989 iterator2 (self_type &m, size_type it1, size_type it2):
Chris@16 990 container_reference<self_type> (m), it1_ (it1), it2_ (it2) {}
Chris@16 991
Chris@16 992 // Arithmetic
Chris@16 993 BOOST_UBLAS_INLINE
Chris@16 994 iterator2 &operator ++ () {
Chris@16 995 ++ it2_;
Chris@16 996 return *this;
Chris@16 997 }
Chris@16 998 BOOST_UBLAS_INLINE
Chris@16 999 iterator2 &operator -- () {
Chris@16 1000 -- it2_;
Chris@16 1001 return *this;
Chris@16 1002 }
Chris@16 1003 BOOST_UBLAS_INLINE
Chris@16 1004 iterator2 &operator += (difference_type n) {
Chris@16 1005 it2_ += n;
Chris@16 1006 return *this;
Chris@16 1007 }
Chris@16 1008 BOOST_UBLAS_INLINE
Chris@16 1009 iterator2 &operator -= (difference_type n) {
Chris@16 1010 it2_ -= n;
Chris@16 1011 return *this;
Chris@16 1012 }
Chris@16 1013 BOOST_UBLAS_INLINE
Chris@16 1014 difference_type operator - (const iterator2 &it) const {
Chris@16 1015 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1016 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1017 return it2_ - it.it2_;
Chris@16 1018 }
Chris@16 1019
Chris@16 1020 // Dereference
Chris@16 1021 BOOST_UBLAS_INLINE
Chris@16 1022 reference operator * () const {
Chris@16 1023 return (*this) ().at_element (it1_, it2_);
Chris@16 1024 }
Chris@16 1025 BOOST_UBLAS_INLINE
Chris@16 1026 reference operator [] (difference_type n) const {
Chris@16 1027 return *(*this + n);
Chris@16 1028 }
Chris@16 1029
Chris@16 1030 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1031 BOOST_UBLAS_INLINE
Chris@16 1032 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1033 typename self_type::
Chris@16 1034 #endif
Chris@16 1035 iterator1 begin () const {
Chris@16 1036 return (*this) ().find1 (1, 0, it2_);
Chris@16 1037 }
Chris@16 1038 BOOST_UBLAS_INLINE
Chris@16 1039 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1040 typename self_type::
Chris@16 1041 #endif
Chris@16 1042 iterator1 end () const {
Chris@16 1043 return (*this) ().find1 (1, (*this) ().size1 (), it2_);
Chris@16 1044 }
Chris@16 1045 BOOST_UBLAS_INLINE
Chris@16 1046 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1047 typename self_type::
Chris@16 1048 #endif
Chris@16 1049 reverse_iterator1 rbegin () const {
Chris@16 1050 return reverse_iterator1 (end ());
Chris@16 1051 }
Chris@16 1052 BOOST_UBLAS_INLINE
Chris@16 1053 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1054 typename self_type::
Chris@16 1055 #endif
Chris@16 1056 reverse_iterator1 rend () const {
Chris@16 1057 return reverse_iterator1 (begin ());
Chris@16 1058 }
Chris@16 1059 #endif
Chris@16 1060
Chris@16 1061 // Indices
Chris@16 1062 BOOST_UBLAS_INLINE
Chris@16 1063 size_type index1 () const {
Chris@16 1064 return it1_;
Chris@16 1065 }
Chris@16 1066 BOOST_UBLAS_INLINE
Chris@16 1067 size_type index2 () const {
Chris@16 1068 return it2_;
Chris@16 1069 }
Chris@16 1070
Chris@16 1071 // Assignment
Chris@16 1072 BOOST_UBLAS_INLINE
Chris@16 1073 iterator2 &operator = (const iterator2 &it) {
Chris@16 1074 container_reference<self_type>::assign (&it ());
Chris@16 1075 it1_ = it.it1_;
Chris@16 1076 it2_ = it.it2_;
Chris@16 1077 return *this;
Chris@16 1078 }
Chris@16 1079
Chris@16 1080 // Comparison
Chris@16 1081 BOOST_UBLAS_INLINE
Chris@16 1082 bool operator == (const iterator2 &it) const {
Chris@16 1083 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1084 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1085 return it2_ == it.it2_;
Chris@16 1086 }
Chris@16 1087 BOOST_UBLAS_INLINE
Chris@16 1088 bool operator < (const iterator2 &it) const {
Chris@16 1089 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1090 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1091 return it2_ < it.it2_;
Chris@16 1092 }
Chris@16 1093
Chris@16 1094 private:
Chris@16 1095 size_type it1_;
Chris@16 1096 size_type it2_;
Chris@16 1097
Chris@16 1098 friend class const_iterator2;
Chris@16 1099 };
Chris@16 1100 #endif
Chris@16 1101
Chris@16 1102 BOOST_UBLAS_INLINE
Chris@16 1103 iterator2 begin2 () {
Chris@16 1104 return find2 (0, 0, 0);
Chris@16 1105 }
Chris@16 1106 BOOST_UBLAS_INLINE
Chris@16 1107 iterator2 end2 () {
Chris@16 1108 return find2 (0, 0, size2_);
Chris@16 1109 }
Chris@16 1110
Chris@16 1111 // Reverse iterators
Chris@16 1112
Chris@16 1113 BOOST_UBLAS_INLINE
Chris@16 1114 const_reverse_iterator1 rbegin1 () const {
Chris@16 1115 return const_reverse_iterator1 (end1 ());
Chris@16 1116 }
Chris@16 1117 BOOST_UBLAS_INLINE
Chris@101 1118 const_reverse_iterator1 crbegin1 () const {
Chris@101 1119 return rbegin1 ();
Chris@101 1120 }
Chris@101 1121 BOOST_UBLAS_INLINE
Chris@16 1122 const_reverse_iterator1 rend1 () const {
Chris@16 1123 return const_reverse_iterator1 (begin1 ());
Chris@16 1124 }
Chris@101 1125 BOOST_UBLAS_INLINE
Chris@101 1126 const_reverse_iterator1 crend1 () const {
Chris@101 1127 return rend1 ();
Chris@101 1128 }
Chris@16 1129
Chris@16 1130 BOOST_UBLAS_INLINE
Chris@16 1131 reverse_iterator1 rbegin1 () {
Chris@16 1132 return reverse_iterator1 (end1 ());
Chris@16 1133 }
Chris@16 1134 BOOST_UBLAS_INLINE
Chris@16 1135 reverse_iterator1 rend1 () {
Chris@16 1136 return reverse_iterator1 (begin1 ());
Chris@16 1137 }
Chris@16 1138
Chris@16 1139 BOOST_UBLAS_INLINE
Chris@16 1140 const_reverse_iterator2 rbegin2 () const {
Chris@16 1141 return const_reverse_iterator2 (end2 ());
Chris@16 1142 }
Chris@16 1143 BOOST_UBLAS_INLINE
Chris@101 1144 const_reverse_iterator2 crbegin2 () const {
Chris@101 1145 return rbegin2 ();
Chris@101 1146 }
Chris@101 1147 BOOST_UBLAS_INLINE
Chris@16 1148 const_reverse_iterator2 rend2 () const {
Chris@16 1149 return const_reverse_iterator2 (begin2 ());
Chris@16 1150 }
Chris@101 1151 BOOST_UBLAS_INLINE
Chris@101 1152 const_reverse_iterator2 crend2 () const {
Chris@101 1153 return rend2 ();
Chris@101 1154 }
Chris@16 1155
Chris@16 1156 BOOST_UBLAS_INLINE
Chris@16 1157 reverse_iterator2 rbegin2 () {
Chris@16 1158 return reverse_iterator2 (end2 ());
Chris@16 1159 }
Chris@16 1160 BOOST_UBLAS_INLINE
Chris@16 1161 reverse_iterator2 rend2 () {
Chris@16 1162 return reverse_iterator2 (begin2 ());
Chris@16 1163 }
Chris@16 1164
Chris@16 1165 private:
Chris@16 1166 size_type size1_;
Chris@16 1167 size_type size2_;
Chris@16 1168 size_type lower_;
Chris@16 1169 size_type upper_;
Chris@16 1170 array_type data_;
Chris@16 1171 typedef const value_type const_value_type;
Chris@16 1172 static const_value_type zero_;
Chris@16 1173 };
Chris@16 1174
Chris@16 1175 template<class T, class L, class A>
Chris@16 1176 typename banded_matrix<T, L, A>::const_value_type banded_matrix<T, L, A>::zero_ = value_type/*zero*/();
Chris@16 1177
Chris@16 1178
Chris@16 1179 /** \brief A diagonal matrix of values of type \c T, which is a specialization of a banded matrix
Chris@16 1180 *
Chris@16 1181 * For a \f$(m\times m)\f$-dimensional diagonal matrix, \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$,
Chris@16 1182 * if \f$i\neq j\f$ then \f$b_{i,j}=0\f$. The default storage for diagonal matrices is packed.
Chris@16 1183 * Orientation and storage can also be specified. Default is \c row major \c unbounded_array.
Chris@16 1184 *
Chris@16 1185 * As a specialization of a banded matrix, the constructor of the diagonal matrix creates
Chris@16 1186 * a banded matrix with 0 upper and lower diagonals around the main diagonal and the matrix is
Chris@16 1187 * obviously a square matrix. Operations are optimized based on these 2 assumptions. It is
Chris@16 1188 * \b not required by the storage to initialize elements of the matrix.
Chris@16 1189 *
Chris@16 1190 * \tparam T the type of object stored in the matrix (like double, float, complex, etc...)
Chris@16 1191 * \tparam L the storage organization. It can be either \c row_major or \c column_major. Default is \c row_major
Chris@16 1192 * \tparam A the type of Storage array. Default is \c unbounded_array
Chris@16 1193 */
Chris@16 1194 template<class T, class L, class A>
Chris@16 1195 class diagonal_matrix:
Chris@16 1196 public banded_matrix<T, L, A> {
Chris@16 1197 public:
Chris@16 1198 typedef typename A::size_type size_type;
Chris@16 1199 typedef banded_matrix<T, L, A> matrix_type;
Chris@16 1200 typedef A array_type;
Chris@16 1201
Chris@16 1202 // Construction and destruction
Chris@16 1203 BOOST_UBLAS_INLINE
Chris@16 1204 diagonal_matrix ():
Chris@16 1205 matrix_type () {}
Chris@16 1206 BOOST_UBLAS_INLINE
Chris@16 1207 diagonal_matrix (size_type size):
Chris@16 1208 matrix_type (size, size) {}
Chris@16 1209 BOOST_UBLAS_INLINE
Chris@16 1210 diagonal_matrix (size_type size, const array_type& data):
Chris@16 1211 matrix_type (size, size, 0, 0, data) {}
Chris@16 1212 BOOST_UBLAS_INLINE
Chris@16 1213 diagonal_matrix (size_type size1, size_type size2):
Chris@16 1214 matrix_type (size1, size2) {}
Chris@16 1215 template<class AE>
Chris@16 1216 BOOST_UBLAS_INLINE
Chris@16 1217 diagonal_matrix (const matrix_expression<AE> &ae):
Chris@16 1218 matrix_type (ae) {}
Chris@16 1219 BOOST_UBLAS_INLINE
Chris@16 1220 ~diagonal_matrix () {}
Chris@16 1221
Chris@16 1222 // Assignment
Chris@16 1223 BOOST_UBLAS_INLINE
Chris@16 1224 diagonal_matrix &operator = (const diagonal_matrix &m) {
Chris@16 1225 matrix_type::operator = (m);
Chris@16 1226 return *this;
Chris@16 1227 }
Chris@16 1228 template<class AE>
Chris@16 1229 BOOST_UBLAS_INLINE
Chris@16 1230 diagonal_matrix &operator = (const matrix_expression<AE> &ae) {
Chris@16 1231 matrix_type::operator = (ae);
Chris@16 1232 return *this;
Chris@16 1233 }
Chris@16 1234 };
Chris@16 1235
Chris@16 1236 /** \brief A banded matrix adaptator: convert a any matrix into a banded matrix expression
Chris@16 1237 *
Chris@16 1238 * For a \f$(m\times n)\f$-dimensional matrix, the \c banded_adaptor will provide a banded matrix
Chris@16 1239 * with \f$l\f$ lower and \f$u\f$ upper diagonals and \f$0 \leq i < m\f$ and \f$0 \leq j < n\f$,
Chris@16 1240 * if \f$i>j+l\f$ or \f$i<j-u\f$ then \f$b_{i,j}=0\f$.
Chris@16 1241 *
Chris@16 1242 * Storage and location are based on those of the underlying matrix. This is important because
Chris@16 1243 * a \c banded_adaptor does not copy the matrix data to a new place. Therefore, modifying values
Chris@16 1244 * in a \c banded_adaptor matrix will also modify the underlying matrix too.
Chris@16 1245 *
Chris@16 1246 * \tparam M the type of matrix used to generate a banded matrix
Chris@16 1247 */
Chris@16 1248 template<class M>
Chris@16 1249 class banded_adaptor:
Chris@16 1250 public matrix_expression<banded_adaptor<M> > {
Chris@16 1251
Chris@16 1252 typedef banded_adaptor<M> self_type;
Chris@101 1253
Chris@16 1254 public:
Chris@16 1255 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 1256 using matrix_expression<self_type>::operator ();
Chris@16 1257 #endif
Chris@16 1258 typedef const M const_matrix_type;
Chris@16 1259 typedef M matrix_type;
Chris@16 1260 typedef typename M::size_type size_type;
Chris@16 1261 typedef typename M::difference_type difference_type;
Chris@16 1262 typedef typename M::value_type value_type;
Chris@16 1263 typedef typename M::const_reference const_reference;
Chris@16 1264 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1265 typename M::const_reference,
Chris@16 1266 typename M::reference>::type reference;
Chris@16 1267 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1268 typename M::const_closure_type,
Chris@16 1269 typename M::closure_type>::type matrix_closure_type;
Chris@16 1270 typedef const self_type const_closure_type;
Chris@16 1271 typedef self_type closure_type;
Chris@16 1272 // Replaced by _temporary_traits to avoid type requirements on M
Chris@16 1273 //typedef typename M::vector_temporary_type vector_temporary_type;
Chris@16 1274 //typedef typename M::matrix_temporary_type matrix_temporary_type;
Chris@16 1275 typedef typename storage_restrict_traits<typename M::storage_category,
Chris@16 1276 packed_proxy_tag>::storage_category storage_category;
Chris@16 1277 typedef typename M::orientation_category orientation_category;
Chris@16 1278
Chris@16 1279 // Construction and destruction
Chris@16 1280 BOOST_UBLAS_INLINE
Chris@16 1281 banded_adaptor (matrix_type &data, size_type lower = 0, size_type upper = 0):
Chris@16 1282 matrix_expression<self_type> (),
Chris@16 1283 data_ (data), lower_ (lower), upper_ (upper) {}
Chris@16 1284 BOOST_UBLAS_INLINE
Chris@16 1285 banded_adaptor (const banded_adaptor &m):
Chris@16 1286 matrix_expression<self_type> (),
Chris@16 1287 data_ (m.data_), lower_ (m.lower_), upper_ (m.upper_) {}
Chris@16 1288
Chris@16 1289 // Accessors
Chris@16 1290 BOOST_UBLAS_INLINE
Chris@16 1291 size_type size1 () const {
Chris@16 1292 return data_.size1 ();
Chris@16 1293 }
Chris@16 1294 BOOST_UBLAS_INLINE
Chris@16 1295 size_type size2 () const {
Chris@16 1296 return data_.size2 ();
Chris@16 1297 }
Chris@16 1298 BOOST_UBLAS_INLINE
Chris@16 1299 size_type lower () const {
Chris@16 1300 return lower_;
Chris@16 1301 }
Chris@16 1302 BOOST_UBLAS_INLINE
Chris@16 1303 size_type upper () const {
Chris@16 1304 return upper_;
Chris@16 1305 }
Chris@16 1306
Chris@16 1307 // Storage accessors
Chris@16 1308 BOOST_UBLAS_INLINE
Chris@16 1309 const matrix_closure_type &data () const {
Chris@16 1310 return data_;
Chris@16 1311 }
Chris@16 1312 BOOST_UBLAS_INLINE
Chris@16 1313 matrix_closure_type &data () {
Chris@16 1314 return data_;
Chris@16 1315 }
Chris@16 1316
Chris@101 1317 #if !defined (BOOST_UBLAS_OWN_BANDED)||(BOOST_UBLAS_LEGACY_BANDED)
Chris@101 1318 BOOST_UBLAS_INLINE
Chris@101 1319 bool is_element_in_band(size_type i, size_type j) const{
Chris@101 1320 //return (upper_+i >= j) && i <= std::min(size1() - 1, j + lower_); // We don't need to check if i is outside because it is checked anyway in the accessors.
Chris@101 1321 return (upper_+i >= j) && i <= ( j + lower_); // Essentially this band has "infinite" positive dimensions
Chris@101 1322 }
Chris@101 1323 #endif
Chris@101 1324
Chris@16 1325 // Element access
Chris@16 1326 #ifndef BOOST_UBLAS_PROXY_CONST_MEMBER
Chris@16 1327 BOOST_UBLAS_INLINE
Chris@16 1328 const_reference operator () (size_type i, size_type j) const {
Chris@16 1329 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1330 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1331 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 1332 size_type k = (std::max) (i, j);
Chris@16 1333 size_type l = lower_ + j - i;
Chris@16 1334 if (k < (std::max) (size1 (), size2 ()) &&
Chris@16 1335 l < lower_ + 1 + upper_)
Chris@16 1336 return data () (i, j);
Chris@101 1337 #elif BOOST_UBLAS_LEGACY_BANDED
Chris@16 1338 size_type k = j;
Chris@16 1339 size_type l = upper_ + i - j;
Chris@16 1340 if (k < size2 () &&
Chris@16 1341 l < lower_ + 1 + upper_)
Chris@16 1342 return data () (i, j);
Chris@101 1343 #else
Chris@101 1344 if (is_element_in_band( i, j))
Chris@101 1345 return data () (i, j);
Chris@16 1346 #endif
Chris@16 1347 return zero_;
Chris@16 1348 }
Chris@16 1349 BOOST_UBLAS_INLINE
Chris@16 1350 reference operator () (size_type i, size_type j) {
Chris@16 1351 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1352 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1353 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 1354 size_type k = (std::max) (i, j);
Chris@16 1355 size_type l = lower_ + j - i;
Chris@16 1356 if (k < (std::max) (size1 (), size2 ()) &&
Chris@16 1357 l < lower_ + 1 + upper_)
Chris@16 1358 return data () (i, j);
Chris@101 1359 #elif BOOST_UBLAS_LEGACY_BANDED
Chris@16 1360 size_type k = j;
Chris@16 1361 size_type l = upper_ + i - j;
Chris@16 1362 if (k < size2 () &&
Chris@16 1363 l < lower_ + 1 + upper_)
Chris@16 1364 return data () (i, j);
Chris@101 1365 #else
Chris@101 1366 if (is_element_in_band( i, j))
Chris@101 1367 return data () (i, j);
Chris@16 1368 #endif
Chris@16 1369 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
Chris@16 1370 bad_index ().raise ();
Chris@16 1371 #endif
Chris@16 1372 return const_cast<reference>(zero_);
Chris@16 1373 }
Chris@16 1374 #else
Chris@16 1375 BOOST_UBLAS_INLINE
Chris@16 1376 reference operator () (size_type i, size_type j) const {
Chris@16 1377 BOOST_UBLAS_CHECK (i < size1 (), bad_index ());
Chris@16 1378 BOOST_UBLAS_CHECK (j < size2 (), bad_index ());
Chris@16 1379 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 1380 size_type k = (std::max) (i, j);
Chris@16 1381 size_type l = lower_ + j - i;
Chris@16 1382 if (k < (std::max) (size1 (), size2 ()) &&
Chris@16 1383 l < lower_ + 1 + upper_)
Chris@16 1384 return data () (i, j);
Chris@101 1385 #elif BOOST_UBLAS_LEGACY_BANDED
Chris@16 1386 size_type k = j;
Chris@16 1387 size_type l = upper_ + i - j;
Chris@16 1388 if (k < size2 () &&
Chris@16 1389 l < lower_ + 1 + upper_)
Chris@16 1390 return data () (i, j);
Chris@101 1391 #else
Chris@101 1392 if (is_element_in_band( i, j))
Chris@101 1393 return data () (i, j);
Chris@16 1394 #endif
Chris@16 1395 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
Chris@16 1396 bad_index ().raise ();
Chris@16 1397 #endif
Chris@16 1398 return const_cast<reference>(zero_);
Chris@16 1399 }
Chris@16 1400 #endif
Chris@16 1401
Chris@16 1402 // Assignment
Chris@16 1403 BOOST_UBLAS_INLINE
Chris@16 1404 banded_adaptor &operator = (const banded_adaptor &m) {
Chris@16 1405 matrix_assign<scalar_assign> (*this, m);
Chris@16 1406 return *this;
Chris@16 1407 }
Chris@16 1408 BOOST_UBLAS_INLINE
Chris@16 1409 banded_adaptor &assign_temporary (banded_adaptor &m) {
Chris@16 1410 *this = m;
Chris@16 1411 return *this;
Chris@16 1412 }
Chris@16 1413 template<class AE>
Chris@16 1414 BOOST_UBLAS_INLINE
Chris@16 1415 banded_adaptor &operator = (const matrix_expression<AE> &ae) {
Chris@16 1416 matrix_assign<scalar_assign> (*this, matrix<value_type> (ae));
Chris@16 1417 return *this;
Chris@16 1418 }
Chris@16 1419 template<class AE>
Chris@16 1420 BOOST_UBLAS_INLINE
Chris@16 1421 banded_adaptor &assign (const matrix_expression<AE> &ae) {
Chris@16 1422 matrix_assign<scalar_assign> (*this, ae);
Chris@16 1423 return *this;
Chris@16 1424 }
Chris@16 1425 template<class AE>
Chris@16 1426 BOOST_UBLAS_INLINE
Chris@16 1427 banded_adaptor& operator += (const matrix_expression<AE> &ae) {
Chris@16 1428 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this + ae));
Chris@16 1429 return *this;
Chris@16 1430 }
Chris@16 1431 template<class AE>
Chris@16 1432 BOOST_UBLAS_INLINE
Chris@16 1433 banded_adaptor &plus_assign (const matrix_expression<AE> &ae) {
Chris@16 1434 matrix_assign<scalar_plus_assign> (*this, ae);
Chris@16 1435 return *this;
Chris@16 1436 }
Chris@16 1437 template<class AE>
Chris@16 1438 BOOST_UBLAS_INLINE
Chris@16 1439 banded_adaptor& operator -= (const matrix_expression<AE> &ae) {
Chris@16 1440 matrix_assign<scalar_assign> (*this, matrix<value_type> (*this - ae));
Chris@16 1441 return *this;
Chris@16 1442 }
Chris@16 1443 template<class AE>
Chris@16 1444 BOOST_UBLAS_INLINE
Chris@16 1445 banded_adaptor &minus_assign (const matrix_expression<AE> &ae) {
Chris@16 1446 matrix_assign<scalar_minus_assign> (*this, ae);
Chris@16 1447 return *this;
Chris@16 1448 }
Chris@16 1449 template<class AT>
Chris@16 1450 BOOST_UBLAS_INLINE
Chris@16 1451 banded_adaptor& operator *= (const AT &at) {
Chris@16 1452 matrix_assign_scalar<scalar_multiplies_assign> (*this, at);
Chris@16 1453 return *this;
Chris@16 1454 }
Chris@16 1455 template<class AT>
Chris@16 1456 BOOST_UBLAS_INLINE
Chris@16 1457 banded_adaptor& operator /= (const AT &at) {
Chris@16 1458 matrix_assign_scalar<scalar_divides_assign> (*this, at);
Chris@16 1459 return *this;
Chris@16 1460 }
Chris@16 1461
Chris@16 1462 // Closure comparison
Chris@16 1463 BOOST_UBLAS_INLINE
Chris@16 1464 bool same_closure (const banded_adaptor &ba) const {
Chris@16 1465 return (*this).data ().same_closure (ba.data ());
Chris@16 1466 }
Chris@16 1467
Chris@16 1468 // Swapping
Chris@16 1469 BOOST_UBLAS_INLINE
Chris@16 1470 void swap (banded_adaptor &m) {
Chris@16 1471 if (this != &m) {
Chris@16 1472 BOOST_UBLAS_CHECK (lower_ == m.lower_, bad_size ());
Chris@16 1473 BOOST_UBLAS_CHECK (upper_ == m.upper_, bad_size ());
Chris@16 1474 matrix_swap<scalar_swap> (*this, m);
Chris@16 1475 }
Chris@16 1476 }
Chris@16 1477 BOOST_UBLAS_INLINE
Chris@16 1478 friend void swap (banded_adaptor &m1, banded_adaptor &m2) {
Chris@16 1479 m1.swap (m2);
Chris@16 1480 }
Chris@16 1481
Chris@16 1482 // Iterator types
Chris@16 1483 private:
Chris@16 1484 // Use the matrix iterator
Chris@16 1485 typedef typename M::const_iterator1 const_subiterator1_type;
Chris@16 1486 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1487 typename M::const_iterator1,
Chris@16 1488 typename M::iterator1>::type subiterator1_type;
Chris@16 1489 typedef typename M::const_iterator2 const_subiterator2_type;
Chris@16 1490 typedef typename boost::mpl::if_<boost::is_const<M>,
Chris@16 1491 typename M::const_iterator2,
Chris@16 1492 typename M::iterator2>::type subiterator2_type;
Chris@16 1493
Chris@16 1494 public:
Chris@16 1495 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1496 typedef indexed_iterator1<self_type, packed_random_access_iterator_tag> iterator1;
Chris@16 1497 typedef indexed_iterator2<self_type, packed_random_access_iterator_tag> iterator2;
Chris@16 1498 typedef indexed_const_iterator1<self_type, packed_random_access_iterator_tag> const_iterator1;
Chris@16 1499 typedef indexed_const_iterator2<self_type, packed_random_access_iterator_tag> const_iterator2;
Chris@16 1500 #else
Chris@16 1501 class const_iterator1;
Chris@16 1502 class iterator1;
Chris@16 1503 class const_iterator2;
Chris@16 1504 class iterator2;
Chris@16 1505 #endif
Chris@16 1506 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
Chris@16 1507 typedef reverse_iterator_base1<iterator1> reverse_iterator1;
Chris@16 1508 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
Chris@16 1509 typedef reverse_iterator_base2<iterator2> reverse_iterator2;
Chris@16 1510
Chris@16 1511 // Element lookup
Chris@16 1512 BOOST_UBLAS_INLINE
Chris@16 1513 const_iterator1 find1 (int rank, size_type i, size_type j) const {
Chris@16 1514 if (rank == 1) {
Chris@16 1515 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
Chris@16 1516 i = (std::max) (i, lower_i);
Chris@16 1517 size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
Chris@16 1518 i = (std::min) (i, upper_i);
Chris@16 1519 }
Chris@16 1520 return const_iterator1 (*this, data ().find1 (rank, i, j));
Chris@16 1521 }
Chris@16 1522 BOOST_UBLAS_INLINE
Chris@16 1523 iterator1 find1 (int rank, size_type i, size_type j) {
Chris@16 1524 if (rank == 1) {
Chris@16 1525 size_type lower_i = (std::max) (difference_type (j - upper_), difference_type (0));
Chris@16 1526 i = (std::max) (i, lower_i);
Chris@16 1527 size_type upper_i = (std::min) (j + 1 + lower_, size1 ());
Chris@16 1528 i = (std::min) (i, upper_i);
Chris@16 1529 }
Chris@16 1530 return iterator1 (*this, data ().find1 (rank, i, j));
Chris@16 1531 }
Chris@16 1532 BOOST_UBLAS_INLINE
Chris@16 1533 const_iterator2 find2 (int rank, size_type i, size_type j) const {
Chris@16 1534 if (rank == 1) {
Chris@16 1535 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
Chris@16 1536 j = (std::max) (j, lower_j);
Chris@16 1537 size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
Chris@16 1538 j = (std::min) (j, upper_j);
Chris@16 1539 }
Chris@16 1540 return const_iterator2 (*this, data ().find2 (rank, i, j));
Chris@16 1541 }
Chris@16 1542 BOOST_UBLAS_INLINE
Chris@16 1543 iterator2 find2 (int rank, size_type i, size_type j) {
Chris@16 1544 if (rank == 1) {
Chris@16 1545 size_type lower_j = (std::max) (difference_type (i - lower_), difference_type (0));
Chris@16 1546 j = (std::max) (j, lower_j);
Chris@16 1547 size_type upper_j = (std::min) (i + 1 + upper_, size2 ());
Chris@16 1548 j = (std::min) (j, upper_j);
Chris@16 1549 }
Chris@16 1550 return iterator2 (*this, data ().find2 (rank, i, j));
Chris@16 1551 }
Chris@16 1552
Chris@16 1553 // Iterators simply are indices.
Chris@16 1554
Chris@16 1555 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1556 class const_iterator1:
Chris@16 1557 public container_const_reference<banded_adaptor>,
Chris@16 1558 public random_access_iterator_base<typename iterator_restrict_traits<
Chris@16 1559 typename const_subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
Chris@16 1560 const_iterator1, value_type> {
Chris@16 1561 public:
Chris@16 1562 typedef typename const_subiterator1_type::value_type value_type;
Chris@16 1563 typedef typename const_subiterator1_type::difference_type difference_type;
Chris@16 1564 typedef typename const_subiterator1_type::reference reference;
Chris@16 1565 typedef typename const_subiterator1_type::pointer pointer;
Chris@16 1566
Chris@16 1567 typedef const_iterator2 dual_iterator_type;
Chris@16 1568 typedef const_reverse_iterator2 dual_reverse_iterator_type;
Chris@16 1569
Chris@16 1570 // Construction and destruction
Chris@16 1571 BOOST_UBLAS_INLINE
Chris@16 1572 const_iterator1 ():
Chris@16 1573 container_const_reference<self_type> (), it1_ () {}
Chris@16 1574 BOOST_UBLAS_INLINE
Chris@16 1575 const_iterator1 (const self_type &m, const const_subiterator1_type &it1):
Chris@16 1576 container_const_reference<self_type> (m), it1_ (it1) {}
Chris@16 1577 BOOST_UBLAS_INLINE
Chris@16 1578 const_iterator1 (const iterator1 &it):
Chris@16 1579 container_const_reference<self_type> (it ()), it1_ (it.it1_) {}
Chris@16 1580
Chris@16 1581 // Arithmetic
Chris@16 1582 BOOST_UBLAS_INLINE
Chris@16 1583 const_iterator1 &operator ++ () {
Chris@16 1584 ++ it1_;
Chris@16 1585 return *this;
Chris@16 1586 }
Chris@16 1587 BOOST_UBLAS_INLINE
Chris@16 1588 const_iterator1 &operator -- () {
Chris@16 1589 -- it1_;
Chris@16 1590 return *this;
Chris@16 1591 }
Chris@16 1592 BOOST_UBLAS_INLINE
Chris@16 1593 const_iterator1 &operator += (difference_type n) {
Chris@16 1594 it1_ += n;
Chris@16 1595 return *this;
Chris@16 1596 }
Chris@16 1597 BOOST_UBLAS_INLINE
Chris@16 1598 const_iterator1 &operator -= (difference_type n) {
Chris@16 1599 it1_ -= n;
Chris@16 1600 return *this;
Chris@16 1601 }
Chris@16 1602 BOOST_UBLAS_INLINE
Chris@16 1603 difference_type operator - (const const_iterator1 &it) const {
Chris@16 1604 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1605 return it1_ - it.it1_;
Chris@16 1606 }
Chris@16 1607
Chris@16 1608 // Dereference
Chris@16 1609 BOOST_UBLAS_INLINE
Chris@16 1610 const_reference operator * () const {
Chris@16 1611 size_type i = index1 ();
Chris@16 1612 size_type j = index2 ();
Chris@16 1613 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
Chris@16 1614 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
Chris@16 1615 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 1616 size_type k = (std::max) (i, j);
Chris@16 1617 size_type l = (*this) ().lower () + j - i;
Chris@16 1618 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
Chris@16 1619 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 1620 return *it1_;
Chris@16 1621 #else
Chris@16 1622 size_type k = j;
Chris@16 1623 size_type l = (*this) ().upper () + i - j;
Chris@16 1624 if (k < (*this) ().size2 () &&
Chris@16 1625 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 1626 return *it1_;
Chris@16 1627 #endif
Chris@16 1628 return (*this) () (i, j);
Chris@16 1629 }
Chris@16 1630 BOOST_UBLAS_INLINE
Chris@16 1631 const_reference operator [] (difference_type n) const {
Chris@16 1632 return *(*this + n);
Chris@16 1633 }
Chris@16 1634
Chris@16 1635 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1636 BOOST_UBLAS_INLINE
Chris@16 1637 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1638 typename self_type::
Chris@16 1639 #endif
Chris@16 1640 const_iterator2 begin () const {
Chris@16 1641 return (*this) ().find2 (1, index1 (), 0);
Chris@16 1642 }
Chris@16 1643 BOOST_UBLAS_INLINE
Chris@16 1644 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1645 typename self_type::
Chris@16 1646 #endif
Chris@101 1647 const_iterator2 cbegin () const {
Chris@101 1648 return begin ();
Chris@101 1649 }
Chris@101 1650 BOOST_UBLAS_INLINE
Chris@101 1651 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1652 typename self_type::
Chris@101 1653 #endif
Chris@16 1654 const_iterator2 end () const {
Chris@16 1655 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
Chris@16 1656 }
Chris@16 1657 BOOST_UBLAS_INLINE
Chris@16 1658 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1659 typename self_type::
Chris@16 1660 #endif
Chris@101 1661 const_iterator2 cend () const {
Chris@101 1662 return end ();
Chris@101 1663 }
Chris@101 1664 BOOST_UBLAS_INLINE
Chris@101 1665 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1666 typename self_type::
Chris@101 1667 #endif
Chris@16 1668 const_reverse_iterator2 rbegin () const {
Chris@16 1669 return const_reverse_iterator2 (end ());
Chris@16 1670 }
Chris@16 1671 BOOST_UBLAS_INLINE
Chris@16 1672 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1673 typename self_type::
Chris@16 1674 #endif
Chris@101 1675 const_reverse_iterator2 crbegin () const {
Chris@101 1676 return rbegin ();
Chris@101 1677 }
Chris@101 1678 BOOST_UBLAS_INLINE
Chris@101 1679 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1680 typename self_type::
Chris@101 1681 #endif
Chris@16 1682 const_reverse_iterator2 rend () const {
Chris@16 1683 return const_reverse_iterator2 (begin ());
Chris@16 1684 }
Chris@101 1685 BOOST_UBLAS_INLINE
Chris@101 1686 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1687 typename self_type::
Chris@101 1688 #endif
Chris@101 1689 const_reverse_iterator2 crend () const {
Chris@101 1690 return rend ();
Chris@101 1691 }
Chris@16 1692 #endif
Chris@16 1693
Chris@16 1694 // Indices
Chris@16 1695 BOOST_UBLAS_INLINE
Chris@16 1696 size_type index1 () const {
Chris@16 1697 return it1_.index1 ();
Chris@16 1698 }
Chris@16 1699 BOOST_UBLAS_INLINE
Chris@16 1700 size_type index2 () const {
Chris@16 1701 return it1_.index2 ();
Chris@16 1702 }
Chris@16 1703
Chris@16 1704 // Assignment
Chris@16 1705 BOOST_UBLAS_INLINE
Chris@16 1706 const_iterator1 &operator = (const const_iterator1 &it) {
Chris@16 1707 container_const_reference<self_type>::assign (&it ());
Chris@16 1708 it1_ = it.it1_;
Chris@16 1709 return *this;
Chris@16 1710 }
Chris@16 1711
Chris@16 1712 // Comparison
Chris@16 1713 BOOST_UBLAS_INLINE
Chris@16 1714 bool operator == (const const_iterator1 &it) const {
Chris@16 1715 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1716 return it1_ == it.it1_;
Chris@16 1717 }
Chris@16 1718 BOOST_UBLAS_INLINE
Chris@16 1719 bool operator < (const const_iterator1 &it) const {
Chris@16 1720 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1721 return it1_ < it.it1_;
Chris@16 1722 }
Chris@16 1723
Chris@16 1724 private:
Chris@16 1725 const_subiterator1_type it1_;
Chris@16 1726 };
Chris@16 1727 #endif
Chris@16 1728
Chris@16 1729 BOOST_UBLAS_INLINE
Chris@16 1730 const_iterator1 begin1 () const {
Chris@16 1731 return find1 (0, 0, 0);
Chris@16 1732 }
Chris@16 1733 BOOST_UBLAS_INLINE
Chris@101 1734 const_iterator1 cbegin1 () const {
Chris@101 1735 return begin1 ();
Chris@101 1736 }
Chris@101 1737 BOOST_UBLAS_INLINE
Chris@16 1738 const_iterator1 end1 () const {
Chris@16 1739 return find1 (0, size1 (), 0);
Chris@16 1740 }
Chris@101 1741 BOOST_UBLAS_INLINE
Chris@101 1742 const_iterator1 cend1 () const {
Chris@101 1743 return end1 ();
Chris@101 1744 }
Chris@16 1745
Chris@16 1746 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1747 class iterator1:
Chris@16 1748 public container_reference<banded_adaptor>,
Chris@16 1749 public random_access_iterator_base<typename iterator_restrict_traits<
Chris@16 1750 typename subiterator1_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
Chris@16 1751 iterator1, value_type> {
Chris@16 1752 public:
Chris@16 1753 typedef typename subiterator1_type::value_type value_type;
Chris@16 1754 typedef typename subiterator1_type::difference_type difference_type;
Chris@16 1755 typedef typename subiterator1_type::reference reference;
Chris@16 1756 typedef typename subiterator1_type::pointer pointer;
Chris@16 1757
Chris@16 1758 typedef iterator2 dual_iterator_type;
Chris@16 1759 typedef reverse_iterator2 dual_reverse_iterator_type;
Chris@16 1760
Chris@16 1761 // Construction and destruction
Chris@16 1762 BOOST_UBLAS_INLINE
Chris@16 1763 iterator1 ():
Chris@16 1764 container_reference<self_type> (), it1_ () {}
Chris@16 1765 BOOST_UBLAS_INLINE
Chris@16 1766 iterator1 (self_type &m, const subiterator1_type &it1):
Chris@16 1767 container_reference<self_type> (m), it1_ (it1) {}
Chris@16 1768
Chris@16 1769 // Arithmetic
Chris@16 1770 BOOST_UBLAS_INLINE
Chris@16 1771 iterator1 &operator ++ () {
Chris@16 1772 ++ it1_;
Chris@16 1773 return *this;
Chris@16 1774 }
Chris@16 1775 BOOST_UBLAS_INLINE
Chris@16 1776 iterator1 &operator -- () {
Chris@16 1777 -- it1_;
Chris@16 1778 return *this;
Chris@16 1779 }
Chris@16 1780 BOOST_UBLAS_INLINE
Chris@16 1781 iterator1 &operator += (difference_type n) {
Chris@16 1782 it1_ += n;
Chris@16 1783 return *this;
Chris@16 1784 }
Chris@16 1785 BOOST_UBLAS_INLINE
Chris@16 1786 iterator1 &operator -= (difference_type n) {
Chris@16 1787 it1_ -= n;
Chris@16 1788 return *this;
Chris@16 1789 }
Chris@16 1790 BOOST_UBLAS_INLINE
Chris@16 1791 difference_type operator - (const iterator1 &it) const {
Chris@16 1792 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1793 return it1_ - it.it1_;
Chris@16 1794 }
Chris@16 1795
Chris@16 1796 // Dereference
Chris@16 1797 BOOST_UBLAS_INLINE
Chris@16 1798 reference operator * () const {
Chris@16 1799 size_type i = index1 ();
Chris@16 1800 size_type j = index2 ();
Chris@16 1801 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
Chris@16 1802 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
Chris@16 1803 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 1804 size_type k = (std::max) (i, j);
Chris@16 1805 size_type l = (*this) ().lower () + j - i;
Chris@16 1806 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
Chris@16 1807 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 1808 return *it1_;
Chris@16 1809 #else
Chris@16 1810 size_type k = j;
Chris@16 1811 size_type l = (*this) ().upper () + i - j;
Chris@16 1812 if (k < (*this) ().size2 () &&
Chris@16 1813 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 1814 return *it1_;
Chris@16 1815 #endif
Chris@16 1816 return (*this) () (i, j);
Chris@16 1817 }
Chris@16 1818 BOOST_UBLAS_INLINE
Chris@16 1819 reference operator [] (difference_type n) const {
Chris@16 1820 return *(*this + n);
Chris@16 1821 }
Chris@16 1822
Chris@16 1823 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1824 BOOST_UBLAS_INLINE
Chris@16 1825 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1826 typename self_type::
Chris@16 1827 #endif
Chris@16 1828 iterator2 begin () const {
Chris@16 1829 return (*this) ().find2 (1, index1 (), 0);
Chris@16 1830 }
Chris@16 1831 BOOST_UBLAS_INLINE
Chris@16 1832 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1833 typename self_type::
Chris@16 1834 #endif
Chris@16 1835 iterator2 end () const {
Chris@16 1836 return (*this) ().find2 (1, index1 (), (*this) ().size2 ());
Chris@16 1837 }
Chris@16 1838 BOOST_UBLAS_INLINE
Chris@16 1839 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1840 typename self_type::
Chris@16 1841 #endif
Chris@16 1842 reverse_iterator2 rbegin () const {
Chris@16 1843 return reverse_iterator2 (end ());
Chris@16 1844 }
Chris@16 1845 BOOST_UBLAS_INLINE
Chris@16 1846 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1847 typename self_type::
Chris@16 1848 #endif
Chris@16 1849 reverse_iterator2 rend () const {
Chris@16 1850 return reverse_iterator2 (begin ());
Chris@16 1851 }
Chris@16 1852 #endif
Chris@16 1853
Chris@16 1854 // Indices
Chris@16 1855 BOOST_UBLAS_INLINE
Chris@16 1856 size_type index1 () const {
Chris@16 1857 return it1_.index1 ();
Chris@16 1858 }
Chris@16 1859 BOOST_UBLAS_INLINE
Chris@16 1860 size_type index2 () const {
Chris@16 1861 return it1_.index2 ();
Chris@16 1862 }
Chris@16 1863
Chris@16 1864 // Assignment
Chris@16 1865 BOOST_UBLAS_INLINE
Chris@16 1866 iterator1 &operator = (const iterator1 &it) {
Chris@16 1867 container_reference<self_type>::assign (&it ());
Chris@16 1868 it1_ = it.it1_;
Chris@16 1869 return *this;
Chris@16 1870 }
Chris@16 1871
Chris@16 1872 // Comparison
Chris@16 1873 BOOST_UBLAS_INLINE
Chris@16 1874 bool operator == (const iterator1 &it) const {
Chris@16 1875 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1876 return it1_ == it.it1_;
Chris@16 1877 }
Chris@16 1878 BOOST_UBLAS_INLINE
Chris@16 1879 bool operator < (const iterator1 &it) const {
Chris@16 1880 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1881 return it1_ < it.it1_;
Chris@16 1882 }
Chris@16 1883
Chris@16 1884 private:
Chris@16 1885 subiterator1_type it1_;
Chris@16 1886
Chris@16 1887 friend class const_iterator1;
Chris@16 1888 };
Chris@16 1889 #endif
Chris@16 1890
Chris@16 1891 BOOST_UBLAS_INLINE
Chris@16 1892 iterator1 begin1 () {
Chris@16 1893 return find1 (0, 0, 0);
Chris@16 1894 }
Chris@16 1895 BOOST_UBLAS_INLINE
Chris@16 1896 iterator1 end1 () {
Chris@16 1897 return find1 (0, size1 (), 0);
Chris@16 1898 }
Chris@16 1899
Chris@16 1900 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1901 class const_iterator2:
Chris@16 1902 public container_const_reference<banded_adaptor>,
Chris@16 1903 public random_access_iterator_base<packed_random_access_iterator_tag,
Chris@16 1904 const_iterator2, value_type> {
Chris@16 1905 public:
Chris@16 1906 typedef typename iterator_restrict_traits<typename const_subiterator2_type::iterator_category,
Chris@16 1907 packed_random_access_iterator_tag>::iterator_category iterator_category;
Chris@16 1908 typedef typename const_subiterator2_type::value_type value_type;
Chris@16 1909 typedef typename const_subiterator2_type::difference_type difference_type;
Chris@16 1910 typedef typename const_subiterator2_type::reference reference;
Chris@16 1911 typedef typename const_subiterator2_type::pointer pointer;
Chris@16 1912
Chris@16 1913 typedef const_iterator1 dual_iterator_type;
Chris@16 1914 typedef const_reverse_iterator1 dual_reverse_iterator_type;
Chris@16 1915
Chris@16 1916 // Construction and destruction
Chris@16 1917 BOOST_UBLAS_INLINE
Chris@16 1918 const_iterator2 ():
Chris@16 1919 container_const_reference<self_type> (), it2_ () {}
Chris@16 1920 BOOST_UBLAS_INLINE
Chris@16 1921 const_iterator2 (const self_type &m, const const_subiterator2_type &it2):
Chris@16 1922 container_const_reference<self_type> (m), it2_ (it2) {}
Chris@16 1923 BOOST_UBLAS_INLINE
Chris@16 1924 const_iterator2 (const iterator2 &it):
Chris@16 1925 container_const_reference<self_type> (it ()), it2_ (it.it2_) {}
Chris@16 1926
Chris@16 1927 // Arithmetic
Chris@16 1928 BOOST_UBLAS_INLINE
Chris@16 1929 const_iterator2 &operator ++ () {
Chris@16 1930 ++ it2_;
Chris@16 1931 return *this;
Chris@16 1932 }
Chris@16 1933 BOOST_UBLAS_INLINE
Chris@16 1934 const_iterator2 &operator -- () {
Chris@16 1935 -- it2_;
Chris@16 1936 return *this;
Chris@16 1937 }
Chris@16 1938 BOOST_UBLAS_INLINE
Chris@16 1939 const_iterator2 &operator += (difference_type n) {
Chris@16 1940 it2_ += n;
Chris@16 1941 return *this;
Chris@16 1942 }
Chris@16 1943 BOOST_UBLAS_INLINE
Chris@16 1944 const_iterator2 &operator -= (difference_type n) {
Chris@16 1945 it2_ -= n;
Chris@16 1946 return *this;
Chris@16 1947 }
Chris@16 1948 BOOST_UBLAS_INLINE
Chris@16 1949 difference_type operator - (const const_iterator2 &it) const {
Chris@16 1950 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 1951 return it2_ - it.it2_;
Chris@16 1952 }
Chris@16 1953
Chris@16 1954 // Dereference
Chris@16 1955 BOOST_UBLAS_INLINE
Chris@16 1956 const_reference operator * () const {
Chris@16 1957 size_type i = index1 ();
Chris@16 1958 size_type j = index2 ();
Chris@16 1959 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
Chris@16 1960 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
Chris@16 1961 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 1962 size_type k = (std::max) (i, j);
Chris@16 1963 size_type l = (*this) ().lower () + j - i;
Chris@16 1964 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
Chris@16 1965 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 1966 return *it2_;
Chris@16 1967 #else
Chris@16 1968 size_type k = j;
Chris@16 1969 size_type l = (*this) ().upper () + i - j;
Chris@16 1970 if (k < (*this) ().size2 () &&
Chris@16 1971 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 1972 return *it2_;
Chris@16 1973 #endif
Chris@16 1974 return (*this) () (i, j);
Chris@16 1975 }
Chris@16 1976 BOOST_UBLAS_INLINE
Chris@16 1977 const_reference operator [] (difference_type n) const {
Chris@16 1978 return *(*this + n);
Chris@16 1979 }
Chris@16 1980
Chris@16 1981 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 1982 BOOST_UBLAS_INLINE
Chris@16 1983 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1984 typename self_type::
Chris@16 1985 #endif
Chris@16 1986 const_iterator1 begin () const {
Chris@16 1987 return (*this) ().find1 (1, 0, index2 ());
Chris@16 1988 }
Chris@16 1989 BOOST_UBLAS_INLINE
Chris@16 1990 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 1991 typename self_type::
Chris@16 1992 #endif
Chris@101 1993 const_iterator1 cbegin () const {
Chris@101 1994 return begin ();
Chris@101 1995 }
Chris@101 1996 BOOST_UBLAS_INLINE
Chris@101 1997 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 1998 typename self_type::
Chris@101 1999 #endif
Chris@16 2000 const_iterator1 end () const {
Chris@16 2001 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
Chris@16 2002 }
Chris@16 2003 BOOST_UBLAS_INLINE
Chris@16 2004 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2005 typename self_type::
Chris@16 2006 #endif
Chris@101 2007 const_iterator1 cend () const {
Chris@101 2008 return end ();
Chris@101 2009 }
Chris@101 2010 BOOST_UBLAS_INLINE
Chris@101 2011 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2012 typename self_type::
Chris@101 2013 #endif
Chris@16 2014 const_reverse_iterator1 rbegin () const {
Chris@16 2015 return const_reverse_iterator1 (end ());
Chris@16 2016 }
Chris@16 2017 BOOST_UBLAS_INLINE
Chris@16 2018 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2019 typename self_type::
Chris@16 2020 #endif
Chris@101 2021 const_reverse_iterator1 crbegin () const {
Chris@101 2022 return rbegin ();
Chris@101 2023 }
Chris@101 2024 BOOST_UBLAS_INLINE
Chris@101 2025 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2026 typename self_type::
Chris@101 2027 #endif
Chris@16 2028 const_reverse_iterator1 rend () const {
Chris@16 2029 return const_reverse_iterator1 (begin ());
Chris@16 2030 }
Chris@101 2031 BOOST_UBLAS_INLINE
Chris@101 2032 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@101 2033 typename self_type::
Chris@101 2034 #endif
Chris@101 2035 const_reverse_iterator1 crend () const {
Chris@101 2036 return rend ();
Chris@101 2037 }
Chris@16 2038 #endif
Chris@16 2039
Chris@16 2040 // Indices
Chris@16 2041 BOOST_UBLAS_INLINE
Chris@16 2042 size_type index1 () const {
Chris@16 2043 return it2_.index1 ();
Chris@16 2044 }
Chris@16 2045 BOOST_UBLAS_INLINE
Chris@16 2046 size_type index2 () const {
Chris@16 2047 return it2_.index2 ();
Chris@16 2048 }
Chris@16 2049
Chris@16 2050 // Assignment
Chris@16 2051 BOOST_UBLAS_INLINE
Chris@16 2052 const_iterator2 &operator = (const const_iterator2 &it) {
Chris@16 2053 container_const_reference<self_type>::assign (&it ());
Chris@16 2054 it2_ = it.it2_;
Chris@16 2055 return *this;
Chris@16 2056 }
Chris@16 2057
Chris@16 2058 // Comparison
Chris@16 2059 BOOST_UBLAS_INLINE
Chris@16 2060 bool operator == (const const_iterator2 &it) const {
Chris@16 2061 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2062 return it2_ == it.it2_;
Chris@16 2063 }
Chris@16 2064 BOOST_UBLAS_INLINE
Chris@16 2065 bool operator < (const const_iterator2 &it) const {
Chris@16 2066 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2067 return it2_ < it.it2_;
Chris@16 2068 }
Chris@16 2069
Chris@16 2070 private:
Chris@16 2071 const_subiterator2_type it2_;
Chris@16 2072 };
Chris@16 2073 #endif
Chris@16 2074
Chris@16 2075 BOOST_UBLAS_INLINE
Chris@16 2076 const_iterator2 begin2 () const {
Chris@16 2077 return find2 (0, 0, 0);
Chris@16 2078 }
Chris@16 2079 BOOST_UBLAS_INLINE
Chris@101 2080 const_iterator2 cbegin2 () const {
Chris@101 2081 return begin2 ();
Chris@101 2082 }
Chris@101 2083 BOOST_UBLAS_INLINE
Chris@16 2084 const_iterator2 end2 () const {
Chris@16 2085 return find2 (0, 0, size2 ());
Chris@16 2086 }
Chris@101 2087 BOOST_UBLAS_INLINE
Chris@101 2088 const_iterator2 cend2 () const {
Chris@101 2089 return end2 ();
Chris@101 2090 }
Chris@16 2091
Chris@16 2092 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 2093 class iterator2:
Chris@16 2094 public container_reference<banded_adaptor>,
Chris@16 2095 public random_access_iterator_base<typename iterator_restrict_traits<
Chris@16 2096 typename subiterator2_type::iterator_category, packed_random_access_iterator_tag>::iterator_category,
Chris@16 2097 iterator2, value_type> {
Chris@16 2098 public:
Chris@16 2099 typedef typename subiterator2_type::value_type value_type;
Chris@16 2100 typedef typename subiterator2_type::difference_type difference_type;
Chris@16 2101 typedef typename subiterator2_type::reference reference;
Chris@16 2102 typedef typename subiterator2_type::pointer pointer;
Chris@16 2103
Chris@16 2104 typedef iterator1 dual_iterator_type;
Chris@16 2105 typedef reverse_iterator1 dual_reverse_iterator_type;
Chris@16 2106
Chris@16 2107 // Construction and destruction
Chris@16 2108 BOOST_UBLAS_INLINE
Chris@16 2109 iterator2 ():
Chris@16 2110 container_reference<self_type> (), it2_ () {}
Chris@16 2111 BOOST_UBLAS_INLINE
Chris@16 2112 iterator2 (self_type &m, const subiterator2_type &it2):
Chris@16 2113 container_reference<self_type> (m), it2_ (it2) {}
Chris@16 2114
Chris@16 2115 // Arithmetic
Chris@16 2116 BOOST_UBLAS_INLINE
Chris@16 2117 iterator2 &operator ++ () {
Chris@16 2118 ++ it2_;
Chris@16 2119 return *this;
Chris@16 2120 }
Chris@16 2121 BOOST_UBLAS_INLINE
Chris@16 2122 iterator2 &operator -- () {
Chris@16 2123 -- it2_;
Chris@16 2124 return *this;
Chris@16 2125 }
Chris@16 2126 BOOST_UBLAS_INLINE
Chris@16 2127 iterator2 &operator += (difference_type n) {
Chris@16 2128 it2_ += n;
Chris@16 2129 return *this;
Chris@16 2130 }
Chris@16 2131 BOOST_UBLAS_INLINE
Chris@16 2132 iterator2 &operator -= (difference_type n) {
Chris@16 2133 it2_ -= n;
Chris@16 2134 return *this;
Chris@16 2135 }
Chris@16 2136 BOOST_UBLAS_INLINE
Chris@16 2137 difference_type operator - (const iterator2 &it) const {
Chris@16 2138 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2139 return it2_ - it.it2_;
Chris@16 2140 }
Chris@16 2141
Chris@16 2142 // Dereference
Chris@16 2143 BOOST_UBLAS_INLINE
Chris@16 2144 reference operator * () const {
Chris@16 2145 size_type i = index1 ();
Chris@16 2146 size_type j = index2 ();
Chris@16 2147 BOOST_UBLAS_CHECK (i < (*this) ().size1 (), bad_index ());
Chris@16 2148 BOOST_UBLAS_CHECK (j < (*this) ().size2 (), bad_index ());
Chris@16 2149 #ifdef BOOST_UBLAS_OWN_BANDED
Chris@16 2150 size_type k = (std::max) (i, j);
Chris@16 2151 size_type l = (*this) ().lower () + j - i;
Chris@16 2152 if (k < (std::max) ((*this) ().size1 (), (*this) ().size2 ()) &&
Chris@16 2153 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 2154 return *it2_;
Chris@16 2155 #else
Chris@16 2156 size_type k = j;
Chris@16 2157 size_type l = (*this) ().upper () + i - j;
Chris@16 2158 if (k < (*this) ().size2 () &&
Chris@16 2159 l < (*this) ().lower () + 1 + (*this) ().upper ())
Chris@16 2160 return *it2_;
Chris@16 2161 #endif
Chris@16 2162 return (*this) () (i, j);
Chris@16 2163 }
Chris@16 2164 BOOST_UBLAS_INLINE
Chris@16 2165 reference operator [] (difference_type n) const {
Chris@16 2166 return *(*this + n);
Chris@16 2167 }
Chris@16 2168
Chris@16 2169 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 2170 BOOST_UBLAS_INLINE
Chris@16 2171 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2172 typename self_type::
Chris@16 2173 #endif
Chris@16 2174 iterator1 begin () const {
Chris@16 2175 return (*this) ().find1 (1, 0, index2 ());
Chris@16 2176 }
Chris@16 2177 BOOST_UBLAS_INLINE
Chris@16 2178 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2179 typename self_type::
Chris@16 2180 #endif
Chris@16 2181 iterator1 end () const {
Chris@16 2182 return (*this) ().find1 (1, (*this) ().size1 (), index2 ());
Chris@16 2183 }
Chris@16 2184 BOOST_UBLAS_INLINE
Chris@16 2185 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2186 typename self_type::
Chris@16 2187 #endif
Chris@16 2188 reverse_iterator1 rbegin () const {
Chris@16 2189 return reverse_iterator1 (end ());
Chris@16 2190 }
Chris@16 2191 BOOST_UBLAS_INLINE
Chris@16 2192 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION
Chris@16 2193 typename self_type::
Chris@16 2194 #endif
Chris@16 2195 reverse_iterator1 rend () const {
Chris@16 2196 return reverse_iterator1 (begin ());
Chris@16 2197 }
Chris@16 2198 #endif
Chris@16 2199
Chris@16 2200 // Indices
Chris@16 2201 BOOST_UBLAS_INLINE
Chris@16 2202 size_type index1 () const {
Chris@16 2203 return it2_.index1 ();
Chris@16 2204 }
Chris@16 2205 BOOST_UBLAS_INLINE
Chris@16 2206 size_type index2 () const {
Chris@16 2207 return it2_.index2 ();
Chris@16 2208 }
Chris@16 2209
Chris@16 2210 // Assignment
Chris@16 2211 BOOST_UBLAS_INLINE
Chris@16 2212 iterator2 &operator = (const iterator2 &it) {
Chris@16 2213 container_reference<self_type>::assign (&it ());
Chris@16 2214 it2_ = it.it2_;
Chris@16 2215 return *this;
Chris@16 2216 }
Chris@16 2217
Chris@16 2218 // Comparison
Chris@16 2219 BOOST_UBLAS_INLINE
Chris@16 2220 bool operator == (const iterator2 &it) const {
Chris@16 2221 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2222 return it2_ == it.it2_;
Chris@16 2223 }
Chris@16 2224 BOOST_UBLAS_INLINE
Chris@16 2225 bool operator < (const iterator2 &it) const {
Chris@16 2226 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
Chris@16 2227 return it2_ < it.it2_;
Chris@16 2228 }
Chris@16 2229
Chris@16 2230 private:
Chris@16 2231 subiterator2_type it2_;
Chris@16 2232
Chris@16 2233 friend class const_iterator2;
Chris@16 2234 };
Chris@16 2235 #endif
Chris@16 2236
Chris@16 2237 BOOST_UBLAS_INLINE
Chris@16 2238 iterator2 begin2 () {
Chris@16 2239 return find2 (0, 0, 0);
Chris@16 2240 }
Chris@16 2241 BOOST_UBLAS_INLINE
Chris@16 2242 iterator2 end2 () {
Chris@16 2243 return find2 (0, 0, size2 ());
Chris@16 2244 }
Chris@16 2245
Chris@16 2246 // Reverse iterators
Chris@16 2247
Chris@16 2248 BOOST_UBLAS_INLINE
Chris@16 2249 const_reverse_iterator1 rbegin1 () const {
Chris@16 2250 return const_reverse_iterator1 (end1 ());
Chris@16 2251 }
Chris@16 2252 BOOST_UBLAS_INLINE
Chris@101 2253 const_reverse_iterator1 crbegin1 () const {
Chris@101 2254 return rbegin1 ();
Chris@101 2255 }
Chris@101 2256 BOOST_UBLAS_INLINE
Chris@16 2257 const_reverse_iterator1 rend1 () const {
Chris@16 2258 return const_reverse_iterator1 (begin1 ());
Chris@16 2259 }
Chris@101 2260 BOOST_UBLAS_INLINE
Chris@101 2261 const_reverse_iterator1 crend1 () const {
Chris@101 2262 return rend1 ();
Chris@101 2263 }
Chris@16 2264
Chris@16 2265 BOOST_UBLAS_INLINE
Chris@16 2266 reverse_iterator1 rbegin1 () {
Chris@16 2267 return reverse_iterator1 (end1 ());
Chris@16 2268 }
Chris@16 2269 BOOST_UBLAS_INLINE
Chris@16 2270 reverse_iterator1 rend1 () {
Chris@16 2271 return reverse_iterator1 (begin1 ());
Chris@16 2272 }
Chris@16 2273
Chris@16 2274 BOOST_UBLAS_INLINE
Chris@16 2275 const_reverse_iterator2 rbegin2 () const {
Chris@16 2276 return const_reverse_iterator2 (end2 ());
Chris@16 2277 }
Chris@16 2278 BOOST_UBLAS_INLINE
Chris@101 2279 const_reverse_iterator2 crbegin2 () const {
Chris@101 2280 return rbegin2 ();
Chris@101 2281 }
Chris@101 2282 BOOST_UBLAS_INLINE
Chris@16 2283 const_reverse_iterator2 rend2 () const {
Chris@16 2284 return const_reverse_iterator2 (begin2 ());
Chris@16 2285 }
Chris@101 2286 BOOST_UBLAS_INLINE
Chris@101 2287 const_reverse_iterator2 crend2 () const {
Chris@101 2288 return rend2 ();
Chris@101 2289 }
Chris@16 2290
Chris@16 2291 BOOST_UBLAS_INLINE
Chris@16 2292 reverse_iterator2 rbegin2 () {
Chris@16 2293 return reverse_iterator2 (end2 ());
Chris@16 2294 }
Chris@16 2295 BOOST_UBLAS_INLINE
Chris@16 2296 reverse_iterator2 rend2 () {
Chris@16 2297 return reverse_iterator2 (begin2 ());
Chris@16 2298 }
Chris@16 2299
Chris@16 2300 private:
Chris@16 2301 matrix_closure_type data_;
Chris@16 2302 size_type lower_;
Chris@16 2303 size_type upper_;
Chris@16 2304 typedef const value_type const_value_type;
Chris@16 2305 static const_value_type zero_;
Chris@16 2306 };
Chris@16 2307
Chris@16 2308 // Specialization for temporary_traits
Chris@16 2309 template <class M>
Chris@16 2310 struct vector_temporary_traits< banded_adaptor<M> >
Chris@16 2311 : vector_temporary_traits< M > {} ;
Chris@16 2312 template <class M>
Chris@16 2313 struct vector_temporary_traits< const banded_adaptor<M> >
Chris@16 2314 : vector_temporary_traits< M > {} ;
Chris@16 2315
Chris@16 2316 template <class M>
Chris@16 2317 struct matrix_temporary_traits< banded_adaptor<M> >
Chris@16 2318 : matrix_temporary_traits< M > {} ;
Chris@16 2319 template <class M>
Chris@16 2320 struct matrix_temporary_traits< const banded_adaptor<M> >
Chris@16 2321 : matrix_temporary_traits< M > {} ;
Chris@16 2322
Chris@16 2323
Chris@16 2324 template<class M>
Chris@16 2325 typename banded_adaptor<M>::const_value_type banded_adaptor<M>::zero_ = value_type/*zero*/();
Chris@16 2326
Chris@16 2327 /** \brief A diagonal matrix adaptator: convert a any matrix into a diagonal matrix expression
Chris@16 2328 *
Chris@16 2329 * For a \f$(m\times m)\f$-dimensional matrix, the \c diagonal_adaptor will provide a diagonal matrix
Chris@16 2330 * with \f$0 \leq i < m\f$ and \f$0 \leq j < m\f$, if \f$i\neq j\f$ then \f$b_{i,j}=0\f$.
Chris@16 2331 *
Chris@16 2332 * Storage and location are based on those of the underlying matrix. This is important because
Chris@16 2333 * a \c diagonal_adaptor does not copy the matrix data to a new place. Therefore, modifying values
Chris@16 2334 * in a \c diagonal_adaptor matrix will also modify the underlying matrix too.
Chris@16 2335 *
Chris@16 2336 * \tparam M the type of matrix used to generate the diagonal matrix
Chris@16 2337 */
Chris@16 2338
Chris@16 2339 template<class M>
Chris@16 2340 class diagonal_adaptor:
Chris@16 2341 public banded_adaptor<M> {
Chris@16 2342 public:
Chris@16 2343 typedef M matrix_type;
Chris@16 2344 typedef banded_adaptor<M> adaptor_type;
Chris@16 2345
Chris@16 2346 // Construction and destruction
Chris@16 2347 BOOST_UBLAS_INLINE
Chris@16 2348 diagonal_adaptor ():
Chris@16 2349 adaptor_type () {}
Chris@16 2350 BOOST_UBLAS_INLINE
Chris@16 2351 diagonal_adaptor (matrix_type &data):
Chris@16 2352 adaptor_type (data) {}
Chris@16 2353 BOOST_UBLAS_INLINE
Chris@16 2354 ~diagonal_adaptor () {}
Chris@16 2355
Chris@16 2356 // Assignment
Chris@16 2357 BOOST_UBLAS_INLINE
Chris@16 2358 diagonal_adaptor &operator = (const diagonal_adaptor &m) {
Chris@16 2359 adaptor_type::operator = (m);
Chris@16 2360 return *this;
Chris@16 2361 }
Chris@16 2362 template<class AE>
Chris@16 2363 BOOST_UBLAS_INLINE
Chris@16 2364 diagonal_adaptor &operator = (const matrix_expression<AE> &ae) {
Chris@16 2365 adaptor_type::operator = (ae);
Chris@16 2366 return *this;
Chris@16 2367 }
Chris@16 2368 };
Chris@16 2369
Chris@16 2370 }}}
Chris@16 2371
Chris@16 2372 #endif