![]() |
Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms
|
00001 // Copyright (c) 2000-2011 Joerg Walter, Mathias Koch, Gunter Winkler, David Bellot 00002 // 00003 // Distributed under the Boost Software License, Version 1.0. (See 00004 // accompanying file LICENSE_1_0.txt or copy at 00005 // http://www.boost.org/LICENSE_1_0.txt) 00006 00007 #ifndef _BOOST_UBLAS_MATRIX_ 00008 #define _BOOST_UBLAS_MATRIX_ 00009 00010 #include <boost/numeric/ublas/vector.hpp> 00011 #include <boost/numeric/ublas/matrix_expression.hpp> 00012 #include <boost/numeric/ublas/detail/matrix_assign.hpp> 00013 #include <boost/serialization/collection_size_type.hpp> 00014 #include <boost/serialization/array.hpp> 00015 #include <boost/serialization/nvp.hpp> 00016 00017 // Iterators based on ideas of Jeremy Siek 00018 00019 namespace boost { namespace numeric { 00020 00034 namespace ublas { 00035 00036 namespace detail { 00037 using namespace boost::numeric::ublas; 00038 00039 // Matrix resizing algorithm 00040 template <class L, class M> 00041 BOOST_UBLAS_INLINE 00042 void matrix_resize_preserve (M& m, M& temporary) { 00043 typedef L layout_type; 00044 typedef typename M::size_type size_type; 00045 const size_type msize1 (m.size1 ()); // original size 00046 const size_type msize2 (m.size2 ()); 00047 const size_type size1 (temporary.size1 ()); // new size is specified by temporary 00048 const size_type size2 (temporary.size2 ()); 00049 // Common elements to preserve 00050 const size_type size1_min = (std::min) (size1, msize1); 00051 const size_type size2_min = (std::min) (size2, msize2); 00052 // Order for major and minor sizes 00053 const size_type major_size = layout_type::size_M (size1_min, size2_min); 00054 const size_type minor_size = layout_type::size_m (size1_min, size2_min); 00055 // Indexing copy over major 00056 for (size_type major = 0; major != major_size; ++major) { 00057 for (size_type minor = 0; minor != minor_size; ++minor) { 00058 // find indexes - use invertability of element_ functions 00059 const size_type i1 = layout_type::index_M(major, minor); 00060 const size_type i2 = layout_type::index_m(major, minor); 00061 temporary.data () [layout_type::element (i1, size1, i2, size2)] = 00062 m.data() [layout_type::element (i1, msize1, i2, msize2)]; 00063 } 00064 } 00065 m.assign_temporary (temporary); 00066 } 00067 } 00068 00083 template<class T, class L, class A> 00084 class matrix: 00085 public matrix_container<matrix<T, L, A> > { 00086 00087 typedef T *pointer; 00088 typedef L layout_type; 00089 typedef matrix<T, L, A> self_type; 00090 public: 00091 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 00092 using matrix_container<self_type>::operator (); 00093 #endif 00094 typedef typename A::size_type size_type; 00095 typedef typename A::difference_type difference_type; 00096 typedef T value_type; 00097 typedef const T &const_reference; 00098 typedef T &reference; 00099 typedef A array_type; 00100 typedef const matrix_reference<const self_type> const_closure_type; 00101 typedef matrix_reference<self_type> closure_type; 00102 typedef vector<T, A> vector_temporary_type; 00103 typedef self_type matrix_temporary_type; 00104 typedef dense_tag storage_category; 00105 // This could be better for performance, 00106 // typedef typename unknown_orientation_tag orientation_category; 00107 // but others depend on the orientation information... 00108 typedef typename L::orientation_category orientation_category; 00109 00110 // Construction and destruction 00111 00113 BOOST_UBLAS_INLINE 00114 matrix (): 00115 matrix_container<self_type> (), 00116 size1_ (0), size2_ (0), data_ () {} 00117 00122 BOOST_UBLAS_INLINE 00123 matrix (size_type size1, size_type size2): 00124 matrix_container<self_type> (), 00125 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2)) { 00126 } 00127 00133 matrix (size_type size1, size_type size2, const value_type &init): 00134 matrix_container<self_type> (), 00135 size1_ (size1), size2_ (size2), data_ (layout_type::storage_size (size1, size2), init) { 00136 } 00137 00143 BOOST_UBLAS_INLINE 00144 matrix (size_type size1, size_type size2, const array_type &data): 00145 matrix_container<self_type> (), 00146 size1_ (size1), size2_ (size2), data_ (data) {} 00147 00151 BOOST_UBLAS_INLINE 00152 matrix (const matrix &m): 00153 matrix_container<self_type> (), 00154 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {} 00155 00159 template<class AE> 00160 BOOST_UBLAS_INLINE 00161 matrix (const matrix_expression<AE> &ae): 00162 matrix_container<self_type> (), 00163 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::storage_size (size1_, size2_)) { 00164 matrix_assign<scalar_assign> (*this, ae); 00165 } 00166 00167 // Accessors 00171 BOOST_UBLAS_INLINE 00172 size_type size1 () const { 00173 return size1_; 00174 } 00175 00179 BOOST_UBLAS_INLINE 00180 size_type size2 () const { 00181 return size2_; 00182 } 00183 00184 // Storage accessors 00188 BOOST_UBLAS_INLINE 00189 const array_type &data () const { 00190 return data_; 00191 } 00195 BOOST_UBLAS_INLINE 00196 array_type &data () { 00197 return data_; 00198 } 00199 00200 // Resizing 00208 BOOST_UBLAS_INLINE 00209 void resize (size_type size1, size_type size2, bool preserve = true) { 00210 if (preserve) { 00211 self_type temporary (size1, size2); 00212 detail::matrix_resize_preserve<layout_type> (*this, temporary); 00213 } 00214 else { 00215 data ().resize (layout_type::storage_size (size1, size2)); 00216 size1_ = size1; 00217 size2_ = size2; 00218 } 00219 } 00220 00221 // Element access 00222 00228 BOOST_UBLAS_INLINE 00229 const_reference operator () (size_type i, size_type j) const { 00230 return data () [layout_type::element (i, size1_, j, size2_)]; 00231 } 00232 00238 BOOST_UBLAS_INLINE 00239 reference at_element (size_type i, size_type j) { 00240 return data () [layout_type::element (i, size1_, j, size2_)]; 00241 } 00242 00248 BOOST_UBLAS_INLINE 00249 reference operator () (size_type i, size_type j) { 00250 return at_element (i, j); 00251 } 00252 00253 // Element assignment 00254 00261 BOOST_UBLAS_INLINE 00262 reference insert_element (size_type i, size_type j, const_reference t) { 00263 return (at_element (i, j) = t); 00264 } 00265 00273 void erase_element (size_type i, size_type j) { 00274 at_element (i, j) = value_type/*zero*/(); 00275 } 00276 00277 // Zeroing 00283 BOOST_UBLAS_INLINE 00284 void clear () { 00285 std::fill (data ().begin (), data ().end (), value_type/*zero*/()); 00286 } 00287 00288 // Assignment 00289 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 00290 00292 BOOST_UBLAS_INLINE 00293 matrix &operator = (matrix m) { 00294 assign_temporary(m); 00295 return *this; 00296 } 00297 #else 00298 BOOST_UBLAS_INLINE 00299 matrix &operator = (const matrix &m) { 00300 size1_ = m.size1_; 00301 size2_ = m.size2_; 00302 data () = m.data (); 00303 return *this; 00304 } 00305 #endif 00306 template<class C> // Container assignment without temporary 00307 BOOST_UBLAS_INLINE 00308 matrix &operator = (const matrix_container<C> &m) { 00309 resize (m ().size1 (), m ().size2 (), false); 00310 assign (m); 00311 return *this; 00312 } 00313 BOOST_UBLAS_INLINE 00314 matrix &assign_temporary (matrix &m) { 00315 swap (m); 00316 return *this; 00317 } 00318 template<class AE> 00319 BOOST_UBLAS_INLINE 00320 matrix &operator = (const matrix_expression<AE> &ae) { 00321 self_type temporary (ae); 00322 return assign_temporary (temporary); 00323 } 00324 template<class AE> 00325 BOOST_UBLAS_INLINE 00326 matrix &assign (const matrix_expression<AE> &ae) { 00327 matrix_assign<scalar_assign> (*this, ae); 00328 return *this; 00329 } 00330 template<class AE> 00331 BOOST_UBLAS_INLINE 00332 matrix& operator += (const matrix_expression<AE> &ae) { 00333 self_type temporary (*this + ae); 00334 return assign_temporary (temporary); 00335 } 00336 template<class C> // Container assignment without temporary 00337 BOOST_UBLAS_INLINE 00338 matrix &operator += (const matrix_container<C> &m) { 00339 plus_assign (m); 00340 return *this; 00341 } 00342 template<class AE> 00343 BOOST_UBLAS_INLINE 00344 matrix &plus_assign (const matrix_expression<AE> &ae) { 00345 matrix_assign<scalar_plus_assign> (*this, ae); 00346 return *this; 00347 } 00348 template<class AE> 00349 BOOST_UBLAS_INLINE 00350 matrix& operator -= (const matrix_expression<AE> &ae) { 00351 self_type temporary (*this - ae); 00352 return assign_temporary (temporary); 00353 } 00354 template<class C> // Container assignment without temporary 00355 BOOST_UBLAS_INLINE 00356 matrix &operator -= (const matrix_container<C> &m) { 00357 minus_assign (m); 00358 return *this; 00359 } 00360 template<class AE> 00361 BOOST_UBLAS_INLINE 00362 matrix &minus_assign (const matrix_expression<AE> &ae) { 00363 matrix_assign<scalar_minus_assign> (*this, ae); 00364 return *this; 00365 } 00366 template<class AT> 00367 BOOST_UBLAS_INLINE 00368 matrix& operator *= (const AT &at) { 00369 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 00370 return *this; 00371 } 00372 template<class AT> 00373 BOOST_UBLAS_INLINE 00374 matrix& operator /= (const AT &at) { 00375 matrix_assign_scalar<scalar_divides_assign> (*this, at); 00376 return *this; 00377 } 00378 00379 // Swapping 00380 BOOST_UBLAS_INLINE 00381 void swap (matrix &m) { 00382 if (this != &m) { 00383 std::swap (size1_, m.size1_); 00384 std::swap (size2_, m.size2_); 00385 data ().swap (m.data ()); 00386 } 00387 } 00388 BOOST_UBLAS_INLINE 00389 friend void swap (matrix &m1, matrix &m2) { 00390 m1.swap (m2); 00391 } 00392 00393 // Iterator types 00394 private: 00395 // Use the storage array iterator 00396 typedef typename A::const_iterator const_subiterator_type; 00397 typedef typename A::iterator subiterator_type; 00398 00399 public: 00400 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00401 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1; 00402 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2; 00403 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1; 00404 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2; 00405 #else 00406 class const_iterator1; 00407 class iterator1; 00408 class const_iterator2; 00409 class iterator2; 00410 #endif 00411 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 00412 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 00413 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 00414 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 00415 00416 // Element lookup 00417 BOOST_UBLAS_INLINE 00418 const_iterator1 find1 (int /* rank */, size_type i, size_type j) const { 00419 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00420 return const_iterator1 (*this, i, j); 00421 #else 00422 return const_iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); 00423 #endif 00424 } 00425 BOOST_UBLAS_INLINE 00426 iterator1 find1 (int /* rank */, size_type i, size_type j) { 00427 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00428 return iterator1 (*this, i, j); 00429 #else 00430 return iterator1 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); 00431 #endif 00432 } 00433 BOOST_UBLAS_INLINE 00434 const_iterator2 find2 (int /* rank */, size_type i, size_type j) const { 00435 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00436 return const_iterator2 (*this, i, j); 00437 #else 00438 return const_iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); 00439 #endif 00440 } 00441 BOOST_UBLAS_INLINE 00442 iterator2 find2 (int /* rank */, size_type i, size_type j) { 00443 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 00444 return iterator2 (*this, i, j); 00445 #else 00446 return iterator2 (*this, data ().begin () + layout_type::address (i, size1_, j, size2_)); 00447 #endif 00448 } 00449 00450 00451 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00452 class const_iterator1: 00453 public container_const_reference<matrix>, 00454 public random_access_iterator_base<dense_random_access_iterator_tag, 00455 const_iterator1, value_type> { 00456 public: 00457 typedef typename matrix::value_type value_type; 00458 typedef typename matrix::difference_type difference_type; 00459 typedef typename matrix::const_reference reference; 00460 typedef const typename matrix::pointer pointer; 00461 00462 typedef const_iterator2 dual_iterator_type; 00463 typedef const_reverse_iterator2 dual_reverse_iterator_type; 00464 00465 // Construction and destruction 00466 BOOST_UBLAS_INLINE 00467 const_iterator1 (): 00468 container_const_reference<self_type> (), it_ () {} 00469 BOOST_UBLAS_INLINE 00470 const_iterator1 (const self_type &m, const const_subiterator_type &it): 00471 container_const_reference<self_type> (m), it_ (it) {} 00472 BOOST_UBLAS_INLINE 00473 const_iterator1 (const iterator1 &it): 00474 container_const_reference<self_type> (it ()), it_ (it.it_) {} 00475 00476 // Arithmetic 00477 BOOST_UBLAS_INLINE 00478 const_iterator1 &operator ++ () { 00479 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ()); 00480 return *this; 00481 } 00482 BOOST_UBLAS_INLINE 00483 const_iterator1 &operator -- () { 00484 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ()); 00485 return *this; 00486 } 00487 BOOST_UBLAS_INLINE 00488 const_iterator1 &operator += (difference_type n) { 00489 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00490 return *this; 00491 } 00492 BOOST_UBLAS_INLINE 00493 const_iterator1 &operator -= (difference_type n) { 00494 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00495 return *this; 00496 } 00497 BOOST_UBLAS_INLINE 00498 difference_type operator - (const const_iterator1 &it) const { 00499 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00500 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); 00501 } 00502 00503 // Dereference 00504 BOOST_UBLAS_INLINE 00505 const_reference operator * () const { 00506 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 00507 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 00508 return *it_; 00509 } 00510 BOOST_UBLAS_INLINE 00511 const_reference operator [] (difference_type n) const { 00512 return *(*this + n); 00513 } 00514 00515 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00516 BOOST_UBLAS_INLINE 00517 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00518 typename self_type:: 00519 #endif 00520 const_iterator2 begin () const { 00521 const self_type &m = (*this) (); 00522 return m.find2 (1, index1 (), 0); 00523 } 00524 BOOST_UBLAS_INLINE 00525 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00526 typename self_type:: 00527 #endif 00528 const_iterator2 end () const { 00529 const self_type &m = (*this) (); 00530 return m.find2 (1, index1 (), m.size2 ()); 00531 } 00532 BOOST_UBLAS_INLINE 00533 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00534 typename self_type:: 00535 #endif 00536 const_reverse_iterator2 rbegin () const { 00537 return const_reverse_iterator2 (end ()); 00538 } 00539 BOOST_UBLAS_INLINE 00540 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00541 typename self_type:: 00542 #endif 00543 const_reverse_iterator2 rend () const { 00544 return const_reverse_iterator2 (begin ()); 00545 } 00546 #endif 00547 00548 // Indices 00549 BOOST_UBLAS_INLINE 00550 size_type index1 () const { 00551 const self_type &m = (*this) (); 00552 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); 00553 } 00554 BOOST_UBLAS_INLINE 00555 size_type index2 () const { 00556 const self_type &m = (*this) (); 00557 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); 00558 } 00559 00560 // Assignment 00561 BOOST_UBLAS_INLINE 00562 const_iterator1 &operator = (const const_iterator1 &it) { 00563 container_const_reference<self_type>::assign (&it ()); 00564 it_ = it.it_; 00565 return *this; 00566 } 00567 00568 // Comparison 00569 BOOST_UBLAS_INLINE 00570 bool operator == (const const_iterator1 &it) const { 00571 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00572 return it_ == it.it_; 00573 } 00574 BOOST_UBLAS_INLINE 00575 bool operator < (const const_iterator1 &it) const { 00576 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00577 return it_ < it.it_; 00578 } 00579 00580 private: 00581 const_subiterator_type it_; 00582 00583 friend class iterator1; 00584 }; 00585 #endif 00586 00587 BOOST_UBLAS_INLINE 00588 const_iterator1 begin1 () const { 00589 return find1 (0, 0, 0); 00590 } 00591 BOOST_UBLAS_INLINE 00592 const_iterator1 end1 () const { 00593 return find1 (0, size1_, 0); 00594 } 00595 00596 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00597 class iterator1: 00598 public container_reference<matrix>, 00599 public random_access_iterator_base<dense_random_access_iterator_tag, 00600 iterator1, value_type> { 00601 public: 00602 typedef typename matrix::value_type value_type; 00603 typedef typename matrix::difference_type difference_type; 00604 typedef typename matrix::reference reference; 00605 typedef typename matrix::pointer pointer; 00606 00607 typedef iterator2 dual_iterator_type; 00608 typedef reverse_iterator2 dual_reverse_iterator_type; 00609 00610 // Construction and destruction 00611 BOOST_UBLAS_INLINE 00612 iterator1 (): 00613 container_reference<self_type> (), it_ () {} 00614 BOOST_UBLAS_INLINE 00615 iterator1 (self_type &m, const subiterator_type &it): 00616 container_reference<self_type> (m), it_ (it) {} 00617 00618 // Arithmetic 00619 BOOST_UBLAS_INLINE 00620 iterator1 &operator ++ () { 00621 layout_type::increment_i (it_, (*this) ().size1 (), (*this) ().size2 ()); 00622 return *this; 00623 } 00624 BOOST_UBLAS_INLINE 00625 iterator1 &operator -- () { 00626 layout_type::decrement_i (it_, (*this) ().size1 (), (*this) ().size2 ()); 00627 return *this; 00628 } 00629 BOOST_UBLAS_INLINE 00630 iterator1 &operator += (difference_type n) { 00631 layout_type::increment_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00632 return *this; 00633 } 00634 BOOST_UBLAS_INLINE 00635 iterator1 &operator -= (difference_type n) { 00636 layout_type::decrement_i (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00637 return *this; 00638 } 00639 BOOST_UBLAS_INLINE 00640 difference_type operator - (const iterator1 &it) const { 00641 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00642 return layout_type::distance_i (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); 00643 } 00644 00645 // Dereference 00646 BOOST_UBLAS_INLINE 00647 reference operator * () const { 00648 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 00649 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 00650 return *it_; 00651 } 00652 BOOST_UBLAS_INLINE 00653 reference operator [] (difference_type n) const { 00654 return *(*this + n); 00655 } 00656 00657 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00658 BOOST_UBLAS_INLINE 00659 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00660 typename self_type:: 00661 #endif 00662 iterator2 begin () const { 00663 self_type &m = (*this) (); 00664 return m.find2 (1, index1 (), 0); 00665 } 00666 BOOST_UBLAS_INLINE 00667 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00668 typename self_type:: 00669 #endif 00670 iterator2 end () const { 00671 self_type &m = (*this) (); 00672 return m.find2 (1, index1 (), m.size2 ()); 00673 } 00674 BOOST_UBLAS_INLINE 00675 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00676 typename self_type:: 00677 #endif 00678 reverse_iterator2 rbegin () const { 00679 return reverse_iterator2 (end ()); 00680 } 00681 BOOST_UBLAS_INLINE 00682 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00683 typename self_type:: 00684 #endif 00685 reverse_iterator2 rend () const { 00686 return reverse_iterator2 (begin ()); 00687 } 00688 #endif 00689 00690 // Indices 00691 BOOST_UBLAS_INLINE 00692 size_type index1 () const { 00693 self_type &m = (*this) (); 00694 return layout_type::index_i (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); 00695 } 00696 BOOST_UBLAS_INLINE 00697 size_type index2 () const { 00698 self_type &m = (*this) (); 00699 return layout_type::index_j (it_ - m.begin1 ().it_, m.size1 (), m.size2 ()); 00700 } 00701 00702 // Assignment 00703 BOOST_UBLAS_INLINE 00704 iterator1 &operator = (const iterator1 &it) { 00705 container_reference<self_type>::assign (&it ()); 00706 it_ = it.it_; 00707 return *this; 00708 } 00709 00710 // Comparison 00711 BOOST_UBLAS_INLINE 00712 bool operator == (const iterator1 &it) const { 00713 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00714 return it_ == it.it_; 00715 } 00716 BOOST_UBLAS_INLINE 00717 bool operator < (const iterator1 &it) const { 00718 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00719 return it_ < it.it_; 00720 } 00721 00722 private: 00723 subiterator_type it_; 00724 00725 friend class const_iterator1; 00726 }; 00727 #endif 00728 00729 BOOST_UBLAS_INLINE 00730 iterator1 begin1 () { 00731 return find1 (0, 0, 0); 00732 } 00733 BOOST_UBLAS_INLINE 00734 iterator1 end1 () { 00735 return find1 (0, size1_, 0); 00736 } 00737 00738 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00739 class const_iterator2: 00740 public container_const_reference<matrix>, 00741 public random_access_iterator_base<dense_random_access_iterator_tag, 00742 const_iterator2, value_type> { 00743 public: 00744 typedef typename matrix::value_type value_type; 00745 typedef typename matrix::difference_type difference_type; 00746 typedef typename matrix::const_reference reference; 00747 typedef const typename matrix::pointer pointer; 00748 00749 typedef const_iterator1 dual_iterator_type; 00750 typedef const_reverse_iterator1 dual_reverse_iterator_type; 00751 00752 // Construction and destruction 00753 BOOST_UBLAS_INLINE 00754 const_iterator2 (): 00755 container_const_reference<self_type> (), it_ () {} 00756 BOOST_UBLAS_INLINE 00757 const_iterator2 (const self_type &m, const const_subiterator_type &it): 00758 container_const_reference<self_type> (m), it_ (it) {} 00759 BOOST_UBLAS_INLINE 00760 const_iterator2 (const iterator2 &it): 00761 container_const_reference<self_type> (it ()), it_ (it.it_) {} 00762 00763 // Arithmetic 00764 BOOST_UBLAS_INLINE 00765 const_iterator2 &operator ++ () { 00766 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ()); 00767 return *this; 00768 } 00769 BOOST_UBLAS_INLINE 00770 const_iterator2 &operator -- () { 00771 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ()); 00772 return *this; 00773 } 00774 BOOST_UBLAS_INLINE 00775 const_iterator2 &operator += (difference_type n) { 00776 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00777 return *this; 00778 } 00779 BOOST_UBLAS_INLINE 00780 const_iterator2 &operator -= (difference_type n) { 00781 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00782 return *this; 00783 } 00784 BOOST_UBLAS_INLINE 00785 difference_type operator - (const const_iterator2 &it) const { 00786 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00787 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); 00788 } 00789 00790 // Dereference 00791 BOOST_UBLAS_INLINE 00792 const_reference operator * () const { 00793 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 00794 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 00795 return *it_; 00796 } 00797 BOOST_UBLAS_INLINE 00798 const_reference operator [] (difference_type n) const { 00799 return *(*this + n); 00800 } 00801 00802 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00803 BOOST_UBLAS_INLINE 00804 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00805 typename self_type:: 00806 #endif 00807 const_iterator1 begin () const { 00808 const self_type &m = (*this) (); 00809 return m.find1 (1, 0, index2 ()); 00810 } 00811 BOOST_UBLAS_INLINE 00812 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00813 typename self_type:: 00814 #endif 00815 const_iterator1 end () const { 00816 const self_type &m = (*this) (); 00817 return m.find1 (1, m.size1 (), index2 ()); 00818 } 00819 BOOST_UBLAS_INLINE 00820 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00821 typename self_type:: 00822 #endif 00823 const_reverse_iterator1 rbegin () const { 00824 return const_reverse_iterator1 (end ()); 00825 } 00826 BOOST_UBLAS_INLINE 00827 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00828 typename self_type:: 00829 #endif 00830 const_reverse_iterator1 rend () const { 00831 return const_reverse_iterator1 (begin ()); 00832 } 00833 #endif 00834 00835 // Indices 00836 BOOST_UBLAS_INLINE 00837 size_type index1 () const { 00838 const self_type &m = (*this) (); 00839 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); 00840 } 00841 BOOST_UBLAS_INLINE 00842 size_type index2 () const { 00843 const self_type &m = (*this) (); 00844 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); 00845 } 00846 00847 // Assignment 00848 BOOST_UBLAS_INLINE 00849 const_iterator2 &operator = (const const_iterator2 &it) { 00850 container_const_reference<self_type>::assign (&it ()); 00851 it_ = it.it_; 00852 return *this; 00853 } 00854 00855 // Comparison 00856 BOOST_UBLAS_INLINE 00857 bool operator == (const const_iterator2 &it) const { 00858 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00859 return it_ == it.it_; 00860 } 00861 BOOST_UBLAS_INLINE 00862 bool operator < (const const_iterator2 &it) const { 00863 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00864 return it_ < it.it_; 00865 } 00866 00867 private: 00868 const_subiterator_type it_; 00869 00870 friend class iterator2; 00871 }; 00872 #endif 00873 00874 BOOST_UBLAS_INLINE 00875 const_iterator2 begin2 () const { 00876 return find2 (0, 0, 0); 00877 } 00878 BOOST_UBLAS_INLINE 00879 const_iterator2 end2 () const { 00880 return find2 (0, 0, size2_); 00881 } 00882 00883 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 00884 class iterator2: 00885 public container_reference<matrix>, 00886 public random_access_iterator_base<dense_random_access_iterator_tag, 00887 iterator2, value_type> { 00888 public: 00889 typedef typename matrix::value_type value_type; 00890 typedef typename matrix::difference_type difference_type; 00891 typedef typename matrix::reference reference; 00892 typedef typename matrix::pointer pointer; 00893 00894 typedef iterator1 dual_iterator_type; 00895 typedef reverse_iterator1 dual_reverse_iterator_type; 00896 00897 // Construction and destruction 00898 BOOST_UBLAS_INLINE 00899 iterator2 (): 00900 container_reference<self_type> (), it_ () {} 00901 BOOST_UBLAS_INLINE 00902 iterator2 (self_type &m, const subiterator_type &it): 00903 container_reference<self_type> (m), it_ (it) {} 00904 00905 // Arithmetic 00906 BOOST_UBLAS_INLINE 00907 iterator2 &operator ++ () { 00908 layout_type::increment_j (it_, (*this) ().size1 (), (*this) ().size2 ()); 00909 return *this; 00910 } 00911 BOOST_UBLAS_INLINE 00912 iterator2 &operator -- () { 00913 layout_type::decrement_j (it_, (*this) ().size1 (), (*this) ().size2 ()); 00914 return *this; 00915 } 00916 BOOST_UBLAS_INLINE 00917 iterator2 &operator += (difference_type n) { 00918 layout_type::increment_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00919 return *this; 00920 } 00921 BOOST_UBLAS_INLINE 00922 iterator2 &operator -= (difference_type n) { 00923 layout_type::decrement_j (it_, n, (*this) ().size1 (), (*this) ().size2 ()); 00924 return *this; 00925 } 00926 BOOST_UBLAS_INLINE 00927 difference_type operator - (const iterator2 &it) const { 00928 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 00929 return layout_type::distance_j (it_ - it.it_, (*this) ().size1 (), (*this) ().size2 ()); 00930 } 00931 00932 // Dereference 00933 BOOST_UBLAS_INLINE 00934 reference operator * () const { 00935 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 00936 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 00937 return *it_; 00938 } 00939 BOOST_UBLAS_INLINE 00940 reference operator [] (difference_type n) const { 00941 return *(*this + n); 00942 } 00943 00944 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 00945 BOOST_UBLAS_INLINE 00946 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00947 typename self_type:: 00948 #endif 00949 iterator1 begin () const { 00950 self_type &m = (*this) (); 00951 return m.find1 (1, 0, index2 ()); 00952 } 00953 BOOST_UBLAS_INLINE 00954 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00955 typename self_type:: 00956 #endif 00957 iterator1 end () const { 00958 self_type &m = (*this) (); 00959 return m.find1 (1, m.size1 (), index2 ()); 00960 } 00961 BOOST_UBLAS_INLINE 00962 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00963 typename self_type:: 00964 #endif 00965 reverse_iterator1 rbegin () const { 00966 return reverse_iterator1 (end ()); 00967 } 00968 BOOST_UBLAS_INLINE 00969 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 00970 typename self_type:: 00971 #endif 00972 reverse_iterator1 rend () const { 00973 return reverse_iterator1 (begin ()); 00974 } 00975 #endif 00976 00977 // Indices 00978 BOOST_UBLAS_INLINE 00979 size_type index1 () const { 00980 self_type &m = (*this) (); 00981 return layout_type::index_i (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); 00982 } 00983 BOOST_UBLAS_INLINE 00984 size_type index2 () const { 00985 self_type &m = (*this) (); 00986 return layout_type::index_j (it_ - m.begin2 ().it_, m.size1 (), m.size2 ()); 00987 } 00988 00989 // Assignment 00990 BOOST_UBLAS_INLINE 00991 iterator2 &operator = (const iterator2 &it) { 00992 container_reference<self_type>::assign (&it ()); 00993 it_ = it.it_; 00994 return *this; 00995 } 00996 00997 // Comparison 00998 BOOST_UBLAS_INLINE 00999 bool operator == (const iterator2 &it) const { 01000 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01001 return it_ == it.it_; 01002 } 01003 BOOST_UBLAS_INLINE 01004 bool operator < (const iterator2 &it) const { 01005 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01006 return it_ < it.it_; 01007 } 01008 01009 private: 01010 subiterator_type it_; 01011 01012 friend class const_iterator2; 01013 }; 01014 #endif 01015 01016 BOOST_UBLAS_INLINE 01017 iterator2 begin2 () { 01018 return find2 (0, 0, 0); 01019 } 01020 BOOST_UBLAS_INLINE 01021 iterator2 end2 () { 01022 return find2 (0, 0, size2_); 01023 } 01024 01025 // Reverse iterators 01026 01027 BOOST_UBLAS_INLINE 01028 const_reverse_iterator1 rbegin1 () const { 01029 return const_reverse_iterator1 (end1 ()); 01030 } 01031 BOOST_UBLAS_INLINE 01032 const_reverse_iterator1 rend1 () const { 01033 return const_reverse_iterator1 (begin1 ()); 01034 } 01035 01036 BOOST_UBLAS_INLINE 01037 reverse_iterator1 rbegin1 () { 01038 return reverse_iterator1 (end1 ()); 01039 } 01040 BOOST_UBLAS_INLINE 01041 reverse_iterator1 rend1 () { 01042 return reverse_iterator1 (begin1 ()); 01043 } 01044 01045 BOOST_UBLAS_INLINE 01046 const_reverse_iterator2 rbegin2 () const { 01047 return const_reverse_iterator2 (end2 ()); 01048 } 01049 BOOST_UBLAS_INLINE 01050 const_reverse_iterator2 rend2 () const { 01051 return const_reverse_iterator2 (begin2 ()); 01052 } 01053 01054 BOOST_UBLAS_INLINE 01055 reverse_iterator2 rbegin2 () { 01056 return reverse_iterator2 (end2 ()); 01057 } 01058 BOOST_UBLAS_INLINE 01059 reverse_iterator2 rend2 () { 01060 return reverse_iterator2 (begin2 ()); 01061 } 01062 01063 // Serialization 01064 template<class Archive> 01065 void serialize(Archive & ar, const unsigned int /* file_version */){ 01066 01067 // we need to copy to a collection_size_type to get a portable 01068 // and efficient serialization 01069 serialization::collection_size_type s1 (size1_); 01070 serialization::collection_size_type s2 (size2_); 01071 01072 // serialize the sizes 01073 ar & serialization::make_nvp("size1",s1) 01074 & serialization::make_nvp("size2",s2); 01075 01076 // copy the values back if loading 01077 if (Archive::is_loading::value) { 01078 size1_ = s1; 01079 size2_ = s2; 01080 } 01081 ar & serialization::make_nvp("data",data_); 01082 } 01083 01084 private: 01085 size_type size1_; 01086 size_type size2_; 01087 array_type data_; 01088 }; 01089 01106 template<class T, std::size_t M, std::size_t N, class L> 01107 class bounded_matrix: 01108 public matrix<T, L, bounded_array<T, M * N> > { 01109 01110 typedef matrix<T, L, bounded_array<T, M * N> > matrix_type; 01111 public: 01112 typedef typename matrix_type::size_type size_type; 01113 static const size_type max_size1 = M; 01114 static const size_type max_size2 = N; 01115 01116 // Construction and destruction 01117 BOOST_UBLAS_INLINE 01118 bounded_matrix (): 01119 matrix_type (M, N) {} 01120 BOOST_UBLAS_INLINE 01121 bounded_matrix (size_type size1, size_type size2): 01122 matrix_type (size1, size2) {} 01123 BOOST_UBLAS_INLINE 01124 bounded_matrix (const bounded_matrix &m): 01125 matrix_type (m) {} 01126 template<class A2> // Allow matrix<T, L, bounded_array<M,N> > construction 01127 BOOST_UBLAS_INLINE 01128 bounded_matrix (const matrix<T, L, A2> &m): 01129 matrix_type (m) {} 01130 template<class AE> 01131 BOOST_UBLAS_INLINE 01132 bounded_matrix (const matrix_expression<AE> &ae): 01133 matrix_type (ae) {} 01134 BOOST_UBLAS_INLINE 01135 ~bounded_matrix () {} 01136 01137 // Assignment 01138 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 01139 01141 BOOST_UBLAS_INLINE 01142 bounded_matrix &operator = (bounded_matrix m) { 01143 matrix_type::operator = (m); 01144 return *this; 01145 } 01146 #else 01147 BOOST_UBLAS_INLINE 01148 bounded_matrix &operator = (const bounded_matrix &m) { 01149 matrix_type::operator = (m); 01150 return *this; 01151 } 01152 #endif 01153 template<class L2, class A2> // Generic matrix assignment 01154 BOOST_UBLAS_INLINE 01155 bounded_matrix &operator = (const matrix<T, L2, A2> &m) { 01156 matrix_type::operator = (m); 01157 return *this; 01158 } 01159 template<class C> // Container assignment without temporary 01160 BOOST_UBLAS_INLINE 01161 bounded_matrix &operator = (const matrix_container<C> &m) { 01162 matrix_type::operator = (m); 01163 return *this; 01164 } 01165 template<class AE> 01166 BOOST_UBLAS_INLINE 01167 bounded_matrix &operator = (const matrix_expression<AE> &ae) { 01168 matrix_type::operator = (ae); 01169 return *this; 01170 } 01171 }; 01172 01188 template<class T, class L, class A> 01189 class vector_of_vector: 01190 public matrix_container<vector_of_vector<T, L, A> > { 01191 01192 typedef T *pointer; 01193 typedef L layout_type; 01194 typedef vector_of_vector<T, L, A> self_type; 01195 public: 01196 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 01197 using matrix_container<self_type>::operator (); 01198 #endif 01199 typedef typename A::size_type size_type; 01200 typedef typename A::difference_type difference_type; 01201 typedef T value_type; 01202 typedef const T &const_reference; 01203 typedef T &reference; 01204 typedef A array_type; 01205 typedef const matrix_reference<const self_type> const_closure_type; 01206 typedef matrix_reference<self_type> closure_type; 01207 typedef vector<T, typename A::value_type> vector_temporary_type; 01208 typedef self_type matrix_temporary_type; 01209 typedef dense_tag storage_category; 01210 // This could be better for performance, 01211 // typedef typename unknown_orientation_tag orientation_category; 01212 // but others depend on the orientation information... 01213 typedef typename L::orientation_category orientation_category; 01214 01215 // Construction and destruction 01216 BOOST_UBLAS_INLINE 01217 vector_of_vector (): 01218 matrix_container<self_type> (), 01219 size1_ (0), size2_ (0), data_ (1) {} 01220 BOOST_UBLAS_INLINE 01221 vector_of_vector (size_type size1, size_type size2): 01222 matrix_container<self_type> (), 01223 size1_ (size1), size2_ (size2), data_ (1) { 01224 resize (size1, size2, true); 01225 } 01226 BOOST_UBLAS_INLINE 01227 vector_of_vector (const vector_of_vector &m): 01228 matrix_container<self_type> (), 01229 size1_ (m.size1_), size2_ (m.size2_), data_ (m.data_) {} 01230 template<class AE> 01231 BOOST_UBLAS_INLINE 01232 vector_of_vector (const matrix_expression<AE> &ae): 01233 matrix_container<self_type> (), 01234 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()), data_ (layout_type::size_M (size1_, size2_) + 1) { 01235 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k) 01236 data ()[k].resize (layout_type::size_m (size1_, size2_)); 01237 matrix_assign<scalar_assign> (*this, ae); 01238 } 01239 01240 // Accessors 01241 BOOST_UBLAS_INLINE 01242 size_type size1 () const { 01243 return size1_; 01244 } 01245 BOOST_UBLAS_INLINE 01246 size_type size2 () const { 01247 return size2_; 01248 } 01249 01250 // Storage accessors 01251 BOOST_UBLAS_INLINE 01252 const array_type &data () const { 01253 return data_; 01254 } 01255 BOOST_UBLAS_INLINE 01256 array_type &data () { 01257 return data_; 01258 } 01259 01260 // Resizing 01261 BOOST_UBLAS_INLINE 01262 void resize (size_type size1, size_type size2, bool preserve = true) { 01263 size1_ = size1; 01264 size2_ = size2; 01265 if (preserve) 01266 data ().resize (layout_type::size_M (size1, size2) + 1, typename array_type::value_type ()); 01267 else 01268 data ().resize (layout_type::size_M (size1, size2) + 1); 01269 for (size_type k = 0; k < layout_type::size_M (size1, size2); ++ k) { 01270 if (preserve) 01271 data () [k].resize (layout_type::size_m (size1, size2), value_type ()); 01272 else 01273 data () [k].resize (layout_type::size_m (size1, size2)); 01274 } 01275 } 01276 01277 // Element access 01278 BOOST_UBLAS_INLINE 01279 const_reference operator () (size_type i, size_type j) const { 01280 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)]; 01281 } 01282 BOOST_UBLAS_INLINE 01283 reference at_element (size_type i, size_type j) { 01284 return data () [layout_type::index_M (i, j)] [layout_type::index_m (i, j)]; 01285 } 01286 BOOST_UBLAS_INLINE 01287 reference operator () (size_type i, size_type j) { 01288 return at_element (i, j); 01289 } 01290 01291 // Element assignment 01292 BOOST_UBLAS_INLINE 01293 reference insert_element (size_type i, size_type j, const_reference t) { 01294 return (at_element (i, j) = t); 01295 } 01296 BOOST_UBLAS_INLINE 01297 void erase_element (size_type i, size_type j) { 01298 at_element (i, j) = value_type/*zero*/(); 01299 } 01300 01301 // Zeroing 01302 BOOST_UBLAS_INLINE 01303 void clear () { 01304 for (size_type k = 0; k < layout_type::size_M (size1_, size2_); ++ k) 01305 std::fill (data () [k].begin (), data () [k].end (), value_type/*zero*/()); 01306 } 01307 01308 // Assignment 01309 BOOST_UBLAS_INLINE 01310 vector_of_vector &operator = (const vector_of_vector &m) { 01311 size1_ = m.size1_; 01312 size2_ = m.size2_; 01313 data () = m.data (); 01314 return *this; 01315 } 01316 BOOST_UBLAS_INLINE 01317 vector_of_vector &assign_temporary (vector_of_vector &m) { 01318 swap (m); 01319 return *this; 01320 } 01321 template<class AE> 01322 BOOST_UBLAS_INLINE 01323 vector_of_vector &operator = (const matrix_expression<AE> &ae) { 01324 self_type temporary (ae); 01325 return assign_temporary (temporary); 01326 } 01327 template<class C> // Container assignment without temporary 01328 BOOST_UBLAS_INLINE 01329 vector_of_vector &operator = (const matrix_container<C> &m) { 01330 resize (m ().size1 (), m ().size2 (), false); 01331 assign (m); 01332 return *this; 01333 } 01334 template<class AE> 01335 BOOST_UBLAS_INLINE 01336 vector_of_vector &assign (const matrix_expression<AE> &ae) { 01337 matrix_assign<scalar_assign> (*this, ae); 01338 return *this; 01339 } 01340 template<class AE> 01341 BOOST_UBLAS_INLINE 01342 vector_of_vector& operator += (const matrix_expression<AE> &ae) { 01343 self_type temporary (*this + ae); 01344 return assign_temporary (temporary); 01345 } 01346 template<class C> // Container assignment without temporary 01347 BOOST_UBLAS_INLINE 01348 vector_of_vector &operator += (const matrix_container<C> &m) { 01349 plus_assign (m); 01350 return *this; 01351 } 01352 template<class AE> 01353 BOOST_UBLAS_INLINE 01354 vector_of_vector &plus_assign (const matrix_expression<AE> &ae) { 01355 matrix_assign<scalar_plus_assign> (*this, ae); 01356 return *this; 01357 } 01358 template<class AE> 01359 BOOST_UBLAS_INLINE 01360 vector_of_vector& operator -= (const matrix_expression<AE> &ae) { 01361 self_type temporary (*this - ae); 01362 return assign_temporary (temporary); 01363 } 01364 template<class C> // Container assignment without temporary 01365 BOOST_UBLAS_INLINE 01366 vector_of_vector &operator -= (const matrix_container<C> &m) { 01367 minus_assign (m); 01368 return *this; 01369 } 01370 template<class AE> 01371 BOOST_UBLAS_INLINE 01372 vector_of_vector &minus_assign (const matrix_expression<AE> &ae) { 01373 matrix_assign<scalar_minus_assign> (*this, ae); 01374 return *this; 01375 } 01376 template<class AT> 01377 BOOST_UBLAS_INLINE 01378 vector_of_vector& operator *= (const AT &at) { 01379 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 01380 return *this; 01381 } 01382 template<class AT> 01383 BOOST_UBLAS_INLINE 01384 vector_of_vector& operator /= (const AT &at) { 01385 matrix_assign_scalar<scalar_divides_assign> (*this, at); 01386 return *this; 01387 } 01388 01389 // Swapping 01390 BOOST_UBLAS_INLINE 01391 void swap (vector_of_vector &m) { 01392 if (this != &m) { 01393 std::swap (size1_, m.size1_); 01394 std::swap (size2_, m.size2_); 01395 data ().swap (m.data ()); 01396 } 01397 } 01398 BOOST_UBLAS_INLINE 01399 friend void swap (vector_of_vector &m1, vector_of_vector &m2) { 01400 m1.swap (m2); 01401 } 01402 01403 // Iterator types 01404 private: 01405 // Use the vector iterator 01406 typedef typename A::value_type::const_iterator const_subiterator_type; 01407 typedef typename A::value_type::iterator subiterator_type; 01408 public: 01409 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 01410 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1; 01411 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2; 01412 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1; 01413 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2; 01414 #else 01415 class const_iterator1; 01416 class iterator1; 01417 class const_iterator2; 01418 class iterator2; 01419 #endif 01420 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 01421 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 01422 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 01423 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 01424 01425 // Element lookup 01426 BOOST_UBLAS_INLINE 01427 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const { 01428 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 01429 return const_iterator1 (*this, i, j); 01430 #else 01431 return const_iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); 01432 #endif 01433 } 01434 BOOST_UBLAS_INLINE 01435 iterator1 find1 (int /*rank*/, size_type i, size_type j) { 01436 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 01437 return iterator1 (*this, i, j); 01438 #else 01439 return iterator1 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); 01440 #endif 01441 } 01442 BOOST_UBLAS_INLINE 01443 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const { 01444 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 01445 return const_iterator2 (*this, i, j); 01446 #else 01447 return const_iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); 01448 #endif 01449 } 01450 BOOST_UBLAS_INLINE 01451 iterator2 find2 (int /*rank*/, size_type i, size_type j) { 01452 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 01453 return iterator2 (*this, i, j); 01454 #else 01455 return iterator2 (*this, i, j, data () [layout_type::index_M (i, j)].begin () + layout_type::index_m (i, j)); 01456 #endif 01457 } 01458 01459 01460 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01461 class const_iterator1: 01462 public container_const_reference<vector_of_vector>, 01463 public random_access_iterator_base<dense_random_access_iterator_tag, 01464 const_iterator1, value_type> { 01465 public: 01466 typedef typename vector_of_vector::value_type value_type; 01467 typedef typename vector_of_vector::difference_type difference_type; 01468 typedef typename vector_of_vector::const_reference reference; 01469 typedef const typename vector_of_vector::pointer pointer; 01470 01471 typedef const_iterator2 dual_iterator_type; 01472 typedef const_reverse_iterator2 dual_reverse_iterator_type; 01473 01474 // Construction and destruction 01475 BOOST_UBLAS_INLINE 01476 const_iterator1 (): 01477 container_const_reference<self_type> (), i_ (), j_ (), it_ () {} 01478 BOOST_UBLAS_INLINE 01479 const_iterator1 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it): 01480 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {} 01481 BOOST_UBLAS_INLINE 01482 const_iterator1 (const iterator1 &it): 01483 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} 01484 01485 // Arithmetic 01486 BOOST_UBLAS_INLINE 01487 const_iterator1 &operator ++ () { 01488 ++ i_; 01489 const self_type &m = (*this) (); 01490 if (layout_type::fast_i ()) 01491 ++ it_; 01492 else 01493 it_ = m.find1 (1, i_, j_).it_; 01494 return *this; 01495 } 01496 BOOST_UBLAS_INLINE 01497 const_iterator1 &operator -- () { 01498 -- i_; 01499 const self_type &m = (*this) (); 01500 if (layout_type::fast_i ()) 01501 -- it_; 01502 else 01503 it_ = m.find1 (1, i_, j_).it_; 01504 return *this; 01505 } 01506 BOOST_UBLAS_INLINE 01507 const_iterator1 &operator += (difference_type n) { 01508 i_ += n; 01509 const self_type &m = (*this) (); 01510 it_ = m.find1 (1, i_, j_).it_; 01511 return *this; 01512 } 01513 BOOST_UBLAS_INLINE 01514 const_iterator1 &operator -= (difference_type n) { 01515 i_ -= n; 01516 const self_type &m = (*this) (); 01517 it_ = m.find1 (1, i_, j_).it_; 01518 return *this; 01519 } 01520 BOOST_UBLAS_INLINE 01521 difference_type operator - (const const_iterator1 &it) const { 01522 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01523 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); 01524 return index1 () - it.index1 (); 01525 } 01526 01527 // Dereference 01528 BOOST_UBLAS_INLINE 01529 const_reference operator * () const { 01530 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 01531 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 01532 return *it_; 01533 } 01534 BOOST_UBLAS_INLINE 01535 const_reference operator [] (difference_type n) const { 01536 return *(*this + n); 01537 } 01538 01539 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 01540 BOOST_UBLAS_INLINE 01541 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01542 typename self_type:: 01543 #endif 01544 const_iterator2 begin () const { 01545 const self_type &m = (*this) (); 01546 return m.find2 (1, index1 (), 0); 01547 } 01548 BOOST_UBLAS_INLINE 01549 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01550 typename self_type:: 01551 #endif 01552 const_iterator2 end () const { 01553 const self_type &m = (*this) (); 01554 return m.find2 (1, index1 (), m.size2 ()); 01555 } 01556 BOOST_UBLAS_INLINE 01557 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01558 typename self_type:: 01559 #endif 01560 const_reverse_iterator2 rbegin () const { 01561 return const_reverse_iterator2 (end ()); 01562 } 01563 BOOST_UBLAS_INLINE 01564 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01565 typename self_type:: 01566 #endif 01567 const_reverse_iterator2 rend () const { 01568 return const_reverse_iterator2 (begin ()); 01569 } 01570 #endif 01571 01572 // Indices 01573 BOOST_UBLAS_INLINE 01574 size_type index1 () const { 01575 return i_; 01576 } 01577 BOOST_UBLAS_INLINE 01578 size_type index2 () const { 01579 return j_; 01580 } 01581 01582 // Assignment 01583 BOOST_UBLAS_INLINE 01584 const_iterator1 &operator = (const const_iterator1 &it) { 01585 container_const_reference<self_type>::assign (&it ()); 01586 it_ = it.it_; 01587 return *this; 01588 } 01589 01590 // Comparison 01591 BOOST_UBLAS_INLINE 01592 bool operator == (const const_iterator1 &it) const { 01593 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01594 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); 01595 return it_ == it.it_; 01596 } 01597 BOOST_UBLAS_INLINE 01598 bool operator < (const const_iterator1 &it) const { 01599 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01600 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); 01601 return it_ < it.it_; 01602 } 01603 01604 private: 01605 size_type i_; 01606 size_type j_; 01607 const_subiterator_type it_; 01608 01609 friend class iterator1; 01610 }; 01611 #endif 01612 01613 BOOST_UBLAS_INLINE 01614 const_iterator1 begin1 () const { 01615 return find1 (0, 0, 0); 01616 } 01617 BOOST_UBLAS_INLINE 01618 const_iterator1 end1 () const { 01619 return find1 (0, size1_, 0); 01620 } 01621 01622 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01623 class iterator1: 01624 public container_reference<vector_of_vector>, 01625 public random_access_iterator_base<dense_random_access_iterator_tag, 01626 iterator1, value_type> { 01627 public: 01628 typedef typename vector_of_vector::value_type value_type; 01629 typedef typename vector_of_vector::difference_type difference_type; 01630 typedef typename vector_of_vector::reference reference; 01631 typedef typename vector_of_vector::pointer pointer; 01632 01633 typedef iterator2 dual_iterator_type; 01634 typedef reverse_iterator2 dual_reverse_iterator_type; 01635 01636 // Construction and destruction 01637 BOOST_UBLAS_INLINE 01638 iterator1 (): 01639 container_reference<self_type> (), i_ (), j_ (), it_ () {} 01640 BOOST_UBLAS_INLINE 01641 iterator1 (self_type &m, size_type i, size_type j, const subiterator_type &it): 01642 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {} 01643 01644 // Arithmetic 01645 BOOST_UBLAS_INLINE 01646 iterator1 &operator ++ () { 01647 ++ i_; 01648 self_type &m = (*this) (); 01649 if (layout_type::fast_i ()) 01650 ++ it_; 01651 else 01652 it_ = m.find1 (1, i_, j_).it_; 01653 return *this; 01654 } 01655 BOOST_UBLAS_INLINE 01656 iterator1 &operator -- () { 01657 -- i_; 01658 self_type &m = (*this) (); 01659 if (layout_type::fast_i ()) 01660 -- it_; 01661 else 01662 it_ = m.find1 (1, i_, j_).it_; 01663 return *this; 01664 } 01665 BOOST_UBLAS_INLINE 01666 iterator1 &operator += (difference_type n) { 01667 i_ += n; 01668 self_type &m = (*this) (); 01669 it_ = m.find1 (1, i_, j_).it_; 01670 return *this; 01671 } 01672 BOOST_UBLAS_INLINE 01673 iterator1 &operator -= (difference_type n) { 01674 i_ -= n; 01675 self_type &m = (*this) (); 01676 it_ = m.find1 (1, i_, j_).it_; 01677 return *this; 01678 } 01679 BOOST_UBLAS_INLINE 01680 difference_type operator - (const iterator1 &it) const { 01681 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01682 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); 01683 return index1 () - it.index1 (); 01684 } 01685 01686 // Dereference 01687 BOOST_UBLAS_INLINE 01688 reference operator * () const { 01689 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 01690 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 01691 return *it_; 01692 } 01693 BOOST_UBLAS_INLINE 01694 reference operator [] (difference_type n) const { 01695 return *(*this + n); 01696 } 01697 01698 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 01699 BOOST_UBLAS_INLINE 01700 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01701 typename self_type:: 01702 #endif 01703 iterator2 begin () const { 01704 self_type &m = (*this) (); 01705 return m.find2 (1, index1 (), 0); 01706 } 01707 BOOST_UBLAS_INLINE 01708 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01709 typename self_type:: 01710 #endif 01711 iterator2 end () const { 01712 self_type &m = (*this) (); 01713 return m.find2 (1, index1 (), m.size2 ()); 01714 } 01715 BOOST_UBLAS_INLINE 01716 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01717 typename self_type:: 01718 #endif 01719 reverse_iterator2 rbegin () const { 01720 return reverse_iterator2 (end ()); 01721 } 01722 BOOST_UBLAS_INLINE 01723 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01724 typename self_type:: 01725 #endif 01726 reverse_iterator2 rend () const { 01727 return reverse_iterator2 (begin ()); 01728 } 01729 #endif 01730 01731 // Indices 01732 BOOST_UBLAS_INLINE 01733 size_type index1 () const { 01734 return i_; 01735 } 01736 BOOST_UBLAS_INLINE 01737 size_type index2 () const { 01738 return j_; 01739 } 01740 01741 // Assignment 01742 BOOST_UBLAS_INLINE 01743 iterator1 &operator = (const iterator1 &it) { 01744 container_reference<self_type>::assign (&it ()); 01745 it_ = it.it_; 01746 return *this; 01747 } 01748 01749 // Comparison 01750 BOOST_UBLAS_INLINE 01751 bool operator == (const iterator1 &it) const { 01752 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01753 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); 01754 return it_ == it.it_; 01755 } 01756 BOOST_UBLAS_INLINE 01757 bool operator < (const iterator1 &it) const { 01758 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01759 BOOST_UBLAS_CHECK (index2 () == it.index2 (), bad_index ()); 01760 return it_ < it.it_; 01761 } 01762 01763 private: 01764 size_type i_; 01765 size_type j_; 01766 subiterator_type it_; 01767 01768 friend class const_iterator1; 01769 }; 01770 #endif 01771 01772 BOOST_UBLAS_INLINE 01773 iterator1 begin1 () { 01774 return find1 (0, 0, 0); 01775 } 01776 BOOST_UBLAS_INLINE 01777 iterator1 end1 () { 01778 return find1 (0, size1_, 0); 01779 } 01780 01781 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01782 class const_iterator2: 01783 public container_const_reference<vector_of_vector>, 01784 public random_access_iterator_base<dense_random_access_iterator_tag, 01785 const_iterator2, value_type> { 01786 public: 01787 typedef typename vector_of_vector::value_type value_type; 01788 typedef typename vector_of_vector::difference_type difference_type; 01789 typedef typename vector_of_vector::const_reference reference; 01790 typedef const typename vector_of_vector::pointer pointer; 01791 01792 typedef const_iterator1 dual_iterator_type; 01793 typedef const_reverse_iterator1 dual_reverse_iterator_type; 01794 01795 // Construction and destruction 01796 BOOST_UBLAS_INLINE 01797 const_iterator2 (): 01798 container_const_reference<self_type> (), i_ (), j_ (), it_ () {} 01799 BOOST_UBLAS_INLINE 01800 const_iterator2 (const self_type &m, size_type i, size_type j, const const_subiterator_type &it): 01801 container_const_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {} 01802 BOOST_UBLAS_INLINE 01803 const_iterator2 (const iterator2 &it): 01804 container_const_reference<self_type> (it ()), i_ (it.i_), j_ (it.j_), it_ (it.it_) {} 01805 01806 // Arithmetic 01807 BOOST_UBLAS_INLINE 01808 const_iterator2 &operator ++ () { 01809 ++ j_; 01810 const self_type &m = (*this) (); 01811 if (layout_type::fast_j ()) 01812 ++ it_; 01813 else 01814 it_ = m.find2 (1, i_, j_).it_; 01815 return *this; 01816 } 01817 BOOST_UBLAS_INLINE 01818 const_iterator2 &operator -- () { 01819 -- j_; 01820 const self_type &m = (*this) (); 01821 if (layout_type::fast_j ()) 01822 -- it_; 01823 else 01824 it_ = m.find2 (1, i_, j_).it_; 01825 return *this; 01826 } 01827 BOOST_UBLAS_INLINE 01828 const_iterator2 &operator += (difference_type n) { 01829 j_ += n; 01830 const self_type &m = (*this) (); 01831 it_ = m.find2 (1, i_, j_).it_; 01832 return *this; 01833 } 01834 BOOST_UBLAS_INLINE 01835 const_iterator2 &operator -= (difference_type n) { 01836 j_ -= n; 01837 const self_type &m = (*this) (); 01838 it_ = m.find2 (1, i_, j_).it_; 01839 return *this; 01840 } 01841 BOOST_UBLAS_INLINE 01842 difference_type operator - (const const_iterator2 &it) const { 01843 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01844 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); 01845 return index2 () - it.index2 (); 01846 } 01847 01848 // Dereference 01849 BOOST_UBLAS_INLINE 01850 const_reference operator * () const { 01851 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 01852 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 01853 return *it_; 01854 } 01855 BOOST_UBLAS_INLINE 01856 const_reference operator [] (difference_type n) const { 01857 return *(*this + n); 01858 } 01859 01860 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 01861 BOOST_UBLAS_INLINE 01862 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01863 typename self_type:: 01864 #endif 01865 const_iterator1 begin () const { 01866 const self_type &m = (*this) (); 01867 return m.find1 (1, 0, index2 ()); 01868 } 01869 BOOST_UBLAS_INLINE 01870 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01871 typename self_type:: 01872 #endif 01873 const_iterator1 end () const { 01874 const self_type &m = (*this) (); 01875 return m.find1 (1, m.size1 (), index2 ()); 01876 } 01877 BOOST_UBLAS_INLINE 01878 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01879 typename self_type:: 01880 #endif 01881 const_reverse_iterator1 rbegin () const { 01882 return const_reverse_iterator1 (end ()); 01883 } 01884 BOOST_UBLAS_INLINE 01885 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 01886 typename self_type:: 01887 #endif 01888 const_reverse_iterator1 rend () const { 01889 return const_reverse_iterator1 (begin ()); 01890 } 01891 #endif 01892 01893 // Indices 01894 BOOST_UBLAS_INLINE 01895 size_type index1 () const { 01896 return i_; 01897 } 01898 BOOST_UBLAS_INLINE 01899 size_type index2 () const { 01900 return j_; 01901 } 01902 01903 // Assignment 01904 BOOST_UBLAS_INLINE 01905 const_iterator2 &operator = (const const_iterator2 &it) { 01906 container_const_reference<self_type>::assign (&it ()); 01907 it_ = it.it_; 01908 return *this; 01909 } 01910 01911 // Comparison 01912 BOOST_UBLAS_INLINE 01913 bool operator == (const const_iterator2 &it) const { 01914 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01915 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); 01916 return it_ == it.it_; 01917 } 01918 BOOST_UBLAS_INLINE 01919 bool operator < (const const_iterator2 &it) const { 01920 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 01921 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); 01922 return it_ < it.it_; 01923 } 01924 01925 private: 01926 size_type i_; 01927 size_type j_; 01928 const_subiterator_type it_; 01929 01930 friend class iterator2; 01931 }; 01932 #endif 01933 01934 BOOST_UBLAS_INLINE 01935 const_iterator2 begin2 () const { 01936 return find2 (0, 0, 0); 01937 } 01938 BOOST_UBLAS_INLINE 01939 const_iterator2 end2 () const { 01940 return find2 (0, 0, size2_); 01941 } 01942 01943 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 01944 class iterator2: 01945 public container_reference<vector_of_vector>, 01946 public random_access_iterator_base<dense_random_access_iterator_tag, 01947 iterator2, value_type> { 01948 public: 01949 typedef typename vector_of_vector::value_type value_type; 01950 typedef typename vector_of_vector::difference_type difference_type; 01951 typedef typename vector_of_vector::reference reference; 01952 typedef typename vector_of_vector::pointer pointer; 01953 01954 typedef iterator1 dual_iterator_type; 01955 typedef reverse_iterator1 dual_reverse_iterator_type; 01956 01957 // Construction and destruction 01958 BOOST_UBLAS_INLINE 01959 iterator2 (): 01960 container_reference<self_type> (), i_ (), j_ (), it_ () {} 01961 BOOST_UBLAS_INLINE 01962 iterator2 (self_type &m, size_type i, size_type j, const subiterator_type &it): 01963 container_reference<self_type> (m), i_ (i), j_ (j), it_ (it) {} 01964 01965 // Arithmetic 01966 BOOST_UBLAS_INLINE 01967 iterator2 &operator ++ () { 01968 ++ j_; 01969 self_type &m = (*this) (); 01970 if (layout_type::fast_j ()) 01971 ++ it_; 01972 else 01973 it_ = m.find2 (1, i_, j_).it_; 01974 return *this; 01975 } 01976 BOOST_UBLAS_INLINE 01977 iterator2 &operator -- () { 01978 -- j_; 01979 self_type &m = (*this) (); 01980 if (layout_type::fast_j ()) 01981 -- it_; 01982 else 01983 it_ = m.find2 (1, i_, j_).it_; 01984 return *this; 01985 } 01986 BOOST_UBLAS_INLINE 01987 iterator2 &operator += (difference_type n) { 01988 j_ += n; 01989 self_type &m = (*this) (); 01990 it_ = m.find2 (1, i_, j_).it_; 01991 return *this; 01992 } 01993 BOOST_UBLAS_INLINE 01994 iterator2 &operator -= (difference_type n) { 01995 j_ -= n; 01996 self_type &m = (*this) (); 01997 it_ = m.find2 (1, i_, j_).it_; 01998 return *this; 01999 } 02000 BOOST_UBLAS_INLINE 02001 difference_type operator - (const iterator2 &it) const { 02002 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 02003 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); 02004 return index2 () - it.index2 (); 02005 } 02006 02007 // Dereference 02008 BOOST_UBLAS_INLINE 02009 reference operator * () const { 02010 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 02011 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 02012 return *it_; 02013 } 02014 BOOST_UBLAS_INLINE 02015 reference operator [] (difference_type n) const { 02016 return *(*this + n); 02017 } 02018 02019 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02020 BOOST_UBLAS_INLINE 02021 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02022 typename self_type:: 02023 #endif 02024 iterator1 begin () const { 02025 self_type &m = (*this) (); 02026 return m.find1 (1, 0, index2 ()); 02027 } 02028 BOOST_UBLAS_INLINE 02029 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02030 typename self_type:: 02031 #endif 02032 iterator1 end () const { 02033 self_type &m = (*this) (); 02034 return m.find1 (1, m.size1 (), index2 ()); 02035 } 02036 BOOST_UBLAS_INLINE 02037 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02038 typename self_type:: 02039 #endif 02040 reverse_iterator1 rbegin () const { 02041 return reverse_iterator1 (end ()); 02042 } 02043 BOOST_UBLAS_INLINE 02044 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02045 typename self_type:: 02046 #endif 02047 reverse_iterator1 rend () const { 02048 return reverse_iterator1 (begin ()); 02049 } 02050 #endif 02051 02052 // Indices 02053 BOOST_UBLAS_INLINE 02054 size_type index1 () const { 02055 return i_; 02056 } 02057 BOOST_UBLAS_INLINE 02058 size_type index2 () const { 02059 return j_; 02060 } 02061 02062 // Assignment 02063 BOOST_UBLAS_INLINE 02064 iterator2 &operator = (const iterator2 &it) { 02065 container_reference<self_type>::assign (&it ()); 02066 it_ = it.it_; 02067 return *this; 02068 } 02069 02070 // Comparison 02071 BOOST_UBLAS_INLINE 02072 bool operator == (const iterator2 &it) const { 02073 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 02074 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); 02075 return it_ == it.it_; 02076 } 02077 BOOST_UBLAS_INLINE 02078 bool operator < (const iterator2 &it) const { 02079 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 02080 BOOST_UBLAS_CHECK (index1 () == it.index1 (), bad_index ()); 02081 return it_ < it.it_; 02082 } 02083 02084 private: 02085 size_type i_; 02086 size_type j_; 02087 subiterator_type it_; 02088 02089 friend class const_iterator2; 02090 }; 02091 #endif 02092 02093 BOOST_UBLAS_INLINE 02094 iterator2 begin2 () { 02095 return find2 (0, 0, 0); 02096 } 02097 BOOST_UBLAS_INLINE 02098 iterator2 end2 () { 02099 return find2 (0, 0, size2_); 02100 } 02101 02102 // Reverse iterators 02103 02104 BOOST_UBLAS_INLINE 02105 const_reverse_iterator1 rbegin1 () const { 02106 return const_reverse_iterator1 (end1 ()); 02107 } 02108 BOOST_UBLAS_INLINE 02109 const_reverse_iterator1 rend1 () const { 02110 return const_reverse_iterator1 (begin1 ()); 02111 } 02112 02113 BOOST_UBLAS_INLINE 02114 reverse_iterator1 rbegin1 () { 02115 return reverse_iterator1 (end1 ()); 02116 } 02117 BOOST_UBLAS_INLINE 02118 reverse_iterator1 rend1 () { 02119 return reverse_iterator1 (begin1 ()); 02120 } 02121 02122 BOOST_UBLAS_INLINE 02123 const_reverse_iterator2 rbegin2 () const { 02124 return const_reverse_iterator2 (end2 ()); 02125 } 02126 BOOST_UBLAS_INLINE 02127 const_reverse_iterator2 rend2 () const { 02128 return const_reverse_iterator2 (begin2 ()); 02129 } 02130 02131 BOOST_UBLAS_INLINE 02132 reverse_iterator2 rbegin2 () { 02133 return reverse_iterator2 (end2 ()); 02134 } 02135 BOOST_UBLAS_INLINE 02136 reverse_iterator2 rend2 () { 02137 return reverse_iterator2 (begin2 ()); 02138 } 02139 02140 // Serialization 02141 template<class Archive> 02142 void serialize(Archive & ar, const unsigned int /* file_version */){ 02143 02144 // we need to copy to a collection_size_type to get a portable 02145 // and efficient serialization 02146 serialization::collection_size_type s1 (size1_); 02147 serialization::collection_size_type s2 (size2_); 02148 02149 // serialize the sizes 02150 ar & serialization::make_nvp("size1",s1) 02151 & serialization::make_nvp("size2",s2); 02152 02153 // copy the values back if loading 02154 if (Archive::is_loading::value) { 02155 size1_ = s1; 02156 size2_ = s2; 02157 } 02158 ar & serialization::make_nvp("data",data_); 02159 } 02160 02161 private: 02162 size_type size1_; 02163 size_type size2_; 02164 array_type data_; 02165 }; 02166 02167 02176 template<class T, class ALLOC> 02177 class zero_matrix: 02178 public matrix_container<zero_matrix<T, ALLOC> > { 02179 02180 typedef const T *const_pointer; 02181 typedef zero_matrix<T, ALLOC> self_type; 02182 public: 02183 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 02184 using matrix_container<self_type>::operator (); 02185 #endif 02186 typedef typename ALLOC::size_type size_type; 02187 typedef typename ALLOC::difference_type difference_type; 02188 typedef T value_type; 02189 typedef const T &const_reference; 02190 typedef T &reference; 02191 typedef const matrix_reference<const self_type> const_closure_type; 02192 typedef matrix_reference<self_type> closure_type; 02193 typedef sparse_tag storage_category; 02194 typedef unknown_orientation_tag orientation_category; 02195 02196 // Construction and destruction 02197 BOOST_UBLAS_INLINE 02198 zero_matrix (): 02199 matrix_container<self_type> (), 02200 size1_ (0), size2_ (0) {} 02201 BOOST_UBLAS_INLINE 02202 zero_matrix (size_type size): 02203 matrix_container<self_type> (), 02204 size1_ (size), size2_ (size) {} 02205 BOOST_UBLAS_INLINE 02206 zero_matrix (size_type size1, size_type size2): 02207 matrix_container<self_type> (), 02208 size1_ (size1), size2_ (size2) {} 02209 BOOST_UBLAS_INLINE 02210 zero_matrix (const zero_matrix &m): 02211 matrix_container<self_type> (), 02212 size1_ (m.size1_), size2_ (m.size2_) {} 02213 02214 // Accessors 02215 BOOST_UBLAS_INLINE 02216 size_type size1 () const { 02217 return size1_; 02218 } 02219 BOOST_UBLAS_INLINE 02220 size_type size2 () const { 02221 return size2_; 02222 } 02223 02224 // Resizing 02225 BOOST_UBLAS_INLINE 02226 void resize (size_type size, bool preserve = true) { 02227 size1_ = size; 02228 size2_ = size; 02229 } 02230 BOOST_UBLAS_INLINE 02231 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { 02232 size1_ = size1; 02233 size2_ = size2; 02234 } 02235 02236 // Element access 02237 BOOST_UBLAS_INLINE 02238 const_reference operator () (size_type /* i */, size_type /* j */) const { 02239 return zero_; 02240 } 02241 02242 // Assignment 02243 BOOST_UBLAS_INLINE 02244 zero_matrix &operator = (const zero_matrix &m) { 02245 size1_ = m.size1_; 02246 size2_ = m.size2_; 02247 return *this; 02248 } 02249 BOOST_UBLAS_INLINE 02250 zero_matrix &assign_temporary (zero_matrix &m) { 02251 swap (m); 02252 return *this; 02253 } 02254 02255 // Swapping 02256 BOOST_UBLAS_INLINE 02257 void swap (zero_matrix &m) { 02258 if (this != &m) { 02259 std::swap (size1_, m.size1_); 02260 std::swap (size2_, m.size2_); 02261 } 02262 } 02263 BOOST_UBLAS_INLINE 02264 friend void swap (zero_matrix &m1, zero_matrix &m2) { 02265 m1.swap (m2); 02266 } 02267 02268 // Iterator types 02269 public: 02270 class const_iterator1; 02271 class const_iterator2; 02272 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 02273 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 02274 02275 // Element lookup 02276 BOOST_UBLAS_INLINE 02277 const_iterator1 find1 (int /*rank*/, size_type /*i*/, size_type /*j*/) const { 02278 return const_iterator1 (*this); 02279 } 02280 BOOST_UBLAS_INLINE 02281 const_iterator2 find2 (int /*rank*/, size_type /*i*/, size_type /*j*/) const { 02282 return const_iterator2 (*this); 02283 } 02284 02285 class const_iterator1: 02286 public container_const_reference<zero_matrix>, 02287 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 02288 const_iterator1, value_type> { 02289 public: 02290 typedef typename zero_matrix::value_type value_type; 02291 typedef typename zero_matrix::difference_type difference_type; 02292 typedef typename zero_matrix::const_reference reference; 02293 typedef typename zero_matrix::const_pointer pointer; 02294 02295 typedef const_iterator2 dual_iterator_type; 02296 typedef const_reverse_iterator2 dual_reverse_iterator_type; 02297 02298 // Construction and destruction 02299 BOOST_UBLAS_INLINE 02300 const_iterator1 (): 02301 container_const_reference<self_type> () {} 02302 BOOST_UBLAS_INLINE 02303 const_iterator1 (const self_type &m): 02304 container_const_reference<self_type> (m) {} 02305 02306 // Arithmetic 02307 BOOST_UBLAS_INLINE 02308 const_iterator1 &operator ++ () { 02309 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02310 return *this; 02311 } 02312 BOOST_UBLAS_INLINE 02313 const_iterator1 &operator -- () { 02314 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02315 return *this; 02316 } 02317 02318 // Dereference 02319 BOOST_UBLAS_INLINE 02320 const_reference operator * () const { 02321 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02322 return zero_; // arbitary return value 02323 } 02324 02325 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02326 BOOST_UBLAS_INLINE 02327 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02328 typename self_type:: 02329 #endif 02330 const_iterator2 begin () const { 02331 return const_iterator2 ((*this) ()); 02332 } 02333 BOOST_UBLAS_INLINE 02334 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02335 typename self_type:: 02336 #endif 02337 const_iterator2 end () const { 02338 return const_iterator2 ((*this) ()); 02339 } 02340 BOOST_UBLAS_INLINE 02341 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02342 typename self_type:: 02343 #endif 02344 const_reverse_iterator2 rbegin () const { 02345 return const_reverse_iterator2 (end ()); 02346 } 02347 BOOST_UBLAS_INLINE 02348 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02349 typename self_type:: 02350 #endif 02351 const_reverse_iterator2 rend () const { 02352 return const_reverse_iterator2 (begin ()); 02353 } 02354 #endif 02355 02356 // Indices 02357 BOOST_UBLAS_INLINE 02358 size_type index1 () const { 02359 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02360 return 0; // arbitary return value 02361 } 02362 BOOST_UBLAS_INLINE 02363 size_type index2 () const { 02364 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02365 return 0; // arbitary return value 02366 } 02367 02368 // Assignment 02369 BOOST_UBLAS_INLINE 02370 const_iterator1 &operator = (const const_iterator1 &it) { 02371 container_const_reference<self_type>::assign (&it ()); 02372 return *this; 02373 } 02374 02375 // Comparison 02376 BOOST_UBLAS_INLINE 02377 bool operator == (const const_iterator1 &it) const { 02378 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 02379 detail::ignore_unused_variable_warning(it); 02380 return true; 02381 } 02382 }; 02383 02384 typedef const_iterator1 iterator1; 02385 02386 BOOST_UBLAS_INLINE 02387 const_iterator1 begin1 () const { 02388 return const_iterator1 (*this); 02389 } 02390 BOOST_UBLAS_INLINE 02391 const_iterator1 end1 () const { 02392 return const_iterator1 (*this); 02393 } 02394 02395 class const_iterator2: 02396 public container_const_reference<zero_matrix>, 02397 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 02398 const_iterator2, value_type> { 02399 public: 02400 typedef typename zero_matrix::value_type value_type; 02401 typedef typename zero_matrix::difference_type difference_type; 02402 typedef typename zero_matrix::const_reference reference; 02403 typedef typename zero_matrix::const_pointer pointer; 02404 02405 typedef const_iterator1 dual_iterator_type; 02406 typedef const_reverse_iterator1 dual_reverse_iterator_type; 02407 02408 // Construction and destruction 02409 BOOST_UBLAS_INLINE 02410 const_iterator2 (): 02411 container_const_reference<self_type> () {} 02412 BOOST_UBLAS_INLINE 02413 const_iterator2 (const self_type &m): 02414 container_const_reference<self_type> (m) {} 02415 02416 // Arithmetic 02417 BOOST_UBLAS_INLINE 02418 const_iterator2 &operator ++ () { 02419 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02420 return *this; 02421 } 02422 BOOST_UBLAS_INLINE 02423 const_iterator2 &operator -- () { 02424 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02425 return *this; 02426 } 02427 02428 // Dereference 02429 BOOST_UBLAS_INLINE 02430 const_reference operator * () const { 02431 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02432 return zero_; // arbitary return value 02433 } 02434 02435 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02436 BOOST_UBLAS_INLINE 02437 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02438 typename self_type:: 02439 #endif 02440 const_iterator1 begin () const { 02441 return const_iterator1 ((*this) ()); 02442 } 02443 BOOST_UBLAS_INLINE 02444 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02445 typename self_type:: 02446 #endif 02447 const_iterator1 end () const { 02448 return const_iterator1 ((*this) ()); 02449 } 02450 BOOST_UBLAS_INLINE 02451 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02452 typename self_type:: 02453 #endif 02454 const_reverse_iterator1 rbegin () const { 02455 return const_reverse_iterator1 (end ()); 02456 } 02457 BOOST_UBLAS_INLINE 02458 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02459 typename self_type:: 02460 #endif 02461 const_reverse_iterator1 rend () const { 02462 return const_reverse_iterator1 (begin ()); 02463 } 02464 #endif 02465 02466 // Indices 02467 BOOST_UBLAS_INLINE 02468 size_type index1 () const { 02469 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02470 return 0; // arbitary return value 02471 } 02472 BOOST_UBLAS_INLINE 02473 size_type index2 () const { 02474 BOOST_UBLAS_CHECK_FALSE (bad_index ()); 02475 return 0; // arbitary return value 02476 } 02477 02478 // Assignment 02479 BOOST_UBLAS_INLINE 02480 const_iterator2 &operator = (const const_iterator2 &it) { 02481 container_const_reference<self_type>::assign (&it ()); 02482 return *this; 02483 } 02484 02485 // Comparison 02486 BOOST_UBLAS_INLINE 02487 bool operator == (const const_iterator2 &it) const { 02488 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 02489 detail::ignore_unused_variable_warning(it); 02490 return true; 02491 } 02492 }; 02493 02494 typedef const_iterator2 iterator2; 02495 02496 BOOST_UBLAS_INLINE 02497 const_iterator2 begin2 () const { 02498 return find2 (0, 0, 0); 02499 } 02500 BOOST_UBLAS_INLINE 02501 const_iterator2 end2 () const { 02502 return find2 (0, 0, size2_); 02503 } 02504 02505 // Reverse iterators 02506 02507 BOOST_UBLAS_INLINE 02508 const_reverse_iterator1 rbegin1 () const { 02509 return const_reverse_iterator1 (end1 ()); 02510 } 02511 BOOST_UBLAS_INLINE 02512 const_reverse_iterator1 rend1 () const { 02513 return const_reverse_iterator1 (begin1 ()); 02514 } 02515 02516 BOOST_UBLAS_INLINE 02517 const_reverse_iterator2 rbegin2 () const { 02518 return const_reverse_iterator2 (end2 ()); 02519 } 02520 BOOST_UBLAS_INLINE 02521 const_reverse_iterator2 rend2 () const { 02522 return const_reverse_iterator2 (begin2 ()); 02523 } 02524 02525 // Serialization 02526 template<class Archive> 02527 void serialize(Archive & ar, const unsigned int /* file_version */){ 02528 02529 // we need to copy to a collection_size_type to get a portable 02530 // and efficient serialization 02531 serialization::collection_size_type s1 (size1_); 02532 serialization::collection_size_type s2 (size2_); 02533 02534 // serialize the sizes 02535 ar & serialization::make_nvp("size1",s1) 02536 & serialization::make_nvp("size2",s2); 02537 02538 // copy the values back if loading 02539 if (Archive::is_loading::value) { 02540 size1_ = s1; 02541 size2_ = s2; 02542 } 02543 } 02544 02545 private: 02546 size_type size1_; 02547 size_type size2_; 02548 static const value_type zero_; 02549 }; 02550 02551 template<class T, class ALLOC> 02552 const typename zero_matrix<T, ALLOC>::value_type zero_matrix<T, ALLOC>::zero_ = T(/*zero*/); 02553 02563 template<class T, class ALLOC> 02564 class identity_matrix: 02565 public matrix_container<identity_matrix<T, ALLOC> > { 02566 02567 typedef const T *const_pointer; 02568 typedef identity_matrix<T, ALLOC> self_type; 02569 public: 02570 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 02571 using matrix_container<self_type>::operator (); 02572 #endif 02573 typedef typename ALLOC::size_type size_type; 02574 typedef typename ALLOC::difference_type difference_type; 02575 typedef T value_type; 02576 typedef const T &const_reference; 02577 typedef T &reference; 02578 typedef const matrix_reference<const self_type> const_closure_type; 02579 typedef matrix_reference<self_type> closure_type; 02580 typedef sparse_tag storage_category; 02581 typedef unknown_orientation_tag orientation_category; 02582 02583 // Construction and destruction 02584 BOOST_UBLAS_INLINE 02585 identity_matrix (): 02586 matrix_container<self_type> (), 02587 size1_ (0), size2_ (0), size_common_ (0) {} 02588 BOOST_UBLAS_INLINE 02589 identity_matrix (size_type size): 02590 matrix_container<self_type> (), 02591 size1_ (size), size2_ (size), size_common_ ((std::min) (size1_, size2_)) {} 02592 BOOST_UBLAS_INLINE 02593 identity_matrix (size_type size1, size_type size2): 02594 matrix_container<self_type> (), 02595 size1_ (size1), size2_ (size2), size_common_ ((std::min) (size1_, size2_)) {} 02596 BOOST_UBLAS_INLINE 02597 identity_matrix (const identity_matrix &m): 02598 matrix_container<self_type> (), 02599 size1_ (m.size1_), size2_ (m.size2_), size_common_ ((std::min) (size1_, size2_)) {} 02600 02601 // Accessors 02602 BOOST_UBLAS_INLINE 02603 size_type size1 () const { 02604 return size1_; 02605 } 02606 BOOST_UBLAS_INLINE 02607 size_type size2 () const { 02608 return size2_; 02609 } 02610 02611 // Resizing 02612 BOOST_UBLAS_INLINE 02613 void resize (size_type size, bool preserve = true) { 02614 size1_ = size; 02615 size2_ = size; 02616 size_common_ = ((std::min)(size1_, size2_)); 02617 } 02618 BOOST_UBLAS_INLINE 02619 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { 02620 size1_ = size1; 02621 size2_ = size2; 02622 size_common_ = ((std::min)(size1_, size2_)); 02623 } 02624 02625 // Element access 02626 BOOST_UBLAS_INLINE 02627 const_reference operator () (size_type i, size_type j) const { 02628 if (i == j) 02629 return one_; 02630 else 02631 return zero_; 02632 } 02633 02634 // Assignment 02635 BOOST_UBLAS_INLINE 02636 identity_matrix &operator = (const identity_matrix &m) { 02637 size1_ = m.size1_; 02638 size2_ = m.size2_; 02639 size_common_ = m.size_common_; 02640 return *this; 02641 } 02642 BOOST_UBLAS_INLINE 02643 identity_matrix &assign_temporary (identity_matrix &m) { 02644 swap (m); 02645 return *this; 02646 } 02647 02648 // Swapping 02649 BOOST_UBLAS_INLINE 02650 void swap (identity_matrix &m) { 02651 if (this != &m) { 02652 std::swap (size1_, m.size1_); 02653 std::swap (size2_, m.size2_); 02654 std::swap (size_common_, m.size_common_); 02655 } 02656 } 02657 BOOST_UBLAS_INLINE 02658 friend void swap (identity_matrix &m1, identity_matrix &m2) { 02659 m1.swap (m2); 02660 } 02661 02662 // Iterator types 02663 private: 02664 // Use an index 02665 typedef size_type const_subiterator_type; 02666 02667 public: 02668 class const_iterator1; 02669 class const_iterator2; 02670 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 02671 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 02672 02673 // Element lookup 02674 BOOST_UBLAS_INLINE 02675 const_iterator1 find1 (int rank, size_type i, size_type j) const { 02676 if (rank == 1) { 02677 i = (std::max) (i, j); 02678 i = (std::min) (i, j + 1); 02679 } 02680 return const_iterator1 (*this, i); 02681 } 02682 BOOST_UBLAS_INLINE 02683 const_iterator2 find2 (int rank, size_type i, size_type j) const { 02684 if (rank == 1) { 02685 j = (std::max) (j, i); 02686 j = (std::min) (j, i + 1); 02687 } 02688 return const_iterator2 (*this, j); 02689 } 02690 02691 02692 class const_iterator1: 02693 public container_const_reference<identity_matrix>, 02694 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 02695 const_iterator1, value_type> { 02696 public: 02697 typedef typename identity_matrix::value_type value_type; 02698 typedef typename identity_matrix::difference_type difference_type; 02699 typedef typename identity_matrix::const_reference reference; 02700 typedef typename identity_matrix::const_pointer pointer; 02701 02702 typedef const_iterator2 dual_iterator_type; 02703 typedef const_reverse_iterator2 dual_reverse_iterator_type; 02704 02705 // Construction and destruction 02706 BOOST_UBLAS_INLINE 02707 const_iterator1 (): 02708 container_const_reference<self_type> (), it_ () {} 02709 BOOST_UBLAS_INLINE 02710 const_iterator1 (const self_type &m, const const_subiterator_type &it): 02711 container_const_reference<self_type> (m), it_ (it) {} 02712 02713 // Arithmetic 02714 BOOST_UBLAS_INLINE 02715 const_iterator1 &operator ++ () { 02716 BOOST_UBLAS_CHECK (it_ < (*this) ().size1 (), bad_index ()); 02717 ++it_; 02718 return *this; 02719 } 02720 BOOST_UBLAS_INLINE 02721 const_iterator1 &operator -- () { 02722 BOOST_UBLAS_CHECK (it_ > 0, bad_index ()); 02723 --it_; 02724 return *this; 02725 } 02726 02727 // Dereference 02728 BOOST_UBLAS_INLINE 02729 const_reference operator * () const { 02730 return one_; 02731 } 02732 02733 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02734 BOOST_UBLAS_INLINE 02735 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02736 typename self_type:: 02737 #endif 02738 const_iterator2 begin () const { 02739 return const_iterator2 ((*this) (), it_); 02740 } 02741 BOOST_UBLAS_INLINE 02742 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02743 typename self_type:: 02744 #endif 02745 const_iterator2 end () const { 02746 return const_iterator2 ((*this) (), it_ + 1); 02747 } 02748 BOOST_UBLAS_INLINE 02749 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02750 typename self_type:: 02751 #endif 02752 const_reverse_iterator2 rbegin () const { 02753 return const_reverse_iterator2 (end ()); 02754 } 02755 BOOST_UBLAS_INLINE 02756 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02757 typename self_type:: 02758 #endif 02759 const_reverse_iterator2 rend () const { 02760 return const_reverse_iterator2 (begin ()); 02761 } 02762 #endif 02763 02764 // Indices 02765 BOOST_UBLAS_INLINE 02766 size_type index1 () const { 02767 return it_; 02768 } 02769 BOOST_UBLAS_INLINE 02770 size_type index2 () const { 02771 return it_; 02772 } 02773 02774 // Assignment 02775 BOOST_UBLAS_INLINE 02776 const_iterator1 &operator = (const const_iterator1 &it) { 02777 container_const_reference<self_type>::assign (&it ()); 02778 it_ = it.it_; 02779 return *this; 02780 } 02781 02782 // Comparison 02783 BOOST_UBLAS_INLINE 02784 bool operator == (const const_iterator1 &it) const { 02785 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 02786 return it_ == it.it_; 02787 } 02788 02789 private: 02790 const_subiterator_type it_; 02791 }; 02792 02793 typedef const_iterator1 iterator1; 02794 02795 BOOST_UBLAS_INLINE 02796 const_iterator1 begin1 () const { 02797 return const_iterator1 (*this, 0); 02798 } 02799 BOOST_UBLAS_INLINE 02800 const_iterator1 end1 () const { 02801 return const_iterator1 (*this, size_common_); 02802 } 02803 02804 class const_iterator2: 02805 public container_const_reference<identity_matrix>, 02806 public bidirectional_iterator_base<sparse_bidirectional_iterator_tag, 02807 const_iterator2, value_type> { 02808 public: 02809 typedef typename identity_matrix::value_type value_type; 02810 typedef typename identity_matrix::difference_type difference_type; 02811 typedef typename identity_matrix::const_reference reference; 02812 typedef typename identity_matrix::const_pointer pointer; 02813 02814 typedef const_iterator1 dual_iterator_type; 02815 typedef const_reverse_iterator1 dual_reverse_iterator_type; 02816 02817 // Construction and destruction 02818 BOOST_UBLAS_INLINE 02819 const_iterator2 (): 02820 container_const_reference<self_type> (), it_ () {} 02821 BOOST_UBLAS_INLINE 02822 const_iterator2 (const self_type &m, const const_subiterator_type &it): 02823 container_const_reference<self_type> (m), it_ (it) {} 02824 02825 // Arithmetic 02826 BOOST_UBLAS_INLINE 02827 const_iterator2 &operator ++ () { 02828 BOOST_UBLAS_CHECK (it_ < (*this) ().size_common_, bad_index ()); 02829 ++it_; 02830 return *this; 02831 } 02832 BOOST_UBLAS_INLINE 02833 const_iterator2 &operator -- () { 02834 BOOST_UBLAS_CHECK (it_ > 0, bad_index ()); 02835 --it_; 02836 return *this; 02837 } 02838 02839 // Dereference 02840 BOOST_UBLAS_INLINE 02841 const_reference operator * () const { 02842 return one_; 02843 } 02844 02845 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 02846 BOOST_UBLAS_INLINE 02847 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02848 typename self_type:: 02849 #endif 02850 const_iterator1 begin () const { 02851 return const_iterator1 ((*this) (), it_); 02852 } 02853 BOOST_UBLAS_INLINE 02854 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02855 typename self_type:: 02856 #endif 02857 const_iterator1 end () const { 02858 return const_iterator1 ((*this) (), it_ + 1); 02859 } 02860 BOOST_UBLAS_INLINE 02861 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02862 typename self_type:: 02863 #endif 02864 const_reverse_iterator1 rbegin () const { 02865 return const_reverse_iterator1 (end ()); 02866 } 02867 BOOST_UBLAS_INLINE 02868 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 02869 typename self_type:: 02870 #endif 02871 const_reverse_iterator1 rend () const { 02872 return const_reverse_iterator1 (begin ()); 02873 } 02874 #endif 02875 02876 // Indices 02877 BOOST_UBLAS_INLINE 02878 size_type index1 () const { 02879 return it_; 02880 } 02881 BOOST_UBLAS_INLINE 02882 size_type index2 () const { 02883 return it_; 02884 } 02885 02886 // Assignment 02887 BOOST_UBLAS_INLINE 02888 const_iterator2 &operator = (const const_iterator2 &it) { 02889 container_const_reference<self_type>::assign (&it ()); 02890 it_ = it.it_; 02891 return *this; 02892 } 02893 02894 // Comparison 02895 BOOST_UBLAS_INLINE 02896 bool operator == (const const_iterator2 &it) const { 02897 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 02898 return it_ == it.it_; 02899 } 02900 02901 private: 02902 const_subiterator_type it_; 02903 }; 02904 02905 typedef const_iterator2 iterator2; 02906 02907 BOOST_UBLAS_INLINE 02908 const_iterator2 begin2 () const { 02909 return const_iterator2 (*this, 0); 02910 } 02911 BOOST_UBLAS_INLINE 02912 const_iterator2 end2 () const { 02913 return const_iterator2 (*this, size_common_); 02914 } 02915 02916 // Reverse iterators 02917 02918 BOOST_UBLAS_INLINE 02919 const_reverse_iterator1 rbegin1 () const { 02920 return const_reverse_iterator1 (end1 ()); 02921 } 02922 BOOST_UBLAS_INLINE 02923 const_reverse_iterator1 rend1 () const { 02924 return const_reverse_iterator1 (begin1 ()); 02925 } 02926 02927 BOOST_UBLAS_INLINE 02928 const_reverse_iterator2 rbegin2 () const { 02929 return const_reverse_iterator2 (end2 ()); 02930 } 02931 BOOST_UBLAS_INLINE 02932 const_reverse_iterator2 rend2 () const { 02933 return const_reverse_iterator2 (begin2 ()); 02934 } 02935 02936 // Serialization 02937 template<class Archive> 02938 void serialize(Archive & ar, const unsigned int /* file_version */){ 02939 02940 // we need to copy to a collection_size_type to get a portable 02941 // and efficient serialization 02942 serialization::collection_size_type s1 (size1_); 02943 serialization::collection_size_type s2 (size2_); 02944 02945 // serialize the sizes 02946 ar & serialization::make_nvp("size1",s1) 02947 & serialization::make_nvp("size2",s2); 02948 02949 // copy the values back if loading 02950 if (Archive::is_loading::value) { 02951 size1_ = s1; 02952 size2_ = s2; 02953 size_common_ = ((std::min)(size1_, size2_)); 02954 } 02955 } 02956 02957 private: 02958 size_type size1_; 02959 size_type size2_; 02960 size_type size_common_; 02961 static const value_type zero_; 02962 static const value_type one_; 02963 }; 02964 02965 template<class T, class ALLOC> 02966 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::zero_ = T(/*zero*/); 02967 template<class T, class ALLOC> 02968 const typename identity_matrix<T, ALLOC>::value_type identity_matrix<T, ALLOC>::one_ (1); // ISSUE: need 'one'-traits here 02969 02970 02979 template<class T, class ALLOC> 02980 class scalar_matrix: 02981 public matrix_container<scalar_matrix<T, ALLOC> > { 02982 02983 typedef const T *const_pointer; 02984 typedef scalar_matrix<T, ALLOC> self_type; 02985 public: 02986 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 02987 using matrix_container<self_type>::operator (); 02988 #endif 02989 typedef std::size_t size_type; 02990 typedef std::ptrdiff_t difference_type; 02991 typedef T value_type; 02992 typedef const T &const_reference; 02993 typedef T &reference; 02994 typedef const matrix_reference<const self_type> const_closure_type; 02995 typedef matrix_reference<self_type> closure_type; 02996 typedef dense_tag storage_category; 02997 typedef unknown_orientation_tag orientation_category; 02998 02999 // Construction and destruction 03000 BOOST_UBLAS_INLINE 03001 scalar_matrix (): 03002 matrix_container<self_type> (), 03003 size1_ (0), size2_ (0), value_ () {} 03004 BOOST_UBLAS_INLINE 03005 scalar_matrix (size_type size1, size_type size2, const value_type &value = value_type(1)): 03006 matrix_container<self_type> (), 03007 size1_ (size1), size2_ (size2), value_ (value) {} 03008 BOOST_UBLAS_INLINE 03009 scalar_matrix (const scalar_matrix &m): 03010 matrix_container<self_type> (), 03011 size1_ (m.size1_), size2_ (m.size2_), value_ (m.value_) {} 03012 03013 // Accessors 03014 BOOST_UBLAS_INLINE 03015 size_type size1 () const { 03016 return size1_; 03017 } 03018 BOOST_UBLAS_INLINE 03019 size_type size2 () const { 03020 return size2_; 03021 } 03022 03023 // Resizing 03024 BOOST_UBLAS_INLINE 03025 void resize (size_type size1, size_type size2, bool /*preserve*/ = true) { 03026 size1_ = size1; 03027 size2_ = size2; 03028 } 03029 03030 // Element access 03031 BOOST_UBLAS_INLINE 03032 const_reference operator () (size_type /*i*/, size_type /*j*/) const { 03033 return value_; 03034 } 03035 03036 // Assignment 03037 BOOST_UBLAS_INLINE 03038 scalar_matrix &operator = (const scalar_matrix &m) { 03039 size1_ = m.size1_; 03040 size2_ = m.size2_; 03041 value_ = m.value_; 03042 return *this; 03043 } 03044 BOOST_UBLAS_INLINE 03045 scalar_matrix &assign_temporary (scalar_matrix &m) { 03046 swap (m); 03047 return *this; 03048 } 03049 03050 // Swapping 03051 BOOST_UBLAS_INLINE 03052 void swap (scalar_matrix &m) { 03053 if (this != &m) { 03054 std::swap (size1_, m.size1_); 03055 std::swap (size2_, m.size2_); 03056 std::swap (value_, m.value_); 03057 } 03058 } 03059 BOOST_UBLAS_INLINE 03060 friend void swap (scalar_matrix &m1, scalar_matrix &m2) { 03061 m1.swap (m2); 03062 } 03063 03064 // Iterator types 03065 private: 03066 // Use an index 03067 typedef size_type const_subiterator_type; 03068 03069 public: 03070 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03071 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> iterator1; 03072 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> iterator2; 03073 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1; 03074 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2; 03075 #else 03076 class const_iterator1; 03077 class const_iterator2; 03078 #endif 03079 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 03080 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 03081 03082 // Element lookup 03083 BOOST_UBLAS_INLINE 03084 const_iterator1 find1 (int /*rank*/, size_type i, size_type j) const { 03085 return const_iterator1 (*this, i, j); 03086 } 03087 BOOST_UBLAS_INLINE 03088 const_iterator2 find2 (int /*rank*/, size_type i, size_type j) const { 03089 return const_iterator2 (*this, i, j); 03090 } 03091 03092 03093 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03094 class const_iterator1: 03095 public container_const_reference<scalar_matrix>, 03096 public random_access_iterator_base<dense_random_access_iterator_tag, 03097 const_iterator1, value_type> { 03098 public: 03099 typedef typename scalar_matrix::value_type value_type; 03100 typedef typename scalar_matrix::difference_type difference_type; 03101 typedef typename scalar_matrix::const_reference reference; 03102 typedef typename scalar_matrix::const_pointer pointer; 03103 03104 typedef const_iterator2 dual_iterator_type; 03105 typedef const_reverse_iterator2 dual_reverse_iterator_type; 03106 03107 // Construction and destruction 03108 BOOST_UBLAS_INLINE 03109 const_iterator1 (): 03110 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {} 03111 BOOST_UBLAS_INLINE 03112 const_iterator1 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): 03113 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {} 03114 03115 // Arithmetic 03116 BOOST_UBLAS_INLINE 03117 const_iterator1 &operator ++ () { 03118 ++ it1_; 03119 return *this; 03120 } 03121 BOOST_UBLAS_INLINE 03122 const_iterator1 &operator -- () { 03123 -- it1_; 03124 return *this; 03125 } 03126 BOOST_UBLAS_INLINE 03127 const_iterator1 &operator += (difference_type n) { 03128 it1_ += n; 03129 return *this; 03130 } 03131 BOOST_UBLAS_INLINE 03132 const_iterator1 &operator -= (difference_type n) { 03133 it1_ -= n; 03134 return *this; 03135 } 03136 BOOST_UBLAS_INLINE 03137 difference_type operator - (const const_iterator1 &it) const { 03138 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03139 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03140 return it1_ - it.it1_; 03141 } 03142 03143 // Dereference 03144 BOOST_UBLAS_INLINE 03145 const_reference operator * () const { 03146 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 03147 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 03148 return (*this) () (index1 (), index2 ()); 03149 } 03150 BOOST_UBLAS_INLINE 03151 const_reference operator [] (difference_type n) const { 03152 return *(*this + n); 03153 } 03154 03155 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03156 BOOST_UBLAS_INLINE 03157 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03158 typename self_type:: 03159 #endif 03160 const_iterator2 begin () const { 03161 const scalar_matrix &m = (*this) (); 03162 return m.find2 (1, index1 (), 0); 03163 } 03164 BOOST_UBLAS_INLINE 03165 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03166 typename self_type:: 03167 #endif 03168 const_iterator2 end () const { 03169 const scalar_matrix &m = (*this) (); 03170 return m.find2 (1, index1 (), m.size2 ()); 03171 } 03172 BOOST_UBLAS_INLINE 03173 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03174 typename self_type:: 03175 #endif 03176 const_reverse_iterator2 rbegin () const { 03177 return const_reverse_iterator2 (end ()); 03178 } 03179 BOOST_UBLAS_INLINE 03180 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03181 typename self_type:: 03182 #endif 03183 const_reverse_iterator2 rend () const { 03184 return const_reverse_iterator2 (begin ()); 03185 } 03186 #endif 03187 03188 // Indices 03189 BOOST_UBLAS_INLINE 03190 size_type index1 () const { 03191 return it1_; 03192 } 03193 BOOST_UBLAS_INLINE 03194 size_type index2 () const { 03195 return it2_; 03196 } 03197 03198 // Assignment 03199 BOOST_UBLAS_INLINE 03200 const_iterator1 &operator = (const const_iterator1 &it) { 03201 container_const_reference<scalar_matrix>::assign (&it ()); 03202 it1_ = it.it1_; 03203 it2_ = it.it2_; 03204 return *this; 03205 } 03206 03207 // Comparison 03208 BOOST_UBLAS_INLINE 03209 bool operator == (const const_iterator1 &it) const { 03210 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03211 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03212 return it1_ == it.it1_; 03213 } 03214 BOOST_UBLAS_INLINE 03215 bool operator < (const const_iterator1 &it) const { 03216 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03217 BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); 03218 return it1_ < it.it1_; 03219 } 03220 03221 private: 03222 const_subiterator_type it1_; 03223 const_subiterator_type it2_; 03224 }; 03225 03226 typedef const_iterator1 iterator1; 03227 #endif 03228 03229 BOOST_UBLAS_INLINE 03230 const_iterator1 begin1 () const { 03231 return find1 (0, 0, 0); 03232 } 03233 BOOST_UBLAS_INLINE 03234 const_iterator1 end1 () const { 03235 return find1 (0, size1_, 0); 03236 } 03237 03238 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03239 class const_iterator2: 03240 public container_const_reference<scalar_matrix>, 03241 public random_access_iterator_base<dense_random_access_iterator_tag, 03242 const_iterator2, value_type> { 03243 public: 03244 typedef typename scalar_matrix::value_type value_type; 03245 typedef typename scalar_matrix::difference_type difference_type; 03246 typedef typename scalar_matrix::const_reference reference; 03247 typedef typename scalar_matrix::const_pointer pointer; 03248 03249 typedef const_iterator1 dual_iterator_type; 03250 typedef const_reverse_iterator1 dual_reverse_iterator_type; 03251 03252 // Construction and destruction 03253 BOOST_UBLAS_INLINE 03254 const_iterator2 (): 03255 container_const_reference<scalar_matrix> (), it1_ (), it2_ () {} 03256 BOOST_UBLAS_INLINE 03257 const_iterator2 (const scalar_matrix &m, const const_subiterator_type &it1, const const_subiterator_type &it2): 03258 container_const_reference<scalar_matrix> (m), it1_ (it1), it2_ (it2) {} 03259 03260 // Arithmetic 03261 BOOST_UBLAS_INLINE 03262 const_iterator2 &operator ++ () { 03263 ++ it2_; 03264 return *this; 03265 } 03266 BOOST_UBLAS_INLINE 03267 const_iterator2 &operator -- () { 03268 -- it2_; 03269 return *this; 03270 } 03271 BOOST_UBLAS_INLINE 03272 const_iterator2 &operator += (difference_type n) { 03273 it2_ += n; 03274 return *this; 03275 } 03276 BOOST_UBLAS_INLINE 03277 const_iterator2 &operator -= (difference_type n) { 03278 it2_ -= n; 03279 return *this; 03280 } 03281 BOOST_UBLAS_INLINE 03282 difference_type operator - (const const_iterator2 &it) const { 03283 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03284 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 03285 return it2_ - it.it2_; 03286 } 03287 03288 // Dereference 03289 BOOST_UBLAS_INLINE 03290 const_reference operator * () const { 03291 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 03292 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 03293 return (*this) () (index1 (), index2 ()); 03294 } 03295 BOOST_UBLAS_INLINE 03296 const_reference operator [] (difference_type n) const { 03297 return *(*this + n); 03298 } 03299 03300 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03301 BOOST_UBLAS_INLINE 03302 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03303 typename self_type:: 03304 #endif 03305 const_iterator1 begin () const { 03306 const scalar_matrix &m = (*this) (); 03307 return m.find1 (1, 0, index2 ()); 03308 } 03309 BOOST_UBLAS_INLINE 03310 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03311 typename self_type:: 03312 #endif 03313 const_iterator1 end () const { 03314 const scalar_matrix &m = (*this) (); 03315 return m.find1 (1, m.size1 (), index2 ()); 03316 } 03317 BOOST_UBLAS_INLINE 03318 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03319 typename self_type:: 03320 #endif 03321 const_reverse_iterator1 rbegin () const { 03322 return const_reverse_iterator1 (end ()); 03323 } 03324 BOOST_UBLAS_INLINE 03325 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03326 typename self_type:: 03327 #endif 03328 const_reverse_iterator1 rend () const { 03329 return const_reverse_iterator1 (begin ()); 03330 } 03331 #endif 03332 03333 // Indices 03334 BOOST_UBLAS_INLINE 03335 size_type index1 () const { 03336 return it1_; 03337 } 03338 BOOST_UBLAS_INLINE 03339 size_type index2 () const { 03340 return it2_; 03341 } 03342 03343 // Assignment 03344 BOOST_UBLAS_INLINE 03345 const_iterator2 &operator = (const const_iterator2 &it) { 03346 container_const_reference<scalar_matrix>::assign (&it ()); 03347 it1_ = it.it1_; 03348 it2_ = it.it2_; 03349 return *this; 03350 } 03351 03352 // Comparison 03353 BOOST_UBLAS_INLINE 03354 bool operator == (const const_iterator2 &it) const { 03355 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03356 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 03357 return it2_ == it.it2_; 03358 } 03359 BOOST_UBLAS_INLINE 03360 bool operator < (const const_iterator2 &it) const { 03361 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03362 BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); 03363 return it2_ < it.it2_; 03364 } 03365 03366 private: 03367 const_subiterator_type it1_; 03368 const_subiterator_type it2_; 03369 }; 03370 03371 typedef const_iterator2 iterator2; 03372 #endif 03373 03374 BOOST_UBLAS_INLINE 03375 const_iterator2 begin2 () const { 03376 return find2 (0, 0, 0); 03377 } 03378 BOOST_UBLAS_INLINE 03379 const_iterator2 end2 () const { 03380 return find2 (0, 0, size2_); 03381 } 03382 03383 // Reverse iterators 03384 03385 BOOST_UBLAS_INLINE 03386 const_reverse_iterator1 rbegin1 () const { 03387 return const_reverse_iterator1 (end1 ()); 03388 } 03389 BOOST_UBLAS_INLINE 03390 const_reverse_iterator1 rend1 () const { 03391 return const_reverse_iterator1 (begin1 ()); 03392 } 03393 03394 BOOST_UBLAS_INLINE 03395 const_reverse_iterator2 rbegin2 () const { 03396 return const_reverse_iterator2 (end2 ()); 03397 } 03398 BOOST_UBLAS_INLINE 03399 const_reverse_iterator2 rend2 () const { 03400 return const_reverse_iterator2 (begin2 ()); 03401 } 03402 03403 // Serialization 03404 template<class Archive> 03405 void serialize(Archive & ar, const unsigned int /* file_version */){ 03406 03407 // we need to copy to a collection_size_type to get a portable 03408 // and efficient serialization 03409 serialization::collection_size_type s1 (size1_); 03410 serialization::collection_size_type s2 (size2_); 03411 03412 // serialize the sizes 03413 ar & serialization::make_nvp("size1",s1) 03414 & serialization::make_nvp("size2",s2); 03415 03416 // copy the values back if loading 03417 if (Archive::is_loading::value) { 03418 size1_ = s1; 03419 size2_ = s2; 03420 } 03421 03422 ar & serialization::make_nvp("value", value_); 03423 } 03424 03425 private: 03426 size_type size1_; 03427 size_type size2_; 03428 value_type value_; 03429 }; 03430 03431 03449 template<class T, std::size_t N, std::size_t M> 03450 class c_matrix: 03451 public matrix_container<c_matrix<T, N, M> > { 03452 03453 typedef c_matrix<T, N, M> self_type; 03454 public: 03455 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS 03456 using matrix_container<self_type>::operator (); 03457 #endif 03458 typedef std::size_t size_type; 03459 typedef std::ptrdiff_t difference_type; 03460 typedef T value_type; 03461 typedef const T &const_reference; 03462 typedef T &reference; 03463 typedef const T *const_pointer; 03464 typedef T *pointer; 03465 typedef const matrix_reference<const self_type> const_closure_type; 03466 typedef matrix_reference<self_type> closure_type; 03467 typedef c_vector<T, N * M> vector_temporary_type; // vector able to store all elements of c_matrix 03468 typedef self_type matrix_temporary_type; 03469 typedef dense_tag storage_category; 03470 // This could be better for performance, 03471 // typedef typename unknown_orientation_tag orientation_category; 03472 // but others depend on the orientation information... 03473 typedef row_major_tag orientation_category; 03474 03475 // Construction and destruction 03476 BOOST_UBLAS_INLINE 03477 c_matrix (): 03478 size1_ (N), size2_ (M) /* , data_ () */ { 03479 } 03480 BOOST_UBLAS_INLINE 03481 c_matrix (size_type size1, size_type size2): 03482 size1_ (size1), size2_ (size2) /* , data_ () */ { 03483 if (size1_ > N || size2_ > M) 03484 bad_size ().raise (); 03485 } 03486 BOOST_UBLAS_INLINE 03487 c_matrix (const c_matrix &m): 03488 size1_ (m.size1_), size2_ (m.size2_) /* , data_ () */ { 03489 if (size1_ > N || size2_ > M) 03490 bad_size ().raise (); 03491 assign(m); 03492 } 03493 template<class AE> 03494 BOOST_UBLAS_INLINE 03495 c_matrix (const matrix_expression<AE> &ae): 03496 size1_ (ae ().size1 ()), size2_ (ae ().size2 ()) /* , data_ () */ { 03497 if (size1_ > N || size2_ > M) 03498 bad_size ().raise (); 03499 matrix_assign<scalar_assign> (*this, ae); 03500 } 03501 03502 // Accessors 03503 BOOST_UBLAS_INLINE 03504 size_type size1 () const { 03505 return size1_; 03506 } 03507 BOOST_UBLAS_INLINE 03508 size_type size2 () const { 03509 return size2_; 03510 } 03511 BOOST_UBLAS_INLINE 03512 const_pointer data () const { 03513 return reinterpret_cast<const_pointer> (data_); 03514 } 03515 BOOST_UBLAS_INLINE 03516 pointer data () { 03517 return reinterpret_cast<pointer> (data_); 03518 } 03519 03520 // Resizing 03521 BOOST_UBLAS_INLINE 03522 void resize (size_type size1, size_type size2, bool preserve = true) { 03523 if (size1 > N || size2 > M) 03524 bad_size ().raise (); 03525 if (preserve) { 03526 self_type temporary (size1, size2); 03527 // Common elements to preserve 03528 const size_type size1_min = (std::min) (size1, size1_); 03529 const size_type size2_min = (std::min) (size2, size2_); 03530 for (size_type i = 0; i != size1_min; ++i) { // indexing copy over major 03531 for (size_type j = 0; j != size2_min; ++j) { 03532 temporary.data_[i][j] = data_[i][j]; 03533 } 03534 } 03535 assign_temporary (temporary); 03536 } 03537 else { 03538 size1_ = size1; 03539 size2_ = size2; 03540 } 03541 } 03542 03543 // Element access 03544 BOOST_UBLAS_INLINE 03545 const_reference operator () (size_type i, size_type j) const { 03546 BOOST_UBLAS_CHECK (i < size1_, bad_index ()); 03547 BOOST_UBLAS_CHECK (j < size2_, bad_index ()); 03548 return data_ [i] [j]; 03549 } 03550 BOOST_UBLAS_INLINE 03551 reference at_element (size_type i, size_type j) { 03552 BOOST_UBLAS_CHECK (i < size1_, bad_index ()); 03553 BOOST_UBLAS_CHECK (j < size2_, bad_index ()); 03554 return data_ [i] [j]; 03555 } 03556 BOOST_UBLAS_INLINE 03557 reference operator () (size_type i, size_type j) { 03558 return at_element (i, j); 03559 } 03560 03561 // Element assignment 03562 BOOST_UBLAS_INLINE 03563 reference insert_element (size_type i, size_type j, const_reference t) { 03564 return (at_element (i, j) = t); 03565 } 03566 03567 // Zeroing 03568 BOOST_UBLAS_INLINE 03569 void clear () { 03570 for (size_type i = 0; i < size1_; ++ i) 03571 std::fill (data_ [i], data_ [i] + size2_, value_type/*zero*/()); 03572 } 03573 03574 // Assignment 03575 #ifdef BOOST_UBLAS_MOVE_SEMANTICS 03576 03578 BOOST_UBLAS_INLINE 03579 c_matrix &operator = (c_matrix m) { 03580 assign_temporary(m); 03581 return *this; 03582 } 03583 #else 03584 BOOST_UBLAS_INLINE 03585 c_matrix &operator = (const c_matrix &m) { 03586 size1_ = m.size1_; 03587 size2_ = m.size2_; 03588 for (size_type i = 0; i < m.size1_; ++ i) 03589 std::copy (m.data_ [i], m.data_ [i] + m.size2_, data_ [i]); 03590 return *this; 03591 } 03592 #endif 03593 template<class C> // Container assignment without temporary 03594 BOOST_UBLAS_INLINE 03595 c_matrix &operator = (const matrix_container<C> &m) { 03596 resize (m ().size1 (), m ().size2 (), false); 03597 assign (m); 03598 return *this; 03599 } 03600 BOOST_UBLAS_INLINE 03601 c_matrix &assign_temporary (c_matrix &m) { 03602 swap (m); 03603 return *this; 03604 } 03605 template<class AE> 03606 BOOST_UBLAS_INLINE 03607 c_matrix &operator = (const matrix_expression<AE> &ae) { 03608 self_type temporary (ae); 03609 return assign_temporary (temporary); 03610 } 03611 template<class AE> 03612 BOOST_UBLAS_INLINE 03613 c_matrix &assign (const matrix_expression<AE> &ae) { 03614 matrix_assign<scalar_assign> (*this, ae); 03615 return *this; 03616 } 03617 template<class AE> 03618 BOOST_UBLAS_INLINE 03619 c_matrix& operator += (const matrix_expression<AE> &ae) { 03620 self_type temporary (*this + ae); 03621 return assign_temporary (temporary); 03622 } 03623 template<class C> // Container assignment without temporary 03624 BOOST_UBLAS_INLINE 03625 c_matrix &operator += (const matrix_container<C> &m) { 03626 plus_assign (m); 03627 return *this; 03628 } 03629 template<class AE> 03630 BOOST_UBLAS_INLINE 03631 c_matrix &plus_assign (const matrix_expression<AE> &ae) { 03632 matrix_assign<scalar_plus_assign> (*this, ae); 03633 return *this; 03634 } 03635 template<class AE> 03636 BOOST_UBLAS_INLINE 03637 c_matrix& operator -= (const matrix_expression<AE> &ae) { 03638 self_type temporary (*this - ae); 03639 return assign_temporary (temporary); 03640 } 03641 template<class C> // Container assignment without temporary 03642 BOOST_UBLAS_INLINE 03643 c_matrix &operator -= (const matrix_container<C> &m) { 03644 minus_assign (m); 03645 return *this; 03646 } 03647 template<class AE> 03648 BOOST_UBLAS_INLINE 03649 c_matrix &minus_assign (const matrix_expression<AE> &ae) { 03650 matrix_assign<scalar_minus_assign> (*this, ae); 03651 return *this; 03652 } 03653 template<class AT> 03654 BOOST_UBLAS_INLINE 03655 c_matrix& operator *= (const AT &at) { 03656 matrix_assign_scalar<scalar_multiplies_assign> (*this, at); 03657 return *this; 03658 } 03659 template<class AT> 03660 BOOST_UBLAS_INLINE 03661 c_matrix& operator /= (const AT &at) { 03662 matrix_assign_scalar<scalar_divides_assign> (*this, at); 03663 return *this; 03664 } 03665 03666 // Swapping 03667 BOOST_UBLAS_INLINE 03668 void swap (c_matrix &m) { 03669 if (this != &m) { 03670 BOOST_UBLAS_CHECK (size1_ == m.size1_, bad_size ()); 03671 BOOST_UBLAS_CHECK (size2_ == m.size2_, bad_size ()); 03672 std::swap (size1_, m.size1_); 03673 std::swap (size2_, m.size2_); 03674 for (size_type i = 0; i < size1_; ++ i) 03675 std::swap_ranges (data_ [i], data_ [i] + size2_, m.data_ [i]); 03676 } 03677 } 03678 BOOST_UBLAS_INLINE 03679 friend void swap (c_matrix &m1, c_matrix &m2) { 03680 m1.swap (m2); 03681 } 03682 03683 // Iterator types 03684 private: 03685 // Use pointers for iterator 03686 typedef const_pointer const_subiterator_type; 03687 typedef pointer subiterator_type; 03688 03689 public: 03690 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03691 typedef indexed_iterator1<self_type, dense_random_access_iterator_tag> iterator1; 03692 typedef indexed_iterator2<self_type, dense_random_access_iterator_tag> iterator2; 03693 typedef indexed_const_iterator1<self_type, dense_random_access_iterator_tag> const_iterator1; 03694 typedef indexed_const_iterator2<self_type, dense_random_access_iterator_tag> const_iterator2; 03695 #else 03696 class const_iterator1; 03697 class iterator1; 03698 class const_iterator2; 03699 class iterator2; 03700 #endif 03701 typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1; 03702 typedef reverse_iterator_base1<iterator1> reverse_iterator1; 03703 typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2; 03704 typedef reverse_iterator_base2<iterator2> reverse_iterator2; 03705 03706 // Element lookup 03707 BOOST_UBLAS_INLINE 03708 const_iterator1 find1 (int rank, size_type i, size_type j) const { 03709 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03710 return const_iterator1 (*this, i, j); 03711 #else 03712 return const_iterator1 (*this, &data_ [i] [j]); 03713 #endif 03714 } 03715 BOOST_UBLAS_INLINE 03716 iterator1 find1 (int rank, size_type i, size_type j) { 03717 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03718 return iterator1 (*this, i, j); 03719 #else 03720 return iterator1 (*this, &data_ [i] [j]); 03721 #endif 03722 } 03723 BOOST_UBLAS_INLINE 03724 const_iterator2 find2 (int rank, size_type i, size_type j) const { 03725 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03726 return const_iterator2 (*this, i, j); 03727 #else 03728 return const_iterator2 (*this, &data_ [i] [j]); 03729 #endif 03730 } 03731 BOOST_UBLAS_INLINE 03732 iterator2 find2 (int rank, size_type i, size_type j) { 03733 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR 03734 return iterator2 (*this, i, j); 03735 #else 03736 return iterator2 (*this, &data_ [i] [j]); 03737 #endif 03738 } 03739 03740 03741 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03742 class const_iterator1: 03743 public container_const_reference<c_matrix>, 03744 public random_access_iterator_base<dense_random_access_iterator_tag, 03745 const_iterator1, value_type> { 03746 public: 03747 typedef typename c_matrix::difference_type difference_type; 03748 typedef typename c_matrix::value_type value_type; 03749 typedef typename c_matrix::const_reference reference; 03750 typedef typename c_matrix::const_pointer pointer; 03751 03752 typedef const_iterator2 dual_iterator_type; 03753 typedef const_reverse_iterator2 dual_reverse_iterator_type; 03754 03755 // Construction and destruction 03756 BOOST_UBLAS_INLINE 03757 const_iterator1 (): 03758 container_const_reference<self_type> (), it_ () {} 03759 BOOST_UBLAS_INLINE 03760 const_iterator1 (const self_type &m, const const_subiterator_type &it): 03761 container_const_reference<self_type> (m), it_ (it) {} 03762 BOOST_UBLAS_INLINE 03763 const_iterator1 (const iterator1 &it): 03764 container_const_reference<self_type> (it ()), it_ (it.it_) {} 03765 03766 // Arithmetic 03767 BOOST_UBLAS_INLINE 03768 const_iterator1 &operator ++ () { 03769 it_ += M; 03770 return *this; 03771 } 03772 BOOST_UBLAS_INLINE 03773 const_iterator1 &operator -- () { 03774 it_ -= M; 03775 return *this; 03776 } 03777 BOOST_UBLAS_INLINE 03778 const_iterator1 &operator += (difference_type n) { 03779 it_ += n * M; 03780 return *this; 03781 } 03782 BOOST_UBLAS_INLINE 03783 const_iterator1 &operator -= (difference_type n) { 03784 it_ -= n * M; 03785 return *this; 03786 } 03787 BOOST_UBLAS_INLINE 03788 difference_type operator - (const const_iterator1 &it) const { 03789 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03790 return (it_ - it.it_) / M; 03791 } 03792 03793 // Dereference 03794 BOOST_UBLAS_INLINE 03795 const_reference operator * () const { 03796 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 03797 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 03798 return *it_; 03799 } 03800 BOOST_UBLAS_INLINE 03801 const_reference operator [] (difference_type n) const { 03802 return *(*this + n); 03803 } 03804 03805 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03806 BOOST_UBLAS_INLINE 03807 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03808 typename self_type:: 03809 #endif 03810 const_iterator2 begin () const { 03811 const self_type &m = (*this) (); 03812 return m.find2 (1, index1 (), 0); 03813 } 03814 BOOST_UBLAS_INLINE 03815 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03816 typename self_type:: 03817 #endif 03818 const_iterator2 end () const { 03819 const self_type &m = (*this) (); 03820 return m.find2 (1, index1 (), m.size2 ()); 03821 } 03822 BOOST_UBLAS_INLINE 03823 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03824 typename self_type:: 03825 #endif 03826 const_reverse_iterator2 rbegin () const { 03827 return const_reverse_iterator2 (end ()); 03828 } 03829 BOOST_UBLAS_INLINE 03830 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03831 typename self_type:: 03832 #endif 03833 const_reverse_iterator2 rend () const { 03834 return const_reverse_iterator2 (begin ()); 03835 } 03836 #endif 03837 03838 // Indices 03839 BOOST_UBLAS_INLINE 03840 size_type index1 () const { 03841 const self_type &m = (*this) (); 03842 return (it_ - m.begin1 ().it_) / M; 03843 } 03844 BOOST_UBLAS_INLINE 03845 size_type index2 () const { 03846 const self_type &m = (*this) (); 03847 return (it_ - m.begin1 ().it_) % M; 03848 } 03849 03850 // Assignment 03851 BOOST_UBLAS_INLINE 03852 const_iterator1 &operator = (const const_iterator1 &it) { 03853 container_const_reference<self_type>::assign (&it ()); 03854 it_ = it.it_; 03855 return *this; 03856 } 03857 03858 // Comparison 03859 BOOST_UBLAS_INLINE 03860 bool operator == (const const_iterator1 &it) const { 03861 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03862 return it_ == it.it_; 03863 } 03864 BOOST_UBLAS_INLINE 03865 bool operator < (const const_iterator1 &it) const { 03866 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03867 return it_ < it.it_; 03868 } 03869 03870 private: 03871 const_subiterator_type it_; 03872 03873 friend class iterator1; 03874 }; 03875 #endif 03876 03877 BOOST_UBLAS_INLINE 03878 const_iterator1 begin1 () const { 03879 return find1 (0, 0, 0); 03880 } 03881 BOOST_UBLAS_INLINE 03882 const_iterator1 end1 () const { 03883 return find1 (0, size1_, 0); 03884 } 03885 03886 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 03887 class iterator1: 03888 public container_reference<c_matrix>, 03889 public random_access_iterator_base<dense_random_access_iterator_tag, 03890 iterator1, value_type> { 03891 public: 03892 03893 typedef typename c_matrix::difference_type difference_type; 03894 typedef typename c_matrix::value_type value_type; 03895 typedef typename c_matrix::reference reference; 03896 typedef typename c_matrix::pointer pointer; 03897 03898 typedef iterator2 dual_iterator_type; 03899 typedef reverse_iterator2 dual_reverse_iterator_type; 03900 03901 // Construction and destruction 03902 BOOST_UBLAS_INLINE 03903 iterator1 (): 03904 container_reference<self_type> (), it_ () {} 03905 BOOST_UBLAS_INLINE 03906 iterator1 (self_type &m, const subiterator_type &it): 03907 container_reference<self_type> (m), it_ (it) {} 03908 03909 // Arithmetic 03910 BOOST_UBLAS_INLINE 03911 iterator1 &operator ++ () { 03912 it_ += M; 03913 return *this; 03914 } 03915 BOOST_UBLAS_INLINE 03916 iterator1 &operator -- () { 03917 it_ -= M; 03918 return *this; 03919 } 03920 BOOST_UBLAS_INLINE 03921 iterator1 &operator += (difference_type n) { 03922 it_ += n * M; 03923 return *this; 03924 } 03925 BOOST_UBLAS_INLINE 03926 iterator1 &operator -= (difference_type n) { 03927 it_ -= n * M; 03928 return *this; 03929 } 03930 BOOST_UBLAS_INLINE 03931 difference_type operator - (const iterator1 &it) const { 03932 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 03933 return (it_ - it.it_) / M; 03934 } 03935 03936 // Dereference 03937 BOOST_UBLAS_INLINE 03938 reference operator * () const { 03939 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 03940 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 03941 return *it_; 03942 } 03943 BOOST_UBLAS_INLINE 03944 reference operator [] (difference_type n) const { 03945 return *(*this + n); 03946 } 03947 03948 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 03949 BOOST_UBLAS_INLINE 03950 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03951 typename self_type:: 03952 #endif 03953 iterator2 begin () const { 03954 self_type &m = (*this) (); 03955 return m.find2 (1, index1 (), 0); 03956 } 03957 BOOST_UBLAS_INLINE 03958 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03959 typename self_type:: 03960 #endif 03961 iterator2 end () const { 03962 self_type &m = (*this) (); 03963 return m.find2 (1, index1 (), m.size2 ()); 03964 } 03965 BOOST_UBLAS_INLINE 03966 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03967 typename self_type:: 03968 #endif 03969 reverse_iterator2 rbegin () const { 03970 return reverse_iterator2 (end ()); 03971 } 03972 BOOST_UBLAS_INLINE 03973 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 03974 typename self_type:: 03975 #endif 03976 reverse_iterator2 rend () const { 03977 return reverse_iterator2 (begin ()); 03978 } 03979 #endif 03980 03981 // Indices 03982 BOOST_UBLAS_INLINE 03983 size_type index1 () const { 03984 const self_type &m = (*this) (); 03985 return (it_ - m.begin1 ().it_) / M; 03986 } 03987 BOOST_UBLAS_INLINE 03988 size_type index2 () const { 03989 const self_type &m = (*this) (); 03990 return (it_ - m.begin1 ().it_) % M; 03991 } 03992 03993 // Assignment 03994 BOOST_UBLAS_INLINE 03995 iterator1 &operator = (const iterator1 &it) { 03996 container_reference<self_type>::assign (&it ()); 03997 it_ = it.it_; 03998 return *this; 03999 } 04000 04001 // Comparison 04002 BOOST_UBLAS_INLINE 04003 bool operator == (const iterator1 &it) const { 04004 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04005 return it_ == it.it_; 04006 } 04007 BOOST_UBLAS_INLINE 04008 bool operator < (const iterator1 &it) const { 04009 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04010 return it_ < it.it_; 04011 } 04012 04013 private: 04014 subiterator_type it_; 04015 04016 friend class const_iterator1; 04017 }; 04018 #endif 04019 04020 BOOST_UBLAS_INLINE 04021 iterator1 begin1 () { 04022 return find1 (0, 0, 0); 04023 } 04024 BOOST_UBLAS_INLINE 04025 iterator1 end1 () { 04026 return find1 (0, size1_, 0); 04027 } 04028 04029 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 04030 class const_iterator2: 04031 public container_const_reference<c_matrix>, 04032 public random_access_iterator_base<dense_random_access_iterator_tag, 04033 const_iterator2, value_type> { 04034 public: 04035 typedef typename c_matrix::difference_type difference_type; 04036 typedef typename c_matrix::value_type value_type; 04037 typedef typename c_matrix::const_reference reference; 04038 typedef typename c_matrix::const_reference pointer; 04039 04040 typedef const_iterator1 dual_iterator_type; 04041 typedef const_reverse_iterator1 dual_reverse_iterator_type; 04042 04043 // Construction and destruction 04044 BOOST_UBLAS_INLINE 04045 const_iterator2 (): 04046 container_const_reference<self_type> (), it_ () {} 04047 BOOST_UBLAS_INLINE 04048 const_iterator2 (const self_type &m, const const_subiterator_type &it): 04049 container_const_reference<self_type> (m), it_ (it) {} 04050 BOOST_UBLAS_INLINE 04051 const_iterator2 (const iterator2 &it): 04052 container_const_reference<self_type> (it ()), it_ (it.it_) {} 04053 04054 // Arithmetic 04055 BOOST_UBLAS_INLINE 04056 const_iterator2 &operator ++ () { 04057 ++ it_; 04058 return *this; 04059 } 04060 BOOST_UBLAS_INLINE 04061 const_iterator2 &operator -- () { 04062 -- it_; 04063 return *this; 04064 } 04065 BOOST_UBLAS_INLINE 04066 const_iterator2 &operator += (difference_type n) { 04067 it_ += n; 04068 return *this; 04069 } 04070 BOOST_UBLAS_INLINE 04071 const_iterator2 &operator -= (difference_type n) { 04072 it_ -= n; 04073 return *this; 04074 } 04075 BOOST_UBLAS_INLINE 04076 difference_type operator - (const const_iterator2 &it) const { 04077 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04078 return it_ - it.it_; 04079 } 04080 04081 // Dereference 04082 BOOST_UBLAS_INLINE 04083 const_reference operator * () const { 04084 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 04085 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 04086 return *it_; 04087 } 04088 BOOST_UBLAS_INLINE 04089 const_reference operator [] (difference_type n) const { 04090 return *(*this + n); 04091 } 04092 04093 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 04094 BOOST_UBLAS_INLINE 04095 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04096 typename self_type:: 04097 #endif 04098 const_iterator1 begin () const { 04099 const self_type &m = (*this) (); 04100 return m.find1 (1, 0, index2 ()); 04101 } 04102 BOOST_UBLAS_INLINE 04103 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04104 typename self_type:: 04105 #endif 04106 const_iterator1 end () const { 04107 const self_type &m = (*this) (); 04108 return m.find1 (1, m.size1 (), index2 ()); 04109 } 04110 BOOST_UBLAS_INLINE 04111 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04112 typename self_type:: 04113 #endif 04114 const_reverse_iterator1 rbegin () const { 04115 return const_reverse_iterator1 (end ()); 04116 } 04117 BOOST_UBLAS_INLINE 04118 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04119 typename self_type:: 04120 #endif 04121 const_reverse_iterator1 rend () const { 04122 return const_reverse_iterator1 (begin ()); 04123 } 04124 #endif 04125 04126 // Indices 04127 BOOST_UBLAS_INLINE 04128 size_type index1 () const { 04129 const self_type &m = (*this) (); 04130 return (it_ - m.begin2 ().it_) / M; 04131 } 04132 BOOST_UBLAS_INLINE 04133 size_type index2 () const { 04134 const self_type &m = (*this) (); 04135 return (it_ - m.begin2 ().it_) % M; 04136 } 04137 04138 // Assignment 04139 BOOST_UBLAS_INLINE 04140 const_iterator2 &operator = (const const_iterator2 &it) { 04141 container_const_reference<self_type>::assign (&it ()); 04142 it_ = it.it_; 04143 return *this; 04144 } 04145 04146 // Comparison 04147 BOOST_UBLAS_INLINE 04148 bool operator == (const const_iterator2 &it) const { 04149 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04150 return it_ == it.it_; 04151 } 04152 BOOST_UBLAS_INLINE 04153 bool operator < (const const_iterator2 &it) const { 04154 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04155 return it_ < it.it_; 04156 } 04157 04158 private: 04159 const_subiterator_type it_; 04160 04161 friend class iterator2; 04162 }; 04163 #endif 04164 04165 BOOST_UBLAS_INLINE 04166 const_iterator2 begin2 () const { 04167 return find2 (0, 0, 0); 04168 } 04169 BOOST_UBLAS_INLINE 04170 const_iterator2 end2 () const { 04171 return find2 (0, 0, size2_); 04172 } 04173 04174 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR 04175 class iterator2: 04176 public container_reference<c_matrix>, 04177 public random_access_iterator_base<dense_random_access_iterator_tag, 04178 iterator2, value_type> { 04179 public: 04180 typedef typename c_matrix::difference_type difference_type; 04181 typedef typename c_matrix::value_type value_type; 04182 typedef typename c_matrix::reference reference; 04183 typedef typename c_matrix::pointer pointer; 04184 04185 typedef iterator1 dual_iterator_type; 04186 typedef reverse_iterator1 dual_reverse_iterator_type; 04187 04188 // Construction and destruction 04189 BOOST_UBLAS_INLINE 04190 iterator2 (): 04191 container_reference<self_type> (), it_ () {} 04192 BOOST_UBLAS_INLINE 04193 iterator2 (self_type &m, const subiterator_type &it): 04194 container_reference<self_type> (m), it_ (it) {} 04195 04196 // Arithmetic 04197 BOOST_UBLAS_INLINE 04198 iterator2 &operator ++ () { 04199 ++ it_; 04200 return *this; 04201 } 04202 BOOST_UBLAS_INLINE 04203 iterator2 &operator -- () { 04204 -- it_; 04205 return *this; 04206 } 04207 BOOST_UBLAS_INLINE 04208 iterator2 &operator += (difference_type n) { 04209 it_ += n; 04210 return *this; 04211 } 04212 BOOST_UBLAS_INLINE 04213 iterator2 &operator -= (difference_type n) { 04214 it_ -= n; 04215 return *this; 04216 } 04217 BOOST_UBLAS_INLINE 04218 difference_type operator - (const iterator2 &it) const { 04219 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04220 return it_ - it.it_; 04221 } 04222 04223 // Dereference 04224 BOOST_UBLAS_INLINE 04225 reference operator * () const { 04226 BOOST_UBLAS_CHECK (index1 () < (*this) ().size1 (), bad_index ()); 04227 BOOST_UBLAS_CHECK (index2 () < (*this) ().size2 (), bad_index ()); 04228 return *it_; 04229 } 04230 BOOST_UBLAS_INLINE 04231 reference operator [] (difference_type n) const { 04232 return *(*this + n); 04233 } 04234 04235 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION 04236 BOOST_UBLAS_INLINE 04237 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04238 typename self_type:: 04239 #endif 04240 iterator1 begin () const { 04241 self_type &m = (*this) (); 04242 return m.find1 (1, 0, index2 ()); 04243 } 04244 BOOST_UBLAS_INLINE 04245 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04246 typename self_type:: 04247 #endif 04248 iterator1 end () const { 04249 self_type &m = (*this) (); 04250 return m.find1 (1, m.size1 (), index2 ()); 04251 } 04252 BOOST_UBLAS_INLINE 04253 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04254 typename self_type:: 04255 #endif 04256 reverse_iterator1 rbegin () const { 04257 return reverse_iterator1 (end ()); 04258 } 04259 BOOST_UBLAS_INLINE 04260 #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION 04261 typename self_type:: 04262 #endif 04263 reverse_iterator1 rend () const { 04264 return reverse_iterator1 (begin ()); 04265 } 04266 #endif 04267 04268 // Indices 04269 BOOST_UBLAS_INLINE 04270 size_type index1 () const { 04271 const self_type &m = (*this) (); 04272 return (it_ - m.begin2 ().it_) / M; 04273 } 04274 BOOST_UBLAS_INLINE 04275 size_type index2 () const { 04276 const self_type &m = (*this) (); 04277 return (it_ - m.begin2 ().it_) % M; 04278 } 04279 04280 // Assignment 04281 BOOST_UBLAS_INLINE 04282 iterator2 &operator = (const iterator2 &it) { 04283 container_reference<self_type>::assign (&it ()); 04284 it_ = it.it_; 04285 return *this; 04286 } 04287 04288 // Comparison 04289 BOOST_UBLAS_INLINE 04290 bool operator == (const iterator2 &it) const { 04291 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04292 return it_ == it.it_; 04293 } 04294 BOOST_UBLAS_INLINE 04295 bool operator < (const iterator2 &it) const { 04296 BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ()); 04297 return it_ < it.it_; 04298 } 04299 04300 private: 04301 subiterator_type it_; 04302 04303 friend class const_iterator2; 04304 }; 04305 #endif 04306 04307 BOOST_UBLAS_INLINE 04308 iterator2 begin2 () { 04309 return find2 (0, 0, 0); 04310 } 04311 BOOST_UBLAS_INLINE 04312 iterator2 end2 () { 04313 return find2 (0, 0, size2_); 04314 } 04315 04316 // Reverse iterators 04317 04318 BOOST_UBLAS_INLINE 04319 const_reverse_iterator1 rbegin1 () const { 04320 return const_reverse_iterator1 (end1 ()); 04321 } 04322 BOOST_UBLAS_INLINE 04323 const_reverse_iterator1 rend1 () const { 04324 return const_reverse_iterator1 (begin1 ()); 04325 } 04326 04327 BOOST_UBLAS_INLINE 04328 reverse_iterator1 rbegin1 () { 04329 return reverse_iterator1 (end1 ()); 04330 } 04331 BOOST_UBLAS_INLINE 04332 reverse_iterator1 rend1 () { 04333 return reverse_iterator1 (begin1 ()); 04334 } 04335 04336 BOOST_UBLAS_INLINE 04337 const_reverse_iterator2 rbegin2 () const { 04338 return const_reverse_iterator2 (end2 ()); 04339 } 04340 BOOST_UBLAS_INLINE 04341 const_reverse_iterator2 rend2 () const { 04342 return const_reverse_iterator2 (begin2 ()); 04343 } 04344 04345 BOOST_UBLAS_INLINE 04346 reverse_iterator2 rbegin2 () { 04347 return reverse_iterator2 (end2 ()); 04348 } 04349 BOOST_UBLAS_INLINE 04350 reverse_iterator2 rend2 () { 04351 return reverse_iterator2 (begin2 ()); 04352 } 04353 04354 // Serialization 04355 template<class Archive> 04356 void serialize(Archive & ar, const unsigned int /* file_version */){ 04357 04358 // we need to copy to a collection_size_type to get a portable 04359 // and efficient serialization 04360 serialization::collection_size_type s1 (size1_); 04361 serialization::collection_size_type s2 (size2_); 04362 04363 // serialize the sizes 04364 ar & serialization::make_nvp("size1",s1) 04365 & serialization::make_nvp("size2",s2); 04366 04367 // copy the values back if loading 04368 if (Archive::is_loading::value) { 04369 size1_ = s1; 04370 size2_ = s2; 04371 } 04372 // could probably use make_array( &(data[0][0]), N*M ) 04373 ar & serialization::make_array(data_, N); 04374 } 04375 04376 private: 04377 size_type size1_; 04378 size_type size2_; 04379 value_type data_ [N] [M]; 04380 }; 04381 04382 }}} 04383 04384 #endif