![]() |
Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms
|
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