File indexing completed on 2025-01-18 09:43:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _BOOST_UBLAS_EXPRESSION_TYPE_
0012 #define _BOOST_UBLAS_EXPRESSION_TYPE_
0013
0014 #include <boost/numeric/ublas/exception.hpp>
0015 #include <boost/numeric/ublas/traits.hpp>
0016 #include <boost/numeric/ublas/functional.hpp>
0017
0018
0019
0020
0021
0022 namespace boost { namespace numeric { namespace ublas {
0023
0024
0025
0026
0027
0028
0029
0030
0031 template<class E>
0032 class ublas_expression {
0033 public:
0034 typedef E expression_type;
0035
0036
0037
0038
0039
0040 protected:
0041 ublas_expression () {}
0042 ~ublas_expression () {}
0043 private:
0044 const ublas_expression& operator= (const ublas_expression &);
0045 };
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template<class E>
0059 class scalar_expression:
0060 public ublas_expression<E> {
0061 public:
0062 typedef E expression_type;
0063 typedef scalar_tag type_category;
0064
0065 BOOST_UBLAS_INLINE
0066 const expression_type &operator () () const {
0067 return *static_cast<const expression_type *> (this);
0068 }
0069 BOOST_UBLAS_INLINE
0070 expression_type &operator () () {
0071 return *static_cast<expression_type *> (this);
0072 }
0073 };
0074
0075 template<class T>
0076 class scalar_reference:
0077 public scalar_expression<scalar_reference<T> > {
0078
0079 typedef scalar_reference<T> self_type;
0080 public:
0081 typedef T value_type;
0082 typedef const value_type &const_reference;
0083 typedef typename boost::mpl::if_<boost::is_const<T>,
0084 const_reference,
0085 value_type &>::type reference;
0086 typedef const self_type const_closure_type;
0087 typedef const_closure_type closure_type;
0088
0089
0090 BOOST_UBLAS_INLINE
0091 explicit scalar_reference (reference t):
0092 t_ (t) {}
0093
0094
0095 BOOST_UBLAS_INLINE
0096 operator value_type () const {
0097 return t_;
0098 }
0099
0100
0101 BOOST_UBLAS_INLINE
0102 scalar_reference &operator = (const scalar_reference &s) {
0103 t_ = s.t_;
0104 return *this;
0105 }
0106 template<class AE>
0107 BOOST_UBLAS_INLINE
0108 scalar_reference &operator = (const scalar_expression<AE> &ae) {
0109 t_ = ae;
0110 return *this;
0111 }
0112
0113
0114 BOOST_UBLAS_INLINE
0115 bool same_closure (const scalar_reference &sr) const {
0116 return &t_ == &sr.t_;
0117 }
0118
0119 private:
0120 reference t_;
0121 };
0122
0123 template<class T>
0124 class scalar_value:
0125 public scalar_expression<scalar_value<T> > {
0126
0127 typedef scalar_value<T> self_type;
0128 public:
0129 typedef T value_type;
0130 typedef const value_type &const_reference;
0131 typedef typename boost::mpl::if_<boost::is_const<T>,
0132 const_reference,
0133 value_type &>::type reference;
0134 typedef const scalar_reference<const self_type> const_closure_type;
0135 typedef scalar_reference<self_type> closure_type;
0136
0137
0138 BOOST_UBLAS_INLINE
0139 scalar_value ():
0140 t_ () {}
0141 BOOST_UBLAS_INLINE
0142 scalar_value (const value_type &t):
0143 t_ (t) {}
0144
0145 BOOST_UBLAS_INLINE
0146 operator value_type () const {
0147 return t_;
0148 }
0149
0150
0151 BOOST_UBLAS_INLINE
0152 scalar_value &operator = (const scalar_value &s) {
0153 t_ = s.t_;
0154 return *this;
0155 }
0156 template<class AE>
0157 BOOST_UBLAS_INLINE
0158 scalar_value &operator = (const scalar_expression<AE> &ae) {
0159 t_ = ae;
0160 return *this;
0161 }
0162
0163
0164 BOOST_UBLAS_INLINE
0165 bool same_closure (const scalar_value &sv) const {
0166 return this == &sv;
0167 }
0168
0169 private:
0170 value_type t_;
0171 };
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 template<class E>
0182 class vector_expression:
0183 public ublas_expression<E> {
0184 public:
0185 static const unsigned complexity = 0;
0186 typedef E expression_type;
0187 typedef vector_tag type_category;
0188
0189
0190
0191
0192 BOOST_UBLAS_INLINE
0193 const expression_type &operator () () const {
0194 return *static_cast<const expression_type *> (this);
0195 }
0196 BOOST_UBLAS_INLINE
0197 expression_type &operator () () {
0198 return *static_cast<expression_type *> (this);
0199 }
0200
0201 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0202 private:
0203
0204 typedef vector_range<E> vector_range_type;
0205 typedef vector_range<const E> const_vector_range_type;
0206 typedef vector_slice<E> vector_slice_type;
0207 typedef vector_slice<const E> const_vector_slice_type;
0208
0209 typedef basic_range<> default_range;
0210 typedef basic_slice<> default_slice;
0211 public:
0212 BOOST_UBLAS_INLINE
0213 const_vector_range_type operator () (const default_range &r) const {
0214 return const_vector_range_type (operator () (), r);
0215 }
0216 BOOST_UBLAS_INLINE
0217 vector_range_type operator () (const default_range &r) {
0218 return vector_range_type (operator () (), r);
0219 }
0220 BOOST_UBLAS_INLINE
0221 const_vector_slice_type operator () (const default_slice &s) const {
0222 return const_vector_slice_type (operator () (), s);
0223 }
0224 BOOST_UBLAS_INLINE
0225 vector_slice_type operator () (const default_slice &s) {
0226 return vector_slice_type (operator () (), s);
0227 }
0228 template<class A>
0229 BOOST_UBLAS_INLINE
0230 const vector_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia) const {
0231 return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
0232 }
0233 template<class A>
0234 BOOST_UBLAS_INLINE
0235 vector_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia) {
0236 return vector_indirect<E, indirect_array<A> > (operator () (), ia);
0237 }
0238
0239 BOOST_UBLAS_INLINE
0240 const_vector_range_type project (const default_range &r) const {
0241 return const_vector_range_type (operator () (), r);
0242 }
0243 BOOST_UBLAS_INLINE
0244 vector_range_type project (const default_range &r) {
0245 return vector_range_type (operator () (), r);
0246 }
0247 BOOST_UBLAS_INLINE
0248 const_vector_slice_type project (const default_slice &s) const {
0249 return const_vector_slice_type (operator () (), s);
0250 }
0251 BOOST_UBLAS_INLINE
0252 vector_slice_type project (const default_slice &s) {
0253 return vector_slice_type (operator () (), s);
0254 }
0255 template<class A>
0256 BOOST_UBLAS_INLINE
0257 const vector_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia) const {
0258 return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
0259 }
0260 template<class A>
0261 BOOST_UBLAS_INLINE
0262 vector_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia) {
0263 return vector_indirect<E, indirect_array<A> > (operator () (), ia);
0264 }
0265 #endif
0266 };
0267
0268
0269
0270
0271
0272
0273
0274
0275 template<class C>
0276 class vector_container:
0277 public vector_expression<C> {
0278 public:
0279 static const unsigned complexity = 0;
0280 typedef C container_type;
0281 typedef vector_tag type_category;
0282
0283 BOOST_UBLAS_INLINE
0284 const container_type &operator () () const {
0285 return *static_cast<const container_type *> (this);
0286 }
0287 BOOST_UBLAS_INLINE
0288 container_type &operator () () {
0289 return *static_cast<container_type *> (this);
0290 }
0291
0292 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0293 using vector_expression<C>::operator ();
0294 #endif
0295 };
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 template<class E>
0306 class matrix_expression:
0307 public ublas_expression<E> {
0308 private:
0309 typedef matrix_expression<E> self_type;
0310 public:
0311 static const unsigned complexity = 0;
0312 typedef E expression_type;
0313 typedef matrix_tag type_category;
0314
0315
0316
0317
0318 BOOST_UBLAS_INLINE
0319 const expression_type &operator () () const {
0320 return *static_cast<const expression_type *> (this);
0321 }
0322 BOOST_UBLAS_INLINE
0323 expression_type &operator () () {
0324 return *static_cast<expression_type *> (this);
0325 }
0326
0327 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0328 private:
0329
0330 typedef vector_range<E> vector_range_type;
0331 typedef const vector_range<const E> const_vector_range_type;
0332 typedef vector_slice<E> vector_slice_type;
0333 typedef const vector_slice<const E> const_vector_slice_type;
0334 typedef matrix_row<E> matrix_row_type;
0335 typedef const matrix_row<const E> const_matrix_row_type;
0336 typedef matrix_column<E> matrix_column_type;
0337 typedef const matrix_column<const E> const_matrix_column_type;
0338 typedef matrix_range<E> matrix_range_type;
0339 typedef const matrix_range<const E> const_matrix_range_type;
0340 typedef matrix_slice<E> matrix_slice_type;
0341 typedef const matrix_slice<const E> const_matrix_slice_type;
0342
0343 typedef basic_range<> default_range;
0344 typedef basic_slice<> default_slice;
0345
0346 public:
0347 BOOST_UBLAS_INLINE
0348 const_matrix_row_type operator [] (std::size_t i) const {
0349 return const_matrix_row_type (operator () (), i);
0350 }
0351 BOOST_UBLAS_INLINE
0352 matrix_row_type operator [] (std::size_t i) {
0353 return matrix_row_type (operator () (), i);
0354 }
0355 BOOST_UBLAS_INLINE
0356 const_matrix_row_type row (std::size_t i) const {
0357 return const_matrix_row_type (operator () (), i);
0358 }
0359 BOOST_UBLAS_INLINE
0360 matrix_row_type row (std::size_t i) {
0361 return matrix_row_type (operator () (), i);
0362 }
0363 BOOST_UBLAS_INLINE
0364 const_matrix_column_type column (std::size_t j) const {
0365 return const_matrix_column_type (operator () (), j);
0366 }
0367 BOOST_UBLAS_INLINE
0368 matrix_column_type column (std::size_t j) {
0369 return matrix_column_type (operator () (), j);
0370 }
0371
0372 BOOST_UBLAS_INLINE
0373 const_matrix_range_type operator () (const default_range &r1, const default_range &r2) const {
0374 return const_matrix_range_type (operator () (), r1, r2);
0375 }
0376 BOOST_UBLAS_INLINE
0377 matrix_range_type operator () (const default_range &r1, const default_range &r2) {
0378 return matrix_range_type (operator () (), r1, r2);
0379 }
0380 BOOST_UBLAS_INLINE
0381 const_matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) const {
0382 return const_matrix_slice_type (operator () (), s1, s2);
0383 }
0384 BOOST_UBLAS_INLINE
0385 matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) {
0386 return matrix_slice_type (operator () (), s1, s2);
0387 }
0388 template<class A>
0389 BOOST_UBLAS_INLINE
0390 const matrix_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
0391 return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
0392 }
0393 template<class A>
0394 BOOST_UBLAS_INLINE
0395 matrix_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
0396 return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
0397 }
0398
0399 BOOST_UBLAS_INLINE
0400 const_matrix_range_type project (const default_range &r1, const default_range &r2) const {
0401 return const_matrix_range_type (operator () (), r1, r2);
0402 }
0403 BOOST_UBLAS_INLINE
0404 matrix_range_type project (const default_range &r1, const default_range &r2) {
0405 return matrix_range_type (operator () (), r1, r2);
0406 }
0407 BOOST_UBLAS_INLINE
0408 const_matrix_slice_type project (const default_slice &s1, const default_slice &s2) const {
0409 return const_matrix_slice_type (operator () (), s1, s2);
0410 }
0411 BOOST_UBLAS_INLINE
0412 matrix_slice_type project (const default_slice &s1, const default_slice &s2) {
0413 return matrix_slice_type (operator () (), s1, s2);
0414 }
0415 template<class A>
0416 BOOST_UBLAS_INLINE
0417 const matrix_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
0418 return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
0419 }
0420 template<class A>
0421 BOOST_UBLAS_INLINE
0422 matrix_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
0423 return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
0424 }
0425 #endif
0426 };
0427
0428 #ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
0429 struct iterator1_tag {};
0430 struct iterator2_tag {};
0431
0432 template<class I>
0433 BOOST_UBLAS_INLINE
0434 typename I::dual_iterator_type begin (const I &it, iterator1_tag) {
0435 return it ().find2 (1, it.index1 (), 0);
0436 }
0437 template<class I>
0438 BOOST_UBLAS_INLINE
0439 typename I::dual_iterator_type end (const I &it, iterator1_tag) {
0440 return it ().find2 (1, it.index1 (), it ().size2 ());
0441 }
0442 template<class I>
0443 BOOST_UBLAS_INLINE
0444 typename I::dual_reverse_iterator_type rbegin (const I &it, iterator1_tag) {
0445 return typename I::dual_reverse_iterator_type (end (it, iterator1_tag ()));
0446 }
0447 template<class I>
0448 BOOST_UBLAS_INLINE
0449 typename I::dual_reverse_iterator_type rend (const I &it, iterator1_tag) {
0450 return typename I::dual_reverse_iterator_type (begin (it, iterator1_tag ()));
0451 }
0452
0453 template<class I>
0454 BOOST_UBLAS_INLINE
0455 typename I::dual_iterator_type begin (const I &it, iterator2_tag) {
0456 return it ().find1 (1, 0, it.index2 ());
0457 }
0458 template<class I>
0459 BOOST_UBLAS_INLINE
0460 typename I::dual_iterator_type end (const I &it, iterator2_tag) {
0461 return it ().find1 (1, it ().size1 (), it.index2 ());
0462 }
0463 template<class I>
0464 BOOST_UBLAS_INLINE
0465 typename I::dual_reverse_iterator_type rbegin (const I &it, iterator2_tag) {
0466 return typename I::dual_reverse_iterator_type (end (it, iterator2_tag ()));
0467 }
0468 template<class I>
0469 BOOST_UBLAS_INLINE
0470 typename I::dual_reverse_iterator_type rend (const I &it, iterator2_tag) {
0471 return typename I::dual_reverse_iterator_type (begin (it, iterator2_tag ()));
0472 }
0473 #endif
0474
0475
0476
0477
0478
0479
0480
0481
0482 template<class C>
0483 class matrix_container:
0484 public matrix_expression<C> {
0485 public:
0486 static const unsigned complexity = 0;
0487 typedef C container_type;
0488 typedef matrix_tag type_category;
0489
0490 BOOST_UBLAS_INLINE
0491 const container_type &operator () () const {
0492 return *static_cast<const container_type *> (this);
0493 }
0494 BOOST_UBLAS_INLINE
0495 container_type &operator () () {
0496 return *static_cast<container_type *> (this);
0497 }
0498
0499 #ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
0500 using matrix_expression<C>::operator ();
0501 #endif
0502 };
0503
0504 }}}
0505
0506 #endif