DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
// // Copyright (c) 2000-2002 // Joerg Walter, Mathias Koch // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // The authors gratefully acknowledge the support of // GeNeSys mbH & Co. KG in producing this work. // #ifndef _BOOST_UBLAS_MATRIX_EXPRESSION_ #define _BOOST_UBLAS_MATRIX_EXPRESSION_ #include
// Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish // Iterators based on ideas of Jeremy Siek // // Classes that model the Matrix Expression concept namespace boost { namespace numeric { namespace ublas { template
class matrix_reference: public matrix_expression
> { typedef matrix_reference
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_expression
::operator (); #endif typedef typename E::size_type size_type; typedef typename E::difference_type difference_type; typedef typename E::value_type value_type; typedef typename E::const_reference const_reference; typedef typename boost::mpl::if_
, typename E::const_reference, typename E::reference>::type reference; typedef E referred_type; typedef const self_type const_closure_type; typedef self_type closure_type; typedef typename E::orientation_category orientation_category; typedef typename E::storage_category storage_category; // Construction and destruction BOOST_UBLAS_INLINE explicit matrix_reference (referred_type &e): e_ (e) {} // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return e_.size1 (); } BOOST_UBLAS_INLINE size_type size2 () const { return e_.size2 (); } public: // Expression accessors - const correct BOOST_UBLAS_INLINE const referred_type &expression () const { return e_; } BOOST_UBLAS_INLINE referred_type &expression () { return e_; } public: // Element access #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return expression () (i, j); } BOOST_UBLAS_INLINE reference operator () (size_type i, size_type j) { return expression () (i, j); } #else BOOST_UBLAS_INLINE reference operator () (size_type i, size_type j) const { return expression () (i, j); } #endif // Assignment BOOST_UBLAS_INLINE matrix_reference &operator = (const matrix_reference &m) { expression ().operator = (m); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &operator = (const matrix_expression
&ae) { expression ().operator = (ae); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &assign (const matrix_expression
&ae) { expression ().assign (ae); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &operator += (const matrix_expression
&ae) { expression ().operator += (ae); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &plus_assign (const matrix_expression
&ae) { expression ().plus_assign (ae); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &operator -= (const matrix_expression
&ae) { expression ().operator -= (ae); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &minus_assign (const matrix_expression
&ae) { expression ().minus_assign (ae); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &operator *= (const AT &at) { expression ().operator *= (at); return *this; } template
BOOST_UBLAS_INLINE matrix_reference &operator /= (const AT &at) { expression ().operator /= (at); return *this; } // Swapping BOOST_UBLAS_INLINE void swap (matrix_reference &m) { expression ().swap (m.expression ()); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_reference &mr) const { return &(*this).e_ == &mr.e_; } // Iterator types typedef typename E::const_iterator1 const_iterator1; typedef typename boost::mpl::if_
, typename E::const_iterator1, typename E::iterator1>::type iterator1; typedef typename E::const_iterator2 const_iterator2; typedef typename boost::mpl::if_
, typename E::const_iterator2, typename E::iterator2>::type iterator2; // Element lookup BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { return expression ().find1 (rank, i, j); } BOOST_UBLAS_INLINE iterator1 find1 (int rank, size_type i, size_type j) { return expression ().find1 (rank, i, j); } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { return expression ().find2 (rank, i, j); } BOOST_UBLAS_INLINE iterator2 find2 (int rank, size_type i, size_type j) { return expression ().find2 (rank, i, j); } // Iterators are the iterators of the referenced expression. BOOST_UBLAS_INLINE const_iterator1 begin1 () const { return expression ().begin1 (); } BOOST_UBLAS_INLINE const_iterator1 end1 () const { return expression ().end1 (); } BOOST_UBLAS_INLINE iterator1 begin1 () { return expression ().begin1 (); } BOOST_UBLAS_INLINE iterator1 end1 () { return expression ().end1 (); } BOOST_UBLAS_INLINE const_iterator2 begin2 () const { return expression ().begin2 (); } BOOST_UBLAS_INLINE const_iterator2 end2 () const { return expression ().end2 (); } BOOST_UBLAS_INLINE iterator2 begin2 () { return expression ().begin2 (); } BOOST_UBLAS_INLINE iterator2 end2 () { return expression ().end2 (); } // Reverse iterators typedef reverse_iterator_base1
const_reverse_iterator1; typedef reverse_iterator_base1
reverse_iterator1; BOOST_UBLAS_INLINE const_reverse_iterator1 rbegin1 () const { return const_reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator1 rend1 () const { return const_reverse_iterator1 (begin1 ()); } BOOST_UBLAS_INLINE reverse_iterator1 rbegin1 () { return reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE reverse_iterator1 rend1 () { return reverse_iterator1 (begin1 ()); } typedef reverse_iterator_base2
const_reverse_iterator2; typedef reverse_iterator_base2
reverse_iterator2; BOOST_UBLAS_INLINE const_reverse_iterator2 rbegin2 () const { return const_reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rend2 () const { return const_reverse_iterator2 (begin2 ()); } BOOST_UBLAS_INLINE reverse_iterator2 rbegin2 () { return reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE reverse_iterator2 rend2 () { return reverse_iterator2 (begin2 ()); } private: referred_type &e_; }; template
class vector_matrix_binary: public matrix_expression
> { typedef E1 expression1_type; typedef E2 expression2_type; public: typedef typename E1::const_closure_type expression1_closure_type; typedef typename E2::const_closure_type expression2_closure_type; private: typedef vector_matrix_binary
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_expression
::operator (); #endif typedef F functor_type; typedef typename promote_traits
::promote_type size_type; typedef typename promote_traits
::promote_type difference_type; typedef typename F::result_type value_type; typedef value_type const_reference; typedef const_reference reference; typedef const self_type const_closure_type; typedef const_closure_type closure_type; typedef unknown_orientation_tag orientation_category; typedef unknown_storage_tag storage_category; // Construction and destruction BOOST_UBLAS_INLINE vector_matrix_binary (const expression1_type &e1, const expression2_type &e2): e1_ (e1), e2_ (e2) {} // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return e1_.size (); } BOOST_UBLAS_INLINE size_type size2 () const { return e2_.size (); } public: // Expression accessors BOOST_UBLAS_INLINE const expression1_closure_type &expression1 () const { return e1_; } BOOST_UBLAS_INLINE const expression2_closure_type &expression2 () const { return e2_; } public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return functor_type::apply (e1_ (i), e2_ (j)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const vector_matrix_binary &vmb) const { return (*this).expression1 ().same_closure (vmb.expression1 ()) && (*this).expression2 ().same_closure (vmb.expression2 ()); } // Iterator types private: typedef typename E1::const_iterator const_subiterator1_type; typedef typename E2::const_iterator const_subiterator2_type; typedef const value_type *const_pointer; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef typename iterator_restrict_traits
::iterator_category iterator_category; typedef indexed_const_iterator1
const_iterator1; typedef const_iterator1 iterator1; typedef indexed_const_iterator2
const_iterator2; typedef const_iterator2 iterator2; #else class const_iterator1; typedef const_iterator1 iterator1; class const_iterator2; typedef const_iterator2 iterator2; #endif typedef reverse_iterator_base1
const_reverse_iterator1; typedef reverse_iterator_base2
const_reverse_iterator2; // Element lookup BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { const_subiterator1_type it1 (e1_.find (i)); const_subiterator1_type it1_end (e1_.find (size1 ())); const_subiterator2_type it2 (e2_.find (j)); const_subiterator2_type it2_end (e2_.find (size2 ())); if (it2 == it2_end || (rank == 1 && (it2.index () != j || *it2 == value_type/*zero*/()))) { it1 = it1_end; it2 = it2_end; } #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, it1.index (), it2.index ()); #else #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING return const_iterator1 (*this, it1, it2, it2 != it2_end ? *it2 : value_type/*zero*/()); #else return const_iterator1 (*this, it1, it2); #endif #endif } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { const_subiterator2_type it2 (e2_.find (j)); const_subiterator2_type it2_end (e2_.find (size2 ())); const_subiterator1_type it1 (e1_.find (i)); const_subiterator1_type it1_end (e1_.find (size1 ())); if (it1 == it1_end || (rank == 1 && (it1.index () != i || *it1 == value_type/*zero*/()))) { it2 = it2_end; it1 = it1_end; } #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, it1.index (), it2.index ()); #else #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING return const_iterator2 (*this, it1, it2, it1 != it1_end ? *it1 : value_type/*zero*/()); #else return const_iterator2 (*this, it1, it2); #endif #endif } // Iterators enhance the iterators of the referenced expressions // with the binary functor. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator1: public container_const_reference
, public iterator_base_traits
::iterator_category>::template iterator_base
::type { public: typedef typename iterator_restrict_traits
::iterator_category iterator_category; typedef typename vector_matrix_binary::difference_type difference_type; typedef typename vector_matrix_binary::value_type value_type; typedef typename vector_matrix_binary::const_reference reference; typedef typename vector_matrix_binary::const_pointer pointer; typedef const_iterator2 dual_iterator_type; typedef const_reverse_iterator2 dual_reverse_iterator_type; // Construction and destruction #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference
(), it1_ (), it2_ (), t2_ () {} BOOST_UBLAS_INLINE const_iterator1 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2, value_type t2): container_const_reference
(vmb), it1_ (it1), it2_ (it2), t2_ (t2) {} #else BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator1 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2): container_const_reference
(vmb), it1_ (it1), it2_ (it2) {} #endif // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { ++ it1_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -- () { -- it1_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator += (difference_type n) { it1_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -= (difference_type n) { it1_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ - it.it1_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING return functor_type::apply (*it1_, t2_); #else return functor_type::apply (*it1_, *it2_); #endif } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 begin () const { return (*this) ().find2 (1, index1 (), 0); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 end () const { return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rbegin () const { return const_reverse_iterator2 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rend () const { return const_reverse_iterator2 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it1_.index (); } BOOST_UBLAS_INLINE size_type index2 () const { return it2_.index (); } // Assignment BOOST_UBLAS_INLINE const_iterator1 &operator = (const const_iterator1 &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING t2_ = it.t2_; #endif return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ == it.it1_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ < it.it1_; } private: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING const_subiterator1_type it1_; // Mutable due to assignment /* const */ const_subiterator2_type it2_; value_type t2_; #else const_subiterator1_type it1_; const_subiterator2_type it2_; #endif }; #endif BOOST_UBLAS_INLINE const_iterator1 begin1 () const { return find1 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator1 end1 () const { return find1 (0, size1 (), 0); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator2: public container_const_reference
, public iterator_base_traits
::iterator_category>::template iterator_base
::type { public: typedef typename iterator_restrict_traits
::iterator_category iterator_category; typedef typename vector_matrix_binary::difference_type difference_type; typedef typename vector_matrix_binary::value_type value_type; typedef typename vector_matrix_binary::const_reference reference; typedef typename vector_matrix_binary::const_pointer pointer; typedef const_iterator1 dual_iterator_type; typedef const_reverse_iterator1 dual_reverse_iterator_type; // Construction and destruction #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING BOOST_UBLAS_INLINE const_iterator2 (): container_const_reference
(), it1_ (), it2_ (), t1_ () {} BOOST_UBLAS_INLINE const_iterator2 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2, value_type t1): container_const_reference
(vmb), it1_ (it1), it2_ (it2), t1_ (t1) {} #else BOOST_UBLAS_INLINE const_iterator2 (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator2 (const self_type &vmb, const const_subiterator1_type &it1, const const_subiterator2_type &it2): container_const_reference
(vmb), it1_ (it1), it2_ (it2) {} #endif // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { ++ it2_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -- () { -- it2_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator += (difference_type n) { it2_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -= (difference_type n) { it2_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure(it ()), external_logic ()); BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ - it.it2_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING return functor_type::apply (t1_, *it2_); #else return functor_type::apply (*it1_, *it2_); #endif } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 begin () const { return (*this) ().find1 (1, 0, index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 end () const { return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rbegin () const { return const_reverse_iterator1 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rend () const { return const_reverse_iterator1 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it1_.index (); } BOOST_UBLAS_INLINE size_type index2 () const { return it2_.index (); } // Assignment BOOST_UBLAS_INLINE const_iterator2 &operator = (const const_iterator2 &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING t1_ = it.t1_; #endif return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure( it ()), external_logic ()); BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ == it.it2_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ < it.it2_; } private: #ifdef BOOST_UBLAS_USE_INVARIANT_HOISTING // Mutable due to assignment /* const */ const_subiterator1_type it1_; const_subiterator2_type it2_; value_type t1_; #else const_subiterator1_type it1_; const_subiterator2_type it2_; #endif }; #endif BOOST_UBLAS_INLINE const_iterator2 begin2 () const { return find2 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator2 end2 () const { return find2 (0, 0, size2 ()); } // Reverse iterators BOOST_UBLAS_INLINE const_reverse_iterator1 rbegin1 () const { return const_reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator1 rend1 () const { return const_reverse_iterator1 (begin1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rbegin2 () const { return const_reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rend2 () const { return const_reverse_iterator2 (begin2 ()); } private: expression1_closure_type e1_; expression2_closure_type e2_; }; template
struct vector_matrix_binary_traits { typedef vector_matrix_binary
expression_type; #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else // ISSUE matrix is arbitary temporary type typedef matrix
result_type; #endif }; // (outer_prod (v1, v2)) [i] [j] = v1 [i] * v2 [j] template
BOOST_UBLAS_INLINE typename vector_matrix_binary_traits
>::result_type outer_prod (const vector_expression
&e1, const vector_expression
&e2) { BOOST_STATIC_ASSERT (E1::complexity == 0 && E2::complexity == 0); typedef typename vector_matrix_binary_traits
>::expression_type expression_type; return expression_type (e1 (), e2 ()); } template
class matrix_unary1: public matrix_expression
> { typedef E expression_type; typedef F functor_type; public: typedef typename E::const_closure_type expression_closure_type; private: typedef matrix_unary1
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_expression
::operator (); #endif typedef typename E::size_type size_type; typedef typename E::difference_type difference_type; typedef typename F::result_type value_type; typedef value_type const_reference; typedef const_reference reference; typedef const self_type const_closure_type; typedef const_closure_type closure_type; typedef typename E::orientation_category orientation_category; typedef unknown_storage_tag storage_category; // Construction and destruction BOOST_UBLAS_INLINE explicit matrix_unary1 (const expression_type &e): e_ (e) {} // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return e_.size1 (); } BOOST_UBLAS_INLINE size_type size2 () const { return e_.size2 (); } public: // Expression accessors BOOST_UBLAS_INLINE const expression_closure_type &expression () const { return e_; } public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return functor_type::apply (e_ (i, j)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_unary1 &mu1) const { return (*this).expression ().same_closure (mu1.expression ()); } // Iterator types private: typedef typename E::const_iterator1 const_subiterator1_type; typedef typename E::const_iterator2 const_subiterator2_type; typedef const value_type *const_pointer; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef indexed_const_iterator1
const_iterator1; typedef const_iterator1 iterator1; typedef indexed_const_iterator2
const_iterator2; typedef const_iterator2 iterator2; #else class const_iterator1; typedef const_iterator1 iterator1; class const_iterator2; typedef const_iterator2 iterator2; #endif typedef reverse_iterator_base1
const_reverse_iterator1; typedef reverse_iterator_base2
const_reverse_iterator2; // Element lookup BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { const_subiterator1_type it1 (e_.find1 (rank, i, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, it1.index1 (), it1.index2 ()); #else return const_iterator1 (*this, it1); #endif } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { const_subiterator2_type it2 (e_.find2 (rank, i, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, it2.index1 (), it2.index2 ()); #else return const_iterator2 (*this, it2); #endif } // Iterators enhance the iterators of the referenced expression // with the unary functor. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator1: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E::const_iterator1::iterator_category iterator_category; typedef typename matrix_unary1::difference_type difference_type; typedef typename matrix_unary1::value_type value_type; typedef typename matrix_unary1::const_reference reference; typedef typename matrix_unary1::const_pointer pointer; typedef const_iterator2 dual_iterator_type; typedef const_reverse_iterator2 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference
(), it_ () {} BOOST_UBLAS_INLINE const_iterator1 (const self_type &mu, const const_subiterator1_type &it): container_const_reference
(mu), it_ (it) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (*it_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 begin () const { return (*this) ().find2 (1, index1 (), 0); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 end () const { return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rbegin () const { return const_reverse_iterator2 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rend () const { return const_reverse_iterator2 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it_.index1 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it_.index2 (); } // Assignment BOOST_UBLAS_INLINE const_iterator1 &operator = (const const_iterator1 &it) { container_const_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: const_subiterator1_type it_; }; #endif BOOST_UBLAS_INLINE const_iterator1 begin1 () const { return find1 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator1 end1 () const { return find1 (0, size1 (), 0); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator2: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E::const_iterator2::iterator_category iterator_category; typedef typename matrix_unary1::difference_type difference_type; typedef typename matrix_unary1::value_type value_type; typedef typename matrix_unary1::const_reference reference; typedef typename matrix_unary1::const_pointer pointer; typedef const_iterator1 dual_iterator_type; typedef const_reverse_iterator1 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator2 (): container_const_reference
(), it_ () {} BOOST_UBLAS_INLINE const_iterator2 (const self_type &mu, const const_subiterator2_type &it): container_const_reference
(mu), it_ (it) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (*it_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 begin () const { return (*this) ().find1 (1, 0, index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 end () const { return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rbegin () const { return const_reverse_iterator1 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rend () const { return const_reverse_iterator1 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it_.index1 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it_.index2 (); } // Assignment BOOST_UBLAS_INLINE const_iterator2 &operator = (const const_iterator2 &it) { container_const_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: const_subiterator2_type it_; }; #endif BOOST_UBLAS_INLINE const_iterator2 begin2 () const { return find2 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator2 end2 () const { return find2 (0, 0, size2 ()); } // Reverse iterators BOOST_UBLAS_INLINE const_reverse_iterator1 rbegin1 () const { return const_reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator1 rend1 () const { return const_reverse_iterator1 (begin1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rbegin2 () const { return const_reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rend2 () const { return const_reverse_iterator2 (begin2 ()); } private: expression_closure_type e_; }; template
struct matrix_unary1_traits { typedef matrix_unary1
expression_type; #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else typedef typename E::matrix_temporary_type result_type; #endif }; // (- m) [i] [j] = - m [i] [j] template
BOOST_UBLAS_INLINE typename matrix_unary1_traits
>::result_type operator - (const matrix_expression
&e) { typedef typename matrix_unary1_traits
>::expression_type expression_type; return expression_type (e ()); } // (conj m) [i] [j] = conj (m [i] [j]) template
BOOST_UBLAS_INLINE typename matrix_unary1_traits
>::result_type conj (const matrix_expression
&e) { typedef typename matrix_unary1_traits
>::expression_type expression_type; return expression_type (e ()); } // (real m) [i] [j] = real (m [i] [j]) template
BOOST_UBLAS_INLINE typename matrix_unary1_traits
>::result_type real (const matrix_expression
&e) { typedef typename matrix_unary1_traits
>::expression_type expression_type; return expression_type (e ()); } // (imag m) [i] [j] = imag (m [i] [j]) template
BOOST_UBLAS_INLINE typename matrix_unary1_traits
>::result_type imag (const matrix_expression
&e) { typedef typename matrix_unary1_traits
>::expression_type expression_type; return expression_type (e ()); } template
class matrix_unary2: public matrix_expression
> { typedef typename boost::mpl::if_
>, E, const E>::type expression_type; typedef F functor_type; public: typedef typename boost::mpl::if_
, typename E::const_closure_type, typename E::closure_type>::type expression_closure_type; private: typedef matrix_unary2
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_expression
::operator (); #endif typedef typename E::size_type size_type; typedef typename E::difference_type difference_type; typedef typename F::result_type value_type; typedef value_type const_reference; typedef typename boost::mpl::if_
>, typename E::reference, value_type>::type reference; typedef const self_type const_closure_type; typedef self_type closure_type; typedef typename boost::mpl::if_
, column_major_tag, typename boost::mpl::if_
, row_major_tag, typename E::orientation_category>::type>::type orientation_category; typedef typename E::storage_category storage_category; // Construction and destruction BOOST_UBLAS_INLINE // matrix_unary2 may be used as mutable expression - // this is the only non const expression constructor explicit matrix_unary2 (expression_type &e): e_ (e) {} // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return e_.size2 (); } BOOST_UBLAS_INLINE size_type size2 () const { return e_.size1 (); } public: // Expression accessors BOOST_UBLAS_INLINE const expression_closure_type &expression () const { return e_; } public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return functor_type::apply (e_ (j, i)); } BOOST_UBLAS_INLINE reference operator () (size_type i, size_type j) { BOOST_STATIC_ASSERT ((boost::is_same
>::value)); return e_ (j, i); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_unary2 &mu2) const { return (*this).expression ().same_closure (mu2.expression ()); } // Iterator types private: typedef typename E::const_iterator1 const_subiterator2_type; typedef typename E::const_iterator2 const_subiterator1_type; typedef const value_type *const_pointer; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef indexed_const_iterator1
const_iterator1; typedef const_iterator1 iterator1; typedef indexed_const_iterator2
const_iterator2; typedef const_iterator2 iterator2; #else class const_iterator1; typedef const_iterator1 iterator1; class const_iterator2; typedef const_iterator2 iterator2; #endif typedef reverse_iterator_base1
const_reverse_iterator1; typedef reverse_iterator_base2
const_reverse_iterator2; // Element lookup BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { const_subiterator1_type it1 (e_.find2 (rank, j, i)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, it1.index2 (), it1.index1 ()); #else return const_iterator1 (*this, it1); #endif } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { const_subiterator2_type it2 (e_.find1 (rank, j, i)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, it2.index2 (), it2.index1 ()); #else return const_iterator2 (*this, it2); #endif } // Iterators enhance the iterators of the referenced expression // with the unary functor. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator1: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E::const_iterator2::iterator_category iterator_category; typedef typename matrix_unary2::difference_type difference_type; typedef typename matrix_unary2::value_type value_type; typedef typename matrix_unary2::const_reference reference; typedef typename matrix_unary2::const_pointer pointer; typedef const_iterator2 dual_iterator_type; typedef const_reverse_iterator2 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference
(), it_ () {} BOOST_UBLAS_INLINE const_iterator1 (const self_type &mu, const const_subiterator1_type &it): container_const_reference
(mu), it_ (it) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (*it_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 begin () const { return (*this) ().find2 (1, index1 (), 0); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 end () const { return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rbegin () const { return const_reverse_iterator2 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rend () const { return const_reverse_iterator2 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it_.index2 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it_.index1 (); } // Assignment BOOST_UBLAS_INLINE const_iterator1 &operator = (const const_iterator1 &it) { container_const_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: const_subiterator1_type it_; }; #endif BOOST_UBLAS_INLINE const_iterator1 begin1 () const { return find1 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator1 end1 () const { return find1 (0, size1 (), 0); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator2: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E::const_iterator1::iterator_category iterator_category; typedef typename matrix_unary2::difference_type difference_type; typedef typename matrix_unary2::value_type value_type; typedef typename matrix_unary2::const_reference reference; typedef typename matrix_unary2::const_pointer pointer; typedef const_iterator1 dual_iterator_type; typedef const_reverse_iterator1 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator2 (): container_const_reference
(), it_ () {} BOOST_UBLAS_INLINE const_iterator2 (const self_type &mu, const const_subiterator2_type &it): container_const_reference
(mu), it_ (it) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { ++ it_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -- () { -- it_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator += (difference_type n) { it_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -= (difference_type n) { it_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ - it.it_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (*it_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 begin () const { return (*this) ().find1 (1, 0, index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 end () const { return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rbegin () const { return const_reverse_iterator1 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rend () const { return const_reverse_iterator1 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it_.index2 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it_.index1 (); } // Assignment BOOST_UBLAS_INLINE const_iterator2 &operator = (const const_iterator2 &it) { container_const_reference
::assign (&it ()); it_ = it.it_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ == it.it_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); return it_ < it.it_; } private: const_subiterator2_type it_; }; #endif BOOST_UBLAS_INLINE const_iterator2 begin2 () const { return find2 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator2 end2 () const { return find2 (0, 0, size2 ()); } // Reverse iterators BOOST_UBLAS_INLINE const_reverse_iterator1 rbegin1 () const { return const_reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator1 rend1 () const { return const_reverse_iterator1 (begin1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rbegin2 () const { return const_reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rend2 () const { return const_reverse_iterator2 (begin2 ()); } private: expression_closure_type e_; }; template
struct matrix_unary2_traits { typedef matrix_unary2
expression_type; #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else typedef typename E::matrix_temporary_type result_type; #endif }; // (trans m) [i] [j] = m [j] [i] template
BOOST_UBLAS_INLINE typename matrix_unary2_traits
>::result_type trans (const matrix_expression
&e) { typedef typename matrix_unary2_traits
>::expression_type expression_type; return expression_type (e ()); } template
BOOST_UBLAS_INLINE typename matrix_unary2_traits
>::result_type trans (matrix_expression
&e) { typedef typename matrix_unary2_traits
>::expression_type expression_type; return expression_type (e ()); } // (herm m) [i] [j] = conj (m [j] [i]) template
BOOST_UBLAS_INLINE typename matrix_unary2_traits
>::result_type herm (const matrix_expression
&e) { typedef typename matrix_unary2_traits
>::expression_type expression_type; return expression_type (e ()); } template
class matrix_binary: public matrix_expression
> { typedef E1 expression1_type; typedef E2 expression2_type; typedef F functor_type; public: typedef typename E1::const_closure_type expression1_closure_type; typedef typename E2::const_closure_type expression2_closure_type; private: typedef matrix_binary
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_expression
::operator (); #endif typedef typename promote_traits
::promote_type size_type; typedef typename promote_traits
::promote_type difference_type; typedef typename F::result_type value_type; typedef value_type const_reference; typedef const_reference reference; typedef const self_type const_closure_type; typedef const_closure_type closure_type; typedef unknown_orientation_tag orientation_category; typedef unknown_storage_tag storage_category; // Construction and destruction BOOST_UBLAS_INLINE matrix_binary (const E1 &e1, const E2 &e2): e1_ (e1), e2_ (e2) {} // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return BOOST_UBLAS_SAME (e1_.size1 (), e2_.size1 ()); } BOOST_UBLAS_INLINE size_type size2 () const { return BOOST_UBLAS_SAME (e1_.size2 (), e2_.size2 ()); } public: // Expression accessors BOOST_UBLAS_INLINE const expression1_closure_type &expression1 () const { return e1_; } BOOST_UBLAS_INLINE const expression2_closure_type &expression2 () const { return e2_; } public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return functor_type::apply (e1_ (i, j), e2_ (i, j)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_binary &mb) const { return (*this).expression1 ().same_closure (mb.expression1 ()) && (*this).expression2 ().same_closure (mb.expression2 ()); } // Iterator types private: typedef typename E1::const_iterator1 const_iterator11_type; typedef typename E1::const_iterator2 const_iterator12_type; typedef typename E2::const_iterator1 const_iterator21_type; typedef typename E2::const_iterator2 const_iterator22_type; typedef const value_type *const_pointer; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef typename iterator_restrict_traits
::iterator_category iterator_category1; typedef indexed_const_iterator1
const_iterator1; typedef const_iterator1 iterator1; typedef typename iterator_restrict_traits
::iterator_category iterator_category2; typedef indexed_const_iterator2
const_iterator2; typedef const_iterator2 iterator2; #else class const_iterator1; typedef const_iterator1 iterator1; class const_iterator2; typedef const_iterator2 iterator2; #endif typedef reverse_iterator_base1
const_reverse_iterator1; typedef reverse_iterator_base2
const_reverse_iterator2; // Element lookup BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { const_iterator11_type it11 (e1_.find1 (rank, i, j)); const_iterator11_type it11_end (e1_.find1 (rank, size1 (), j)); const_iterator21_type it21 (e2_.find1 (rank, i, j)); const_iterator21_type it21_end (e2_.find1 (rank, size1 (), j)); BOOST_UBLAS_CHECK (rank == 0 || it11 == it11_end || it11.index2 () == j, internal_logic ()) BOOST_UBLAS_CHECK (rank == 0 || it21 == it21_end || it21.index2 () == j, internal_logic ()) i = (std::min) (it11 != it11_end ? it11.index1 () : size1 (), it21 != it21_end ? it21.index1 () : size1 ()); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, i, j); #else return const_iterator1 (*this, i, j, it11, it11_end, it21, it21_end); #endif } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { const_iterator12_type it12 (e1_.find2 (rank, i, j)); const_iterator12_type it12_end (e1_.find2 (rank, i, size2 ())); const_iterator22_type it22 (e2_.find2 (rank, i, j)); const_iterator22_type it22_end (e2_.find2 (rank, i, size2 ())); BOOST_UBLAS_CHECK (rank == 0 || it12 == it12_end || it12.index1 () == i, internal_logic ()) BOOST_UBLAS_CHECK (rank == 0 || it22 == it22_end || it22.index1 () == i, internal_logic ()) j = (std::min) (it12 != it12_end ? it12.index2 () : size2 (), it22 != it22_end ? it22.index2 () : size2 ()); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, i, j); #else return const_iterator2 (*this, i, j, it12, it12_end, it22, it22_end); #endif } // Iterators enhance the iterators of the referenced expression // with the binary functor. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator1: public container_const_reference
, public iterator_base_traits
::iterator_category>::template iterator_base
::type { public: typedef typename iterator_restrict_traits
::iterator_category iterator_category; typedef typename matrix_binary::difference_type difference_type; typedef typename matrix_binary::value_type value_type; typedef typename matrix_binary::const_reference reference; typedef typename matrix_binary::const_pointer pointer; typedef const_iterator2 dual_iterator_type; typedef const_reverse_iterator2 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference
(), i_ (), j_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {} BOOST_UBLAS_INLINE const_iterator1 (const self_type &mb, size_type i, size_type j, const const_iterator11_type &it1, const const_iterator11_type &it1_end, const const_iterator21_type &it2, const const_iterator21_type &it2_end): container_const_reference
(mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {} private: // Dense specializations BOOST_UBLAS_INLINE void increment (dense_random_access_iterator_tag) { ++ i_; ++ it1_; ++ it2_; } BOOST_UBLAS_INLINE void decrement (dense_random_access_iterator_tag) { -- i_; -- it1_; -- it2_; } BOOST_UBLAS_INLINE void increment (dense_random_access_iterator_tag, difference_type n) { i_ += n; it1_ += n; it2_ += n; } BOOST_UBLAS_INLINE void decrement (dense_random_access_iterator_tag, difference_type n) { i_ -= n; it1_ -= n; it2_ -= n; } BOOST_UBLAS_INLINE value_type dereference (dense_random_access_iterator_tag) const { return functor_type::apply (*it1_, *it2_); } // Packed specializations BOOST_UBLAS_INLINE void increment (packed_random_access_iterator_tag) { if (it1_ != it1_end_) if (it1_.index1 () <= i_) ++ it1_; if (it2_ != it2_end_) if (it2_.index1 () <= i_) ++ it2_; ++ i_; } BOOST_UBLAS_INLINE void decrement (packed_random_access_iterator_tag) { if (it1_ != it1_end_) if (i_ <= it1_.index1 ()) -- it1_; if (it2_ != it2_end_) if (i_ <= it2_.index1 ()) -- it2_; -- i_; } BOOST_UBLAS_INLINE void increment (packed_random_access_iterator_tag, difference_type n) { while (n > 0) { increment (packed_random_access_iterator_tag ()); --n; } while (n < 0) { decrement (packed_random_access_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE void decrement (packed_random_access_iterator_tag, difference_type n) { while (n > 0) { decrement (packed_random_access_iterator_tag ()); --n; } while (n < 0) { increment (packed_random_access_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE value_type dereference (packed_random_access_iterator_tag) const { value_type t1 = value_type/*zero*/(); if (it1_ != it1_end_) { BOOST_UBLAS_CHECK (it1_.index2 () == j_, internal_logic ()); if (it1_.index1 () == i_) t1 = *it1_; } value_type t2 = value_type/*zero*/(); if (it2_ != it2_end_) { BOOST_UBLAS_CHECK (it2_.index2 () == j_, internal_logic ()); if (it2_.index1 () == i_) t2 = *it2_; } return functor_type::apply (t1, t2); } // Sparse specializations BOOST_UBLAS_INLINE void increment (sparse_bidirectional_iterator_tag) { size_type index1 = (*this) ().size1 (); if (it1_ != it1_end_) { if (it1_.index1 () <= i_) ++ it1_; if (it1_ != it1_end_) index1 = it1_.index1 (); } size_type index2 = (*this) ().size1 (); if (it2_ != it2_end_) if (it2_.index1 () <= i_) ++ it2_; if (it2_ != it2_end_) { index2 = it2_.index1 (); } i_ = (std::min) (index1, index2); } BOOST_UBLAS_INLINE void decrement (sparse_bidirectional_iterator_tag) { size_type index1 = (*this) ().size1 (); if (it1_ != it1_end_) { if (i_ <= it1_.index1 ()) -- it1_; if (it1_ != it1_end_) index1 = it1_.index1 (); } size_type index2 = (*this) ().size1 (); if (it2_ != it2_end_) { if (i_ <= it2_.index1 ()) -- it2_; if (it2_ != it2_end_) index2 = it2_.index1 (); } i_ = (std::max) (index1, index2); } BOOST_UBLAS_INLINE void increment (sparse_bidirectional_iterator_tag, difference_type n) { while (n > 0) { increment (sparse_bidirectional_iterator_tag ()); --n; } while (n < 0) { decrement (sparse_bidirectional_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE void decrement (sparse_bidirectional_iterator_tag, difference_type n) { while (n > 0) { decrement (sparse_bidirectional_iterator_tag ()); --n; } while (n < 0) { increment (sparse_bidirectional_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE value_type dereference (sparse_bidirectional_iterator_tag) const { value_type t1 = value_type/*zero*/(); if (it1_ != it1_end_) { BOOST_UBLAS_CHECK (it1_.index2 () == j_, internal_logic ()); if (it1_.index1 () == i_) t1 = *it1_; } value_type t2 = value_type/*zero*/(); if (it2_ != it2_end_) { BOOST_UBLAS_CHECK (it2_.index2 () == j_, internal_logic ()); if (it2_.index1 () == i_) t2 = *it2_; } return functor_type::apply (t1, t2); } public: // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { increment (iterator_category ()); return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -- () { decrement (iterator_category ()); return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator += (difference_type n) { increment (iterator_category (), n); return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -= (difference_type n) { decrement (iterator_category (), n); return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ()); return index1 () - it.index1 (); } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return dereference (iterator_category ()); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 begin () const { return (*this) ().find2 (1, index1 (), 0); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 end () const { return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rbegin () const { return const_reverse_iterator2 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rend () const { return const_reverse_iterator2 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return i_; } BOOST_UBLAS_INLINE size_type index2 () const { // if (it1_ != it1_end_ && it2_ != it2_end_) // return BOOST_UBLAS_SAME (it1_.index2 (), it2_.index2 ()); // else return j_; } // Assignment BOOST_UBLAS_INLINE const_iterator1 &operator = (const const_iterator1 &it) { container_const_reference
::assign (&it ()); i_ = it.i_; j_ = it.j_; it1_ = it.it1_; it1_end_ = it.it1_end_; it2_ = it.it2_; it2_end_ = it.it2_end_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ()); return index1 () == it.index1 (); } BOOST_UBLAS_INLINE bool operator < (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (index2 () == it.index2 (), external_logic ()); return index1 () < it.index1 (); } private: size_type i_; size_type j_; const_iterator11_type it1_; const_iterator11_type it1_end_; const_iterator21_type it2_; const_iterator21_type it2_end_; }; #endif BOOST_UBLAS_INLINE const_iterator1 begin1 () const { return find1 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator1 end1 () const { return find1 (0, size1 (), 0); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator2: public container_const_reference
, public iterator_base_traits
::iterator_category>::template iterator_base
::type { public: typedef typename iterator_restrict_traits
::iterator_category iterator_category; typedef typename matrix_binary::difference_type difference_type; typedef typename matrix_binary::value_type value_type; typedef typename matrix_binary::const_reference reference; typedef typename matrix_binary::const_pointer pointer; typedef const_iterator1 dual_iterator_type; typedef const_reverse_iterator1 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator2 (): container_const_reference
(), i_ (), j_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {} BOOST_UBLAS_INLINE const_iterator2 (const self_type &mb, size_type i, size_type j, const const_iterator12_type &it1, const const_iterator12_type &it1_end, const const_iterator22_type &it2, const const_iterator22_type &it2_end): container_const_reference
(mb), i_ (i), j_ (j), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {} private: // Dense access specializations BOOST_UBLAS_INLINE void increment (dense_random_access_iterator_tag) { ++ j_; ++ it1_; ++ it2_; } BOOST_UBLAS_INLINE void decrement (dense_random_access_iterator_tag) { -- j_; -- it1_; -- it2_; } BOOST_UBLAS_INLINE void increment (dense_random_access_iterator_tag, difference_type n) { j_ += n; it1_ += n; it2_ += n; } BOOST_UBLAS_INLINE void decrement (dense_random_access_iterator_tag, difference_type n) { j_ -= n; it1_ -= n; it2_ -= n; } BOOST_UBLAS_INLINE value_type dereference (dense_random_access_iterator_tag) const { return functor_type::apply (*it1_, *it2_); } // Packed specializations BOOST_UBLAS_INLINE void increment (packed_random_access_iterator_tag) { if (it1_ != it1_end_) if (it1_.index2 () <= j_) ++ it1_; if (it2_ != it2_end_) if (it2_.index2 () <= j_) ++ it2_; ++ j_; } BOOST_UBLAS_INLINE void decrement (packed_random_access_iterator_tag) { if (it1_ != it1_end_) if (j_ <= it1_.index2 ()) -- it1_; if (it2_ != it2_end_) if (j_ <= it2_.index2 ()) -- it2_; -- j_; } BOOST_UBLAS_INLINE void increment (packed_random_access_iterator_tag, difference_type n) { while (n > 0) { increment (packed_random_access_iterator_tag ()); --n; } while (n < 0) { decrement (packed_random_access_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE void decrement (packed_random_access_iterator_tag, difference_type n) { while (n > 0) { decrement (packed_random_access_iterator_tag ()); --n; } while (n < 0) { increment (packed_random_access_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE value_type dereference (packed_random_access_iterator_tag) const { value_type t1 = value_type/*zero*/(); if (it1_ != it1_end_) { BOOST_UBLAS_CHECK (it1_.index1 () == i_, internal_logic ()); if (it1_.index2 () == j_) t1 = *it1_; } value_type t2 = value_type/*zero*/(); if (it2_ != it2_end_) { BOOST_UBLAS_CHECK (it2_.index1 () == i_, internal_logic ()); if (it2_.index2 () == j_) t2 = *it2_; } return functor_type::apply (t1, t2); } // Sparse specializations BOOST_UBLAS_INLINE void increment (sparse_bidirectional_iterator_tag) { size_type index1 = (*this) ().size2 (); if (it1_ != it1_end_) { if (it1_.index2 () <= j_) ++ it1_; if (it1_ != it1_end_) index1 = it1_.index2 (); } size_type index2 = (*this) ().size2 (); if (it2_ != it2_end_) { if (it2_.index2 () <= j_) ++ it2_; if (it2_ != it2_end_) index2 = it2_.index2 (); } j_ = (std::min) (index1, index2); } BOOST_UBLAS_INLINE void decrement (sparse_bidirectional_iterator_tag) { size_type index1 = (*this) ().size2 (); if (it1_ != it1_end_) { if (j_ <= it1_.index2 ()) -- it1_; if (it1_ != it1_end_) index1 = it1_.index2 (); } size_type index2 = (*this) ().size2 (); if (it2_ != it2_end_) { if (j_ <= it2_.index2 ()) -- it2_; if (it2_ != it2_end_) index2 = it2_.index2 (); } j_ = (std::max) (index1, index2); } BOOST_UBLAS_INLINE void increment (sparse_bidirectional_iterator_tag, difference_type n) { while (n > 0) { increment (sparse_bidirectional_iterator_tag ()); --n; } while (n < 0) { decrement (sparse_bidirectional_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE void decrement (sparse_bidirectional_iterator_tag, difference_type n) { while (n > 0) { decrement (sparse_bidirectional_iterator_tag ()); --n; } while (n < 0) { increment (sparse_bidirectional_iterator_tag ()); ++n; } } BOOST_UBLAS_INLINE value_type dereference (sparse_bidirectional_iterator_tag) const { value_type t1 = value_type/*zero*/(); if (it1_ != it1_end_) { BOOST_UBLAS_CHECK (it1_.index1 () == i_, internal_logic ()); if (it1_.index2 () == j_) t1 = *it1_; } value_type t2 = value_type/*zero*/(); if (it2_ != it2_end_) { BOOST_UBLAS_CHECK (it2_.index1 () == i_, internal_logic ()); if (it2_.index2 () == j_) t2 = *it2_; } return functor_type::apply (t1, t2); } public: // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { increment (iterator_category ()); return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -- () { decrement (iterator_category ()); return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator += (difference_type n) { increment (iterator_category (), n); return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -= (difference_type n) { decrement (iterator_category (), n); return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ()); return index2 () - it.index2 (); } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return dereference (iterator_category ()); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 begin () const { return (*this) ().find1 (1, 0, index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 end () const { return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rbegin () const { return const_reverse_iterator1 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rend () const { return const_reverse_iterator1 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { // if (it1_ != it1_end_ && it2_ != it2_end_) // return BOOST_UBLAS_SAME (it1_.index1 (), it2_.index1 ()); // else return i_; } BOOST_UBLAS_INLINE size_type index2 () const { return j_; } // Assignment BOOST_UBLAS_INLINE const_iterator2 &operator = (const const_iterator2 &it) { container_const_reference
::assign (&it ()); i_ = it.i_; j_ = it.j_; it1_ = it.it1_; it1_end_ = it.it1_end_; it2_ = it.it2_; it2_end_ = it.it2_end_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ()); return index2 () == it.index2 (); } BOOST_UBLAS_INLINE bool operator < (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); BOOST_UBLAS_CHECK (index1 () == it.index1 (), external_logic ()); return index2 () < it.index2 (); } private: size_type i_; size_type j_; const_iterator12_type it1_; const_iterator12_type it1_end_; const_iterator22_type it2_; const_iterator22_type it2_end_; }; #endif BOOST_UBLAS_INLINE const_iterator2 begin2 () const { return find2 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator2 end2 () const { return find2 (0, 0, size2 ()); } // Reverse iterators BOOST_UBLAS_INLINE const_reverse_iterator1 rbegin1 () const { return const_reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator1 rend1 () const { return const_reverse_iterator1 (begin1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rbegin2 () const { return const_reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rend2 () const { return const_reverse_iterator2 (begin2 ()); } private: expression1_closure_type e1_; expression2_closure_type e2_; }; template
struct matrix_binary_traits { typedef matrix_binary
expression_type; #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else typedef typename E1::matrix_temporary_type result_type; #endif }; // (m1 + m2) [i] [j] = m1 [i] [j] + m2 [i] [j] template
BOOST_UBLAS_INLINE typename matrix_binary_traits
>::result_type operator + (const matrix_expression
&e1, const matrix_expression
&e2) { typedef typename matrix_binary_traits
>::expression_type expression_type; return expression_type (e1 (), e2 ()); } // (m1 - m2) [i] [j] = m1 [i] [j] - m2 [i] [j] template
BOOST_UBLAS_INLINE typename matrix_binary_traits
>::result_type operator - (const matrix_expression
&e1, const matrix_expression
&e2) { typedef typename matrix_binary_traits
>::expression_type expression_type; return expression_type (e1 (), e2 ()); } // (m1 * m2) [i] [j] = m1 [i] [j] * m2 [i] [j] template
BOOST_UBLAS_INLINE typename matrix_binary_traits
>::result_type element_prod (const matrix_expression
&e1, const matrix_expression
&e2) { typedef typename matrix_binary_traits
>::expression_type expression_type; return expression_type (e1 (), e2 ()); } // (m1 / m2) [i] [j] = m1 [i] [j] / m2 [i] [j] template
BOOST_UBLAS_INLINE typename matrix_binary_traits
>::result_type element_div (const matrix_expression
&e1, const matrix_expression
&e2) { typedef typename matrix_binary_traits
>::expression_type expression_type; return expression_type (e1 (), e2 ()); } template
class matrix_binary_scalar1: public matrix_expression
> { typedef E1 expression1_type; typedef E2 expression2_type; typedef F functor_type; typedef const E1& expression1_closure_type; typedef typename E2::const_closure_type expression2_closure_type; typedef matrix_binary_scalar1
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_expression
::operator (); #endif typedef typename E2::size_type size_type; typedef typename E2::difference_type difference_type; typedef typename F::result_type value_type; typedef value_type const_reference; typedef const_reference reference; typedef const self_type const_closure_type; typedef const_closure_type closure_type; typedef typename E2::orientation_category orientation_category; typedef unknown_storage_tag storage_category; // Construction and destruction BOOST_UBLAS_INLINE matrix_binary_scalar1 (const expression1_type &e1, const expression2_type &e2): e1_ (e1), e2_ (e2) {} // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return e2_.size1 (); } BOOST_UBLAS_INLINE size_type size2 () const { return e2_.size2 (); } public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return functor_type::apply (expression1_type (e1_), e2_ (i, j)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_binary_scalar1 &mbs1) const { return &e1_ == &(mbs1.e1_) && (*this).e2_.same_closure (mbs1.e2_); } // Iterator types private: typedef expression1_type const_subiterator1_type; typedef typename E2::const_iterator1 const_iterator21_type; typedef typename E2::const_iterator2 const_iterator22_type; typedef const value_type *const_pointer; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef indexed_const_iterator1
const_iterator1; typedef const_iterator1 iterator1; typedef indexed_const_iterator2
const_iterator2; typedef const_iterator2 iterator2; #else class const_iterator1; typedef const_iterator1 iterator1; class const_iterator2; typedef const_iterator2 iterator2; #endif typedef reverse_iterator_base1
const_reverse_iterator1; typedef reverse_iterator_base2
const_reverse_iterator2; // Element lookup BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { const_iterator21_type it21 (e2_.find1 (rank, i, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, it21.index1 (), it21.index2 ()); #else return const_iterator1 (*this, const_subiterator1_type (e1_), it21); #endif } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { const_iterator22_type it22 (e2_.find2 (rank, i, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, it22.index1 (), it22.index2 ()); #else return const_iterator2 (*this, const_subiterator1_type (e1_), it22); #endif } // Iterators enhance the iterators of the referenced expression // with the binary functor. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator1: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E2::const_iterator1::iterator_category iterator_category; typedef typename matrix_binary_scalar1::difference_type difference_type; typedef typename matrix_binary_scalar1::value_type value_type; typedef typename matrix_binary_scalar1::const_reference reference; typedef typename matrix_binary_scalar1::const_pointer pointer; typedef const_iterator2 dual_iterator_type; typedef const_reverse_iterator2 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator1 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator21_type &it2): container_const_reference
(mbs), it1_ (it1), it2_ (it2) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { ++ it2_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -- () { -- it2_ ; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator += (difference_type n) { it2_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -= (difference_type n) { it2_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ - it.it2_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (it1_, *it2_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 begin () const { return (*this) ().find2 (1, index1 (), 0); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 end () const { return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rbegin () const { return const_reverse_iterator2 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rend () const { return const_reverse_iterator2 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it2_.index1 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it2_.index2 (); } // Assignment BOOST_UBLAS_INLINE const_iterator1 &operator = (const const_iterator1 &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ == it.it2_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ < it.it2_; } private: const_subiterator1_type it1_; const_iterator21_type it2_; }; #endif BOOST_UBLAS_INLINE const_iterator1 begin1 () const { return find1 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator1 end1 () const { return find1 (0, size1 (), 0); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator2: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E2::const_iterator2::iterator_category iterator_category; typedef typename matrix_binary_scalar1::difference_type difference_type; typedef typename matrix_binary_scalar1::value_type value_type; typedef typename matrix_binary_scalar1::const_reference reference; typedef typename matrix_binary_scalar1::const_pointer pointer; typedef const_iterator1 dual_iterator_type; typedef const_reverse_iterator1 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator2 (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator2 (const self_type &mbs, const const_subiterator1_type &it1, const const_iterator22_type &it2): container_const_reference
(mbs), it1_ (it1), it2_ (it2) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { ++ it2_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -- () { -- it2_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator += (difference_type n) { it2_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -= (difference_type n) { it2_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ - it.it2_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (it1_, *it2_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 begin () const { return (*this) ().find1 (1, 0, index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 end () const { return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rbegin () const { return const_reverse_iterator1 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rend () const { return const_reverse_iterator1 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it2_.index1 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it2_.index2 (); } // Assignment BOOST_UBLAS_INLINE const_iterator2 &operator = (const const_iterator2 &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ == it.it2_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ()); return it2_ < it.it2_; } private: const_subiterator1_type it1_; const_iterator22_type it2_; }; #endif BOOST_UBLAS_INLINE const_iterator2 begin2 () const { return find2 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator2 end2 () const { return find2 (0, 0, size2 ()); } // Reverse iterators BOOST_UBLAS_INLINE const_reverse_iterator1 rbegin1 () const { return const_reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator1 rend1 () const { return const_reverse_iterator1 (begin1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rbegin2 () const { return const_reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rend2 () const { return const_reverse_iterator2 (begin2 ()); } private: expression1_closure_type e1_; expression2_closure_type e2_; }; template
struct matrix_binary_scalar1_traits { typedef matrix_binary_scalar1
expression_type; // allow E1 to be builtin type #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else typedef typename E2::matrix_temporary_type result_type; #endif }; // (t * m) [i] [j] = t * m [i] [j] template
BOOST_UBLAS_INLINE typename matrix_binary_scalar1_traits
>::result_type operator * (const T1 &e1, const matrix_expression
&e2) { typedef typename matrix_binary_scalar1_traits
>::expression_type expression_type; return expression_type (e1, e2 ()); } template
class matrix_binary_scalar2: public matrix_expression
> { typedef E1 expression1_type; typedef E2 expression2_type; typedef F functor_type; public: typedef typename E1::const_closure_type expression1_closure_type; typedef const E2& expression2_closure_type; private: typedef matrix_binary_scalar2
self_type; public: #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS using matrix_expression
::operator (); #endif typedef typename E1::size_type size_type; typedef typename E1::difference_type difference_type; typedef typename F::result_type value_type; typedef value_type const_reference; typedef const_reference reference; typedef const self_type const_closure_type; typedef const_closure_type closure_type; typedef typename E1::orientation_category orientation_category; typedef unknown_storage_tag storage_category; // Construction and destruction BOOST_UBLAS_INLINE matrix_binary_scalar2 (const expression1_type &e1, const expression2_type &e2): e1_ (e1), e2_ (e2) {} // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return e1_.size1 (); } BOOST_UBLAS_INLINE size_type size2 () const { return e1_.size2 (); } public: // Element access BOOST_UBLAS_INLINE const_reference operator () (size_type i, size_type j) const { return functor_type::apply (e1_ (i, j), expression2_type (e2_)); } // Closure comparison BOOST_UBLAS_INLINE bool same_closure (const matrix_binary_scalar2 &mbs2) const { return (*this).e1_.same_closure (mbs2.e1_) && &e2_ == &(mbs2.e2_); } // Iterator types private: typedef typename E1::const_iterator1 const_iterator11_type; typedef typename E1::const_iterator2 const_iterator12_type; typedef expression2_type const_subiterator2_type; typedef const value_type *const_pointer; public: #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR typedef indexed_const_iterator1
const_iterator1; typedef const_iterator1 iterator1; typedef indexed_const_iterator2
const_iterator2; typedef const_iterator2 iterator2; #else class const_iterator1; typedef const_iterator1 iterator1; class const_iterator2; typedef const_iterator2 iterator2; #endif typedef reverse_iterator_base1
const_reverse_iterator1; typedef reverse_iterator_base2
const_reverse_iterator2; // Element lookup BOOST_UBLAS_INLINE const_iterator1 find1 (int rank, size_type i, size_type j) const { const_iterator11_type it11 (e1_.find1 (rank, i, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator1 (*this, it11.index1 (), it11.index2 ()); #else return const_iterator1 (*this, it11, const_subiterator2_type (e2_)); #endif } BOOST_UBLAS_INLINE const_iterator2 find2 (int rank, size_type i, size_type j) const { const_iterator12_type it12 (e1_.find2 (rank, i, j)); #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR return const_iterator2 (*this, it12.index1 (), it12.index2 ()); #else return const_iterator2 (*this, it12, const_subiterator2_type (e2_)); #endif } // Iterators enhance the iterators of the referenced expression // with the binary functor. #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator1: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E1::const_iterator1::iterator_category iterator_category; typedef typename matrix_binary_scalar2::difference_type difference_type; typedef typename matrix_binary_scalar2::value_type value_type; typedef typename matrix_binary_scalar2::const_reference reference; typedef typename matrix_binary_scalar2::const_pointer pointer; typedef const_iterator2 dual_iterator_type; typedef const_reverse_iterator2 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator1 (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator1 (const self_type &mbs, const const_iterator11_type &it1, const const_subiterator2_type &it2): container_const_reference
(mbs), it1_ (it1), it2_ (it2) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator1 &operator ++ () { ++ it1_; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -- () { -- it1_ ; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator += (difference_type n) { it1_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator1 &operator -= (difference_type n) { it1_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ - it.it1_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (*it1_, it2_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 begin () const { return (*this) ().find2 (1, index1 (), 0); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator2 end () const { return (*this) ().find2 (1, index1 (), (*this) ().size2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rbegin () const { return const_reverse_iterator2 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator2 rend () const { return const_reverse_iterator2 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it1_.index1 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it1_.index2 (); } // Assignment BOOST_UBLAS_INLINE const_iterator1 &operator = (const const_iterator1 &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ == it.it1_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator1 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ < it.it1_; } private: const_iterator11_type it1_; const_subiterator2_type it2_; }; #endif BOOST_UBLAS_INLINE const_iterator1 begin1 () const { return find1 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator1 end1 () const { return find1 (0, size1 (), 0); } #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR class const_iterator2: public container_const_reference
, public iterator_base_traits
::template iterator_base
::type { public: typedef typename E1::const_iterator2::iterator_category iterator_category; typedef typename matrix_binary_scalar2::difference_type difference_type; typedef typename matrix_binary_scalar2::value_type value_type; typedef typename matrix_binary_scalar2::const_reference reference; typedef typename matrix_binary_scalar2::const_pointer pointer; typedef const_iterator1 dual_iterator_type; typedef const_reverse_iterator1 dual_reverse_iterator_type; // Construction and destruction BOOST_UBLAS_INLINE const_iterator2 (): container_const_reference
(), it1_ (), it2_ () {} BOOST_UBLAS_INLINE const_iterator2 (const self_type &mbs, const const_iterator12_type &it1, const const_subiterator2_type &it2): container_const_reference
(mbs), it1_ (it1), it2_ (it2) {} // Arithmetic BOOST_UBLAS_INLINE const_iterator2 &operator ++ () { ++ it1_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -- () { -- it1_; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator += (difference_type n) { it1_ += n; return *this; } BOOST_UBLAS_INLINE const_iterator2 &operator -= (difference_type n) { it1_ -= n; return *this; } BOOST_UBLAS_INLINE difference_type operator - (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ - it.it1_; } // Dereference BOOST_UBLAS_INLINE const_reference operator * () const { return functor_type::apply (*it1_, it2_); } BOOST_UBLAS_INLINE const_reference operator [] (difference_type n) const { return *(*this + n); } #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 begin () const { return (*this) ().find1 (1, 0, index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_iterator1 end () const { return (*this) ().find1 (1, (*this) ().size1 (), index2 ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rbegin () const { return const_reverse_iterator1 (end ()); } BOOST_UBLAS_INLINE #ifdef BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION typename self_type:: #endif const_reverse_iterator1 rend () const { return const_reverse_iterator1 (begin ()); } #endif // Indices BOOST_UBLAS_INLINE size_type index1 () const { return it1_.index1 (); } BOOST_UBLAS_INLINE size_type index2 () const { return it1_.index2 (); } // Assignment BOOST_UBLAS_INLINE const_iterator2 &operator = (const const_iterator2 &it) { container_const_reference
::assign (&it ()); it1_ = it.it1_; it2_ = it.it2_; return *this; } // Comparison BOOST_UBLAS_INLINE bool operator == (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ == it.it1_; } BOOST_UBLAS_INLINE bool operator < (const const_iterator2 &it) const { BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ()); // FIXME we shouldn't compare floats // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ()); return it1_ < it.it1_; } private: const_iterator12_type it1_; const_subiterator2_type it2_; }; #endif BOOST_UBLAS_INLINE const_iterator2 begin2 () const { return find2 (0, 0, 0); } BOOST_UBLAS_INLINE const_iterator2 end2 () const { return find2 (0, 0, size2 ()); } // Reverse iterators BOOST_UBLAS_INLINE const_reverse_iterator1 rbegin1 () const { return const_reverse_iterator1 (end1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator1 rend1 () const { return const_reverse_iterator1 (begin1 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rbegin2 () const { return const_reverse_iterator2 (end2 ()); } BOOST_UBLAS_INLINE const_reverse_iterator2 rend2 () const { return const_reverse_iterator2 (begin2 ()); } private: expression1_closure_type e1_; expression2_closure_type e2_; }; template
struct matrix_binary_scalar2_traits { typedef matrix_binary_scalar2
expression_type; // allow E2 to be builtin type #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG typedef expression_type result_type; #else typedef typename E1::matrix_temporary_type result_type; #endif }; // (m * t) [i] [j] = m [i] [j] * t template
BOOST_UBLAS_INLINE typename matrix_binary_scalar2_traits
>::result_type operator * (const matrix_expression
&e1, const T2 &e2) { typedef typename matrix_binary_scalar2_traits
>::expression_type expression_type; return expression_type (e1 (), e2); } // (m / t) [i] [j] = m [i] [j] / t template
BOOST_UBLAS_INLINE typename matrix_binary_scalar2_traits
>::result_type operator / (const matrix_expression
&e1, const T2 &e2) { typedef typename matrix_binary_scalar2_traits
>::expression_type expression_type; return expression_type (e1 (), e2); } template