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