File indexing completed on 2025-01-18 09:43:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _BOOST_UBLAS_VECTOR_EXPRESSION_
0014 #define _BOOST_UBLAS_VECTOR_EXPRESSION_
0015
0016 #include <boost/numeric/ublas/expression_types.hpp>
0017
0018
0019
0020
0021
0022
0023
0024 namespace boost { namespace numeric { namespace ublas {
0025
0026 template<class E>
0027 class vector_reference:
0028 public vector_expression<vector_reference<E> > {
0029
0030 typedef vector_reference<E> self_type;
0031 public:
0032 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0033 using vector_expression<vector_reference<E> >::operator ();
0034 #endif
0035 typedef typename E::size_type size_type;
0036 typedef typename E::difference_type difference_type;
0037 typedef typename E::value_type value_type;
0038 typedef typename E::const_reference const_reference;
0039 typedef typename boost::mpl::if_<boost::is_const<E>,
0040 typename E::const_reference,
0041 typename E::reference>::type reference;
0042 typedef E referred_type;
0043 typedef const self_type const_closure_type;
0044 typedef self_type closure_type;
0045 typedef typename E::storage_category storage_category;
0046
0047
0048 BOOST_UBLAS_INLINE
0049 explicit vector_reference (referred_type &e):
0050 e_ (e) {}
0051
0052
0053 BOOST_UBLAS_INLINE
0054 size_type size () const {
0055 return expression ().size ();
0056 }
0057
0058 public:
0059
0060 BOOST_UBLAS_INLINE
0061 const referred_type &expression () const {
0062 return e_;
0063 }
0064 BOOST_UBLAS_INLINE
0065 referred_type &expression () {
0066 return e_;
0067 }
0068
0069 public:
0070
0071 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
0072 BOOST_UBLAS_INLINE
0073 const_reference operator () (size_type i) const {
0074 return expression () (i);
0075 }
0076 BOOST_UBLAS_INLINE
0077 reference operator () (size_type i) {
0078 return expression () (i);
0079 }
0080
0081 BOOST_UBLAS_INLINE
0082 const_reference operator [] (size_type i) const {
0083 return expression () [i];
0084 }
0085 BOOST_UBLAS_INLINE
0086 reference operator [] (size_type i) {
0087 return expression () [i];
0088 }
0089 #else
0090 BOOST_UBLAS_INLINE
0091 reference operator () (size_type i) const {
0092 return expression () (i);
0093 }
0094
0095 BOOST_UBLAS_INLINE
0096 reference operator [] (size_type i) const {
0097 return expression () [i];
0098 }
0099 #endif
0100
0101
0102 BOOST_UBLAS_INLINE
0103 vector_reference &operator = (const vector_reference &v) {
0104 expression ().operator = (v);
0105 return *this;
0106 }
0107 template<class AE>
0108 BOOST_UBLAS_INLINE
0109 vector_reference &operator = (const vector_expression<AE> &ae) {
0110 expression ().operator = (ae);
0111 return *this;
0112 }
0113 template<class AE>
0114 BOOST_UBLAS_INLINE
0115 vector_reference &assign (const vector_expression<AE> &ae) {
0116 expression ().assign (ae);
0117 return *this;
0118 }
0119 template<class AE>
0120 BOOST_UBLAS_INLINE
0121 vector_reference &operator += (const vector_expression<AE> &ae) {
0122 expression ().operator += (ae);
0123 return *this;
0124 }
0125 template<class AE>
0126 BOOST_UBLAS_INLINE
0127 vector_reference &plus_assign (const vector_expression<AE> &ae) {
0128 expression ().plus_assign (ae);
0129 return *this;
0130 }
0131 template<class AE>
0132 BOOST_UBLAS_INLINE
0133 vector_reference &operator -= (const vector_expression<AE> &ae) {
0134 expression ().operator -= (ae);
0135 return *this;
0136 }
0137 template<class AE>
0138 BOOST_UBLAS_INLINE
0139 vector_reference &minus_assign (const vector_expression<AE> &ae) {
0140 expression ().minus_assign (ae);
0141 return *this;
0142 }
0143 template<class AT>
0144 BOOST_UBLAS_INLINE
0145 vector_reference &operator *= (const AT &at) {
0146 expression ().operator *= (at);
0147 return *this;
0148 }
0149 template<class AT>
0150 BOOST_UBLAS_INLINE
0151 vector_reference &operator /= (const AT &at) {
0152 expression ().operator /= (at);
0153 return *this;
0154 }
0155
0156
0157 BOOST_UBLAS_INLINE
0158 void swap (vector_reference &v) {
0159 expression ().swap (v.expression ());
0160 }
0161
0162
0163 BOOST_UBLAS_INLINE
0164 bool same_closure (const vector_reference &vr) const {
0165 return &(*this).e_ == &vr.e_;
0166 }
0167
0168
0169 typedef typename E::const_iterator const_iterator;
0170 typedef typename boost::mpl::if_<boost::is_const<E>,
0171 typename E::const_iterator,
0172 typename E::iterator>::type iterator;
0173
0174
0175 BOOST_UBLAS_INLINE
0176 const_iterator find (size_type i) const {
0177 return expression ().find (i);
0178 }
0179 BOOST_UBLAS_INLINE
0180 iterator find (size_type i) {
0181 return expression ().find (i);
0182 }
0183
0184
0185
0186 BOOST_UBLAS_INLINE
0187 const_iterator begin () const {
0188 return expression ().begin ();
0189 }
0190 BOOST_UBLAS_INLINE
0191 const_iterator cbegin () const {
0192 return begin ();
0193 }
0194 BOOST_UBLAS_INLINE
0195 const_iterator end () const {
0196 return expression ().end ();
0197 }
0198 BOOST_UBLAS_INLINE
0199 const_iterator cend () const {
0200 return end ();
0201 }
0202
0203 BOOST_UBLAS_INLINE
0204 iterator begin () {
0205 return expression ().begin ();
0206 }
0207 BOOST_UBLAS_INLINE
0208 iterator end () {
0209 return expression ().end ();
0210 }
0211
0212
0213 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
0214 typedef reverse_iterator_base<iterator> reverse_iterator;
0215
0216 BOOST_UBLAS_INLINE
0217 const_reverse_iterator rbegin () const {
0218 return const_reverse_iterator (end ());
0219 }
0220 BOOST_UBLAS_INLINE
0221 const_reverse_iterator crbegin () const {
0222 return rbegin ();
0223 }
0224 BOOST_UBLAS_INLINE
0225 const_reverse_iterator rend () const {
0226 return const_reverse_iterator (begin ());
0227 }
0228 BOOST_UBLAS_INLINE
0229 const_reverse_iterator crend () const {
0230 return rend ();
0231 }
0232
0233 BOOST_UBLAS_INLINE
0234 reverse_iterator rbegin () {
0235 return reverse_iterator (end ());
0236 }
0237 BOOST_UBLAS_INLINE
0238 reverse_iterator rend () {
0239 return reverse_iterator (begin ());
0240 }
0241
0242 private:
0243 referred_type &e_;
0244 };
0245
0246
0247 template<class E, class F>
0248 class vector_unary:
0249 public vector_expression<vector_unary<E, F> > {
0250
0251 typedef F functor_type;
0252 typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<typename E::value_type> >,
0253 E,
0254 const E>::type expression_type;
0255 typedef typename boost::mpl::if_<boost::is_const<expression_type>,
0256 typename E::const_closure_type,
0257 typename E::closure_type>::type expression_closure_type;
0258 typedef vector_unary<E, F> self_type;
0259 public:
0260 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0261 using vector_expression<vector_unary<E, F> >::operator ();
0262 #endif
0263 typedef typename E::size_type size_type;
0264 typedef typename E::difference_type difference_type;
0265 typedef typename F::result_type value_type;
0266 typedef value_type const_reference;
0267 typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<value_type> >,
0268 typename E::reference,
0269 value_type>::type reference;
0270 typedef const self_type const_closure_type;
0271 typedef self_type closure_type;
0272 typedef unknown_storage_tag storage_category;
0273
0274
0275 BOOST_UBLAS_INLINE
0276
0277 explicit vector_unary (expression_type &e):
0278 e_ (e) {}
0279
0280
0281 BOOST_UBLAS_INLINE
0282 size_type size () const {
0283 return e_.size ();
0284 }
0285
0286 public:
0287
0288 BOOST_UBLAS_INLINE
0289 const expression_closure_type &expression () const {
0290 return e_;
0291 }
0292
0293 public:
0294
0295 BOOST_UBLAS_INLINE
0296 const_reference operator () (size_type i) const {
0297 return functor_type::apply (e_ (i));
0298 }
0299 BOOST_UBLAS_INLINE
0300 reference operator () (size_type i) {
0301 BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
0302 return e_ (i);
0303 }
0304
0305 BOOST_UBLAS_INLINE
0306 const_reference operator [] (size_type i) const {
0307 return functor_type::apply (e_ [i]);
0308 }
0309 BOOST_UBLAS_INLINE
0310 reference operator [] (size_type i) {
0311 BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
0312 return e_ [i];
0313 }
0314
0315
0316 BOOST_UBLAS_INLINE
0317 bool same_closure (const vector_unary &vu) const {
0318 return (*this).expression ().same_closure (vu.expression ());
0319 }
0320
0321
0322 private:
0323 typedef typename E::const_iterator const_subiterator_type;
0324 typedef const value_type *const_pointer;
0325
0326 public:
0327 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0328 typedef indexed_const_iterator<const_closure_type, typename const_subiterator_type::iterator_category> const_iterator;
0329 typedef const_iterator iterator;
0330 #else
0331 class const_iterator;
0332 typedef const_iterator iterator;
0333 #endif
0334
0335
0336 BOOST_UBLAS_INLINE
0337 const_iterator find (size_type i) const {
0338 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0339 const_subiterator_type it (e_.find (i));
0340 return const_iterator (*this, it.index ());
0341 #else
0342 return const_iterator (*this, e_.find (i));
0343 #endif
0344 }
0345
0346
0347
0348
0349 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0350 class const_iterator:
0351 public container_const_reference<vector_unary>,
0352 public iterator_base_traits<typename E::const_iterator::iterator_category>::template
0353 iterator_base<const_iterator, value_type>::type {
0354 public:
0355 typedef typename E::const_iterator::iterator_category iterator_category;
0356 typedef typename vector_unary::difference_type difference_type;
0357 typedef typename vector_unary::value_type value_type;
0358 typedef typename vector_unary::const_reference reference;
0359 typedef typename vector_unary::const_pointer pointer;
0360
0361
0362 BOOST_UBLAS_INLINE
0363 const_iterator ():
0364 container_const_reference<self_type> (), it_ () {}
0365 BOOST_UBLAS_INLINE
0366 const_iterator (const self_type &vu, const const_subiterator_type &it):
0367 container_const_reference<self_type> (vu), it_ (it) {}
0368
0369
0370 BOOST_UBLAS_INLINE
0371 const_iterator &operator ++ () {
0372 ++ it_;
0373 return *this;
0374 }
0375 BOOST_UBLAS_INLINE
0376 const_iterator &operator -- () {
0377 -- it_;
0378 return *this;
0379 }
0380 BOOST_UBLAS_INLINE
0381 const_iterator &operator += (difference_type n) {
0382 it_ += n;
0383 return *this;
0384 }
0385 BOOST_UBLAS_INLINE
0386 const_iterator &operator -= (difference_type n) {
0387 it_ -= n;
0388 return *this;
0389 }
0390 BOOST_UBLAS_INLINE
0391 difference_type operator - (const const_iterator &it) const {
0392 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0393 return it_ - it.it_;
0394 }
0395
0396
0397 BOOST_UBLAS_INLINE
0398 const_reference operator * () const {
0399 return functor_type::apply (*it_);
0400 }
0401 BOOST_UBLAS_INLINE
0402 const_reference operator [] (difference_type n) const {
0403 return *(*this + n);
0404 }
0405
0406
0407 BOOST_UBLAS_INLINE
0408 size_type index () const {
0409 return it_.index ();
0410 }
0411
0412
0413 BOOST_UBLAS_INLINE
0414 const_iterator &operator = (const const_iterator &it) {
0415 container_const_reference<self_type>::assign (&it ());
0416 it_ = it.it_;
0417 return *this;
0418 }
0419
0420
0421 BOOST_UBLAS_INLINE
0422 bool operator == (const const_iterator &it) const {
0423 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0424 return it_ == it.it_;
0425 }
0426 BOOST_UBLAS_INLINE
0427 bool operator < (const const_iterator &it) const {
0428 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0429 return it_ < it.it_;
0430 }
0431
0432 private:
0433 const_subiterator_type it_;
0434 };
0435 #endif
0436
0437 BOOST_UBLAS_INLINE
0438 const_iterator begin () const {
0439 return find (0);
0440 }
0441 BOOST_UBLAS_INLINE
0442 const_iterator cbegin () const {
0443 return begin ();
0444 }
0445 BOOST_UBLAS_INLINE
0446 const_iterator end () const {
0447 return find (size ());
0448 }
0449 BOOST_UBLAS_INLINE
0450 const_iterator cend () const {
0451 return end ();
0452 }
0453
0454
0455 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
0456
0457 BOOST_UBLAS_INLINE
0458 const_reverse_iterator rbegin () const {
0459 return const_reverse_iterator (end ());
0460 }
0461 BOOST_UBLAS_INLINE
0462 const_reverse_iterator crbegin () const {
0463 return rbegin ();
0464 }
0465 BOOST_UBLAS_INLINE
0466 const_reverse_iterator rend () const {
0467 return const_reverse_iterator (begin ());
0468 }
0469 BOOST_UBLAS_INLINE
0470 const_reverse_iterator crend () const {
0471 return rend ();
0472 }
0473
0474 private:
0475 expression_closure_type e_;
0476 };
0477
0478 template<class E, class F>
0479 struct vector_unary_traits {
0480 typedef vector_unary<E, F> expression_type;
0481
0482
0483 typedef expression_type result_type;
0484
0485
0486
0487 };
0488
0489
0490 template<class E>
0491 BOOST_UBLAS_INLINE
0492 typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::result_type
0493 operator - (const vector_expression<E> &e) {
0494 typedef typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::expression_type expression_type;
0495 return expression_type (e ());
0496 }
0497
0498
0499 template<class E>
0500 BOOST_UBLAS_INLINE
0501 typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
0502 conj (const vector_expression<E> &e) {
0503 typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
0504 return expression_type (e ());
0505 }
0506
0507
0508 template<class E>
0509 BOOST_UBLAS_INLINE
0510 typename vector_unary_traits<E, scalar_real<typename E::value_type> >::result_type
0511 real (const vector_expression<E> &e) {
0512 typedef typename vector_unary_traits<E, scalar_real<typename E::value_type> >::expression_type expression_type;
0513 return expression_type (e ());
0514 }
0515
0516
0517 template<class E>
0518 BOOST_UBLAS_INLINE
0519 typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::result_type
0520 imag (const vector_expression<E> &e) {
0521 typedef typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::expression_type expression_type;
0522 return expression_type (e ());
0523 }
0524
0525
0526 template<class E>
0527 BOOST_UBLAS_INLINE
0528 typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::result_type
0529 trans (const vector_expression<E> &e) {
0530 typedef typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::expression_type expression_type;
0531 return expression_type (e ());
0532 }
0533 template<class E>
0534 BOOST_UBLAS_INLINE
0535 typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::result_type
0536 trans (vector_expression<E> &e) {
0537 typedef typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::expression_type expression_type;
0538 return expression_type (e ());
0539 }
0540
0541
0542 template<class E>
0543 BOOST_UBLAS_INLINE
0544 typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
0545 herm (const vector_expression<E> &e) {
0546 typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
0547 return expression_type (e ());
0548 }
0549
0550 template<class E1, class E2, class F>
0551 class vector_binary:
0552 public vector_expression<vector_binary<E1, E2, F> > {
0553
0554 typedef E1 expression1_type;
0555 typedef E2 expression2_type;
0556 typedef F functor_type;
0557 typedef typename E1::const_closure_type expression1_closure_type;
0558 typedef typename E2::const_closure_type expression2_closure_type;
0559 typedef vector_binary<E1, E2, F> self_type;
0560 public:
0561 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0562 using vector_expression<vector_binary<E1, E2, F> >::operator ();
0563 #endif
0564 typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
0565 typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
0566 typedef typename F::result_type value_type;
0567 typedef value_type const_reference;
0568 typedef const_reference reference;
0569 typedef const self_type const_closure_type;
0570 typedef const_closure_type closure_type;
0571 typedef unknown_storage_tag storage_category;
0572
0573
0574 BOOST_UBLAS_INLINE
0575 vector_binary (const expression1_type &e1, const expression2_type &e2):
0576 e1_ (e1), e2_ (e2) {}
0577
0578
0579 BOOST_UBLAS_INLINE
0580 size_type size () const {
0581 return BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
0582 }
0583
0584 private:
0585
0586 BOOST_UBLAS_INLINE
0587 const expression1_closure_type &expression1 () const {
0588 return e1_;
0589 }
0590 BOOST_UBLAS_INLINE
0591 const expression2_closure_type &expression2 () const {
0592 return e2_;
0593 }
0594
0595 public:
0596
0597 BOOST_UBLAS_INLINE
0598 const_reference operator () (size_type i) const {
0599 return functor_type::apply (e1_ (i), e2_ (i));
0600 }
0601
0602 BOOST_UBLAS_INLINE
0603 const_reference operator [] (size_type i) const {
0604 return functor_type::apply (e1_ [i], e2_ [i]);
0605 }
0606
0607
0608 BOOST_UBLAS_INLINE
0609 bool same_closure (const vector_binary &vb) const {
0610 return (*this).expression1 ().same_closure (vb.expression1 ()) &&
0611 (*this).expression2 ().same_closure (vb.expression2 ());
0612 }
0613
0614
0615 private:
0616 typedef typename E1::const_iterator const_subiterator1_type;
0617 typedef typename E2::const_iterator const_subiterator2_type;
0618 typedef const value_type *const_pointer;
0619
0620 public:
0621 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0622 typedef typename iterator_restrict_traits<typename const_subiterator1_type::iterator_category,
0623 typename const_subiterator2_type::iterator_category>::iterator_category iterator_category;
0624 typedef indexed_const_iterator<const_closure_type, iterator_category> const_iterator;
0625 typedef const_iterator iterator;
0626 #else
0627 class const_iterator;
0628 typedef const_iterator iterator;
0629 #endif
0630
0631
0632 BOOST_UBLAS_INLINE
0633 const_iterator find (size_type i) const {
0634 const_subiterator1_type it1 (e1_.find (i));
0635 const_subiterator1_type it1_end (e1_.find (size ()));
0636 const_subiterator2_type it2 (e2_.find (i));
0637 const_subiterator2_type it2_end (e2_.find (size ()));
0638 i = (std::min) (it1 != it1_end ? it1.index () : size (),
0639 it2 != it2_end ? it2.index () : size ());
0640 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
0641 return const_iterator (*this, i);
0642 #else
0643 return const_iterator (*this, i, it1, it1_end, it2, it2_end);
0644 #endif
0645 }
0646
0647
0648
0649
0650 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
0651 class const_iterator:
0652 public container_const_reference<vector_binary>,
0653 public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
0654 typename E2::const_iterator::iterator_category>::iterator_category>::template
0655 iterator_base<const_iterator, value_type>::type {
0656 public:
0657 typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
0658 typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
0659 typedef typename vector_binary::difference_type difference_type;
0660 typedef typename vector_binary::value_type value_type;
0661 typedef typename vector_binary::const_reference reference;
0662 typedef typename vector_binary::const_pointer pointer;
0663
0664
0665 BOOST_UBLAS_INLINE
0666 const_iterator ():
0667 container_const_reference<self_type> (), i_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {}
0668 BOOST_UBLAS_INLINE
0669 const_iterator (const self_type &vb, size_type i,
0670 const const_subiterator1_type &it1, const const_subiterator1_type &it1_end,
0671 const const_subiterator2_type &it2, const const_subiterator2_type &it2_end):
0672 container_const_reference<self_type> (vb), i_ (i), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {}
0673
0674 private:
0675
0676 BOOST_UBLAS_INLINE
0677 void increment (dense_random_access_iterator_tag) {
0678 ++ i_; ++ it1_; ++ it2_;
0679 }
0680 BOOST_UBLAS_INLINE
0681 void decrement (dense_random_access_iterator_tag) {
0682 -- i_; -- it1_; -- it2_;
0683 }
0684 BOOST_UBLAS_INLINE
0685 void increment (dense_random_access_iterator_tag, difference_type n) {
0686 i_ += n; it1_ += n; it2_ += n;
0687 }
0688 BOOST_UBLAS_INLINE
0689 void decrement (dense_random_access_iterator_tag, difference_type n) {
0690 i_ -= n; it1_ -= n; it2_ -= n;
0691 }
0692 BOOST_UBLAS_INLINE
0693 value_type dereference (dense_random_access_iterator_tag) const {
0694 return functor_type::apply (*it1_, *it2_);
0695 }
0696
0697
0698 BOOST_UBLAS_INLINE
0699 void increment (packed_random_access_iterator_tag) {
0700 if (it1_ != it1_end_)
0701 if (it1_.index () <= i_)
0702 ++ it1_;
0703 if (it2_ != it2_end_)
0704 if (it2_.index () <= i_)
0705 ++ it2_;
0706 ++ i_;
0707 }
0708 BOOST_UBLAS_INLINE
0709 void decrement (packed_random_access_iterator_tag) {
0710 if (it1_ != it1_end_)
0711 if (i_ <= it1_.index ())
0712 -- it1_;
0713 if (it2_ != it2_end_)
0714 if (i_ <= it2_.index ())
0715 -- it2_;
0716 -- i_;
0717 }
0718 BOOST_UBLAS_INLINE
0719 void increment (packed_random_access_iterator_tag, difference_type n) {
0720 while (n > 0) {
0721 increment (packed_random_access_iterator_tag ());
0722 --n;
0723 }
0724 while (n < 0) {
0725 decrement (packed_random_access_iterator_tag ());
0726 ++n;
0727 }
0728 }
0729 BOOST_UBLAS_INLINE
0730 void decrement (packed_random_access_iterator_tag, difference_type n) {
0731 while (n > 0) {
0732 decrement (packed_random_access_iterator_tag ());
0733 --n;
0734 }
0735 while (n < 0) {
0736 increment (packed_random_access_iterator_tag ());
0737 ++n;
0738 }
0739 }
0740 BOOST_UBLAS_INLINE
0741 value_type dereference (packed_random_access_iterator_tag) const {
0742 typename E1::value_type t1 = typename E1::value_type();
0743 if (it1_ != it1_end_)
0744 if (it1_.index () == i_)
0745 t1 = *it1_;
0746 typename E2::value_type t2 = typename E2::value_type();
0747 if (it2_ != it2_end_)
0748 if (it2_.index () == i_)
0749 t2 = *it2_;
0750 return functor_type::apply (t1, t2);
0751 }
0752
0753
0754 BOOST_UBLAS_INLINE
0755 void increment (sparse_bidirectional_iterator_tag) {
0756 size_type index1 = (*this) ().size ();
0757 if (it1_ != it1_end_) {
0758 if (it1_.index () <= i_)
0759 ++ it1_;
0760 if (it1_ != it1_end_)
0761 index1 = it1_.index ();
0762 }
0763 size_type index2 = (*this) ().size ();
0764 if (it2_ != it2_end_) {
0765 if (it2_.index () <= i_)
0766 ++ it2_;
0767 if (it2_ != it2_end_)
0768 index2 = it2_.index ();
0769 }
0770 i_ = (std::min) (index1, index2);
0771 }
0772 BOOST_UBLAS_INLINE
0773 void decrement (sparse_bidirectional_iterator_tag) {
0774 size_type index1 = (*this) ().size ();
0775 if (it1_ != it1_end_) {
0776 if (i_ <= it1_.index ())
0777 -- it1_;
0778 if (it1_ != it1_end_)
0779 index1 = it1_.index ();
0780 }
0781 size_type index2 = (*this) ().size ();
0782 if (it2_ != it2_end_) {
0783 if (i_ <= it2_.index ())
0784 -- it2_;
0785 if (it2_ != it2_end_)
0786 index2 = it2_.index ();
0787 }
0788 i_ = (std::max) (index1, index2);
0789 }
0790 BOOST_UBLAS_INLINE
0791 void increment (sparse_bidirectional_iterator_tag, difference_type n) {
0792 while (n > 0) {
0793 increment (sparse_bidirectional_iterator_tag ());
0794 --n;
0795 }
0796 while (n < 0) {
0797 decrement (sparse_bidirectional_iterator_tag ());
0798 ++n;
0799 }
0800 }
0801 BOOST_UBLAS_INLINE
0802 void decrement (sparse_bidirectional_iterator_tag, difference_type n) {
0803 while (n > 0) {
0804 decrement (sparse_bidirectional_iterator_tag ());
0805 --n;
0806 }
0807 while (n < 0) {
0808 increment (sparse_bidirectional_iterator_tag ());
0809 ++n;
0810 }
0811 }
0812 BOOST_UBLAS_INLINE
0813 value_type dereference (sparse_bidirectional_iterator_tag) const {
0814 typename E1::value_type t1 = typename E1::value_type();
0815 if (it1_ != it1_end_)
0816 if (it1_.index () == i_)
0817 t1 = *it1_;
0818 typename E2::value_type t2 = typename E2::value_type();
0819 if (it2_ != it2_end_)
0820 if (it2_.index () == i_)
0821 t2 = *it2_;
0822 return static_cast<value_type>(functor_type::apply (t1, t2));
0823 }
0824
0825 public:
0826
0827 BOOST_UBLAS_INLINE
0828 const_iterator &operator ++ () {
0829 increment (iterator_category ());
0830 return *this;
0831 }
0832 BOOST_UBLAS_INLINE
0833 const_iterator &operator -- () {
0834 decrement (iterator_category ());
0835 return *this;
0836 }
0837 BOOST_UBLAS_INLINE
0838 const_iterator &operator += (difference_type n) {
0839 increment (iterator_category (), n);
0840 return *this;
0841 }
0842 BOOST_UBLAS_INLINE
0843 const_iterator &operator -= (difference_type n) {
0844 decrement (iterator_category (), n);
0845 return *this;
0846 }
0847 BOOST_UBLAS_INLINE
0848 difference_type operator - (const const_iterator &it) const {
0849 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0850 return index () - it.index ();
0851 }
0852
0853
0854 BOOST_UBLAS_INLINE
0855 const_reference operator * () const {
0856 return dereference (iterator_category ());
0857 }
0858 BOOST_UBLAS_INLINE
0859 const_reference operator [] (difference_type n) const {
0860 return *(*this + n);
0861 }
0862
0863
0864 BOOST_UBLAS_INLINE
0865 size_type index () const {
0866 return i_;
0867 }
0868
0869
0870 BOOST_UBLAS_INLINE
0871 const_iterator &operator = (const const_iterator &it) {
0872 container_const_reference<self_type>::assign (&it ());
0873 i_ = it.i_;
0874 it1_ = it.it1_;
0875 it1_end_ = it.it1_end_;
0876 it2_ = it.it2_;
0877 it2_end_ = it.it2_end_;
0878 return *this;
0879 }
0880
0881
0882 BOOST_UBLAS_INLINE
0883 bool operator == (const const_iterator &it) const {
0884 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0885 return index () == it.index ();
0886 }
0887 BOOST_UBLAS_INLINE
0888 bool operator < (const const_iterator &it) const {
0889 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
0890 return index () < it.index ();
0891 }
0892
0893 private:
0894 size_type i_;
0895 const_subiterator1_type it1_;
0896 const_subiterator1_type it1_end_;
0897 const_subiterator2_type it2_;
0898 const_subiterator2_type it2_end_;
0899 };
0900 #endif
0901
0902 BOOST_UBLAS_INLINE
0903 const_iterator begin () const {
0904 return find (0);
0905 }
0906 BOOST_UBLAS_INLINE
0907 const_iterator cbegin () const {
0908 return begin ();
0909 }
0910 BOOST_UBLAS_INLINE
0911 const_iterator end () const {
0912 return find (size ());
0913 }
0914 BOOST_UBLAS_INLINE
0915 const_iterator cend () const {
0916 return end ();
0917 }
0918
0919
0920 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
0921
0922 BOOST_UBLAS_INLINE
0923 const_reverse_iterator rbegin () const {
0924 return const_reverse_iterator (end ());
0925 }
0926 BOOST_UBLAS_INLINE
0927 const_reverse_iterator crbegin () const {
0928 return rbegin ();
0929 }
0930 BOOST_UBLAS_INLINE
0931 const_reverse_iterator rend () const {
0932 return const_reverse_iterator (begin ());
0933 }
0934 BOOST_UBLAS_INLINE
0935 const_reverse_iterator crend () const {
0936 return rend ();
0937 }
0938
0939 private:
0940 expression1_closure_type e1_;
0941 expression2_closure_type e2_;
0942 };
0943
0944 template<class E1, class E2, class F>
0945 struct vector_binary_traits {
0946 typedef vector_binary<E1, E2, F> expression_type;
0947 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
0948 typedef expression_type result_type;
0949 #else
0950 typedef typename E1::vector_temporary_type result_type;
0951 #endif
0952 };
0953
0954
0955 template<class E1, class E2>
0956 BOOST_UBLAS_INLINE
0957 typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
0958 typename E2::value_type> >::result_type
0959 operator + (const vector_expression<E1> &e1,
0960 const vector_expression<E2> &e2) {
0961 typedef typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
0962 typename E2::value_type> >::expression_type expression_type;
0963 return expression_type (e1 (), e2 ());
0964 }
0965
0966
0967 template<class E1, class E2>
0968 BOOST_UBLAS_INLINE
0969 typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
0970 typename E2::value_type> >::result_type
0971 operator - (const vector_expression<E1> &e1,
0972 const vector_expression<E2> &e2) {
0973 typedef typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
0974 typename E2::value_type> >::expression_type expression_type;
0975 return expression_type (e1 (), e2 ());
0976 }
0977
0978
0979 template<class E1, class E2>
0980 BOOST_UBLAS_INLINE
0981 typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
0982 typename E2::value_type> >::result_type
0983 element_prod (const vector_expression<E1> &e1,
0984 const vector_expression<E2> &e2) {
0985 typedef typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
0986 typename E2::value_type> >::expression_type expression_type;
0987 return expression_type (e1 (), e2 ());
0988 }
0989
0990
0991 template<class E1, class E2>
0992 BOOST_UBLAS_INLINE
0993 typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
0994 typename E2::value_type> >::result_type
0995 element_div (const vector_expression<E1> &e1,
0996 const vector_expression<E2> &e2) {
0997 typedef typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
0998 typename E2::value_type> >::expression_type expression_type;
0999 return expression_type (e1 (), e2 ());
1000 }
1001
1002
1003 template<class E1, class E2, class F>
1004 class vector_binary_scalar1:
1005 public vector_expression<vector_binary_scalar1<E1, E2, F> > {
1006
1007 typedef F functor_type;
1008 typedef E1 expression1_type;
1009 typedef E2 expression2_type;
1010 public:
1011 typedef const E1& expression1_closure_type;
1012 typedef typename E2::const_closure_type expression2_closure_type;
1013 private:
1014 typedef vector_binary_scalar1<E1, E2, F> self_type;
1015 public:
1016 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1017 using vector_expression<vector_binary_scalar1<E1, E2, F> >::operator ();
1018 #endif
1019 typedef typename E2::size_type size_type;
1020 typedef typename E2::difference_type difference_type;
1021 typedef typename F::result_type value_type;
1022 typedef value_type const_reference;
1023 typedef const_reference reference;
1024 typedef const self_type const_closure_type;
1025 typedef const_closure_type closure_type;
1026 typedef unknown_storage_tag storage_category;
1027
1028
1029 BOOST_UBLAS_INLINE
1030 vector_binary_scalar1 (const expression1_type &e1, const expression2_type &e2):
1031 e1_ (e1), e2_ (e2) {}
1032
1033
1034 BOOST_UBLAS_INLINE
1035 size_type size () const {
1036 return e2_.size ();
1037 }
1038
1039 public:
1040
1041 BOOST_UBLAS_INLINE
1042 const_reference operator () (size_type i) const {
1043 return functor_type::apply (e1_, e2_ (i));
1044 }
1045
1046 BOOST_UBLAS_INLINE
1047 const_reference operator [] (size_type i) const {
1048 return functor_type::apply (e1_, e2_ [i]);
1049 }
1050
1051
1052 BOOST_UBLAS_INLINE
1053 bool same_closure (const vector_binary_scalar1 &vbs1) const {
1054 return &e1_ == &(vbs1.e1_) &&
1055 (*this).e2_.same_closure (vbs1.e2_);
1056 }
1057
1058
1059 private:
1060 typedef expression1_type const_subiterator1_type;
1061 typedef typename expression2_type::const_iterator const_subiterator2_type;
1062 typedef const value_type *const_pointer;
1063
1064 public:
1065 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1066 typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
1067 typedef const_iterator iterator;
1068 #else
1069 class const_iterator;
1070 typedef const_iterator iterator;
1071 #endif
1072
1073
1074 BOOST_UBLAS_INLINE
1075 const_iterator find (size_type i) const {
1076 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1077 const_subiterator2_type it (e2_.find (i));
1078 return const_iterator (*this, it.index ());
1079 #else
1080 return const_iterator (*this, const_subiterator1_type (e1_), e2_.find (i));
1081 #endif
1082 }
1083
1084
1085
1086
1087 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1088 class const_iterator:
1089 public container_const_reference<vector_binary_scalar1>,
1090 public iterator_base_traits<typename E2::const_iterator::iterator_category>::template
1091 iterator_base<const_iterator, value_type>::type {
1092 public:
1093 typedef typename E2::const_iterator::iterator_category iterator_category;
1094 typedef typename vector_binary_scalar1::difference_type difference_type;
1095 typedef typename vector_binary_scalar1::value_type value_type;
1096 typedef typename vector_binary_scalar1::const_reference reference;
1097 typedef typename vector_binary_scalar1::const_pointer pointer;
1098
1099
1100 BOOST_UBLAS_INLINE
1101 const_iterator ():
1102 container_const_reference<self_type> (), it1_ (), it2_ () {}
1103 BOOST_UBLAS_INLINE
1104 const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
1105 container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
1106
1107
1108 BOOST_UBLAS_INLINE
1109 const_iterator &operator ++ () {
1110 ++ it2_;
1111 return *this;
1112 }
1113 BOOST_UBLAS_INLINE
1114 const_iterator &operator -- () {
1115 -- it2_;
1116 return *this;
1117 }
1118 BOOST_UBLAS_INLINE
1119 const_iterator &operator += (difference_type n) {
1120 it2_ += n;
1121 return *this;
1122 }
1123 BOOST_UBLAS_INLINE
1124 const_iterator &operator -= (difference_type n) {
1125 it2_ -= n;
1126 return *this;
1127 }
1128 BOOST_UBLAS_INLINE
1129 difference_type operator - (const const_iterator &it) const {
1130 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1131
1132
1133 return it2_ - it.it2_;
1134 }
1135
1136
1137 BOOST_UBLAS_INLINE
1138 const_reference operator * () const {
1139 return functor_type::apply (it1_, *it2_);
1140 }
1141 BOOST_UBLAS_INLINE
1142 const_reference operator [] (difference_type n) const {
1143 return *(*this + n);
1144 }
1145
1146
1147 BOOST_UBLAS_INLINE
1148 size_type index () const {
1149 return it2_.index ();
1150 }
1151
1152
1153 BOOST_UBLAS_INLINE
1154 const_iterator &operator = (const const_iterator &it) {
1155 container_const_reference<self_type>::assign (&it ());
1156 it1_ = it.it1_;
1157 it2_ = it.it2_;
1158 return *this;
1159 }
1160
1161
1162 BOOST_UBLAS_INLINE
1163 bool operator == (const const_iterator &it) const {
1164 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1165
1166
1167 return it2_ == it.it2_;
1168 }
1169 BOOST_UBLAS_INLINE
1170 bool operator < (const const_iterator &it) const {
1171 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1172
1173
1174 return it2_ < it.it2_;
1175 }
1176
1177 private:
1178 const_subiterator1_type it1_;
1179 const_subiterator2_type it2_;
1180 };
1181 #endif
1182
1183 BOOST_UBLAS_INLINE
1184 const_iterator begin () const {
1185 return find (0);
1186 }
1187 BOOST_UBLAS_INLINE
1188 const_iterator cbegin () const {
1189 return begin ();
1190 }
1191 BOOST_UBLAS_INLINE
1192 const_iterator end () const {
1193 return find (size ());
1194 }
1195 BOOST_UBLAS_INLINE
1196 const_iterator cend () const {
1197 return end ();
1198 }
1199
1200
1201 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1202
1203 BOOST_UBLAS_INLINE
1204 const_reverse_iterator rbegin () const {
1205 return const_reverse_iterator (end ());
1206 }
1207 BOOST_UBLAS_INLINE
1208 const_reverse_iterator crbegin () const {
1209 return rbegin ();
1210 }
1211 BOOST_UBLAS_INLINE
1212 const_reverse_iterator rend () const {
1213 return const_reverse_iterator (begin ());
1214 }
1215 BOOST_UBLAS_INLINE
1216 const_reverse_iterator crend () const {
1217 return end ();
1218 }
1219
1220 private:
1221 expression1_closure_type e1_;
1222 expression2_closure_type e2_;
1223 };
1224
1225 template<class E1, class E2, class F>
1226 struct vector_binary_scalar1_traits {
1227 typedef vector_binary_scalar1<E1, E2, F> expression_type;
1228 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
1229 typedef expression_type result_type;
1230 #else
1231 typedef typename E2::vector_temporary_type result_type;
1232 #endif
1233 };
1234
1235
1236 template<class T1, class E2>
1237 BOOST_UBLAS_INLINE
1238 typename boost::enable_if< is_convertible<T1, typename E2::value_type >,
1239 typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::result_type
1240 >::type
1241 operator * (const T1 &e1,
1242 const vector_expression<E2> &e2) {
1243 typedef typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::expression_type expression_type;
1244 return expression_type (e1, e2 ());
1245 }
1246
1247
1248 template<class E1, class E2, class F>
1249 class vector_binary_scalar2:
1250 public vector_expression<vector_binary_scalar2<E1, E2, F> > {
1251
1252 typedef F functor_type;
1253 typedef E1 expression1_type;
1254 typedef E2 expression2_type;
1255 typedef typename E1::const_closure_type expression1_closure_type;
1256 typedef const E2& expression2_closure_type;
1257 typedef vector_binary_scalar2<E1, E2, F> self_type;
1258 public:
1259 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
1260 using vector_expression<vector_binary_scalar2<E1, E2, F> >::operator ();
1261 #endif
1262 typedef typename E1::size_type size_type;
1263 typedef typename E1::difference_type difference_type;
1264 typedef typename F::result_type value_type;
1265 typedef value_type const_reference;
1266 typedef const_reference reference;
1267 typedef const self_type const_closure_type;
1268 typedef const_closure_type closure_type;
1269 typedef unknown_storage_tag storage_category;
1270
1271
1272 BOOST_UBLAS_INLINE
1273 vector_binary_scalar2 (const expression1_type &e1, const expression2_type &e2):
1274 e1_ (e1), e2_ (e2) {}
1275
1276
1277 BOOST_UBLAS_INLINE
1278 size_type size () const {
1279 return e1_.size ();
1280 }
1281
1282 public:
1283
1284 BOOST_UBLAS_INLINE
1285 const_reference operator () (size_type i) const {
1286 return functor_type::apply (e1_ (i), e2_);
1287 }
1288
1289 BOOST_UBLAS_INLINE
1290 const_reference operator [] (size_type i) const {
1291 return functor_type::apply (e1_ [i], e2_);
1292 }
1293
1294
1295 BOOST_UBLAS_INLINE
1296 bool same_closure (const vector_binary_scalar2 &vbs2) const {
1297 return (*this).e1_.same_closure (vbs2.e1_) &&
1298 &e2_ == &(vbs2.e2_);
1299 }
1300
1301
1302 private:
1303 typedef typename expression1_type::const_iterator const_subiterator1_type;
1304 typedef expression2_type const_subiterator2_type;
1305 typedef const value_type *const_pointer;
1306
1307 public:
1308 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1309 typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
1310 typedef const_iterator iterator;
1311 #else
1312 class const_iterator;
1313 typedef const_iterator iterator;
1314 #endif
1315
1316
1317 BOOST_UBLAS_INLINE
1318 const_iterator find (size_type i) const {
1319 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
1320 const_subiterator1_type it (e1_.find (i));
1321 return const_iterator (*this, it.index ());
1322 #else
1323 return const_iterator (*this, e1_.find (i), const_subiterator2_type (e2_));
1324 #endif
1325 }
1326
1327
1328
1329
1330 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
1331 class const_iterator:
1332 public container_const_reference<vector_binary_scalar2>,
1333 public iterator_base_traits<typename E1::const_iterator::iterator_category>::template
1334 iterator_base<const_iterator, value_type>::type {
1335 public:
1336 typedef typename E1::const_iterator::iterator_category iterator_category;
1337 typedef typename vector_binary_scalar2::difference_type difference_type;
1338 typedef typename vector_binary_scalar2::value_type value_type;
1339 typedef typename vector_binary_scalar2::const_reference reference;
1340 typedef typename vector_binary_scalar2::const_pointer pointer;
1341
1342
1343 BOOST_UBLAS_INLINE
1344 const_iterator ():
1345 container_const_reference<self_type> (), it1_ (), it2_ () {}
1346 BOOST_UBLAS_INLINE
1347 const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
1348 container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
1349
1350
1351 BOOST_UBLAS_INLINE
1352 const_iterator &operator ++ () {
1353 ++ it1_;
1354 return *this;
1355 }
1356 BOOST_UBLAS_INLINE
1357 const_iterator &operator -- () {
1358 -- it1_;
1359 return *this;
1360 }
1361 BOOST_UBLAS_INLINE
1362 const_iterator &operator += (difference_type n) {
1363 it1_ += n;
1364 return *this;
1365 }
1366 BOOST_UBLAS_INLINE
1367 const_iterator &operator -= (difference_type n) {
1368 it1_ -= n;
1369 return *this;
1370 }
1371 BOOST_UBLAS_INLINE
1372 difference_type operator - (const const_iterator &it) const {
1373 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1374
1375
1376 return it1_ - it.it1_;
1377 }
1378
1379
1380 BOOST_UBLAS_INLINE
1381 const_reference operator * () const {
1382 return functor_type::apply (*it1_, it2_);
1383 }
1384 BOOST_UBLAS_INLINE
1385 const_reference operator [] (difference_type n) const {
1386 return *(*this + n);
1387 }
1388
1389
1390 BOOST_UBLAS_INLINE
1391 size_type index () const {
1392 return it1_.index ();
1393 }
1394
1395
1396 BOOST_UBLAS_INLINE
1397 const_iterator &operator = (const const_iterator &it) {
1398 container_const_reference<self_type>::assign (&it ());
1399 it1_ = it.it1_;
1400 it2_ = it.it2_;
1401 return *this;
1402 }
1403
1404
1405 BOOST_UBLAS_INLINE
1406 bool operator == (const const_iterator &it) const {
1407 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1408
1409
1410 return it1_ == it.it1_;
1411 }
1412 BOOST_UBLAS_INLINE
1413 bool operator < (const const_iterator &it) const {
1414 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
1415
1416
1417 return it1_ < it.it1_;
1418 }
1419
1420 private:
1421 const_subiterator1_type it1_;
1422 const_subiterator2_type it2_;
1423 };
1424 #endif
1425
1426 BOOST_UBLAS_INLINE
1427 const_iterator begin () const {
1428 return find (0);
1429 }
1430 BOOST_UBLAS_INLINE
1431 const_iterator cbegin () const {
1432 return begin ();
1433 }
1434 BOOST_UBLAS_INLINE
1435 const_iterator end () const {
1436 return find (size ());
1437 }
1438 BOOST_UBLAS_INLINE
1439 const_iterator cend () const {
1440 return end ();
1441 }
1442
1443
1444 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
1445
1446 BOOST_UBLAS_INLINE
1447 const_reverse_iterator rbegin () const {
1448 return const_reverse_iterator (end ());
1449 }
1450 BOOST_UBLAS_INLINE
1451 const_reverse_iterator crbegin () const {
1452 return rbegin ();
1453 }
1454 BOOST_UBLAS_INLINE
1455 const_reverse_iterator rend () const {
1456 return const_reverse_iterator (begin ());
1457 }
1458 BOOST_UBLAS_INLINE
1459 const_reverse_iterator crend () const {
1460 return rend ();
1461 }
1462
1463 private:
1464 expression1_closure_type e1_;
1465 expression2_closure_type e2_;
1466 };
1467
1468 template<class E1, class E2, class F>
1469 struct vector_binary_scalar2_traits {
1470 typedef vector_binary_scalar2<E1, E2, F> expression_type;
1471 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
1472 typedef expression_type result_type;
1473 #else
1474 typedef typename E1::vector_temporary_type result_type;
1475 #endif
1476 };
1477
1478
1479 template<class E1, class T2>
1480 BOOST_UBLAS_INLINE
1481 typename boost::enable_if< is_convertible<T2, typename E1::value_type >,
1482 typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::result_type
1483 >::type
1484 operator * (const vector_expression<E1> &e1,
1485 const T2 &e2) {
1486 typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::expression_type expression_type;
1487 return expression_type (e1 (), e2);
1488 }
1489
1490
1491 template<class E1, class T2>
1492 BOOST_UBLAS_INLINE
1493 typename boost::enable_if< is_convertible<T2, typename E1::value_type >,
1494 typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::result_type
1495 >::type
1496 operator / (const vector_expression<E1> &e1,
1497 const T2 &e2) {
1498 typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::expression_type expression_type;
1499 return expression_type (e1 (), e2);
1500 }
1501
1502
1503 template<class E, class F>
1504 class vector_scalar_unary:
1505 public scalar_expression<vector_scalar_unary<E, F> > {
1506
1507 typedef E expression_type;
1508 typedef F functor_type;
1509 typedef typename E::const_closure_type expression_closure_type;
1510 typedef typename E::const_iterator::iterator_category iterator_category;
1511 typedef vector_scalar_unary<E, F> self_type;
1512 public:
1513 typedef typename F::result_type value_type;
1514 typedef typename E::difference_type difference_type;
1515 typedef const self_type const_closure_type;
1516 typedef const_closure_type closure_type;
1517 typedef unknown_storage_tag storage_category;
1518
1519
1520 BOOST_UBLAS_INLINE
1521 explicit vector_scalar_unary (const expression_type &e):
1522 e_ (e) {}
1523
1524 private:
1525
1526 BOOST_UBLAS_INLINE
1527 const expression_closure_type &expression () const {
1528 return e_;
1529 }
1530
1531 public:
1532 BOOST_UBLAS_INLINE
1533 operator value_type () const {
1534 return evaluate (iterator_category ());
1535 }
1536
1537 private:
1538
1539 BOOST_UBLAS_INLINE
1540 value_type evaluate (dense_random_access_iterator_tag) const {
1541 #ifdef BOOST_UBLAS_USE_INDEXING
1542 return functor_type::apply (e_);
1543 #elif BOOST_UBLAS_USE_ITERATING
1544 difference_type size = e_.size ();
1545 return functor_type::apply (size, e_.begin ());
1546 #else
1547 difference_type size = e_.size ();
1548 if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
1549 return functor_type::apply (size, e_.begin ());
1550 else
1551 return functor_type::apply (e_);
1552 #endif
1553 }
1554
1555
1556 BOOST_UBLAS_INLINE
1557 value_type evaluate (packed_random_access_iterator_tag) const {
1558 return functor_type::apply (e_.begin (), e_.end ());
1559 }
1560
1561
1562 BOOST_UBLAS_INLINE
1563 value_type evaluate (sparse_bidirectional_iterator_tag) const {
1564 return functor_type::apply (e_.begin (), e_.end ());
1565 }
1566
1567 private:
1568 expression_closure_type e_;
1569 };
1570
1571 template<class E, class F>
1572 struct vector_scalar_unary_traits {
1573 typedef vector_scalar_unary<E, F> expression_type;
1574 #if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
1575
1576
1577 typedef expression_type result_type;
1578 #else
1579 typedef typename F::result_type result_type;
1580 #endif
1581 };
1582
1583
1584 template<class E>
1585 BOOST_UBLAS_INLINE
1586 typename vector_scalar_unary_traits<E, vector_sum<E> >::result_type
1587 sum (const vector_expression<E> &e) {
1588 typedef typename vector_scalar_unary_traits<E, vector_sum<E> >::expression_type expression_type;
1589 return expression_type (e ());
1590 }
1591
1592
1593
1594 template<class E>
1595 BOOST_UBLAS_INLINE
1596 typename vector_scalar_unary_traits<E, vector_norm_1<E> >::result_type
1597 norm_1 (const vector_expression<E> &e) {
1598 typedef typename vector_scalar_unary_traits<E, vector_norm_1<E> >::expression_type expression_type;
1599 return expression_type (e ());
1600 }
1601
1602
1603
1604 template<class E>
1605 BOOST_UBLAS_INLINE
1606 typename vector_scalar_unary_traits<E, vector_norm_2<E> >::result_type
1607 norm_2 (const vector_expression<E> &e) {
1608 typedef typename vector_scalar_unary_traits<E, vector_norm_2<E> >::expression_type expression_type;
1609 return expression_type (e ());
1610 }
1611
1612
1613
1614 template<class E>
1615 BOOST_UBLAS_INLINE
1616 typename vector_scalar_unary_traits<E, vector_norm_2_square<E> >::result_type
1617 norm_2_square (const vector_expression<E> &e) {
1618 typedef typename vector_scalar_unary_traits<E, vector_norm_2_square<E> >::expression_type expression_type;
1619 return expression_type (e ());
1620 }
1621
1622
1623
1624 template<class E>
1625 BOOST_UBLAS_INLINE
1626 typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::result_type
1627 norm_inf (const vector_expression<E> &e) {
1628 typedef typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::expression_type expression_type;
1629 return expression_type (e ());
1630 }
1631
1632
1633 template<class E>
1634 BOOST_UBLAS_INLINE
1635 typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::result_type
1636 index_norm_inf (const vector_expression<E> &e) {
1637 typedef typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::expression_type expression_type;
1638 return expression_type (e ());
1639 }
1640
1641 template<class E1, class E2, class F>
1642 class vector_scalar_binary:
1643 public scalar_expression<vector_scalar_binary<E1, E2, F> > {
1644
1645 typedef E1 expression1_type;
1646 typedef E2 expression2_type;
1647 typedef F functor_type;
1648 typedef typename E1::const_closure_type expression1_closure_type;
1649 typedef typename E2::const_closure_type expression2_closure_type;
1650 typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
1651 typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
1652 typedef vector_scalar_binary<E1, E2, F> self_type;
1653 public:
1654 static const unsigned complexity = 1;
1655 typedef typename F::result_type value_type;
1656 typedef typename E1::difference_type difference_type;
1657 typedef const self_type const_closure_type;
1658 typedef const_closure_type closure_type;
1659 typedef unknown_storage_tag storage_category;
1660
1661
1662 BOOST_UBLAS_INLINE
1663 vector_scalar_binary (const expression1_type &e1, const expression2_type &e2):
1664 e1_ (e1), e2_ (e2) {}
1665
1666 private:
1667
1668 BOOST_UBLAS_INLINE
1669 const expression1_closure_type &expression1 () const {
1670 return e1_;
1671 }
1672 BOOST_UBLAS_INLINE
1673 const expression2_closure_type &expression2 () const {
1674 return e2_;
1675 }
1676
1677 public:
1678 BOOST_UBLAS_INLINE
1679 operator value_type () const {
1680 return evaluate (iterator_category ());
1681 }
1682
1683 private:
1684
1685 BOOST_UBLAS_INLINE
1686 value_type evaluate (dense_random_access_iterator_tag) const {
1687 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
1688 #ifdef BOOST_UBLAS_USE_INDEXING
1689 return functor_type::apply (e1_, e2_);
1690 #elif BOOST_UBLAS_USE_ITERATING
1691 difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
1692 return functor_type::apply (size, e1_.begin (), e2_.begin ());
1693 #else
1694 difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
1695 if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
1696 return functor_type::apply (size, e1_.begin (), e2_.begin ());
1697 else
1698 return functor_type::apply (e1_, e2_);
1699 #endif
1700 }
1701
1702
1703 BOOST_UBLAS_INLINE
1704 value_type evaluate (packed_random_access_iterator_tag) const {
1705 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
1706 return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end ());
1707 }
1708
1709
1710 BOOST_UBLAS_INLINE
1711 value_type evaluate (sparse_bidirectional_iterator_tag) const {
1712 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
1713 return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end (), sparse_bidirectional_iterator_tag ());
1714 }
1715
1716 private:
1717 expression1_closure_type e1_;
1718 expression2_closure_type e2_;
1719 };
1720
1721 template<class E1, class E2, class F>
1722 struct vector_scalar_binary_traits {
1723 typedef vector_scalar_binary<E1, E2, F> expression_type;
1724 #if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
1725
1726
1727 typedef expression_type result_type;
1728 #else
1729 typedef typename F::result_type result_type;
1730 #endif
1731 };
1732
1733
1734 template<class E1, class E2>
1735 BOOST_UBLAS_INLINE
1736 typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
1737 typename promote_traits<typename E1::value_type,
1738 typename E2::value_type>::promote_type> >::result_type
1739 inner_prod (const vector_expression<E1> &e1,
1740 const vector_expression<E2> &e2) {
1741 typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
1742 typename promote_traits<typename E1::value_type,
1743 typename E2::value_type>::promote_type> >::expression_type expression_type;
1744 return expression_type (e1 (), e2 ());
1745 }
1746
1747 template<class E1, class E2>
1748 BOOST_UBLAS_INLINE
1749 typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
1750 typename type_traits<typename promote_traits<typename E1::value_type,
1751 typename E2::value_type>::promote_type>::precision_type> >::result_type
1752 prec_inner_prod (const vector_expression<E1> &e1,
1753 const vector_expression<E2> &e2) {
1754 typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
1755 typename type_traits<typename promote_traits<typename E1::value_type,
1756 typename E2::value_type>::promote_type>::precision_type> >::expression_type expression_type;
1757 return expression_type (e1 (), e2 ());
1758 }
1759
1760 }}}
1761
1762 #endif