00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _BOOST_UBLAS_VECTOR_EXPRESSION_
00014 #define _BOOST_UBLAS_VECTOR_EXPRESSION_
00015
00016 #include <boost/numeric/ublas/expression_types.hpp>
00017
00018
00019
00020
00021
00022
00023
00024 namespace boost { namespace numeric { namespace ublas {
00025
00026 template<class E>
00027 class vector_reference:
00028 public vector_expression<vector_reference<E> > {
00029
00030 typedef vector_reference<E> self_type;
00031 public:
00032 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00033 using vector_expression<vector_reference<E> >::operator ();
00034 #endif
00035 typedef typename E::size_type size_type;
00036 typedef typename E::difference_type difference_type;
00037 typedef typename E::value_type value_type;
00038 typedef typename E::const_reference const_reference;
00039 typedef typename boost::mpl::if_<boost::is_const<E>,
00040 typename E::const_reference,
00041 typename E::reference>::type reference;
00042 typedef E referred_type;
00043 typedef const self_type const_closure_type;
00044 typedef self_type closure_type;
00045 typedef typename E::storage_category storage_category;
00046
00047
00048 BOOST_UBLAS_INLINE
00049 explicit vector_reference (referred_type &e):
00050 e_ (e) {}
00051
00052
00053 BOOST_UBLAS_INLINE
00054 size_type size () const {
00055 return expression ().size ();
00056 }
00057
00058 public:
00059
00060 BOOST_UBLAS_INLINE
00061 const referred_type &expression () const {
00062 return e_;
00063 }
00064 BOOST_UBLAS_INLINE
00065 referred_type &expression () {
00066 return e_;
00067 }
00068
00069 public:
00070
00071 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
00072 BOOST_UBLAS_INLINE
00073 const_reference operator () (size_type i) const {
00074 return expression () (i);
00075 }
00076 BOOST_UBLAS_INLINE
00077 reference operator () (size_type i) {
00078 return expression () (i);
00079 }
00080
00081 BOOST_UBLAS_INLINE
00082 const_reference operator [] (size_type i) const {
00083 return expression () [i];
00084 }
00085 BOOST_UBLAS_INLINE
00086 reference operator [] (size_type i) {
00087 return expression () [i];
00088 }
00089 #else
00090 BOOST_UBLAS_INLINE
00091 reference operator () (size_type i) const {
00092 return expression () (i);
00093 }
00094
00095 BOOST_UBLAS_INLINE
00096 reference operator [] (size_type i) const {
00097 return expression () [i];
00098 }
00099 #endif
00100
00101
00102 BOOST_UBLAS_INLINE
00103 vector_reference &operator = (const vector_reference &v) {
00104 expression ().operator = (v);
00105 return *this;
00106 }
00107 template<class AE>
00108 BOOST_UBLAS_INLINE
00109 vector_reference &operator = (const vector_expression<AE> &ae) {
00110 expression ().operator = (ae);
00111 return *this;
00112 }
00113 template<class AE>
00114 BOOST_UBLAS_INLINE
00115 vector_reference &assign (const vector_expression<AE> &ae) {
00116 expression ().assign (ae);
00117 return *this;
00118 }
00119 template<class AE>
00120 BOOST_UBLAS_INLINE
00121 vector_reference &operator += (const vector_expression<AE> &ae) {
00122 expression ().operator += (ae);
00123 return *this;
00124 }
00125 template<class AE>
00126 BOOST_UBLAS_INLINE
00127 vector_reference &plus_assign (const vector_expression<AE> &ae) {
00128 expression ().plus_assign (ae);
00129 return *this;
00130 }
00131 template<class AE>
00132 BOOST_UBLAS_INLINE
00133 vector_reference &operator -= (const vector_expression<AE> &ae) {
00134 expression ().operator -= (ae);
00135 return *this;
00136 }
00137 template<class AE>
00138 BOOST_UBLAS_INLINE
00139 vector_reference &minus_assign (const vector_expression<AE> &ae) {
00140 expression ().minus_assign (ae);
00141 return *this;
00142 }
00143 template<class AT>
00144 BOOST_UBLAS_INLINE
00145 vector_reference &operator *= (const AT &at) {
00146 expression ().operator *= (at);
00147 return *this;
00148 }
00149 template<class AT>
00150 BOOST_UBLAS_INLINE
00151 vector_reference &operator /= (const AT &at) {
00152 expression ().operator /= (at);
00153 return *this;
00154 }
00155
00156
00157 BOOST_UBLAS_INLINE
00158 void swap (vector_reference &v) {
00159 expression ().swap (v.expression ());
00160 }
00161
00162
00163 BOOST_UBLAS_INLINE
00164 bool same_closure (const vector_reference &vr) const {
00165 return &(*this).e_ == &vr.e_;
00166 }
00167
00168
00169 typedef typename E::const_iterator const_iterator;
00170 typedef typename boost::mpl::if_<boost::is_const<E>,
00171 typename E::const_iterator,
00172 typename E::iterator>::type iterator;
00173
00174
00175 BOOST_UBLAS_INLINE
00176 const_iterator find (size_type i) const {
00177 return expression ().find (i);
00178 }
00179 BOOST_UBLAS_INLINE
00180 iterator find (size_type i) {
00181 return expression ().find (i);
00182 }
00183
00184
00185
00186 BOOST_UBLAS_INLINE
00187 const_iterator begin () const {
00188 return expression ().begin ();
00189 }
00190 BOOST_UBLAS_INLINE
00191 const_iterator end () const {
00192 return expression ().end ();
00193 }
00194
00195 BOOST_UBLAS_INLINE
00196 iterator begin () {
00197 return expression ().begin ();
00198 }
00199 BOOST_UBLAS_INLINE
00200 iterator end () {
00201 return expression ().end ();
00202 }
00203
00204
00205 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
00206 typedef reverse_iterator_base<iterator> reverse_iterator;
00207
00208 BOOST_UBLAS_INLINE
00209 const_reverse_iterator rbegin () const {
00210 return const_reverse_iterator (end ());
00211 }
00212 BOOST_UBLAS_INLINE
00213 const_reverse_iterator rend () const {
00214 return const_reverse_iterator (begin ());
00215 }
00216 BOOST_UBLAS_INLINE
00217 reverse_iterator rbegin () {
00218 return reverse_iterator (end ());
00219 }
00220 BOOST_UBLAS_INLINE
00221 reverse_iterator rend () {
00222 return reverse_iterator (begin ());
00223 }
00224
00225 private:
00226 referred_type &e_;
00227 };
00228
00229
00230 template<class E, class F>
00231 class vector_unary:
00232 public vector_expression<vector_unary<E, F> > {
00233
00234 typedef F functor_type;
00235 typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<typename E::value_type> >,
00236 E,
00237 const E>::type expression_type;
00238 typedef typename boost::mpl::if_<boost::is_const<expression_type>,
00239 typename E::const_closure_type,
00240 typename E::closure_type>::type expression_closure_type;
00241 typedef vector_unary<E, F> self_type;
00242 public:
00243 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00244 using vector_expression<vector_unary<E, F> >::operator ();
00245 #endif
00246 typedef typename E::size_type size_type;
00247 typedef typename E::difference_type difference_type;
00248 typedef typename F::result_type value_type;
00249 typedef value_type const_reference;
00250 typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<value_type> >,
00251 typename E::reference,
00252 value_type>::type reference;
00253 typedef const self_type const_closure_type;
00254 typedef self_type closure_type;
00255 typedef unknown_storage_tag storage_category;
00256
00257
00258 BOOST_UBLAS_INLINE
00259
00260 explicit vector_unary (expression_type &e):
00261 e_ (e) {}
00262
00263
00264 BOOST_UBLAS_INLINE
00265 size_type size () const {
00266 return e_.size ();
00267 }
00268
00269 public:
00270
00271 BOOST_UBLAS_INLINE
00272 const expression_closure_type &expression () const {
00273 return e_;
00274 }
00275
00276 public:
00277
00278 BOOST_UBLAS_INLINE
00279 const_reference operator () (size_type i) const {
00280 return functor_type::apply (e_ (i));
00281 }
00282 BOOST_UBLAS_INLINE
00283 reference operator () (size_type i) {
00284 BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
00285 return e_ (i);
00286 }
00287
00288 BOOST_UBLAS_INLINE
00289 const_reference operator [] (size_type i) const {
00290 return functor_type::apply (e_ [i]);
00291 }
00292 BOOST_UBLAS_INLINE
00293 reference operator [] (size_type i) {
00294 BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
00295 return e_ [i];
00296 }
00297
00298
00299 BOOST_UBLAS_INLINE
00300 bool same_closure (const vector_unary &vu) const {
00301 return (*this).expression ().same_closure (vu.expression ());
00302 }
00303
00304
00305 private:
00306 typedef typename E::const_iterator const_subiterator_type;
00307 typedef const value_type *const_pointer;
00308
00309 public:
00310 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00311 typedef indexed_const_iterator<const_closure_type, typename const_subiterator_type::iterator_category> const_iterator;
00312 typedef const_iterator iterator;
00313 #else
00314 class const_iterator;
00315 typedef const_iterator iterator;
00316 #endif
00317
00318
00319 BOOST_UBLAS_INLINE
00320 const_iterator find (size_type i) const {
00321 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00322 const_subiterator_type it (e_.find (i));
00323 return const_iterator (*this, it.index ());
00324 #else
00325 return const_iterator (*this, e_.find (i));
00326 #endif
00327 }
00328
00329
00330
00331
00332 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00333 class const_iterator:
00334 public container_const_reference<vector_unary>,
00335 public iterator_base_traits<typename E::const_iterator::iterator_category>::template
00336 iterator_base<const_iterator, value_type>::type {
00337 public:
00338 typedef typename E::const_iterator::iterator_category iterator_category;
00339 typedef typename vector_unary::difference_type difference_type;
00340 typedef typename vector_unary::value_type value_type;
00341 typedef typename vector_unary::const_reference reference;
00342 typedef typename vector_unary::const_pointer pointer;
00343
00344
00345 BOOST_UBLAS_INLINE
00346 const_iterator ():
00347 container_const_reference<self_type> (), it_ () {}
00348 BOOST_UBLAS_INLINE
00349 const_iterator (const self_type &vu, const const_subiterator_type &it):
00350 container_const_reference<self_type> (vu), it_ (it) {}
00351
00352
00353 BOOST_UBLAS_INLINE
00354 const_iterator &operator ++ () {
00355 ++ it_;
00356 return *this;
00357 }
00358 BOOST_UBLAS_INLINE
00359 const_iterator &operator -- () {
00360 -- it_;
00361 return *this;
00362 }
00363 BOOST_UBLAS_INLINE
00364 const_iterator &operator += (difference_type n) {
00365 it_ += n;
00366 return *this;
00367 }
00368 BOOST_UBLAS_INLINE
00369 const_iterator &operator -= (difference_type n) {
00370 it_ -= n;
00371 return *this;
00372 }
00373 BOOST_UBLAS_INLINE
00374 difference_type operator - (const const_iterator &it) const {
00375 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00376 return it_ - it.it_;
00377 }
00378
00379
00380 BOOST_UBLAS_INLINE
00381 const_reference operator * () const {
00382 return functor_type::apply (*it_);
00383 }
00384 BOOST_UBLAS_INLINE
00385 const_reference operator [] (difference_type n) const {
00386 return *(*this + n);
00387 }
00388
00389
00390 BOOST_UBLAS_INLINE
00391 size_type index () const {
00392 return it_.index ();
00393 }
00394
00395
00396 BOOST_UBLAS_INLINE
00397 const_iterator &operator = (const const_iterator &it) {
00398 container_const_reference<self_type>::assign (&it ());
00399 it_ = it.it_;
00400 return *this;
00401 }
00402
00403
00404 BOOST_UBLAS_INLINE
00405 bool operator == (const const_iterator &it) const {
00406 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00407 return it_ == it.it_;
00408 }
00409 BOOST_UBLAS_INLINE
00410 bool operator < (const const_iterator &it) const {
00411 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00412 return it_ < it.it_;
00413 }
00414
00415 private:
00416 const_subiterator_type it_;
00417 };
00418 #endif
00419
00420 BOOST_UBLAS_INLINE
00421 const_iterator begin () const {
00422 return find (0);
00423 }
00424 BOOST_UBLAS_INLINE
00425 const_iterator end () const {
00426 return find (size ());
00427 }
00428
00429
00430 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
00431
00432 BOOST_UBLAS_INLINE
00433 const_reverse_iterator rbegin () const {
00434 return const_reverse_iterator (end ());
00435 }
00436 BOOST_UBLAS_INLINE
00437 const_reverse_iterator rend () const {
00438 return const_reverse_iterator (begin ());
00439 }
00440
00441 private:
00442 expression_closure_type e_;
00443 };
00444
00445 template<class E, class F>
00446 struct vector_unary_traits {
00447 typedef vector_unary<E, F> expression_type;
00448
00449
00450 typedef expression_type result_type;
00451
00452
00453
00454 };
00455
00456
00457 template<class E>
00458 BOOST_UBLAS_INLINE
00459 typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::result_type
00460 operator - (const vector_expression<E> &e) {
00461 typedef typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::expression_type expression_type;
00462 return expression_type (e ());
00463 }
00464
00465
00466 template<class E>
00467 BOOST_UBLAS_INLINE
00468 typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
00469 conj (const vector_expression<E> &e) {
00470 typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
00471 return expression_type (e ());
00472 }
00473
00474
00475 template<class E>
00476 BOOST_UBLAS_INLINE
00477 typename vector_unary_traits<E, scalar_real<typename E::value_type> >::result_type
00478 real (const vector_expression<E> &e) {
00479 typedef typename vector_unary_traits<E, scalar_real<typename E::value_type> >::expression_type expression_type;
00480 return expression_type (e ());
00481 }
00482
00483
00484 template<class E>
00485 BOOST_UBLAS_INLINE
00486 typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::result_type
00487 imag (const vector_expression<E> &e) {
00488 typedef typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::expression_type expression_type;
00489 return expression_type (e ());
00490 }
00491
00492
00493 template<class E>
00494 BOOST_UBLAS_INLINE
00495 typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::result_type
00496 trans (const vector_expression<E> &e) {
00497 typedef typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::expression_type expression_type;
00498 return expression_type (e ());
00499 }
00500 template<class E>
00501 BOOST_UBLAS_INLINE
00502 typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::result_type
00503 trans (vector_expression<E> &e) {
00504 typedef typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::expression_type expression_type;
00505 return expression_type (e ());
00506 }
00507
00508
00509 template<class E>
00510 BOOST_UBLAS_INLINE
00511 typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
00512 herm (const vector_expression<E> &e) {
00513 typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
00514 return expression_type (e ());
00515 }
00516
00517 template<class E1, class E2, class F>
00518 class vector_binary:
00519 public vector_expression<vector_binary<E1, E2, F> > {
00520
00521 typedef E1 expression1_type;
00522 typedef E2 expression2_type;
00523 typedef F functor_type;
00524 typedef typename E1::const_closure_type expression1_closure_type;
00525 typedef typename E2::const_closure_type expression2_closure_type;
00526 typedef vector_binary<E1, E2, F> self_type;
00527 public:
00528 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00529 using vector_expression<vector_binary<E1, E2, F> >::operator ();
00530 #endif
00531 typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
00532 typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
00533 typedef typename F::result_type value_type;
00534 typedef value_type const_reference;
00535 typedef const_reference reference;
00536 typedef const self_type const_closure_type;
00537 typedef const_closure_type closure_type;
00538 typedef unknown_storage_tag storage_category;
00539
00540
00541 BOOST_UBLAS_INLINE
00542 vector_binary (const expression1_type &e1, const expression2_type &e2):
00543 e1_ (e1), e2_ (e2) {}
00544
00545
00546 BOOST_UBLAS_INLINE
00547 size_type size () const {
00548 return BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
00549 }
00550
00551 private:
00552
00553 BOOST_UBLAS_INLINE
00554 const expression1_closure_type &expression1 () const {
00555 return e1_;
00556 }
00557 BOOST_UBLAS_INLINE
00558 const expression2_closure_type &expression2 () const {
00559 return e2_;
00560 }
00561
00562 public:
00563
00564 BOOST_UBLAS_INLINE
00565 const_reference operator () (size_type i) const {
00566 return functor_type::apply (e1_ (i), e2_ (i));
00567 }
00568
00569 BOOST_UBLAS_INLINE
00570 const_reference operator [] (size_type i) const {
00571 return functor_type::apply (e1_ [i], e2_ [i]);
00572 }
00573
00574
00575 BOOST_UBLAS_INLINE
00576 bool same_closure (const vector_binary &vb) const {
00577 return (*this).expression1 ().same_closure (vb.expression1 ()) &&
00578 (*this).expression2 ().same_closure (vb.expression2 ());
00579 }
00580
00581
00582 private:
00583 typedef typename E1::const_iterator const_subiterator1_type;
00584 typedef typename E2::const_iterator const_subiterator2_type;
00585 typedef const value_type *const_pointer;
00586
00587 public:
00588 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00589 typedef typename iterator_restrict_traits<typename const_subiterator1_type::iterator_category,
00590 typename const_subiterator2_type::iterator_category>::iterator_category iterator_category;
00591 typedef indexed_const_iterator<const_closure_type, iterator_category> const_iterator;
00592 typedef const_iterator iterator;
00593 #else
00594 class const_iterator;
00595 typedef const_iterator iterator;
00596 #endif
00597
00598
00599 BOOST_UBLAS_INLINE
00600 const_iterator find (size_type i) const {
00601 const_subiterator1_type it1 (e1_.find (i));
00602 const_subiterator1_type it1_end (e1_.find (size ()));
00603 const_subiterator2_type it2 (e2_.find (i));
00604 const_subiterator2_type it2_end (e2_.find (size ()));
00605 i = (std::min) (it1 != it1_end ? it1.index () : size (),
00606 it2 != it2_end ? it2.index () : size ());
00607 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
00608 return const_iterator (*this, i);
00609 #else
00610 return const_iterator (*this, i, it1, it1_end, it2, it2_end);
00611 #endif
00612 }
00613
00614
00615
00616
00617 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
00618 class const_iterator:
00619 public container_const_reference<vector_binary>,
00620 public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
00621 typename E2::const_iterator::iterator_category>::iterator_category>::template
00622 iterator_base<const_iterator, value_type>::type {
00623 public:
00624 typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
00625 typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
00626 typedef typename vector_binary::difference_type difference_type;
00627 typedef typename vector_binary::value_type value_type;
00628 typedef typename vector_binary::const_reference reference;
00629 typedef typename vector_binary::const_pointer pointer;
00630
00631
00632 BOOST_UBLAS_INLINE
00633 const_iterator ():
00634 container_const_reference<self_type> (), i_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {}
00635 BOOST_UBLAS_INLINE
00636 const_iterator (const self_type &vb, size_type i,
00637 const const_subiterator1_type &it1, const const_subiterator1_type &it1_end,
00638 const const_subiterator2_type &it2, const const_subiterator2_type &it2_end):
00639 container_const_reference<self_type> (vb), i_ (i), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {}
00640
00641 private:
00642
00643 BOOST_UBLAS_INLINE
00644 void increment (dense_random_access_iterator_tag) {
00645 ++ i_; ++ it1_; ++ it2_;
00646 }
00647 BOOST_UBLAS_INLINE
00648 void decrement (dense_random_access_iterator_tag) {
00649 -- i_; -- it1_; -- it2_;
00650 }
00651 BOOST_UBLAS_INLINE
00652 void increment (dense_random_access_iterator_tag, difference_type n) {
00653 i_ += n; it1_ += n; it2_ += n;
00654 }
00655 BOOST_UBLAS_INLINE
00656 void decrement (dense_random_access_iterator_tag, difference_type n) {
00657 i_ -= n; it1_ -= n; it2_ -= n;
00658 }
00659 BOOST_UBLAS_INLINE
00660 value_type dereference (dense_random_access_iterator_tag) const {
00661 return functor_type::apply (*it1_, *it2_);
00662 }
00663
00664
00665 BOOST_UBLAS_INLINE
00666 void increment (packed_random_access_iterator_tag) {
00667 if (it1_ != it1_end_)
00668 if (it1_.index () <= i_)
00669 ++ it1_;
00670 if (it2_ != it2_end_)
00671 if (it2_.index () <= i_)
00672 ++ it2_;
00673 ++ i_;
00674 }
00675 BOOST_UBLAS_INLINE
00676 void decrement (packed_random_access_iterator_tag) {
00677 if (it1_ != it1_end_)
00678 if (i_ <= it1_.index ())
00679 -- it1_;
00680 if (it2_ != it2_end_)
00681 if (i_ <= it2_.index ())
00682 -- it2_;
00683 -- i_;
00684 }
00685 BOOST_UBLAS_INLINE
00686 void increment (packed_random_access_iterator_tag, difference_type n) {
00687 while (n > 0) {
00688 increment (packed_random_access_iterator_tag ());
00689 --n;
00690 }
00691 while (n < 0) {
00692 decrement (packed_random_access_iterator_tag ());
00693 ++n;
00694 }
00695 }
00696 BOOST_UBLAS_INLINE
00697 void decrement (packed_random_access_iterator_tag, difference_type n) {
00698 while (n > 0) {
00699 decrement (packed_random_access_iterator_tag ());
00700 --n;
00701 }
00702 while (n < 0) {
00703 increment (packed_random_access_iterator_tag ());
00704 ++n;
00705 }
00706 }
00707 BOOST_UBLAS_INLINE
00708 value_type dereference (packed_random_access_iterator_tag) const {
00709 value_type t1 = value_type();
00710 if (it1_ != it1_end_)
00711 if (it1_.index () == i_)
00712 t1 = *it1_;
00713 value_type t2 = value_type();
00714 if (it2_ != it2_end_)
00715 if (it2_.index () == i_)
00716 t2 = *it2_;
00717 return functor_type::apply (t1, t2);
00718 }
00719
00720
00721 BOOST_UBLAS_INLINE
00722 void increment (sparse_bidirectional_iterator_tag) {
00723 size_type index1 = (*this) ().size ();
00724 if (it1_ != it1_end_) {
00725 if (it1_.index () <= i_)
00726 ++ it1_;
00727 if (it1_ != it1_end_)
00728 index1 = it1_.index ();
00729 }
00730 size_type index2 = (*this) ().size ();
00731 if (it2_ != it2_end_) {
00732 if (it2_.index () <= i_)
00733 ++ it2_;
00734 if (it2_ != it2_end_)
00735 index2 = it2_.index ();
00736 }
00737 i_ = (std::min) (index1, index2);
00738 }
00739 BOOST_UBLAS_INLINE
00740 void decrement (sparse_bidirectional_iterator_tag) {
00741 size_type index1 = (*this) ().size ();
00742 if (it1_ != it1_end_) {
00743 if (i_ <= it1_.index ())
00744 -- it1_;
00745 if (it1_ != it1_end_)
00746 index1 = it1_.index ();
00747 }
00748 size_type index2 = (*this) ().size ();
00749 if (it2_ != it2_end_) {
00750 if (i_ <= it2_.index ())
00751 -- it2_;
00752 if (it2_ != it2_end_)
00753 index2 = it2_.index ();
00754 }
00755 i_ = (std::max) (index1, index2);
00756 }
00757 BOOST_UBLAS_INLINE
00758 void increment (sparse_bidirectional_iterator_tag, difference_type n) {
00759 while (n > 0) {
00760 increment (sparse_bidirectional_iterator_tag ());
00761 --n;
00762 }
00763 while (n < 0) {
00764 decrement (sparse_bidirectional_iterator_tag ());
00765 ++n;
00766 }
00767 }
00768 BOOST_UBLAS_INLINE
00769 void decrement (sparse_bidirectional_iterator_tag, difference_type n) {
00770 while (n > 0) {
00771 decrement (sparse_bidirectional_iterator_tag ());
00772 --n;
00773 }
00774 while (n < 0) {
00775 increment (sparse_bidirectional_iterator_tag ());
00776 ++n;
00777 }
00778 }
00779 BOOST_UBLAS_INLINE
00780 value_type dereference (sparse_bidirectional_iterator_tag) const {
00781 value_type t1 = value_type();
00782 if (it1_ != it1_end_)
00783 if (it1_.index () == i_)
00784 t1 = *it1_;
00785 value_type t2 = value_type();
00786 if (it2_ != it2_end_)
00787 if (it2_.index () == i_)
00788 t2 = *it2_;
00789 return functor_type::apply (t1, t2);
00790 }
00791
00792 public:
00793
00794 BOOST_UBLAS_INLINE
00795 const_iterator &operator ++ () {
00796 increment (iterator_category ());
00797 return *this;
00798 }
00799 BOOST_UBLAS_INLINE
00800 const_iterator &operator -- () {
00801 decrement (iterator_category ());
00802 return *this;
00803 }
00804 BOOST_UBLAS_INLINE
00805 const_iterator &operator += (difference_type n) {
00806 increment (iterator_category (), n);
00807 return *this;
00808 }
00809 BOOST_UBLAS_INLINE
00810 const_iterator &operator -= (difference_type n) {
00811 decrement (iterator_category (), n);
00812 return *this;
00813 }
00814 BOOST_UBLAS_INLINE
00815 difference_type operator - (const const_iterator &it) const {
00816 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00817 return index () - it.index ();
00818 }
00819
00820
00821 BOOST_UBLAS_INLINE
00822 const_reference operator * () const {
00823 return dereference (iterator_category ());
00824 }
00825 BOOST_UBLAS_INLINE
00826 const_reference operator [] (difference_type n) const {
00827 return *(*this + n);
00828 }
00829
00830
00831 BOOST_UBLAS_INLINE
00832 size_type index () const {
00833 return i_;
00834 }
00835
00836
00837 BOOST_UBLAS_INLINE
00838 const_iterator &operator = (const const_iterator &it) {
00839 container_const_reference<self_type>::assign (&it ());
00840 i_ = it.i_;
00841 it1_ = it.it1_;
00842 it1_end_ = it.it1_end_;
00843 it2_ = it.it2_;
00844 it2_end_ = it.it2_end_;
00845 return *this;
00846 }
00847
00848
00849 BOOST_UBLAS_INLINE
00850 bool operator == (const const_iterator &it) const {
00851 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00852 return index () == it.index ();
00853 }
00854 BOOST_UBLAS_INLINE
00855 bool operator < (const const_iterator &it) const {
00856 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
00857 return index () < it.index ();
00858 }
00859
00860 private:
00861 size_type i_;
00862 const_subiterator1_type it1_;
00863 const_subiterator1_type it1_end_;
00864 const_subiterator2_type it2_;
00865 const_subiterator2_type it2_end_;
00866 };
00867 #endif
00868
00869 BOOST_UBLAS_INLINE
00870 const_iterator begin () const {
00871 return find (0);
00872 }
00873 BOOST_UBLAS_INLINE
00874 const_iterator end () const {
00875 return find (size ());
00876 }
00877
00878
00879 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
00880
00881 BOOST_UBLAS_INLINE
00882 const_reverse_iterator rbegin () const {
00883 return const_reverse_iterator (end ());
00884 }
00885 BOOST_UBLAS_INLINE
00886 const_reverse_iterator rend () const {
00887 return const_reverse_iterator (begin ());
00888 }
00889
00890 private:
00891 expression1_closure_type e1_;
00892 expression2_closure_type e2_;
00893 };
00894
00895 template<class E1, class E2, class F>
00896 struct vector_binary_traits {
00897 typedef vector_binary<E1, E2, F> expression_type;
00898 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
00899 typedef expression_type result_type;
00900 #else
00901 typedef typename E1::vector_temporary_type result_type;
00902 #endif
00903 };
00904
00905
00906 template<class E1, class E2>
00907 BOOST_UBLAS_INLINE
00908 typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
00909 typename E2::value_type> >::result_type
00910 operator + (const vector_expression<E1> &e1,
00911 const vector_expression<E2> &e2) {
00912 typedef typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
00913 typename E2::value_type> >::expression_type expression_type;
00914 return expression_type (e1 (), e2 ());
00915 }
00916
00917
00918 template<class E1, class E2>
00919 BOOST_UBLAS_INLINE
00920 typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
00921 typename E2::value_type> >::result_type
00922 operator - (const vector_expression<E1> &e1,
00923 const vector_expression<E2> &e2) {
00924 typedef typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
00925 typename E2::value_type> >::expression_type expression_type;
00926 return expression_type (e1 (), e2 ());
00927 }
00928
00929
00930 template<class E1, class E2>
00931 BOOST_UBLAS_INLINE
00932 typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
00933 typename E2::value_type> >::result_type
00934 element_prod (const vector_expression<E1> &e1,
00935 const vector_expression<E2> &e2) {
00936 typedef typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
00937 typename E2::value_type> >::expression_type expression_type;
00938 return expression_type (e1 (), e2 ());
00939 }
00940
00941
00942 template<class E1, class E2>
00943 BOOST_UBLAS_INLINE
00944 typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
00945 typename E2::value_type> >::result_type
00946 element_div (const vector_expression<E1> &e1,
00947 const vector_expression<E2> &e2) {
00948 typedef typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
00949 typename E2::value_type> >::expression_type expression_type;
00950 return expression_type (e1 (), e2 ());
00951 }
00952
00953
00954 template<class E1, class E2, class F>
00955 class vector_binary_scalar1:
00956 public vector_expression<vector_binary_scalar1<E1, E2, F> > {
00957
00958 typedef F functor_type;
00959 typedef E1 expression1_type;
00960 typedef E2 expression2_type;
00961 public:
00962 typedef const E1& expression1_closure_type;
00963 typedef typename E2::const_closure_type expression2_closure_type;
00964 private:
00965 typedef vector_binary_scalar1<E1, E2, F> self_type;
00966 public:
00967 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
00968 using vector_expression<vector_binary_scalar1<E1, E2, F> >::operator ();
00969 #endif
00970 typedef typename E2::size_type size_type;
00971 typedef typename E2::difference_type difference_type;
00972 typedef typename F::result_type value_type;
00973 typedef value_type const_reference;
00974 typedef const_reference reference;
00975 typedef const self_type const_closure_type;
00976 typedef const_closure_type closure_type;
00977 typedef unknown_storage_tag storage_category;
00978
00979
00980 BOOST_UBLAS_INLINE
00981 vector_binary_scalar1 (const expression1_type &e1, const expression2_type &e2):
00982 e1_ (e1), e2_ (e2) {}
00983
00984
00985 BOOST_UBLAS_INLINE
00986 size_type size () const {
00987 return e2_.size ();
00988 }
00989
00990 public:
00991
00992 BOOST_UBLAS_INLINE
00993 const_reference operator () (size_type i) const {
00994 return functor_type::apply (e1_, e2_ (i));
00995 }
00996
00997 BOOST_UBLAS_INLINE
00998 const_reference operator [] (size_type i) const {
00999 return functor_type::apply (e1_, e2_ [i]);
01000 }
01001
01002
01003 BOOST_UBLAS_INLINE
01004 bool same_closure (const vector_binary_scalar1 &vbs1) const {
01005 return &e1_ == &(vbs1.e1_) &&
01006 (*this).e2_.same_closure (vbs1.e2_);
01007 }
01008
01009
01010 private:
01011 typedef expression1_type const_subiterator1_type;
01012 typedef typename expression2_type::const_iterator const_subiterator2_type;
01013 typedef const value_type *const_pointer;
01014
01015 public:
01016 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01017 typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
01018 typedef const_iterator iterator;
01019 #else
01020 class const_iterator;
01021 typedef const_iterator iterator;
01022 #endif
01023
01024
01025 BOOST_UBLAS_INLINE
01026 const_iterator find (size_type i) const {
01027 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01028 const_subiterator2_type it (e2_.find (i));
01029 return const_iterator (*this, it.index ());
01030 #else
01031 return const_iterator (*this, const_subiterator1_type (e1_), e2_.find (i));
01032 #endif
01033 }
01034
01035
01036
01037
01038 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01039 class const_iterator:
01040 public container_const_reference<vector_binary_scalar1>,
01041 public iterator_base_traits<typename E2::const_iterator::iterator_category>::template
01042 iterator_base<const_iterator, value_type>::type {
01043 public:
01044 typedef typename E2::const_iterator::iterator_category iterator_category;
01045 typedef typename vector_binary_scalar1::difference_type difference_type;
01046 typedef typename vector_binary_scalar1::value_type value_type;
01047 typedef typename vector_binary_scalar1::const_reference reference;
01048 typedef typename vector_binary_scalar1::const_pointer pointer;
01049
01050
01051 BOOST_UBLAS_INLINE
01052 const_iterator ():
01053 container_const_reference<self_type> (), it1_ (), it2_ () {}
01054 BOOST_UBLAS_INLINE
01055 const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
01056 container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
01057
01058
01059 BOOST_UBLAS_INLINE
01060 const_iterator &operator ++ () {
01061 ++ it2_;
01062 return *this;
01063 }
01064 BOOST_UBLAS_INLINE
01065 const_iterator &operator -- () {
01066 -- it2_;
01067 return *this;
01068 }
01069 BOOST_UBLAS_INLINE
01070 const_iterator &operator += (difference_type n) {
01071 it2_ += n;
01072 return *this;
01073 }
01074 BOOST_UBLAS_INLINE
01075 const_iterator &operator -= (difference_type n) {
01076 it2_ -= n;
01077 return *this;
01078 }
01079 BOOST_UBLAS_INLINE
01080 difference_type operator - (const const_iterator &it) const {
01081 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01082
01083
01084 return it2_ - it.it2_;
01085 }
01086
01087
01088 BOOST_UBLAS_INLINE
01089 const_reference operator * () const {
01090 return functor_type::apply (it1_, *it2_);
01091 }
01092 BOOST_UBLAS_INLINE
01093 const_reference operator [] (difference_type n) const {
01094 return *(*this + n);
01095 }
01096
01097
01098 BOOST_UBLAS_INLINE
01099 size_type index () const {
01100 return it2_.index ();
01101 }
01102
01103
01104 BOOST_UBLAS_INLINE
01105 const_iterator &operator = (const const_iterator &it) {
01106 container_const_reference<self_type>::assign (&it ());
01107 it1_ = it.it1_;
01108 it2_ = it.it2_;
01109 return *this;
01110 }
01111
01112
01113 BOOST_UBLAS_INLINE
01114 bool operator == (const const_iterator &it) const {
01115 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01116
01117
01118 return it2_ == it.it2_;
01119 }
01120 BOOST_UBLAS_INLINE
01121 bool operator < (const const_iterator &it) const {
01122 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01123
01124
01125 return it2_ < it.it2_;
01126 }
01127
01128 private:
01129 const_subiterator1_type it1_;
01130 const_subiterator2_type it2_;
01131 };
01132 #endif
01133
01134 BOOST_UBLAS_INLINE
01135 const_iterator begin () const {
01136 return find (0);
01137 }
01138 BOOST_UBLAS_INLINE
01139 const_iterator end () const {
01140 return find (size ());
01141 }
01142
01143
01144 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
01145
01146 BOOST_UBLAS_INLINE
01147 const_reverse_iterator rbegin () const {
01148 return const_reverse_iterator (end ());
01149 }
01150 BOOST_UBLAS_INLINE
01151 const_reverse_iterator rend () const {
01152 return const_reverse_iterator (begin ());
01153 }
01154
01155 private:
01156 expression1_closure_type e1_;
01157 expression2_closure_type e2_;
01158 };
01159
01160 template<class E1, class E2, class F>
01161 struct vector_binary_scalar1_traits {
01162 typedef vector_binary_scalar1<E1, E2, F> expression_type;
01163 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
01164 typedef expression_type result_type;
01165 #else
01166 typedef typename E2::vector_temporary_type result_type;
01167 #endif
01168 };
01169
01170
01171 template<class T1, class E2>
01172 BOOST_UBLAS_INLINE
01173 typename enable_if< is_convertible<T1, typename E2::value_type >,
01174 typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::result_type
01175 >::type
01176 operator * (const T1 &e1,
01177 const vector_expression<E2> &e2) {
01178 typedef typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::expression_type expression_type;
01179 return expression_type (e1, e2 ());
01180 }
01181
01182
01183 template<class E1, class E2, class F>
01184 class vector_binary_scalar2:
01185 public vector_expression<vector_binary_scalar2<E1, E2, F> > {
01186
01187 typedef F functor_type;
01188 typedef E1 expression1_type;
01189 typedef E2 expression2_type;
01190 typedef typename E1::const_closure_type expression1_closure_type;
01191 typedef const E2& expression2_closure_type;
01192 typedef vector_binary_scalar2<E1, E2, F> self_type;
01193 public:
01194 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
01195 using vector_expression<vector_binary_scalar2<E1, E2, F> >::operator ();
01196 #endif
01197 typedef typename E1::size_type size_type;
01198 typedef typename E1::difference_type difference_type;
01199 typedef typename F::result_type value_type;
01200 typedef value_type const_reference;
01201 typedef const_reference reference;
01202 typedef const self_type const_closure_type;
01203 typedef const_closure_type closure_type;
01204 typedef unknown_storage_tag storage_category;
01205
01206
01207 BOOST_UBLAS_INLINE
01208 vector_binary_scalar2 (const expression1_type &e1, const expression2_type &e2):
01209 e1_ (e1), e2_ (e2) {}
01210
01211
01212 BOOST_UBLAS_INLINE
01213 size_type size () const {
01214 return e1_.size ();
01215 }
01216
01217 public:
01218
01219 BOOST_UBLAS_INLINE
01220 const_reference operator () (size_type i) const {
01221 return functor_type::apply (e1_ (i), e2_);
01222 }
01223
01224 BOOST_UBLAS_INLINE
01225 const_reference operator [] (size_type i) const {
01226 return functor_type::apply (e1_ [i], e2_);
01227 }
01228
01229
01230 BOOST_UBLAS_INLINE
01231 bool same_closure (const vector_binary_scalar2 &vbs2) const {
01232 return (*this).e1_.same_closure (vbs2.e1_) &&
01233 &e2_ == &(vbs2.e2_);
01234 }
01235
01236
01237 private:
01238 typedef typename expression1_type::const_iterator const_subiterator1_type;
01239 typedef expression2_type const_subiterator2_type;
01240 typedef const value_type *const_pointer;
01241
01242 public:
01243 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01244 typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
01245 typedef const_iterator iterator;
01246 #else
01247 class const_iterator;
01248 typedef const_iterator iterator;
01249 #endif
01250
01251
01252 BOOST_UBLAS_INLINE
01253 const_iterator find (size_type i) const {
01254 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
01255 const_subiterator1_type it (e1_.find (i));
01256 return const_iterator (*this, it.index ());
01257 #else
01258 return const_iterator (*this, e1_.find (i), const_subiterator2_type (e2_));
01259 #endif
01260 }
01261
01262
01263
01264
01265 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
01266 class const_iterator:
01267 public container_const_reference<vector_binary_scalar2>,
01268 public iterator_base_traits<typename E1::const_iterator::iterator_category>::template
01269 iterator_base<const_iterator, value_type>::type {
01270 public:
01271 typedef typename E1::const_iterator::iterator_category iterator_category;
01272 typedef typename vector_binary_scalar2::difference_type difference_type;
01273 typedef typename vector_binary_scalar2::value_type value_type;
01274 typedef typename vector_binary_scalar2::const_reference reference;
01275 typedef typename vector_binary_scalar2::const_pointer pointer;
01276
01277
01278 BOOST_UBLAS_INLINE
01279 const_iterator ():
01280 container_const_reference<self_type> (), it1_ (), it2_ () {}
01281 BOOST_UBLAS_INLINE
01282 const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
01283 container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
01284
01285
01286 BOOST_UBLAS_INLINE
01287 const_iterator &operator ++ () {
01288 ++ it1_;
01289 return *this;
01290 }
01291 BOOST_UBLAS_INLINE
01292 const_iterator &operator -- () {
01293 -- it1_;
01294 return *this;
01295 }
01296 BOOST_UBLAS_INLINE
01297 const_iterator &operator += (difference_type n) {
01298 it1_ += n;
01299 return *this;
01300 }
01301 BOOST_UBLAS_INLINE
01302 const_iterator &operator -= (difference_type n) {
01303 it1_ -= n;
01304 return *this;
01305 }
01306 BOOST_UBLAS_INLINE
01307 difference_type operator - (const const_iterator &it) const {
01308 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01309
01310
01311 return it1_ - it.it1_;
01312 }
01313
01314
01315 BOOST_UBLAS_INLINE
01316 const_reference operator * () const {
01317 return functor_type::apply (*it1_, it2_);
01318 }
01319 BOOST_UBLAS_INLINE
01320 const_reference operator [] (difference_type n) const {
01321 return *(*this + n);
01322 }
01323
01324
01325 BOOST_UBLAS_INLINE
01326 size_type index () const {
01327 return it1_.index ();
01328 }
01329
01330
01331 BOOST_UBLAS_INLINE
01332 const_iterator &operator = (const const_iterator &it) {
01333 container_const_reference<self_type>::assign (&it ());
01334 it1_ = it.it1_;
01335 it2_ = it.it2_;
01336 return *this;
01337 }
01338
01339
01340 BOOST_UBLAS_INLINE
01341 bool operator == (const const_iterator &it) const {
01342 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01343
01344
01345 return it1_ == it.it1_;
01346 }
01347 BOOST_UBLAS_INLINE
01348 bool operator < (const const_iterator &it) const {
01349 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
01350
01351
01352 return it1_ < it.it1_;
01353 }
01354
01355 private:
01356 const_subiterator1_type it1_;
01357 const_subiterator2_type it2_;
01358 };
01359 #endif
01360
01361 BOOST_UBLAS_INLINE
01362 const_iterator begin () const {
01363 return find (0);
01364 }
01365 BOOST_UBLAS_INLINE
01366 const_iterator end () const {
01367 return find (size ());
01368 }
01369
01370
01371 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
01372
01373 BOOST_UBLAS_INLINE
01374 const_reverse_iterator rbegin () const {
01375 return const_reverse_iterator (end ());
01376 }
01377 BOOST_UBLAS_INLINE
01378 const_reverse_iterator rend () const {
01379 return const_reverse_iterator (begin ());
01380 }
01381
01382 private:
01383 expression1_closure_type e1_;
01384 expression2_closure_type e2_;
01385 };
01386
01387 template<class E1, class E2, class F>
01388 struct vector_binary_scalar2_traits {
01389 typedef vector_binary_scalar2<E1, E2, F> expression_type;
01390 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
01391 typedef expression_type result_type;
01392 #else
01393 typedef typename E1::vector_temporary_type result_type;
01394 #endif
01395 };
01396
01397
01398 template<class E1, class T2>
01399 BOOST_UBLAS_INLINE
01400 typename enable_if< is_convertible<T2, typename E1::value_type >,
01401 typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::result_type
01402 >::type
01403 operator * (const vector_expression<E1> &e1,
01404 const T2 &e2) {
01405 typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::expression_type expression_type;
01406 return expression_type (e1 (), e2);
01407 }
01408
01409
01410 template<class E1, class T2>
01411 BOOST_UBLAS_INLINE
01412 typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::result_type
01413 operator / (const vector_expression<E1> &e1,
01414 const T2 &e2) {
01415 typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::expression_type expression_type;
01416 return expression_type (e1 (), e2);
01417 }
01418
01419
01420 template<class E, class F>
01421 class vector_scalar_unary:
01422 public scalar_expression<vector_scalar_unary<E, F> > {
01423
01424 typedef E expression_type;
01425 typedef F functor_type;
01426 typedef typename E::const_closure_type expression_closure_type;
01427 typedef typename E::const_iterator::iterator_category iterator_category;
01428 typedef vector_scalar_unary<E, F> self_type;
01429 public:
01430 typedef typename F::result_type value_type;
01431 typedef typename E::difference_type difference_type;
01432 typedef const self_type const_closure_type;
01433 typedef const_closure_type closure_type;
01434 typedef unknown_storage_tag storage_category;
01435
01436
01437 BOOST_UBLAS_INLINE
01438 explicit vector_scalar_unary (const expression_type &e):
01439 e_ (e) {}
01440
01441 private:
01442
01443 BOOST_UBLAS_INLINE
01444 const expression_closure_type &expression () const {
01445 return e_;
01446 }
01447
01448 public:
01449 BOOST_UBLAS_INLINE
01450 operator value_type () const {
01451 return evaluate (iterator_category ());
01452 }
01453
01454 private:
01455
01456 BOOST_UBLAS_INLINE
01457 value_type evaluate (dense_random_access_iterator_tag) const {
01458 #ifdef BOOST_UBLAS_USE_INDEXING
01459 return functor_type::apply (e_);
01460 #elif BOOST_UBLAS_USE_ITERATING
01461 difference_type size = e_.size ();
01462 return functor_type::apply (size, e_.begin ());
01463 #else
01464 difference_type size = e_.size ();
01465 if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
01466 return functor_type::apply (size, e_.begin ());
01467 else
01468 return functor_type::apply (e_);
01469 #endif
01470 }
01471
01472
01473 BOOST_UBLAS_INLINE
01474 value_type evaluate (packed_random_access_iterator_tag) const {
01475 return functor_type::apply (e_.begin (), e_.end ());
01476 }
01477
01478
01479 BOOST_UBLAS_INLINE
01480 value_type evaluate (sparse_bidirectional_iterator_tag) const {
01481 return functor_type::apply (e_.begin (), e_.end ());
01482 }
01483
01484 private:
01485 expression_closure_type e_;
01486 };
01487
01488 template<class E, class F>
01489 struct vector_scalar_unary_traits {
01490 typedef vector_scalar_unary<E, F> expression_type;
01491 #if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
01492
01493
01494 typedef expression_type result_type;
01495 #else
01496 typedef typename F::result_type result_type;
01497 #endif
01498 };
01499
01500
01501 template<class E>
01502 BOOST_UBLAS_INLINE
01503 typename vector_scalar_unary_traits<E, vector_sum<E> >::result_type
01504 sum (const vector_expression<E> &e) {
01505 typedef typename vector_scalar_unary_traits<E, vector_sum<E> >::expression_type expression_type;
01506 return expression_type (e ());
01507 }
01508
01509
01510
01511 template<class E>
01512 BOOST_UBLAS_INLINE
01513 typename vector_scalar_unary_traits<E, vector_norm_1<E> >::result_type
01514 norm_1 (const vector_expression<E> &e) {
01515 typedef typename vector_scalar_unary_traits<E, vector_norm_1<E> >::expression_type expression_type;
01516 return expression_type (e ());
01517 }
01518
01519
01520
01521 template<class E>
01522 BOOST_UBLAS_INLINE
01523 typename vector_scalar_unary_traits<E, vector_norm_2<E> >::result_type
01524 norm_2 (const vector_expression<E> &e) {
01525 typedef typename vector_scalar_unary_traits<E, vector_norm_2<E> >::expression_type expression_type;
01526 return expression_type (e ());
01527 }
01528
01529
01530
01531 template<class E>
01532 BOOST_UBLAS_INLINE
01533 typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::result_type
01534 norm_inf (const vector_expression<E> &e) {
01535 typedef typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::expression_type expression_type;
01536 return expression_type (e ());
01537 }
01538
01539
01540 template<class E>
01541 BOOST_UBLAS_INLINE
01542 typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::result_type
01543 index_norm_inf (const vector_expression<E> &e) {
01544 typedef typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::expression_type expression_type;
01545 return expression_type (e ());
01546 }
01547
01548 template<class E1, class E2, class F>
01549 class vector_scalar_binary:
01550 public scalar_expression<vector_scalar_binary<E1, E2, F> > {
01551
01552 typedef E1 expression1_type;
01553 typedef E2 expression2_type;
01554 typedef F functor_type;
01555 typedef typename E1::const_closure_type expression1_closure_type;
01556 typedef typename E2::const_closure_type expression2_closure_type;
01557 typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
01558 typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
01559 typedef vector_scalar_binary<E1, E2, F> self_type;
01560 public:
01561 static const unsigned complexity = 1;
01562 typedef typename F::result_type value_type;
01563 typedef typename E1::difference_type difference_type;
01564 typedef const self_type const_closure_type;
01565 typedef const_closure_type closure_type;
01566 typedef unknown_storage_tag storage_category;
01567
01568
01569 BOOST_UBLAS_INLINE
01570 vector_scalar_binary (const expression1_type &e1, const expression2_type &e2):
01571 e1_ (e1), e2_ (e2) {}
01572
01573 private:
01574
01575 BOOST_UBLAS_INLINE
01576 const expression1_closure_type &expression1 () const {
01577 return e1_;
01578 }
01579 BOOST_UBLAS_INLINE
01580 const expression2_closure_type &expression2 () const {
01581 return e2_;
01582 }
01583
01584 public:
01585 BOOST_UBLAS_INLINE
01586 operator value_type () const {
01587 return evaluate (iterator_category ());
01588 }
01589
01590 private:
01591
01592 BOOST_UBLAS_INLINE
01593 value_type evaluate (dense_random_access_iterator_tag) const {
01594 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
01595 #ifdef BOOST_UBLAS_USE_INDEXING
01596 return functor_type::apply (e1_, e2_);
01597 #elif BOOST_UBLAS_USE_ITERATING
01598 difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
01599 return functor_type::apply (size, e1_.begin (), e2_.begin ());
01600 #else
01601 difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
01602 if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
01603 return functor_type::apply (size, e1_.begin (), e2_.begin ());
01604 else
01605 return functor_type::apply (e1_, e2_);
01606 #endif
01607 }
01608
01609
01610 BOOST_UBLAS_INLINE
01611 value_type evaluate (packed_random_access_iterator_tag) const {
01612 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
01613 return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end ());
01614 }
01615
01616
01617 BOOST_UBLAS_INLINE
01618 value_type evaluate (sparse_bidirectional_iterator_tag) const {
01619 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
01620 return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end (), sparse_bidirectional_iterator_tag ());
01621 }
01622
01623 private:
01624 expression1_closure_type e1_;
01625 expression2_closure_type e2_;
01626 };
01627
01628 template<class E1, class E2, class F>
01629 struct vector_scalar_binary_traits {
01630 typedef vector_scalar_binary<E1, E2, F> expression_type;
01631 #if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
01632
01633
01634 typedef expression_type result_type;
01635 #else
01636 typedef typename F::result_type result_type;
01637 #endif
01638 };
01639
01640
01641 template<class E1, class E2>
01642 BOOST_UBLAS_INLINE
01643 typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
01644 typename promote_traits<typename E1::value_type,
01645 typename E2::value_type>::promote_type> >::result_type
01646 inner_prod (const vector_expression<E1> &e1,
01647 const vector_expression<E2> &e2) {
01648 typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
01649 typename promote_traits<typename E1::value_type,
01650 typename E2::value_type>::promote_type> >::expression_type expression_type;
01651 return expression_type (e1 (), e2 ());
01652 }
01653
01654 template<class E1, class E2>
01655 BOOST_UBLAS_INLINE
01656 typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
01657 typename type_traits<typename promote_traits<typename E1::value_type,
01658 typename E2::value_type>::promote_type>::precision_type> >::result_type
01659 prec_inner_prod (const vector_expression<E1> &e1,
01660 const vector_expression<E2> &e2) {
01661 typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
01662 typename type_traits<typename promote_traits<typename E1::value_type,
01663 typename E2::value_type>::promote_type>::precision_type> >::expression_type expression_type;
01664 return expression_type (e1 (), e2 ());
01665 }
01666
01667 }}}
01668
01669 #endif