Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:04

0001 //  Copyright (c) 2000-2013
0002 //  Joerg Walter, Mathias Koch. David Bellot
0003 //
0004 //  Distributed under the Boost Software License, Version 1.0. (See
0005 //  accompanying file LICENSE_1_0.txt or copy at
0006 //  http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 //  The authors gratefully acknowledge the support of
0009 //  GeNeSys mbH & Co. KG in producing this work.
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 // Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish
0020 // Iterators based on ideas of Jeremy Siek
0021 
0022 namespace boost { namespace numeric { namespace ublas {
0023 
0024     /** \brief Base class for uBLAS statically derived expressions using the the Barton Nackman trick
0025      *
0026      * This is a NonAssignable class
0027      * Directly implement nonassignable - simplifes debugging call trace!
0028      * 
0029      * \tparam E an expression type
0030      */
0031     template<class E>
0032     class ublas_expression {
0033     public:
0034         typedef E expression_type;
0035         /* E can be an incomplete type - to define the following we would need more template arguments
0036         typedef typename E::type_category type_category;
0037         typedef typename E::value_type value_type;
0038         */
0039         
0040     protected:
0041         ublas_expression () {}
0042         ~ublas_expression () {}
0043     private:
0044         const ublas_expression& operator= (const ublas_expression &);
0045     };
0046 
0047 
0048     /** \brief Base class for Scalar Expression models
0049      *
0050      * It does not model the Scalar Expression concept but all derived types should.
0051      * The class defines a common base type and some common interface for all statically 
0052      * derived Scalar Expression classes.
0053      *
0054      * We implement the casts to the statically derived type.
0055      *
0056      * \tparam E an expression type
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         // Construction and destruction
0090         BOOST_UBLAS_INLINE
0091         explicit scalar_reference (reference t):
0092             t_ (t) {}
0093 
0094         // Conversion
0095         BOOST_UBLAS_INLINE
0096         operator value_type () const {
0097             return t_;
0098         }
0099 
0100         // Assignment
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         // Closure comparison
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         // Construction and destruction
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         // Assignment
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         // Closure comparison
0164         BOOST_UBLAS_INLINE
0165         bool same_closure (const scalar_value &sv) const {
0166             return this == &sv;    // self closing on instances value
0167         }
0168 
0169     private:
0170         value_type t_;
0171     };
0172 
0173 
0174     /** \brief Base class for Vector Expression models
0175      *
0176      * it does not model the Vector Expression concept but all derived types should.
0177      * The class defines a common base type and some common interface for all
0178      * statically derived Vector Expression classes.
0179      * We implement the casts to the statically derived type.
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         /* E can be an incomplete type - to define the following we would need more template arguments
0189         typedef typename E::size_type size_type;
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         // projection types
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         // vector_indirect_type will depend on the A template parameter 
0209         typedef basic_range<> default_range;    // required to avoid range/slice name confusion
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     /** \brief Base class for Vector container models
0269      *
0270      * it does not model the Vector concept but all derived types should.
0271      * The class defines a common base type and some common interface for all
0272      * statically derived Vector classes
0273      * We implement the casts to the statically derived type.
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     /** \brief Base class for Matrix Expression models
0299      *
0300      * it does not model the Matrix Expression concept but all derived types should.
0301      * The class defines a common base type and some common interface for all
0302      * statically derived Matrix Expression classes
0303      * We implement the casts to the statically derived type.
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         /* E can be an incomplete type - to define the following we would need more template arguments
0315         typedef typename E::size_type size_type;
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         // projection types
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         // matrix_indirect_type will depend on the A template parameter 
0343         typedef basic_range<> default_range;    // required to avoid range/slice name confusion
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     /** \brief Base class for Matrix container models
0476      *
0477      * it does not model the Matrix concept but all derived types should.
0478      * The class defines a common base type and some common interface for all
0479      * statically derived Matrix classes
0480      * We implement the casts to the statically derived type.
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