annotate DEPENDENCIES/generic/include/boost/numeric/ublas/vector_expression.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //
Chris@16 2 // Copyright (c) 2000-2002
Chris@16 3 // Joerg Walter, Mathias Koch
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // The authors gratefully acknowledge the support of
Chris@16 10 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 11 //
Chris@16 12
Chris@16 13 #ifndef _BOOST_UBLAS_VECTOR_EXPRESSION_
Chris@16 14 #define _BOOST_UBLAS_VECTOR_EXPRESSION_
Chris@16 15
Chris@16 16 #include <boost/numeric/ublas/expression_types.hpp>
Chris@16 17
Chris@16 18
Chris@16 19 // Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish
Chris@16 20 // Iterators based on ideas of Jeremy Siek
Chris@16 21 //
Chris@16 22 // Classes that model the Vector Expression concept
Chris@16 23
Chris@16 24 namespace boost { namespace numeric { namespace ublas {
Chris@16 25
Chris@16 26 template<class E>
Chris@16 27 class vector_reference:
Chris@16 28 public vector_expression<vector_reference<E> > {
Chris@16 29
Chris@16 30 typedef vector_reference<E> self_type;
Chris@16 31 public:
Chris@16 32 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 33 using vector_expression<vector_reference<E> >::operator ();
Chris@16 34 #endif
Chris@16 35 typedef typename E::size_type size_type;
Chris@16 36 typedef typename E::difference_type difference_type;
Chris@16 37 typedef typename E::value_type value_type;
Chris@16 38 typedef typename E::const_reference const_reference;
Chris@16 39 typedef typename boost::mpl::if_<boost::is_const<E>,
Chris@16 40 typename E::const_reference,
Chris@16 41 typename E::reference>::type reference;
Chris@16 42 typedef E referred_type;
Chris@16 43 typedef const self_type const_closure_type;
Chris@16 44 typedef self_type closure_type;
Chris@16 45 typedef typename E::storage_category storage_category;
Chris@16 46
Chris@16 47 // Construction and destruction
Chris@16 48 BOOST_UBLAS_INLINE
Chris@16 49 explicit vector_reference (referred_type &e):
Chris@16 50 e_ (e) {}
Chris@16 51
Chris@16 52 // Accessors
Chris@16 53 BOOST_UBLAS_INLINE
Chris@16 54 size_type size () const {
Chris@16 55 return expression ().size ();
Chris@16 56 }
Chris@16 57
Chris@16 58 public:
Chris@16 59 // Expression accessors - const correct
Chris@16 60 BOOST_UBLAS_INLINE
Chris@16 61 const referred_type &expression () const {
Chris@16 62 return e_;
Chris@16 63 }
Chris@16 64 BOOST_UBLAS_INLINE
Chris@16 65 referred_type &expression () {
Chris@16 66 return e_;
Chris@16 67 }
Chris@16 68
Chris@16 69 public:
Chris@16 70 // Element access
Chris@16 71 #ifndef BOOST_UBLAS_REFERENCE_CONST_MEMBER
Chris@16 72 BOOST_UBLAS_INLINE
Chris@16 73 const_reference operator () (size_type i) const {
Chris@16 74 return expression () (i);
Chris@16 75 }
Chris@16 76 BOOST_UBLAS_INLINE
Chris@16 77 reference operator () (size_type i) {
Chris@16 78 return expression () (i);
Chris@16 79 }
Chris@16 80
Chris@16 81 BOOST_UBLAS_INLINE
Chris@16 82 const_reference operator [] (size_type i) const {
Chris@16 83 return expression () [i];
Chris@16 84 }
Chris@16 85 BOOST_UBLAS_INLINE
Chris@16 86 reference operator [] (size_type i) {
Chris@16 87 return expression () [i];
Chris@16 88 }
Chris@16 89 #else
Chris@16 90 BOOST_UBLAS_INLINE
Chris@16 91 reference operator () (size_type i) const {
Chris@16 92 return expression () (i);
Chris@16 93 }
Chris@16 94
Chris@16 95 BOOST_UBLAS_INLINE
Chris@16 96 reference operator [] (size_type i) const {
Chris@16 97 return expression () [i];
Chris@16 98 }
Chris@16 99 #endif
Chris@16 100
Chris@16 101 // Assignment
Chris@16 102 BOOST_UBLAS_INLINE
Chris@16 103 vector_reference &operator = (const vector_reference &v) {
Chris@16 104 expression ().operator = (v);
Chris@16 105 return *this;
Chris@16 106 }
Chris@16 107 template<class AE>
Chris@16 108 BOOST_UBLAS_INLINE
Chris@16 109 vector_reference &operator = (const vector_expression<AE> &ae) {
Chris@16 110 expression ().operator = (ae);
Chris@16 111 return *this;
Chris@16 112 }
Chris@16 113 template<class AE>
Chris@16 114 BOOST_UBLAS_INLINE
Chris@16 115 vector_reference &assign (const vector_expression<AE> &ae) {
Chris@16 116 expression ().assign (ae);
Chris@16 117 return *this;
Chris@16 118 }
Chris@16 119 template<class AE>
Chris@16 120 BOOST_UBLAS_INLINE
Chris@16 121 vector_reference &operator += (const vector_expression<AE> &ae) {
Chris@16 122 expression ().operator += (ae);
Chris@16 123 return *this;
Chris@16 124 }
Chris@16 125 template<class AE>
Chris@16 126 BOOST_UBLAS_INLINE
Chris@16 127 vector_reference &plus_assign (const vector_expression<AE> &ae) {
Chris@16 128 expression ().plus_assign (ae);
Chris@16 129 return *this;
Chris@16 130 }
Chris@16 131 template<class AE>
Chris@16 132 BOOST_UBLAS_INLINE
Chris@16 133 vector_reference &operator -= (const vector_expression<AE> &ae) {
Chris@16 134 expression ().operator -= (ae);
Chris@16 135 return *this;
Chris@16 136 }
Chris@16 137 template<class AE>
Chris@16 138 BOOST_UBLAS_INLINE
Chris@16 139 vector_reference &minus_assign (const vector_expression<AE> &ae) {
Chris@16 140 expression ().minus_assign (ae);
Chris@16 141 return *this;
Chris@16 142 }
Chris@16 143 template<class AT>
Chris@16 144 BOOST_UBLAS_INLINE
Chris@16 145 vector_reference &operator *= (const AT &at) {
Chris@16 146 expression ().operator *= (at);
Chris@16 147 return *this;
Chris@16 148 }
Chris@16 149 template<class AT>
Chris@16 150 BOOST_UBLAS_INLINE
Chris@16 151 vector_reference &operator /= (const AT &at) {
Chris@16 152 expression ().operator /= (at);
Chris@16 153 return *this;
Chris@16 154 }
Chris@16 155
Chris@16 156 // Swapping
Chris@16 157 BOOST_UBLAS_INLINE
Chris@16 158 void swap (vector_reference &v) {
Chris@16 159 expression ().swap (v.expression ());
Chris@16 160 }
Chris@16 161
Chris@16 162 // Closure comparison
Chris@16 163 BOOST_UBLAS_INLINE
Chris@16 164 bool same_closure (const vector_reference &vr) const {
Chris@16 165 return &(*this).e_ == &vr.e_;
Chris@16 166 }
Chris@16 167
Chris@16 168 // Iterator types
Chris@16 169 typedef typename E::const_iterator const_iterator;
Chris@16 170 typedef typename boost::mpl::if_<boost::is_const<E>,
Chris@16 171 typename E::const_iterator,
Chris@16 172 typename E::iterator>::type iterator;
Chris@16 173
Chris@16 174 // Element lookup
Chris@16 175 BOOST_UBLAS_INLINE
Chris@16 176 const_iterator find (size_type i) const {
Chris@16 177 return expression ().find (i);
Chris@16 178 }
Chris@16 179 BOOST_UBLAS_INLINE
Chris@16 180 iterator find (size_type i) {
Chris@16 181 return expression ().find (i);
Chris@16 182 }
Chris@16 183
Chris@16 184 // Iterator is the iterator of the referenced expression.
Chris@16 185
Chris@16 186 BOOST_UBLAS_INLINE
Chris@16 187 const_iterator begin () const {
Chris@16 188 return expression ().begin ();
Chris@16 189 }
Chris@16 190 BOOST_UBLAS_INLINE
Chris@101 191 const_iterator cbegin () const {
Chris@101 192 return begin ();
Chris@101 193 }
Chris@101 194 BOOST_UBLAS_INLINE
Chris@16 195 const_iterator end () const {
Chris@16 196 return expression ().end ();
Chris@16 197 }
Chris@101 198 BOOST_UBLAS_INLINE
Chris@101 199 const_iterator cend () const {
Chris@101 200 return end ();
Chris@101 201 }
Chris@16 202
Chris@16 203 BOOST_UBLAS_INLINE
Chris@16 204 iterator begin () {
Chris@16 205 return expression ().begin ();
Chris@16 206 }
Chris@16 207 BOOST_UBLAS_INLINE
Chris@16 208 iterator end () {
Chris@16 209 return expression ().end ();
Chris@16 210 }
Chris@16 211
Chris@16 212 // Reverse iterator
Chris@16 213 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 214 typedef reverse_iterator_base<iterator> reverse_iterator;
Chris@16 215
Chris@16 216 BOOST_UBLAS_INLINE
Chris@16 217 const_reverse_iterator rbegin () const {
Chris@16 218 return const_reverse_iterator (end ());
Chris@16 219 }
Chris@16 220 BOOST_UBLAS_INLINE
Chris@101 221 const_reverse_iterator crbegin () const {
Chris@101 222 return rbegin ();
Chris@101 223 }
Chris@101 224 BOOST_UBLAS_INLINE
Chris@16 225 const_reverse_iterator rend () const {
Chris@16 226 return const_reverse_iterator (begin ());
Chris@16 227 }
Chris@16 228 BOOST_UBLAS_INLINE
Chris@101 229 const_reverse_iterator crend () const {
Chris@101 230 return rend ();
Chris@101 231 }
Chris@101 232
Chris@101 233 BOOST_UBLAS_INLINE
Chris@16 234 reverse_iterator rbegin () {
Chris@16 235 return reverse_iterator (end ());
Chris@16 236 }
Chris@16 237 BOOST_UBLAS_INLINE
Chris@16 238 reverse_iterator rend () {
Chris@16 239 return reverse_iterator (begin ());
Chris@16 240 }
Chris@16 241
Chris@16 242 private:
Chris@16 243 referred_type &e_;
Chris@16 244 };
Chris@16 245
Chris@16 246
Chris@16 247 template<class E, class F>
Chris@16 248 class vector_unary:
Chris@16 249 public vector_expression<vector_unary<E, F> > {
Chris@16 250
Chris@16 251 typedef F functor_type;
Chris@16 252 typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<typename E::value_type> >,
Chris@16 253 E,
Chris@16 254 const E>::type expression_type;
Chris@16 255 typedef typename boost::mpl::if_<boost::is_const<expression_type>,
Chris@16 256 typename E::const_closure_type,
Chris@16 257 typename E::closure_type>::type expression_closure_type;
Chris@16 258 typedef vector_unary<E, F> self_type;
Chris@16 259 public:
Chris@16 260 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 261 using vector_expression<vector_unary<E, F> >::operator ();
Chris@16 262 #endif
Chris@16 263 typedef typename E::size_type size_type;
Chris@16 264 typedef typename E::difference_type difference_type;
Chris@16 265 typedef typename F::result_type value_type;
Chris@16 266 typedef value_type const_reference;
Chris@16 267 typedef typename boost::mpl::if_<boost::is_same<F, scalar_identity<value_type> >,
Chris@16 268 typename E::reference,
Chris@16 269 value_type>::type reference;
Chris@16 270 typedef const self_type const_closure_type;
Chris@16 271 typedef self_type closure_type;
Chris@16 272 typedef unknown_storage_tag storage_category;
Chris@16 273
Chris@16 274 // Construction and destruction
Chris@16 275 BOOST_UBLAS_INLINE
Chris@16 276 // May be used as mutable expression.
Chris@16 277 explicit vector_unary (expression_type &e):
Chris@16 278 e_ (e) {}
Chris@16 279
Chris@16 280 // Accessors
Chris@16 281 BOOST_UBLAS_INLINE
Chris@16 282 size_type size () const {
Chris@16 283 return e_.size ();
Chris@16 284 }
Chris@16 285
Chris@16 286 public:
Chris@16 287 // Expression accessors
Chris@16 288 BOOST_UBLAS_INLINE
Chris@16 289 const expression_closure_type &expression () const {
Chris@16 290 return e_;
Chris@16 291 }
Chris@16 292
Chris@16 293 public:
Chris@16 294 // Element access
Chris@16 295 BOOST_UBLAS_INLINE
Chris@16 296 const_reference operator () (size_type i) const {
Chris@16 297 return functor_type::apply (e_ (i));
Chris@16 298 }
Chris@16 299 BOOST_UBLAS_INLINE
Chris@16 300 reference operator () (size_type i) {
Chris@16 301 BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
Chris@16 302 return e_ (i);
Chris@16 303 }
Chris@16 304
Chris@16 305 BOOST_UBLAS_INLINE
Chris@16 306 const_reference operator [] (size_type i) const {
Chris@16 307 return functor_type::apply (e_ [i]);
Chris@16 308 }
Chris@16 309 BOOST_UBLAS_INLINE
Chris@16 310 reference operator [] (size_type i) {
Chris@16 311 BOOST_STATIC_ASSERT ((boost::is_same<functor_type, scalar_identity<value_type > >::value));
Chris@16 312 return e_ [i];
Chris@16 313 }
Chris@16 314
Chris@16 315 // Closure comparison
Chris@16 316 BOOST_UBLAS_INLINE
Chris@16 317 bool same_closure (const vector_unary &vu) const {
Chris@16 318 return (*this).expression ().same_closure (vu.expression ());
Chris@16 319 }
Chris@16 320
Chris@16 321 // Iterator types
Chris@16 322 private:
Chris@16 323 typedef typename E::const_iterator const_subiterator_type;
Chris@16 324 typedef const value_type *const_pointer;
Chris@16 325
Chris@16 326 public:
Chris@16 327 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 328 typedef indexed_const_iterator<const_closure_type, typename const_subiterator_type::iterator_category> const_iterator;
Chris@16 329 typedef const_iterator iterator;
Chris@16 330 #else
Chris@16 331 class const_iterator;
Chris@16 332 typedef const_iterator iterator;
Chris@16 333 #endif
Chris@16 334
Chris@16 335 // Element lookup
Chris@16 336 BOOST_UBLAS_INLINE
Chris@16 337 const_iterator find (size_type i) const {
Chris@16 338 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 339 const_subiterator_type it (e_.find (i));
Chris@16 340 return const_iterator (*this, it.index ());
Chris@16 341 #else
Chris@16 342 return const_iterator (*this, e_.find (i));
Chris@16 343 #endif
Chris@16 344 }
Chris@16 345
Chris@16 346 // Iterator enhances the iterator of the referenced expression
Chris@16 347 // with the unary functor.
Chris@16 348
Chris@16 349 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 350 class const_iterator:
Chris@16 351 public container_const_reference<vector_unary>,
Chris@16 352 public iterator_base_traits<typename E::const_iterator::iterator_category>::template
Chris@16 353 iterator_base<const_iterator, value_type>::type {
Chris@16 354 public:
Chris@16 355 typedef typename E::const_iterator::iterator_category iterator_category;
Chris@16 356 typedef typename vector_unary::difference_type difference_type;
Chris@16 357 typedef typename vector_unary::value_type value_type;
Chris@16 358 typedef typename vector_unary::const_reference reference;
Chris@16 359 typedef typename vector_unary::const_pointer pointer;
Chris@16 360
Chris@16 361 // Construction and destruction
Chris@16 362 BOOST_UBLAS_INLINE
Chris@16 363 const_iterator ():
Chris@16 364 container_const_reference<self_type> (), it_ () {}
Chris@16 365 BOOST_UBLAS_INLINE
Chris@16 366 const_iterator (const self_type &vu, const const_subiterator_type &it):
Chris@16 367 container_const_reference<self_type> (vu), it_ (it) {}
Chris@16 368
Chris@16 369 // Arithmetic
Chris@16 370 BOOST_UBLAS_INLINE
Chris@16 371 const_iterator &operator ++ () {
Chris@16 372 ++ it_;
Chris@16 373 return *this;
Chris@16 374 }
Chris@16 375 BOOST_UBLAS_INLINE
Chris@16 376 const_iterator &operator -- () {
Chris@16 377 -- it_;
Chris@16 378 return *this;
Chris@16 379 }
Chris@16 380 BOOST_UBLAS_INLINE
Chris@16 381 const_iterator &operator += (difference_type n) {
Chris@16 382 it_ += n;
Chris@16 383 return *this;
Chris@16 384 }
Chris@16 385 BOOST_UBLAS_INLINE
Chris@16 386 const_iterator &operator -= (difference_type n) {
Chris@16 387 it_ -= n;
Chris@16 388 return *this;
Chris@16 389 }
Chris@16 390 BOOST_UBLAS_INLINE
Chris@16 391 difference_type operator - (const const_iterator &it) const {
Chris@16 392 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 393 return it_ - it.it_;
Chris@16 394 }
Chris@16 395
Chris@16 396 // Dereference
Chris@16 397 BOOST_UBLAS_INLINE
Chris@16 398 const_reference operator * () const {
Chris@16 399 return functor_type::apply (*it_);
Chris@16 400 }
Chris@16 401 BOOST_UBLAS_INLINE
Chris@16 402 const_reference operator [] (difference_type n) const {
Chris@16 403 return *(*this + n);
Chris@16 404 }
Chris@16 405
Chris@16 406 // Index
Chris@16 407 BOOST_UBLAS_INLINE
Chris@16 408 size_type index () const {
Chris@16 409 return it_.index ();
Chris@16 410 }
Chris@16 411
Chris@16 412 // Assignment
Chris@16 413 BOOST_UBLAS_INLINE
Chris@16 414 const_iterator &operator = (const const_iterator &it) {
Chris@16 415 container_const_reference<self_type>::assign (&it ());
Chris@16 416 it_ = it.it_;
Chris@16 417 return *this;
Chris@16 418 }
Chris@16 419
Chris@16 420 // Comparison
Chris@16 421 BOOST_UBLAS_INLINE
Chris@16 422 bool operator == (const const_iterator &it) const {
Chris@16 423 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 424 return it_ == it.it_;
Chris@16 425 }
Chris@16 426 BOOST_UBLAS_INLINE
Chris@16 427 bool operator < (const const_iterator &it) const {
Chris@16 428 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 429 return it_ < it.it_;
Chris@16 430 }
Chris@16 431
Chris@16 432 private:
Chris@16 433 const_subiterator_type it_;
Chris@16 434 };
Chris@16 435 #endif
Chris@16 436
Chris@16 437 BOOST_UBLAS_INLINE
Chris@16 438 const_iterator begin () const {
Chris@16 439 return find (0);
Chris@16 440 }
Chris@16 441 BOOST_UBLAS_INLINE
Chris@101 442 const_iterator cbegin () const {
Chris@101 443 return begin ();
Chris@101 444 }
Chris@101 445 BOOST_UBLAS_INLINE
Chris@16 446 const_iterator end () const {
Chris@16 447 return find (size ());
Chris@16 448 }
Chris@101 449 BOOST_UBLAS_INLINE
Chris@101 450 const_iterator cend () const {
Chris@101 451 return end ();
Chris@101 452 }
Chris@16 453
Chris@16 454 // Reverse iterator
Chris@16 455 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 456
Chris@16 457 BOOST_UBLAS_INLINE
Chris@16 458 const_reverse_iterator rbegin () const {
Chris@16 459 return const_reverse_iterator (end ());
Chris@16 460 }
Chris@16 461 BOOST_UBLAS_INLINE
Chris@101 462 const_reverse_iterator crbegin () const {
Chris@101 463 return rbegin ();
Chris@101 464 }
Chris@101 465 BOOST_UBLAS_INLINE
Chris@16 466 const_reverse_iterator rend () const {
Chris@16 467 return const_reverse_iterator (begin ());
Chris@16 468 }
Chris@101 469 BOOST_UBLAS_INLINE
Chris@101 470 const_reverse_iterator crend () const {
Chris@101 471 return rend ();
Chris@101 472 }
Chris@16 473
Chris@16 474 private:
Chris@16 475 expression_closure_type e_;
Chris@16 476 };
Chris@16 477
Chris@16 478 template<class E, class F>
Chris@16 479 struct vector_unary_traits {
Chris@16 480 typedef vector_unary<E, F> expression_type;
Chris@16 481 //FIXME
Chris@16 482 // #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
Chris@16 483 typedef expression_type result_type;
Chris@16 484 // #else
Chris@16 485 // typedef typename E::vector_temporary_type result_type;
Chris@16 486 // #endif
Chris@16 487 };
Chris@16 488
Chris@16 489 // (- v) [i] = - v [i]
Chris@16 490 template<class E>
Chris@16 491 BOOST_UBLAS_INLINE
Chris@16 492 typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::result_type
Chris@16 493 operator - (const vector_expression<E> &e) {
Chris@16 494 typedef typename vector_unary_traits<E, scalar_negate<typename E::value_type> >::expression_type expression_type;
Chris@16 495 return expression_type (e ());
Chris@16 496 }
Chris@16 497
Chris@16 498 // (conj v) [i] = conj (v [i])
Chris@16 499 template<class E>
Chris@16 500 BOOST_UBLAS_INLINE
Chris@16 501 typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
Chris@16 502 conj (const vector_expression<E> &e) {
Chris@16 503 typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
Chris@16 504 return expression_type (e ());
Chris@16 505 }
Chris@16 506
Chris@16 507 // (real v) [i] = real (v [i])
Chris@16 508 template<class E>
Chris@16 509 BOOST_UBLAS_INLINE
Chris@16 510 typename vector_unary_traits<E, scalar_real<typename E::value_type> >::result_type
Chris@16 511 real (const vector_expression<E> &e) {
Chris@16 512 typedef typename vector_unary_traits<E, scalar_real<typename E::value_type> >::expression_type expression_type;
Chris@16 513 return expression_type (e ());
Chris@16 514 }
Chris@16 515
Chris@16 516 // (imag v) [i] = imag (v [i])
Chris@16 517 template<class E>
Chris@16 518 BOOST_UBLAS_INLINE
Chris@16 519 typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::result_type
Chris@16 520 imag (const vector_expression<E> &e) {
Chris@16 521 typedef typename vector_unary_traits<E, scalar_imag<typename E::value_type> >::expression_type expression_type;
Chris@16 522 return expression_type (e ());
Chris@16 523 }
Chris@16 524
Chris@16 525 // (trans v) [i] = v [i]
Chris@16 526 template<class E>
Chris@16 527 BOOST_UBLAS_INLINE
Chris@16 528 typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::result_type
Chris@16 529 trans (const vector_expression<E> &e) {
Chris@16 530 typedef typename vector_unary_traits<const E, scalar_identity<typename E::value_type> >::expression_type expression_type;
Chris@16 531 return expression_type (e ());
Chris@16 532 }
Chris@16 533 template<class E>
Chris@16 534 BOOST_UBLAS_INLINE
Chris@16 535 typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::result_type
Chris@16 536 trans (vector_expression<E> &e) {
Chris@16 537 typedef typename vector_unary_traits<E, scalar_identity<typename E::value_type> >::expression_type expression_type;
Chris@16 538 return expression_type (e ());
Chris@16 539 }
Chris@16 540
Chris@16 541 // (herm v) [i] = conj (v [i])
Chris@16 542 template<class E>
Chris@16 543 BOOST_UBLAS_INLINE
Chris@16 544 typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::result_type
Chris@16 545 herm (const vector_expression<E> &e) {
Chris@16 546 typedef typename vector_unary_traits<E, scalar_conj<typename E::value_type> >::expression_type expression_type;
Chris@16 547 return expression_type (e ());
Chris@16 548 }
Chris@16 549
Chris@16 550 template<class E1, class E2, class F>
Chris@16 551 class vector_binary:
Chris@16 552 public vector_expression<vector_binary<E1, E2, F> > {
Chris@16 553
Chris@16 554 typedef E1 expression1_type;
Chris@16 555 typedef E2 expression2_type;
Chris@16 556 typedef F functor_type;
Chris@16 557 typedef typename E1::const_closure_type expression1_closure_type;
Chris@16 558 typedef typename E2::const_closure_type expression2_closure_type;
Chris@16 559 typedef vector_binary<E1, E2, F> self_type;
Chris@16 560 public:
Chris@16 561 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 562 using vector_expression<vector_binary<E1, E2, F> >::operator ();
Chris@16 563 #endif
Chris@16 564 typedef typename promote_traits<typename E1::size_type, typename E2::size_type>::promote_type size_type;
Chris@16 565 typedef typename promote_traits<typename E1::difference_type, typename E2::difference_type>::promote_type difference_type;
Chris@16 566 typedef typename F::result_type value_type;
Chris@16 567 typedef value_type const_reference;
Chris@16 568 typedef const_reference reference;
Chris@16 569 typedef const self_type const_closure_type;
Chris@16 570 typedef const_closure_type closure_type;
Chris@16 571 typedef unknown_storage_tag storage_category;
Chris@16 572
Chris@16 573 // Construction and destruction
Chris@16 574 BOOST_UBLAS_INLINE
Chris@16 575 vector_binary (const expression1_type &e1, const expression2_type &e2):
Chris@16 576 e1_ (e1), e2_ (e2) {}
Chris@16 577
Chris@16 578 // Accessors
Chris@16 579 BOOST_UBLAS_INLINE
Chris@16 580 size_type size () const {
Chris@16 581 return BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
Chris@16 582 }
Chris@16 583
Chris@16 584 private:
Chris@16 585 // Accessors
Chris@16 586 BOOST_UBLAS_INLINE
Chris@16 587 const expression1_closure_type &expression1 () const {
Chris@16 588 return e1_;
Chris@16 589 }
Chris@16 590 BOOST_UBLAS_INLINE
Chris@16 591 const expression2_closure_type &expression2 () const {
Chris@16 592 return e2_;
Chris@16 593 }
Chris@16 594
Chris@16 595 public:
Chris@16 596 // Element access
Chris@16 597 BOOST_UBLAS_INLINE
Chris@16 598 const_reference operator () (size_type i) const {
Chris@16 599 return functor_type::apply (e1_ (i), e2_ (i));
Chris@16 600 }
Chris@16 601
Chris@16 602 BOOST_UBLAS_INLINE
Chris@16 603 const_reference operator [] (size_type i) const {
Chris@16 604 return functor_type::apply (e1_ [i], e2_ [i]);
Chris@16 605 }
Chris@16 606
Chris@16 607 // Closure comparison
Chris@16 608 BOOST_UBLAS_INLINE
Chris@16 609 bool same_closure (const vector_binary &vb) const {
Chris@16 610 return (*this).expression1 ().same_closure (vb.expression1 ()) &&
Chris@16 611 (*this).expression2 ().same_closure (vb.expression2 ());
Chris@16 612 }
Chris@16 613
Chris@16 614 // Iterator types
Chris@16 615 private:
Chris@16 616 typedef typename E1::const_iterator const_subiterator1_type;
Chris@16 617 typedef typename E2::const_iterator const_subiterator2_type;
Chris@16 618 typedef const value_type *const_pointer;
Chris@16 619
Chris@16 620 public:
Chris@16 621 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 622 typedef typename iterator_restrict_traits<typename const_subiterator1_type::iterator_category,
Chris@16 623 typename const_subiterator2_type::iterator_category>::iterator_category iterator_category;
Chris@16 624 typedef indexed_const_iterator<const_closure_type, iterator_category> const_iterator;
Chris@16 625 typedef const_iterator iterator;
Chris@16 626 #else
Chris@16 627 class const_iterator;
Chris@16 628 typedef const_iterator iterator;
Chris@16 629 #endif
Chris@16 630
Chris@16 631 // Element lookup
Chris@16 632 BOOST_UBLAS_INLINE
Chris@16 633 const_iterator find (size_type i) const {
Chris@16 634 const_subiterator1_type it1 (e1_.find (i));
Chris@16 635 const_subiterator1_type it1_end (e1_.find (size ()));
Chris@16 636 const_subiterator2_type it2 (e2_.find (i));
Chris@16 637 const_subiterator2_type it2_end (e2_.find (size ()));
Chris@16 638 i = (std::min) (it1 != it1_end ? it1.index () : size (),
Chris@16 639 it2 != it2_end ? it2.index () : size ());
Chris@16 640 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 641 return const_iterator (*this, i);
Chris@16 642 #else
Chris@16 643 return const_iterator (*this, i, it1, it1_end, it2, it2_end);
Chris@16 644 #endif
Chris@16 645 }
Chris@16 646
Chris@16 647 // Iterator merges the iterators of the referenced expressions and
Chris@16 648 // enhances them with the binary functor.
Chris@16 649
Chris@16 650 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 651 class const_iterator:
Chris@16 652 public container_const_reference<vector_binary>,
Chris@16 653 public iterator_base_traits<typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
Chris@16 654 typename E2::const_iterator::iterator_category>::iterator_category>::template
Chris@16 655 iterator_base<const_iterator, value_type>::type {
Chris@16 656 public:
Chris@16 657 typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
Chris@16 658 typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
Chris@16 659 typedef typename vector_binary::difference_type difference_type;
Chris@16 660 typedef typename vector_binary::value_type value_type;
Chris@16 661 typedef typename vector_binary::const_reference reference;
Chris@16 662 typedef typename vector_binary::const_pointer pointer;
Chris@16 663
Chris@16 664 // Construction and destruction
Chris@16 665 BOOST_UBLAS_INLINE
Chris@16 666 const_iterator ():
Chris@16 667 container_const_reference<self_type> (), i_ (), it1_ (), it1_end_ (), it2_ (), it2_end_ () {}
Chris@16 668 BOOST_UBLAS_INLINE
Chris@16 669 const_iterator (const self_type &vb, size_type i,
Chris@16 670 const const_subiterator1_type &it1, const const_subiterator1_type &it1_end,
Chris@16 671 const const_subiterator2_type &it2, const const_subiterator2_type &it2_end):
Chris@16 672 container_const_reference<self_type> (vb), i_ (i), it1_ (it1), it1_end_ (it1_end), it2_ (it2), it2_end_ (it2_end) {}
Chris@16 673
Chris@16 674 private:
Chris@16 675 // Dense specializations
Chris@16 676 BOOST_UBLAS_INLINE
Chris@16 677 void increment (dense_random_access_iterator_tag) {
Chris@16 678 ++ i_; ++ it1_; ++ it2_;
Chris@16 679 }
Chris@16 680 BOOST_UBLAS_INLINE
Chris@16 681 void decrement (dense_random_access_iterator_tag) {
Chris@16 682 -- i_; -- it1_; -- it2_;
Chris@16 683 }
Chris@16 684 BOOST_UBLAS_INLINE
Chris@16 685 void increment (dense_random_access_iterator_tag, difference_type n) {
Chris@16 686 i_ += n; it1_ += n; it2_ += n;
Chris@16 687 }
Chris@16 688 BOOST_UBLAS_INLINE
Chris@16 689 void decrement (dense_random_access_iterator_tag, difference_type n) {
Chris@16 690 i_ -= n; it1_ -= n; it2_ -= n;
Chris@16 691 }
Chris@16 692 BOOST_UBLAS_INLINE
Chris@16 693 value_type dereference (dense_random_access_iterator_tag) const {
Chris@16 694 return functor_type::apply (*it1_, *it2_);
Chris@16 695 }
Chris@16 696
Chris@16 697 // Packed specializations
Chris@16 698 BOOST_UBLAS_INLINE
Chris@16 699 void increment (packed_random_access_iterator_tag) {
Chris@16 700 if (it1_ != it1_end_)
Chris@16 701 if (it1_.index () <= i_)
Chris@16 702 ++ it1_;
Chris@16 703 if (it2_ != it2_end_)
Chris@16 704 if (it2_.index () <= i_)
Chris@16 705 ++ it2_;
Chris@16 706 ++ i_;
Chris@16 707 }
Chris@16 708 BOOST_UBLAS_INLINE
Chris@16 709 void decrement (packed_random_access_iterator_tag) {
Chris@16 710 if (it1_ != it1_end_)
Chris@16 711 if (i_ <= it1_.index ())
Chris@16 712 -- it1_;
Chris@16 713 if (it2_ != it2_end_)
Chris@16 714 if (i_ <= it2_.index ())
Chris@16 715 -- it2_;
Chris@16 716 -- i_;
Chris@16 717 }
Chris@16 718 BOOST_UBLAS_INLINE
Chris@16 719 void increment (packed_random_access_iterator_tag, difference_type n) {
Chris@16 720 while (n > 0) {
Chris@16 721 increment (packed_random_access_iterator_tag ());
Chris@16 722 --n;
Chris@16 723 }
Chris@16 724 while (n < 0) {
Chris@16 725 decrement (packed_random_access_iterator_tag ());
Chris@16 726 ++n;
Chris@16 727 }
Chris@16 728 }
Chris@16 729 BOOST_UBLAS_INLINE
Chris@16 730 void decrement (packed_random_access_iterator_tag, difference_type n) {
Chris@16 731 while (n > 0) {
Chris@16 732 decrement (packed_random_access_iterator_tag ());
Chris@16 733 --n;
Chris@16 734 }
Chris@16 735 while (n < 0) {
Chris@16 736 increment (packed_random_access_iterator_tag ());
Chris@16 737 ++n;
Chris@16 738 }
Chris@16 739 }
Chris@16 740 BOOST_UBLAS_INLINE
Chris@16 741 value_type dereference (packed_random_access_iterator_tag) const {
Chris@16 742 value_type t1 = value_type/*zero*/();
Chris@16 743 if (it1_ != it1_end_)
Chris@16 744 if (it1_.index () == i_)
Chris@16 745 t1 = *it1_;
Chris@16 746 value_type t2 = value_type/*zero*/();
Chris@16 747 if (it2_ != it2_end_)
Chris@16 748 if (it2_.index () == i_)
Chris@16 749 t2 = *it2_;
Chris@16 750 return functor_type::apply (t1, t2);
Chris@16 751 }
Chris@16 752
Chris@16 753 // Sparse specializations
Chris@16 754 BOOST_UBLAS_INLINE
Chris@16 755 void increment (sparse_bidirectional_iterator_tag) {
Chris@16 756 size_type index1 = (*this) ().size ();
Chris@16 757 if (it1_ != it1_end_) {
Chris@16 758 if (it1_.index () <= i_)
Chris@16 759 ++ it1_;
Chris@16 760 if (it1_ != it1_end_)
Chris@16 761 index1 = it1_.index ();
Chris@16 762 }
Chris@16 763 size_type index2 = (*this) ().size ();
Chris@16 764 if (it2_ != it2_end_) {
Chris@16 765 if (it2_.index () <= i_)
Chris@16 766 ++ it2_;
Chris@16 767 if (it2_ != it2_end_)
Chris@16 768 index2 = it2_.index ();
Chris@16 769 }
Chris@16 770 i_ = (std::min) (index1, index2);
Chris@16 771 }
Chris@16 772 BOOST_UBLAS_INLINE
Chris@16 773 void decrement (sparse_bidirectional_iterator_tag) {
Chris@16 774 size_type index1 = (*this) ().size ();
Chris@16 775 if (it1_ != it1_end_) {
Chris@16 776 if (i_ <= it1_.index ())
Chris@16 777 -- it1_;
Chris@16 778 if (it1_ != it1_end_)
Chris@16 779 index1 = it1_.index ();
Chris@16 780 }
Chris@16 781 size_type index2 = (*this) ().size ();
Chris@16 782 if (it2_ != it2_end_) {
Chris@16 783 if (i_ <= it2_.index ())
Chris@16 784 -- it2_;
Chris@16 785 if (it2_ != it2_end_)
Chris@16 786 index2 = it2_.index ();
Chris@16 787 }
Chris@16 788 i_ = (std::max) (index1, index2);
Chris@16 789 }
Chris@16 790 BOOST_UBLAS_INLINE
Chris@16 791 void increment (sparse_bidirectional_iterator_tag, difference_type n) {
Chris@16 792 while (n > 0) {
Chris@16 793 increment (sparse_bidirectional_iterator_tag ());
Chris@16 794 --n;
Chris@16 795 }
Chris@16 796 while (n < 0) {
Chris@16 797 decrement (sparse_bidirectional_iterator_tag ());
Chris@16 798 ++n;
Chris@16 799 }
Chris@16 800 }
Chris@16 801 BOOST_UBLAS_INLINE
Chris@16 802 void decrement (sparse_bidirectional_iterator_tag, difference_type n) {
Chris@16 803 while (n > 0) {
Chris@16 804 decrement (sparse_bidirectional_iterator_tag ());
Chris@16 805 --n;
Chris@16 806 }
Chris@16 807 while (n < 0) {
Chris@16 808 increment (sparse_bidirectional_iterator_tag ());
Chris@16 809 ++n;
Chris@16 810 }
Chris@16 811 }
Chris@16 812 BOOST_UBLAS_INLINE
Chris@16 813 value_type dereference (sparse_bidirectional_iterator_tag) const {
Chris@16 814 value_type t1 = value_type/*zero*/();
Chris@16 815 if (it1_ != it1_end_)
Chris@16 816 if (it1_.index () == i_)
Chris@16 817 t1 = *it1_;
Chris@16 818 value_type t2 = value_type/*zero*/();
Chris@16 819 if (it2_ != it2_end_)
Chris@16 820 if (it2_.index () == i_)
Chris@16 821 t2 = *it2_;
Chris@16 822 return functor_type::apply (t1, t2);
Chris@16 823 }
Chris@16 824
Chris@16 825 public:
Chris@16 826 // Arithmetic
Chris@16 827 BOOST_UBLAS_INLINE
Chris@16 828 const_iterator &operator ++ () {
Chris@16 829 increment (iterator_category ());
Chris@16 830 return *this;
Chris@16 831 }
Chris@16 832 BOOST_UBLAS_INLINE
Chris@16 833 const_iterator &operator -- () {
Chris@16 834 decrement (iterator_category ());
Chris@16 835 return *this;
Chris@16 836 }
Chris@16 837 BOOST_UBLAS_INLINE
Chris@16 838 const_iterator &operator += (difference_type n) {
Chris@16 839 increment (iterator_category (), n);
Chris@16 840 return *this;
Chris@16 841 }
Chris@16 842 BOOST_UBLAS_INLINE
Chris@16 843 const_iterator &operator -= (difference_type n) {
Chris@16 844 decrement (iterator_category (), n);
Chris@16 845 return *this;
Chris@16 846 }
Chris@16 847 BOOST_UBLAS_INLINE
Chris@16 848 difference_type operator - (const const_iterator &it) const {
Chris@16 849 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 850 return index () - it.index ();
Chris@16 851 }
Chris@16 852
Chris@16 853 // Dereference
Chris@16 854 BOOST_UBLAS_INLINE
Chris@16 855 const_reference operator * () const {
Chris@16 856 return dereference (iterator_category ());
Chris@16 857 }
Chris@16 858 BOOST_UBLAS_INLINE
Chris@16 859 const_reference operator [] (difference_type n) const {
Chris@16 860 return *(*this + n);
Chris@16 861 }
Chris@16 862
Chris@16 863 // Index
Chris@16 864 BOOST_UBLAS_INLINE
Chris@16 865 size_type index () const {
Chris@16 866 return i_;
Chris@16 867 }
Chris@16 868
Chris@16 869 // Assignment
Chris@16 870 BOOST_UBLAS_INLINE
Chris@16 871 const_iterator &operator = (const const_iterator &it) {
Chris@16 872 container_const_reference<self_type>::assign (&it ());
Chris@16 873 i_ = it.i_;
Chris@16 874 it1_ = it.it1_;
Chris@16 875 it1_end_ = it.it1_end_;
Chris@16 876 it2_ = it.it2_;
Chris@16 877 it2_end_ = it.it2_end_;
Chris@16 878 return *this;
Chris@16 879 }
Chris@16 880
Chris@16 881 // Comparison
Chris@16 882 BOOST_UBLAS_INLINE
Chris@16 883 bool operator == (const const_iterator &it) const {
Chris@16 884 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 885 return index () == it.index ();
Chris@16 886 }
Chris@16 887 BOOST_UBLAS_INLINE
Chris@16 888 bool operator < (const const_iterator &it) const {
Chris@16 889 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 890 return index () < it.index ();
Chris@16 891 }
Chris@16 892
Chris@16 893 private:
Chris@16 894 size_type i_;
Chris@16 895 const_subiterator1_type it1_;
Chris@16 896 const_subiterator1_type it1_end_;
Chris@16 897 const_subiterator2_type it2_;
Chris@16 898 const_subiterator2_type it2_end_;
Chris@16 899 };
Chris@16 900 #endif
Chris@16 901
Chris@16 902 BOOST_UBLAS_INLINE
Chris@16 903 const_iterator begin () const {
Chris@16 904 return find (0);
Chris@16 905 }
Chris@16 906 BOOST_UBLAS_INLINE
Chris@101 907 const_iterator cbegin () const {
Chris@101 908 return begin ();
Chris@101 909 }
Chris@101 910 BOOST_UBLAS_INLINE
Chris@16 911 const_iterator end () const {
Chris@16 912 return find (size ());
Chris@16 913 }
Chris@101 914 BOOST_UBLAS_INLINE
Chris@101 915 const_iterator cend () const {
Chris@101 916 return end ();
Chris@101 917 }
Chris@16 918
Chris@16 919 // Reverse iterator
Chris@16 920 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 921
Chris@16 922 BOOST_UBLAS_INLINE
Chris@16 923 const_reverse_iterator rbegin () const {
Chris@16 924 return const_reverse_iterator (end ());
Chris@16 925 }
Chris@16 926 BOOST_UBLAS_INLINE
Chris@101 927 const_reverse_iterator crbegin () const {
Chris@101 928 return rbegin ();
Chris@101 929 }
Chris@101 930 BOOST_UBLAS_INLINE
Chris@16 931 const_reverse_iterator rend () const {
Chris@16 932 return const_reverse_iterator (begin ());
Chris@16 933 }
Chris@101 934 BOOST_UBLAS_INLINE
Chris@101 935 const_reverse_iterator crend () const {
Chris@101 936 return rend ();
Chris@101 937 }
Chris@16 938
Chris@16 939 private:
Chris@16 940 expression1_closure_type e1_;
Chris@16 941 expression2_closure_type e2_;
Chris@16 942 };
Chris@16 943
Chris@16 944 template<class E1, class E2, class F>
Chris@16 945 struct vector_binary_traits {
Chris@16 946 typedef vector_binary<E1, E2, F> expression_type;
Chris@16 947 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
Chris@16 948 typedef expression_type result_type;
Chris@16 949 #else
Chris@16 950 typedef typename E1::vector_temporary_type result_type;
Chris@16 951 #endif
Chris@16 952 };
Chris@16 953
Chris@16 954 // (v1 + v2) [i] = v1 [i] + v2 [i]
Chris@16 955 template<class E1, class E2>
Chris@16 956 BOOST_UBLAS_INLINE
Chris@16 957 typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
Chris@16 958 typename E2::value_type> >::result_type
Chris@16 959 operator + (const vector_expression<E1> &e1,
Chris@16 960 const vector_expression<E2> &e2) {
Chris@16 961 typedef typename vector_binary_traits<E1, E2, scalar_plus<typename E1::value_type,
Chris@16 962 typename E2::value_type> >::expression_type expression_type;
Chris@16 963 return expression_type (e1 (), e2 ());
Chris@16 964 }
Chris@16 965
Chris@16 966 // (v1 - v2) [i] = v1 [i] - v2 [i]
Chris@16 967 template<class E1, class E2>
Chris@16 968 BOOST_UBLAS_INLINE
Chris@16 969 typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
Chris@16 970 typename E2::value_type> >::result_type
Chris@16 971 operator - (const vector_expression<E1> &e1,
Chris@16 972 const vector_expression<E2> &e2) {
Chris@16 973 typedef typename vector_binary_traits<E1, E2, scalar_minus<typename E1::value_type,
Chris@16 974 typename E2::value_type> >::expression_type expression_type;
Chris@16 975 return expression_type (e1 (), e2 ());
Chris@16 976 }
Chris@16 977
Chris@16 978 // (v1 * v2) [i] = v1 [i] * v2 [i]
Chris@16 979 template<class E1, class E2>
Chris@16 980 BOOST_UBLAS_INLINE
Chris@16 981 typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
Chris@16 982 typename E2::value_type> >::result_type
Chris@16 983 element_prod (const vector_expression<E1> &e1,
Chris@16 984 const vector_expression<E2> &e2) {
Chris@16 985 typedef typename vector_binary_traits<E1, E2, scalar_multiplies<typename E1::value_type,
Chris@16 986 typename E2::value_type> >::expression_type expression_type;
Chris@16 987 return expression_type (e1 (), e2 ());
Chris@16 988 }
Chris@16 989
Chris@16 990 // (v1 / v2) [i] = v1 [i] / v2 [i]
Chris@16 991 template<class E1, class E2>
Chris@16 992 BOOST_UBLAS_INLINE
Chris@16 993 typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
Chris@16 994 typename E2::value_type> >::result_type
Chris@16 995 element_div (const vector_expression<E1> &e1,
Chris@16 996 const vector_expression<E2> &e2) {
Chris@16 997 typedef typename vector_binary_traits<E1, E2, scalar_divides<typename E1::value_type,
Chris@16 998 typename E2::value_type> >::expression_type expression_type;
Chris@16 999 return expression_type (e1 (), e2 ());
Chris@16 1000 }
Chris@16 1001
Chris@16 1002
Chris@16 1003 template<class E1, class E2, class F>
Chris@16 1004 class vector_binary_scalar1:
Chris@16 1005 public vector_expression<vector_binary_scalar1<E1, E2, F> > {
Chris@16 1006
Chris@16 1007 typedef F functor_type;
Chris@16 1008 typedef E1 expression1_type;
Chris@16 1009 typedef E2 expression2_type;
Chris@16 1010 public:
Chris@16 1011 typedef const E1& expression1_closure_type;
Chris@16 1012 typedef typename E2::const_closure_type expression2_closure_type;
Chris@16 1013 private:
Chris@16 1014 typedef vector_binary_scalar1<E1, E2, F> self_type;
Chris@16 1015 public:
Chris@16 1016 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 1017 using vector_expression<vector_binary_scalar1<E1, E2, F> >::operator ();
Chris@16 1018 #endif
Chris@16 1019 typedef typename E2::size_type size_type;
Chris@16 1020 typedef typename E2::difference_type difference_type;
Chris@16 1021 typedef typename F::result_type value_type;
Chris@16 1022 typedef value_type const_reference;
Chris@16 1023 typedef const_reference reference;
Chris@16 1024 typedef const self_type const_closure_type;
Chris@16 1025 typedef const_closure_type closure_type;
Chris@16 1026 typedef unknown_storage_tag storage_category;
Chris@16 1027
Chris@16 1028 // Construction and destruction
Chris@16 1029 BOOST_UBLAS_INLINE
Chris@16 1030 vector_binary_scalar1 (const expression1_type &e1, const expression2_type &e2):
Chris@16 1031 e1_ (e1), e2_ (e2) {}
Chris@16 1032
Chris@16 1033 // Accessors
Chris@16 1034 BOOST_UBLAS_INLINE
Chris@16 1035 size_type size () const {
Chris@16 1036 return e2_.size ();
Chris@16 1037 }
Chris@16 1038
Chris@16 1039 public:
Chris@16 1040 // Element access
Chris@16 1041 BOOST_UBLAS_INLINE
Chris@16 1042 const_reference operator () (size_type i) const {
Chris@16 1043 return functor_type::apply (e1_, e2_ (i));
Chris@16 1044 }
Chris@16 1045
Chris@16 1046 BOOST_UBLAS_INLINE
Chris@16 1047 const_reference operator [] (size_type i) const {
Chris@16 1048 return functor_type::apply (e1_, e2_ [i]);
Chris@16 1049 }
Chris@16 1050
Chris@16 1051 // Closure comparison
Chris@16 1052 BOOST_UBLAS_INLINE
Chris@16 1053 bool same_closure (const vector_binary_scalar1 &vbs1) const {
Chris@16 1054 return &e1_ == &(vbs1.e1_) &&
Chris@16 1055 (*this).e2_.same_closure (vbs1.e2_);
Chris@16 1056 }
Chris@16 1057
Chris@16 1058 // Iterator types
Chris@16 1059 private:
Chris@16 1060 typedef expression1_type const_subiterator1_type;
Chris@16 1061 typedef typename expression2_type::const_iterator const_subiterator2_type;
Chris@16 1062 typedef const value_type *const_pointer;
Chris@16 1063
Chris@16 1064 public:
Chris@16 1065 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1066 typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
Chris@16 1067 typedef const_iterator iterator;
Chris@16 1068 #else
Chris@16 1069 class const_iterator;
Chris@16 1070 typedef const_iterator iterator;
Chris@16 1071 #endif
Chris@16 1072
Chris@16 1073 // Element lookup
Chris@16 1074 BOOST_UBLAS_INLINE
Chris@16 1075 const_iterator find (size_type i) const {
Chris@16 1076 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1077 const_subiterator2_type it (e2_.find (i));
Chris@16 1078 return const_iterator (*this, it.index ());
Chris@16 1079 #else
Chris@16 1080 return const_iterator (*this, const_subiterator1_type (e1_), e2_.find (i));
Chris@16 1081 #endif
Chris@16 1082 }
Chris@16 1083
Chris@16 1084 // Iterator enhances the iterator of the referenced vector expression
Chris@16 1085 // with the binary functor.
Chris@16 1086
Chris@16 1087 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1088 class const_iterator:
Chris@16 1089 public container_const_reference<vector_binary_scalar1>,
Chris@16 1090 public iterator_base_traits<typename E2::const_iterator::iterator_category>::template
Chris@16 1091 iterator_base<const_iterator, value_type>::type {
Chris@16 1092 public:
Chris@16 1093 typedef typename E2::const_iterator::iterator_category iterator_category;
Chris@16 1094 typedef typename vector_binary_scalar1::difference_type difference_type;
Chris@16 1095 typedef typename vector_binary_scalar1::value_type value_type;
Chris@16 1096 typedef typename vector_binary_scalar1::const_reference reference;
Chris@16 1097 typedef typename vector_binary_scalar1::const_pointer pointer;
Chris@16 1098
Chris@16 1099 // Construction and destruction
Chris@16 1100 BOOST_UBLAS_INLINE
Chris@16 1101 const_iterator ():
Chris@16 1102 container_const_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 1103 BOOST_UBLAS_INLINE
Chris@16 1104 const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
Chris@16 1105 container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
Chris@16 1106
Chris@16 1107 // Arithmetic
Chris@16 1108 BOOST_UBLAS_INLINE
Chris@16 1109 const_iterator &operator ++ () {
Chris@16 1110 ++ it2_;
Chris@16 1111 return *this;
Chris@16 1112 }
Chris@16 1113 BOOST_UBLAS_INLINE
Chris@16 1114 const_iterator &operator -- () {
Chris@16 1115 -- it2_;
Chris@16 1116 return *this;
Chris@16 1117 }
Chris@16 1118 BOOST_UBLAS_INLINE
Chris@16 1119 const_iterator &operator += (difference_type n) {
Chris@16 1120 it2_ += n;
Chris@16 1121 return *this;
Chris@16 1122 }
Chris@16 1123 BOOST_UBLAS_INLINE
Chris@16 1124 const_iterator &operator -= (difference_type n) {
Chris@16 1125 it2_ -= n;
Chris@16 1126 return *this;
Chris@16 1127 }
Chris@16 1128 BOOST_UBLAS_INLINE
Chris@16 1129 difference_type operator - (const const_iterator &it) const {
Chris@16 1130 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1131 // FIXME we shouldn't compare floats
Chris@16 1132 // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1133 return it2_ - it.it2_;
Chris@16 1134 }
Chris@16 1135
Chris@16 1136 // Dereference
Chris@16 1137 BOOST_UBLAS_INLINE
Chris@16 1138 const_reference operator * () const {
Chris@16 1139 return functor_type::apply (it1_, *it2_);
Chris@16 1140 }
Chris@16 1141 BOOST_UBLAS_INLINE
Chris@16 1142 const_reference operator [] (difference_type n) const {
Chris@16 1143 return *(*this + n);
Chris@16 1144 }
Chris@16 1145
Chris@16 1146 // Index
Chris@16 1147 BOOST_UBLAS_INLINE
Chris@16 1148 size_type index () const {
Chris@16 1149 return it2_.index ();
Chris@16 1150 }
Chris@16 1151
Chris@16 1152 // Assignment
Chris@16 1153 BOOST_UBLAS_INLINE
Chris@16 1154 const_iterator &operator = (const const_iterator &it) {
Chris@16 1155 container_const_reference<self_type>::assign (&it ());
Chris@16 1156 it1_ = it.it1_;
Chris@16 1157 it2_ = it.it2_;
Chris@16 1158 return *this;
Chris@16 1159 }
Chris@16 1160
Chris@16 1161 // Comparison
Chris@16 1162 BOOST_UBLAS_INLINE
Chris@16 1163 bool operator == (const const_iterator &it) const {
Chris@16 1164 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1165 // FIXME we shouldn't compare floats
Chris@16 1166 // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1167 return it2_ == it.it2_;
Chris@16 1168 }
Chris@16 1169 BOOST_UBLAS_INLINE
Chris@16 1170 bool operator < (const const_iterator &it) const {
Chris@16 1171 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1172 // FIXME we shouldn't compare floats
Chris@16 1173 // BOOST_UBLAS_CHECK (it1_ == it.it1_, external_logic ());
Chris@16 1174 return it2_ < it.it2_;
Chris@16 1175 }
Chris@16 1176
Chris@16 1177 private:
Chris@16 1178 const_subiterator1_type it1_;
Chris@16 1179 const_subiterator2_type it2_;
Chris@16 1180 };
Chris@16 1181 #endif
Chris@16 1182
Chris@16 1183 BOOST_UBLAS_INLINE
Chris@16 1184 const_iterator begin () const {
Chris@16 1185 return find (0);
Chris@16 1186 }
Chris@16 1187 BOOST_UBLAS_INLINE
Chris@101 1188 const_iterator cbegin () const {
Chris@101 1189 return begin ();
Chris@101 1190 }
Chris@101 1191 BOOST_UBLAS_INLINE
Chris@16 1192 const_iterator end () const {
Chris@16 1193 return find (size ());
Chris@16 1194 }
Chris@101 1195 BOOST_UBLAS_INLINE
Chris@101 1196 const_iterator cend () const {
Chris@101 1197 return end ();
Chris@101 1198 }
Chris@16 1199
Chris@16 1200 // Reverse iterator
Chris@16 1201 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 1202
Chris@16 1203 BOOST_UBLAS_INLINE
Chris@16 1204 const_reverse_iterator rbegin () const {
Chris@16 1205 return const_reverse_iterator (end ());
Chris@16 1206 }
Chris@16 1207 BOOST_UBLAS_INLINE
Chris@101 1208 const_reverse_iterator crbegin () const {
Chris@101 1209 return rbegin ();
Chris@101 1210 }
Chris@101 1211 BOOST_UBLAS_INLINE
Chris@16 1212 const_reverse_iterator rend () const {
Chris@16 1213 return const_reverse_iterator (begin ());
Chris@16 1214 }
Chris@101 1215 BOOST_UBLAS_INLINE
Chris@101 1216 const_reverse_iterator crend () const {
Chris@101 1217 return end ();
Chris@101 1218 }
Chris@16 1219
Chris@16 1220 private:
Chris@16 1221 expression1_closure_type e1_;
Chris@16 1222 expression2_closure_type e2_;
Chris@16 1223 };
Chris@16 1224
Chris@16 1225 template<class E1, class E2, class F>
Chris@16 1226 struct vector_binary_scalar1_traits {
Chris@16 1227 typedef vector_binary_scalar1<E1, E2, F> expression_type; // allow E1 to be builtin type
Chris@16 1228 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
Chris@16 1229 typedef expression_type result_type;
Chris@16 1230 #else
Chris@16 1231 typedef typename E2::vector_temporary_type result_type;
Chris@16 1232 #endif
Chris@16 1233 };
Chris@16 1234
Chris@16 1235 // (t * v) [i] = t * v [i]
Chris@16 1236 template<class T1, class E2>
Chris@16 1237 BOOST_UBLAS_INLINE
Chris@16 1238 typename enable_if< is_convertible<T1, typename E2::value_type >,
Chris@16 1239 typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::result_type
Chris@16 1240 >::type
Chris@16 1241 operator * (const T1 &e1,
Chris@16 1242 const vector_expression<E2> &e2) {
Chris@16 1243 typedef typename vector_binary_scalar1_traits<const T1, E2, scalar_multiplies<T1, typename E2::value_type> >::expression_type expression_type;
Chris@16 1244 return expression_type (e1, e2 ());
Chris@16 1245 }
Chris@16 1246
Chris@16 1247
Chris@16 1248 template<class E1, class E2, class F>
Chris@16 1249 class vector_binary_scalar2:
Chris@16 1250 public vector_expression<vector_binary_scalar2<E1, E2, F> > {
Chris@16 1251
Chris@16 1252 typedef F functor_type;
Chris@16 1253 typedef E1 expression1_type;
Chris@16 1254 typedef E2 expression2_type;
Chris@16 1255 typedef typename E1::const_closure_type expression1_closure_type;
Chris@16 1256 typedef const E2& expression2_closure_type;
Chris@16 1257 typedef vector_binary_scalar2<E1, E2, F> self_type;
Chris@16 1258 public:
Chris@16 1259 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
Chris@16 1260 using vector_expression<vector_binary_scalar2<E1, E2, F> >::operator ();
Chris@16 1261 #endif
Chris@16 1262 typedef typename E1::size_type size_type;
Chris@16 1263 typedef typename E1::difference_type difference_type;
Chris@16 1264 typedef typename F::result_type value_type;
Chris@16 1265 typedef value_type const_reference;
Chris@16 1266 typedef const_reference reference;
Chris@16 1267 typedef const self_type const_closure_type;
Chris@16 1268 typedef const_closure_type closure_type;
Chris@16 1269 typedef unknown_storage_tag storage_category;
Chris@16 1270
Chris@16 1271 // Construction and destruction
Chris@16 1272 BOOST_UBLAS_INLINE
Chris@16 1273 vector_binary_scalar2 (const expression1_type &e1, const expression2_type &e2):
Chris@16 1274 e1_ (e1), e2_ (e2) {}
Chris@16 1275
Chris@16 1276 // Accessors
Chris@16 1277 BOOST_UBLAS_INLINE
Chris@16 1278 size_type size () const {
Chris@16 1279 return e1_.size ();
Chris@16 1280 }
Chris@16 1281
Chris@16 1282 public:
Chris@16 1283 // Element access
Chris@16 1284 BOOST_UBLAS_INLINE
Chris@16 1285 const_reference operator () (size_type i) const {
Chris@16 1286 return functor_type::apply (e1_ (i), e2_);
Chris@16 1287 }
Chris@16 1288
Chris@16 1289 BOOST_UBLAS_INLINE
Chris@16 1290 const_reference operator [] (size_type i) const {
Chris@16 1291 return functor_type::apply (e1_ [i], e2_);
Chris@16 1292 }
Chris@16 1293
Chris@16 1294 // Closure comparison
Chris@16 1295 BOOST_UBLAS_INLINE
Chris@16 1296 bool same_closure (const vector_binary_scalar2 &vbs2) const {
Chris@16 1297 return (*this).e1_.same_closure (vbs2.e1_) &&
Chris@16 1298 &e2_ == &(vbs2.e2_);
Chris@16 1299 }
Chris@16 1300
Chris@16 1301 // Iterator types
Chris@16 1302 private:
Chris@16 1303 typedef typename expression1_type::const_iterator const_subiterator1_type;
Chris@16 1304 typedef expression2_type const_subiterator2_type;
Chris@16 1305 typedef const value_type *const_pointer;
Chris@16 1306
Chris@16 1307 public:
Chris@16 1308 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1309 typedef indexed_const_iterator<const_closure_type, typename const_subiterator2_type::iterator_category> const_iterator;
Chris@16 1310 typedef const_iterator iterator;
Chris@16 1311 #else
Chris@16 1312 class const_iterator;
Chris@16 1313 typedef const_iterator iterator;
Chris@16 1314 #endif
Chris@16 1315
Chris@16 1316 // Element lookup
Chris@16 1317 BOOST_UBLAS_INLINE
Chris@16 1318 const_iterator find (size_type i) const {
Chris@16 1319 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1320 const_subiterator1_type it (e1_.find (i));
Chris@16 1321 return const_iterator (*this, it.index ());
Chris@16 1322 #else
Chris@16 1323 return const_iterator (*this, e1_.find (i), const_subiterator2_type (e2_));
Chris@16 1324 #endif
Chris@16 1325 }
Chris@16 1326
Chris@16 1327 // Iterator enhances the iterator of the referenced vector expression
Chris@16 1328 // with the binary functor.
Chris@16 1329
Chris@16 1330 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
Chris@16 1331 class const_iterator:
Chris@16 1332 public container_const_reference<vector_binary_scalar2>,
Chris@16 1333 public iterator_base_traits<typename E1::const_iterator::iterator_category>::template
Chris@16 1334 iterator_base<const_iterator, value_type>::type {
Chris@16 1335 public:
Chris@16 1336 typedef typename E1::const_iterator::iterator_category iterator_category;
Chris@16 1337 typedef typename vector_binary_scalar2::difference_type difference_type;
Chris@16 1338 typedef typename vector_binary_scalar2::value_type value_type;
Chris@16 1339 typedef typename vector_binary_scalar2::const_reference reference;
Chris@16 1340 typedef typename vector_binary_scalar2::const_pointer pointer;
Chris@16 1341
Chris@16 1342 // Construction and destruction
Chris@16 1343 BOOST_UBLAS_INLINE
Chris@16 1344 const_iterator ():
Chris@16 1345 container_const_reference<self_type> (), it1_ (), it2_ () {}
Chris@16 1346 BOOST_UBLAS_INLINE
Chris@16 1347 const_iterator (const self_type &vbs, const const_subiterator1_type &it1, const const_subiterator2_type &it2):
Chris@16 1348 container_const_reference<self_type> (vbs), it1_ (it1), it2_ (it2) {}
Chris@16 1349
Chris@16 1350 // Arithmetic
Chris@16 1351 BOOST_UBLAS_INLINE
Chris@16 1352 const_iterator &operator ++ () {
Chris@16 1353 ++ it1_;
Chris@16 1354 return *this;
Chris@16 1355 }
Chris@16 1356 BOOST_UBLAS_INLINE
Chris@16 1357 const_iterator &operator -- () {
Chris@16 1358 -- it1_;
Chris@16 1359 return *this;
Chris@16 1360 }
Chris@16 1361 BOOST_UBLAS_INLINE
Chris@16 1362 const_iterator &operator += (difference_type n) {
Chris@16 1363 it1_ += n;
Chris@16 1364 return *this;
Chris@16 1365 }
Chris@16 1366 BOOST_UBLAS_INLINE
Chris@16 1367 const_iterator &operator -= (difference_type n) {
Chris@16 1368 it1_ -= n;
Chris@16 1369 return *this;
Chris@16 1370 }
Chris@16 1371 BOOST_UBLAS_INLINE
Chris@16 1372 difference_type operator - (const const_iterator &it) const {
Chris@16 1373 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1374 // FIXME we shouldn't compare floats
Chris@16 1375 // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 1376 return it1_ - it.it1_;
Chris@16 1377 }
Chris@16 1378
Chris@16 1379 // Dereference
Chris@16 1380 BOOST_UBLAS_INLINE
Chris@16 1381 const_reference operator * () const {
Chris@16 1382 return functor_type::apply (*it1_, it2_);
Chris@16 1383 }
Chris@16 1384 BOOST_UBLAS_INLINE
Chris@16 1385 const_reference operator [] (difference_type n) const {
Chris@16 1386 return *(*this + n);
Chris@16 1387 }
Chris@16 1388
Chris@16 1389 // Index
Chris@16 1390 BOOST_UBLAS_INLINE
Chris@16 1391 size_type index () const {
Chris@16 1392 return it1_.index ();
Chris@16 1393 }
Chris@16 1394
Chris@16 1395 // Assignment
Chris@16 1396 BOOST_UBLAS_INLINE
Chris@16 1397 const_iterator &operator = (const const_iterator &it) {
Chris@16 1398 container_const_reference<self_type>::assign (&it ());
Chris@16 1399 it1_ = it.it1_;
Chris@16 1400 it2_ = it.it2_;
Chris@16 1401 return *this;
Chris@16 1402 }
Chris@16 1403
Chris@16 1404 // Comparison
Chris@16 1405 BOOST_UBLAS_INLINE
Chris@16 1406 bool operator == (const const_iterator &it) const {
Chris@16 1407 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1408 // FIXME we shouldn't compare floats
Chris@16 1409 // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 1410 return it1_ == it.it1_;
Chris@16 1411 }
Chris@16 1412 BOOST_UBLAS_INLINE
Chris@16 1413 bool operator < (const const_iterator &it) const {
Chris@16 1414 BOOST_UBLAS_CHECK ((*this) ().same_closure (it ()), external_logic ());
Chris@16 1415 // FIXME we shouldn't compare floats
Chris@16 1416 // BOOST_UBLAS_CHECK (it2_ == it.it2_, external_logic ());
Chris@16 1417 return it1_ < it.it1_;
Chris@16 1418 }
Chris@16 1419
Chris@16 1420 private:
Chris@16 1421 const_subiterator1_type it1_;
Chris@16 1422 const_subiterator2_type it2_;
Chris@16 1423 };
Chris@16 1424 #endif
Chris@16 1425
Chris@16 1426 BOOST_UBLAS_INLINE
Chris@16 1427 const_iterator begin () const {
Chris@16 1428 return find (0);
Chris@16 1429 }
Chris@16 1430 BOOST_UBLAS_INLINE
Chris@101 1431 const_iterator cbegin () const {
Chris@101 1432 return begin ();
Chris@101 1433 }
Chris@101 1434 BOOST_UBLAS_INLINE
Chris@16 1435 const_iterator end () const {
Chris@16 1436 return find (size ());
Chris@16 1437 }
Chris@101 1438 BOOST_UBLAS_INLINE
Chris@101 1439 const_iterator cend () const {
Chris@101 1440 return end ();
Chris@101 1441 }
Chris@16 1442
Chris@16 1443 // Reverse iterator
Chris@16 1444 typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
Chris@16 1445
Chris@16 1446 BOOST_UBLAS_INLINE
Chris@16 1447 const_reverse_iterator rbegin () const {
Chris@16 1448 return const_reverse_iterator (end ());
Chris@16 1449 }
Chris@16 1450 BOOST_UBLAS_INLINE
Chris@101 1451 const_reverse_iterator crbegin () const {
Chris@101 1452 return rbegin ();
Chris@101 1453 }
Chris@101 1454 BOOST_UBLAS_INLINE
Chris@16 1455 const_reverse_iterator rend () const {
Chris@16 1456 return const_reverse_iterator (begin ());
Chris@16 1457 }
Chris@101 1458 BOOST_UBLAS_INLINE
Chris@101 1459 const_reverse_iterator crend () const {
Chris@101 1460 return rend ();
Chris@101 1461 }
Chris@16 1462
Chris@16 1463 private:
Chris@16 1464 expression1_closure_type e1_;
Chris@16 1465 expression2_closure_type e2_;
Chris@16 1466 };
Chris@16 1467
Chris@16 1468 template<class E1, class E2, class F>
Chris@16 1469 struct vector_binary_scalar2_traits {
Chris@16 1470 typedef vector_binary_scalar2<E1, E2, F> expression_type; // allow E2 to be builtin type
Chris@16 1471 #ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
Chris@16 1472 typedef expression_type result_type;
Chris@16 1473 #else
Chris@16 1474 typedef typename E1::vector_temporary_type result_type;
Chris@16 1475 #endif
Chris@16 1476 };
Chris@16 1477
Chris@16 1478 // (v * t) [i] = v [i] * t
Chris@16 1479 template<class E1, class T2>
Chris@16 1480 BOOST_UBLAS_INLINE
Chris@16 1481 typename enable_if< is_convertible<T2, typename E1::value_type >,
Chris@16 1482 typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::result_type
Chris@16 1483 >::type
Chris@16 1484 operator * (const vector_expression<E1> &e1,
Chris@16 1485 const T2 &e2) {
Chris@16 1486 typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_multiplies<typename E1::value_type, T2> >::expression_type expression_type;
Chris@16 1487 return expression_type (e1 (), e2);
Chris@16 1488 }
Chris@16 1489
Chris@16 1490 // (v / t) [i] = v [i] / t
Chris@16 1491 template<class E1, class T2>
Chris@16 1492 BOOST_UBLAS_INLINE
Chris@16 1493 typename enable_if< is_convertible<T2, typename E1::value_type >,
Chris@16 1494 typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::result_type
Chris@16 1495 >::type
Chris@16 1496 operator / (const vector_expression<E1> &e1,
Chris@16 1497 const T2 &e2) {
Chris@16 1498 typedef typename vector_binary_scalar2_traits<E1, const T2, scalar_divides<typename E1::value_type, T2> >::expression_type expression_type;
Chris@16 1499 return expression_type (e1 (), e2);
Chris@16 1500 }
Chris@16 1501
Chris@16 1502
Chris@16 1503 template<class E, class F>
Chris@16 1504 class vector_scalar_unary:
Chris@16 1505 public scalar_expression<vector_scalar_unary<E, F> > {
Chris@16 1506
Chris@16 1507 typedef E expression_type;
Chris@16 1508 typedef F functor_type;
Chris@16 1509 typedef typename E::const_closure_type expression_closure_type;
Chris@16 1510 typedef typename E::const_iterator::iterator_category iterator_category;
Chris@16 1511 typedef vector_scalar_unary<E, F> self_type;
Chris@16 1512 public:
Chris@16 1513 typedef typename F::result_type value_type;
Chris@16 1514 typedef typename E::difference_type difference_type;
Chris@16 1515 typedef const self_type const_closure_type;
Chris@16 1516 typedef const_closure_type closure_type;
Chris@16 1517 typedef unknown_storage_tag storage_category;
Chris@16 1518
Chris@16 1519 // Construction and destruction
Chris@16 1520 BOOST_UBLAS_INLINE
Chris@16 1521 explicit vector_scalar_unary (const expression_type &e):
Chris@16 1522 e_ (e) {}
Chris@16 1523
Chris@16 1524 private:
Chris@16 1525 // Expression accessors
Chris@16 1526 BOOST_UBLAS_INLINE
Chris@16 1527 const expression_closure_type &expression () const {
Chris@16 1528 return e_;
Chris@16 1529 }
Chris@16 1530
Chris@16 1531 public:
Chris@16 1532 BOOST_UBLAS_INLINE
Chris@16 1533 operator value_type () const {
Chris@16 1534 return evaluate (iterator_category ());
Chris@16 1535 }
Chris@16 1536
Chris@16 1537 private:
Chris@16 1538 // Dense random access specialization
Chris@16 1539 BOOST_UBLAS_INLINE
Chris@16 1540 value_type evaluate (dense_random_access_iterator_tag) const {
Chris@16 1541 #ifdef BOOST_UBLAS_USE_INDEXING
Chris@16 1542 return functor_type::apply (e_);
Chris@16 1543 #elif BOOST_UBLAS_USE_ITERATING
Chris@16 1544 difference_type size = e_.size ();
Chris@16 1545 return functor_type::apply (size, e_.begin ());
Chris@16 1546 #else
Chris@16 1547 difference_type size = e_.size ();
Chris@16 1548 if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
Chris@16 1549 return functor_type::apply (size, e_.begin ());
Chris@16 1550 else
Chris@16 1551 return functor_type::apply (e_);
Chris@16 1552 #endif
Chris@16 1553 }
Chris@16 1554
Chris@16 1555 // Packed bidirectional specialization
Chris@16 1556 BOOST_UBLAS_INLINE
Chris@16 1557 value_type evaluate (packed_random_access_iterator_tag) const {
Chris@16 1558 return functor_type::apply (e_.begin (), e_.end ());
Chris@16 1559 }
Chris@16 1560
Chris@16 1561 // Sparse bidirectional specialization
Chris@16 1562 BOOST_UBLAS_INLINE
Chris@16 1563 value_type evaluate (sparse_bidirectional_iterator_tag) const {
Chris@16 1564 return functor_type::apply (e_.begin (), e_.end ());
Chris@16 1565 }
Chris@16 1566
Chris@16 1567 private:
Chris@16 1568 expression_closure_type e_;
Chris@16 1569 };
Chris@16 1570
Chris@16 1571 template<class E, class F>
Chris@16 1572 struct vector_scalar_unary_traits {
Chris@16 1573 typedef vector_scalar_unary<E, F> expression_type;
Chris@16 1574 #if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
Chris@16 1575 // FIXME don't define USE_SCALAR_ET other then for testing
Chris@16 1576 // They do not work for complex types
Chris@16 1577 typedef expression_type result_type;
Chris@16 1578 #else
Chris@16 1579 typedef typename F::result_type result_type;
Chris@16 1580 #endif
Chris@16 1581 };
Chris@16 1582
Chris@16 1583 // sum v = sum (v [i])
Chris@16 1584 template<class E>
Chris@16 1585 BOOST_UBLAS_INLINE
Chris@16 1586 typename vector_scalar_unary_traits<E, vector_sum<E> >::result_type
Chris@16 1587 sum (const vector_expression<E> &e) {
Chris@16 1588 typedef typename vector_scalar_unary_traits<E, vector_sum<E> >::expression_type expression_type;
Chris@16 1589 return expression_type (e ());
Chris@16 1590 }
Chris@16 1591
Chris@16 1592 // real: norm_1 v = sum (abs (v [i]))
Chris@16 1593 // complex: norm_1 v = sum (abs (real (v [i])) + abs (imag (v [i])))
Chris@16 1594 template<class E>
Chris@16 1595 BOOST_UBLAS_INLINE
Chris@16 1596 typename vector_scalar_unary_traits<E, vector_norm_1<E> >::result_type
Chris@16 1597 norm_1 (const vector_expression<E> &e) {
Chris@16 1598 typedef typename vector_scalar_unary_traits<E, vector_norm_1<E> >::expression_type expression_type;
Chris@16 1599 return expression_type (e ());
Chris@16 1600 }
Chris@16 1601
Chris@16 1602 // real: norm_2 v = sqrt (sum (v [i] * v [i]))
Chris@16 1603 // complex: norm_2 v = sqrt (sum (v [i] * conj (v [i])))
Chris@16 1604 template<class E>
Chris@16 1605 BOOST_UBLAS_INLINE
Chris@16 1606 typename vector_scalar_unary_traits<E, vector_norm_2<E> >::result_type
Chris@16 1607 norm_2 (const vector_expression<E> &e) {
Chris@16 1608 typedef typename vector_scalar_unary_traits<E, vector_norm_2<E> >::expression_type expression_type;
Chris@16 1609 return expression_type (e ());
Chris@16 1610 }
Chris@16 1611
Chris@16 1612 // real: norm_inf v = maximum (abs (v [i]))
Chris@16 1613 // complex: norm_inf v = maximum (maximum (abs (real (v [i])), abs (imag (v [i]))))
Chris@16 1614 template<class E>
Chris@16 1615 BOOST_UBLAS_INLINE
Chris@16 1616 typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::result_type
Chris@16 1617 norm_inf (const vector_expression<E> &e) {
Chris@16 1618 typedef typename vector_scalar_unary_traits<E, vector_norm_inf<E> >::expression_type expression_type;
Chris@16 1619 return expression_type (e ());
Chris@16 1620 }
Chris@16 1621
Chris@16 1622 // real: index_norm_inf v = minimum (i: abs (v [i]) == maximum (abs (v [i])))
Chris@16 1623 template<class E>
Chris@16 1624 BOOST_UBLAS_INLINE
Chris@16 1625 typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::result_type
Chris@16 1626 index_norm_inf (const vector_expression<E> &e) {
Chris@16 1627 typedef typename vector_scalar_unary_traits<E, vector_index_norm_inf<E> >::expression_type expression_type;
Chris@16 1628 return expression_type (e ());
Chris@16 1629 }
Chris@16 1630
Chris@16 1631 template<class E1, class E2, class F>
Chris@16 1632 class vector_scalar_binary:
Chris@16 1633 public scalar_expression<vector_scalar_binary<E1, E2, F> > {
Chris@16 1634
Chris@16 1635 typedef E1 expression1_type;
Chris@16 1636 typedef E2 expression2_type;
Chris@16 1637 typedef F functor_type;
Chris@16 1638 typedef typename E1::const_closure_type expression1_closure_type;
Chris@16 1639 typedef typename E2::const_closure_type expression2_closure_type;
Chris@16 1640 typedef typename iterator_restrict_traits<typename E1::const_iterator::iterator_category,
Chris@16 1641 typename E2::const_iterator::iterator_category>::iterator_category iterator_category;
Chris@16 1642 typedef vector_scalar_binary<E1, E2, F> self_type;
Chris@16 1643 public:
Chris@16 1644 static const unsigned complexity = 1;
Chris@16 1645 typedef typename F::result_type value_type;
Chris@16 1646 typedef typename E1::difference_type difference_type;
Chris@16 1647 typedef const self_type const_closure_type;
Chris@16 1648 typedef const_closure_type closure_type;
Chris@16 1649 typedef unknown_storage_tag storage_category;
Chris@16 1650
Chris@16 1651 // Construction and destruction
Chris@16 1652 BOOST_UBLAS_INLINE
Chris@16 1653 vector_scalar_binary (const expression1_type &e1, const expression2_type &e2):
Chris@16 1654 e1_ (e1), e2_ (e2) {}
Chris@16 1655
Chris@16 1656 private:
Chris@16 1657 // Accessors
Chris@16 1658 BOOST_UBLAS_INLINE
Chris@16 1659 const expression1_closure_type &expression1 () const {
Chris@16 1660 return e1_;
Chris@16 1661 }
Chris@16 1662 BOOST_UBLAS_INLINE
Chris@16 1663 const expression2_closure_type &expression2 () const {
Chris@16 1664 return e2_;
Chris@16 1665 }
Chris@16 1666
Chris@16 1667 public:
Chris@16 1668 BOOST_UBLAS_INLINE
Chris@16 1669 operator value_type () const {
Chris@16 1670 return evaluate (iterator_category ());
Chris@16 1671 }
Chris@16 1672
Chris@16 1673 private:
Chris@16 1674 // Dense random access specialization
Chris@16 1675 BOOST_UBLAS_INLINE
Chris@16 1676 value_type evaluate (dense_random_access_iterator_tag) const {
Chris@16 1677 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
Chris@16 1678 #ifdef BOOST_UBLAS_USE_INDEXING
Chris@16 1679 return functor_type::apply (e1_, e2_);
Chris@16 1680 #elif BOOST_UBLAS_USE_ITERATING
Chris@16 1681 difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
Chris@16 1682 return functor_type::apply (size, e1_.begin (), e2_.begin ());
Chris@16 1683 #else
Chris@16 1684 difference_type size = BOOST_UBLAS_SAME (e1_.size (), e2_.size ());
Chris@16 1685 if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
Chris@16 1686 return functor_type::apply (size, e1_.begin (), e2_.begin ());
Chris@16 1687 else
Chris@16 1688 return functor_type::apply (e1_, e2_);
Chris@16 1689 #endif
Chris@16 1690 }
Chris@16 1691
Chris@16 1692 // Packed bidirectional specialization
Chris@16 1693 BOOST_UBLAS_INLINE
Chris@16 1694 value_type evaluate (packed_random_access_iterator_tag) const {
Chris@16 1695 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
Chris@16 1696 return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end ());
Chris@16 1697 }
Chris@16 1698
Chris@16 1699 // Sparse bidirectional specialization
Chris@16 1700 BOOST_UBLAS_INLINE
Chris@16 1701 value_type evaluate (sparse_bidirectional_iterator_tag) const {
Chris@16 1702 BOOST_UBLAS_CHECK (e1_.size () == e2_.size (), external_logic());
Chris@16 1703 return functor_type::apply (e1_.begin (), e1_.end (), e2_.begin (), e2_.end (), sparse_bidirectional_iterator_tag ());
Chris@16 1704 }
Chris@16 1705
Chris@16 1706 private:
Chris@16 1707 expression1_closure_type e1_;
Chris@16 1708 expression2_closure_type e2_;
Chris@16 1709 };
Chris@16 1710
Chris@16 1711 template<class E1, class E2, class F>
Chris@16 1712 struct vector_scalar_binary_traits {
Chris@16 1713 typedef vector_scalar_binary<E1, E2, F> expression_type;
Chris@16 1714 #if !defined (BOOST_UBLAS_SIMPLE_ET_DEBUG) && defined (BOOST_UBLAS_USE_SCALAR_ET)
Chris@16 1715 // FIXME don't define USE_SCALAR_ET other then for testing
Chris@16 1716 // They do not work for complex types
Chris@16 1717 typedef expression_type result_type;
Chris@16 1718 #else
Chris@16 1719 typedef typename F::result_type result_type;
Chris@16 1720 #endif
Chris@16 1721 };
Chris@16 1722
Chris@16 1723 // inner_prod (v1, v2) = sum (v1 [i] * v2 [i])
Chris@16 1724 template<class E1, class E2>
Chris@16 1725 BOOST_UBLAS_INLINE
Chris@16 1726 typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
Chris@16 1727 typename promote_traits<typename E1::value_type,
Chris@16 1728 typename E2::value_type>::promote_type> >::result_type
Chris@16 1729 inner_prod (const vector_expression<E1> &e1,
Chris@16 1730 const vector_expression<E2> &e2) {
Chris@16 1731 typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
Chris@16 1732 typename promote_traits<typename E1::value_type,
Chris@16 1733 typename E2::value_type>::promote_type> >::expression_type expression_type;
Chris@16 1734 return expression_type (e1 (), e2 ());
Chris@16 1735 }
Chris@16 1736
Chris@16 1737 template<class E1, class E2>
Chris@16 1738 BOOST_UBLAS_INLINE
Chris@16 1739 typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
Chris@16 1740 typename type_traits<typename promote_traits<typename E1::value_type,
Chris@16 1741 typename E2::value_type>::promote_type>::precision_type> >::result_type
Chris@16 1742 prec_inner_prod (const vector_expression<E1> &e1,
Chris@16 1743 const vector_expression<E2> &e2) {
Chris@16 1744 typedef typename vector_scalar_binary_traits<E1, E2, vector_inner_prod<E1, E2,
Chris@16 1745 typename type_traits<typename promote_traits<typename E1::value_type,
Chris@16 1746 typename E2::value_type>::promote_type>::precision_type> >::expression_type expression_type;
Chris@16 1747 return expression_type (e1 (), e2 ());
Chris@16 1748 }
Chris@16 1749
Chris@16 1750 }}}
Chris@16 1751
Chris@16 1752 #endif