x
Yes
No
Do you want to visit DriveHQ English website?
首页
产品服务
价格
免费试用
下载客户端
关于我们
云文件服务
|
云备份服务
|
FTP服务
|
企业邮箱服务
|
网站托管
|
客户端软件
云文件服务
云备份服务
FTP服务
企业级邮箱服务
网站托管
客户端软件
matrix_expression.hpp - Hosted on DriveHQ Cloud IT Platform
返回上层目录
上传
下载
共享
发布
新建文件夹
新建文件
复制
剪切
删除
粘贴
评论
升级服务
路径: \\game3dprogramming\materials\GameFactory\GameFactoryDemo\references\boost_1_35_0\boost\numeric\ublas\matrix_expression.hpp
旋转
特效
属性
历史版本
// // 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