Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms

definitions.hpp

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2000-2002
00003 //  Joerg Walter, Mathias Koch
00004 //
00005 //  Distributed under the Boost Software License, Version 1.0. (See
00006 //  accompanying file LICENSE_1_0.txt or copy at
00007 //  http://www.boost.org/LICENSE_1_0.txt)
00008 //
00009 //  The authors gratefully acknowledge the support of
00010 //  GeNeSys mbH & Co. KG in producing this work.
00011 //
00012 
00013 #ifndef _BOOST_UBLAS_DEFINITIONS_
00014 #define _BOOST_UBLAS_DEFINITIONS_
00015 
00016 
00017 namespace boost { namespace numeric { namespace ublas {
00018 
00019     namespace detail {
00020         /* Borrowed from boost/concept_checks.hpp
00021            "inline" is used for ignore_unused_variable_warning()
00022            to make sure there is no overhead with g++.
00023          */
00024         template <class T> inline
00025         void ignore_unused_variable_warning(const T&) {}
00026     } // namespace detail
00027 
00028     // Borrowed from Dave Abraham's noncopyable.
00029     // I believe this should be part of utility.hpp one day...
00030     namespace nonassignable_  // protection from unintended ADL
00031     {
00032         class nonassignable {
00033         protected:
00034             nonassignable () {}
00035             ~nonassignable () {}
00036         private:  // emphasize the following members are private
00037             const nonassignable& operator= (const nonassignable &);
00038         }; // nonassignable
00039     }
00040     typedef nonassignable_::nonassignable nonassignable;
00041 
00042 
00043     // Assignment proxy.
00044     // Provides temporary free assigment when LHS has no alias on RHS
00045     template<class C>
00046     class noalias_proxy:
00047         private nonassignable {
00048     public:
00049         typedef typename C::closure_type closure_type;
00050 
00051         BOOST_UBLAS_INLINE
00052         noalias_proxy (C& lval):
00053             nonassignable (), lval_ (lval) {}
00054         BOOST_UBLAS_INLINE
00055         noalias_proxy (const noalias_proxy& p):
00056             nonassignable (), lval_ (p.lval_) {}
00057 
00058         template <class E>
00059         BOOST_UBLAS_INLINE
00060         closure_type &operator= (const E& e) {
00061             lval_.assign (e);
00062             return lval_;
00063         }
00064 
00065         template <class E>
00066         BOOST_UBLAS_INLINE
00067         closure_type &operator+= (const E& e) {
00068             lval_.plus_assign (e);
00069             return lval_;
00070         }
00071 
00072         template <class E>
00073         BOOST_UBLAS_INLINE
00074         closure_type &operator-= (const E& e) {
00075             lval_.minus_assign (e);
00076             return lval_;
00077         }
00078 
00079     private:
00080         closure_type lval_;
00081     };
00082 
00083     // Improve syntax of efficient assignment where no aliases of LHS appear on the RHS
00084     //  noalias(lhs) = rhs_expression
00085     template <class C>
00086     BOOST_UBLAS_INLINE
00087     noalias_proxy<C> noalias (C& lvalue) {
00088         return noalias_proxy<C> (lvalue);
00089     }
00090     template <class C>
00091     BOOST_UBLAS_INLINE
00092     noalias_proxy<const C> noalias (const C& lvalue) {
00093         return noalias_proxy<const C> (lvalue);
00094     }
00095 
00096     // Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS
00097     //  safe(lhs) = rhs_expression
00098     template <class C>
00099     BOOST_UBLAS_INLINE
00100     C& safe (C& lvalue) {
00101         return lvalue;
00102     }
00103     template <class C>
00104     BOOST_UBLAS_INLINE
00105     const C& safe (const C& lvalue) {
00106         return lvalue;
00107     }
00108 
00109 
00110     // Dimension accessors
00111     namespace dimension {
00112 
00113         // Generic accessors
00114         template<unsigned dimension>
00115         struct dimension_properties {};
00116         
00117         template<>
00118         struct dimension_properties<1> {
00119             template <class E>
00120             BOOST_UBLAS_INLINE static
00121             typename E::size_type size (const vector_expression<E> &e) {
00122                 return e ().size ();
00123             }
00124             template <class E>
00125             BOOST_UBLAS_INLINE static
00126             typename E::size_type size (const matrix_expression<E> &e) {
00127                 return e ().size1 ();
00128             }
00129             // Note: Index functions cannot deduce dependant template parameter V or M from i
00130             template <class V>
00131             BOOST_UBLAS_INLINE static
00132             typename V::size_type index (const typename V::iterator &i) {
00133                 return i.index ();
00134             }
00135             template <class M>
00136             BOOST_UBLAS_INLINE static
00137             typename M::size_type index (const typename M::iterator1 &i) {
00138                 return i.index1 ();
00139             }
00140             template <class M>
00141             BOOST_UBLAS_INLINE static
00142             typename M::size_type index (const typename M::iterator2 &i) {
00143                 return i.index1 ();
00144             }
00145         };
00146         template<>
00147         struct dimension_properties<2> {
00148             template <class E>
00149             BOOST_UBLAS_INLINE static
00150             typename E::size_type size (const vector_expression<E> &) {
00151                 return 1;
00152             }
00153             template <class E>
00154             BOOST_UBLAS_INLINE static
00155             typename E::size_type size (const matrix_expression<E> &e) {
00156                 return e ().size2 ();
00157             }
00158             template <class V>
00159             BOOST_UBLAS_INLINE static
00160             typename V::size_type index (const typename V::iterator &) {
00161                 return 1;
00162             }
00163             template <class M>
00164             BOOST_UBLAS_INLINE static
00165             typename M::size_type index (const typename M::iterator1 &i) {
00166                 return i.index2 ();
00167             }
00168             template <class M>
00169             BOOST_UBLAS_INLINE static
00170             typename M::size_type index (const typename M::iterator2 &i) {
00171                 return i.index2 ();
00172             }
00173         };
00174 
00175         template<unsigned dimension, class E>
00176         BOOST_UBLAS_INLINE
00177         typename E::size_type size (const E& e) {
00178             return dimension_properties<dimension>::size (e);
00179         }
00180 
00181         template<unsigned dimension, class I>
00182         BOOST_UBLAS_INLINE
00183         typename I::container_type::size_type
00184         index (const I& i) {
00185             typedef typename I::container_type container_type;
00186             return dimension_properties<dimension>::template index<container_type> (i);
00187         }
00188 
00189 
00190         // Named accessors - just syntactic sugar
00191         template<class V>
00192         typename V::size_type num_elements (const V &v) {
00193             return v.size ();
00194         }
00195         template<class M>
00196         typename M::size_type num_rows (const M &m) {
00197             return m.size1 ();
00198         }
00199         template<class M>
00200         typename M::size_type num_columns (const M &m) {
00201             return m.size2 ();
00202         }
00203         template<class MV>
00204         typename MV::size_type num_non_zeros (const MV &mv) {
00205             return mv.non_zeros ();
00206         }
00207     }
00208 
00209 
00210 }}}
00211 
00212 #endif