Eigne Matrix Class Library
Dependents: Eigen_test Odometry_test AttitudeEstimation_usingTicker MPU9250_Quaternion_Binary_Serial ... more
Ref.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_REF_H 00011 #define EIGEN_REF_H 00012 00013 namespace Eigen { 00014 00015 template<typename Derived> class RefBase; 00016 template<typename PlainObjectType, int Options = 0, 00017 typename StrideType = typename internal::conditional<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> >::type > class Ref; 00018 00019 /** \class Ref 00020 * \ingroup Core_Module 00021 * 00022 * \brief A matrix or vector expression mapping an existing expressions 00023 * 00024 * \tparam PlainObjectType the equivalent matrix type of the mapped data 00025 * \tparam Options specifies whether the pointer is \c #Aligned, or \c #Unaligned. 00026 * The default is \c #Unaligned. 00027 * \tparam StrideType optionally specifies strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1), 00028 * but accept a variable outer stride (leading dimension). 00029 * This can be overridden by specifying strides. 00030 * The type passed here must be a specialization of the Stride template, see examples below. 00031 * 00032 * This class permits to write non template functions taking Eigen's object as parameters while limiting the number of copies. 00033 * A Ref<> object can represent either a const expression or a l-value: 00034 * \code 00035 * // in-out argument: 00036 * void foo1(Ref<VectorXf> x); 00037 * 00038 * // read-only const argument: 00039 * void foo2(const Ref<const VectorXf>& x); 00040 * \endcode 00041 * 00042 * In the in-out case, the input argument must satisfies the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered. 00043 * By default, a Ref<VectorXf> can reference any dense vector expression of float having a contiguous memory layout. 00044 * Likewise, a Ref<MatrixXf> can reference any column major dense matrix expression of float whose column's elements are contiguously stored with 00045 * the possibility to have a constant space inbetween each column, i.e.: the inner stride mmust be equal to 1, but the outer-stride (or leading dimension), 00046 * can be greater than the number of rows. 00047 * 00048 * In the const case, if the input expression does not match the above requirement, then it is evaluated into a temporary before being passed to the function. 00049 * Here are some examples: 00050 * \code 00051 * MatrixXf A; 00052 * VectorXf a; 00053 * foo1(a.head()); // OK 00054 * foo1(A.col()); // OK 00055 * foo1(A.row()); // compilation error because here innerstride!=1 00056 * foo2(A.row()); // The row is copied into a contiguous temporary 00057 * foo2(2*a); // The expression is evaluated into a temporary 00058 * foo2(A.col().segment(2,4)); // No temporary 00059 * \endcode 00060 * 00061 * The range of inputs that can be referenced without temporary can be enlarged using the last two template parameter. 00062 * Here is an example accepting an innerstride!=1: 00063 * \code 00064 * // in-out argument: 00065 * void foo3(Ref<VectorXf,0,InnerStride<> > x); 00066 * foo3(A.row()); // OK 00067 * \endcode 00068 * The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involved more 00069 * expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overloads internally calling a 00070 * template function, e.g.: 00071 * \code 00072 * // in the .h: 00073 * void foo(const Ref<MatrixXf>& A); 00074 * void foo(const Ref<MatrixXf,0,Stride<> >& A); 00075 * 00076 * // in the .cpp: 00077 * template<typename TypeOfA> void foo_impl(const TypeOfA& A) { 00078 * ... // crazy code goes here 00079 * } 00080 * void foo(const Ref<MatrixXf>& A) { foo_impl(A); } 00081 * void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); } 00082 * \endcode 00083 * 00084 * 00085 * \sa PlainObjectBase::Map(), \ref TopicStorageOrders 00086 */ 00087 00088 namespace internal { 00089 00090 template<typename _PlainObjectType, int _Options, typename _StrideType> 00091 struct traits<Ref<_PlainObjectType, _Options, _StrideType> > 00092 : public traits<Map<_PlainObjectType, _Options, _StrideType> > 00093 { 00094 typedef _PlainObjectType PlainObjectType; 00095 typedef _StrideType StrideType; 00096 enum { 00097 Options = _Options, 00098 Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit 00099 }; 00100 00101 template<typename Derived> struct match { 00102 enum { 00103 HasDirectAccess = internal::has_direct_access<Derived>::ret, 00104 StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), 00105 InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) 00106 || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) 00107 || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1), 00108 OuterStrideMatch = Derived::IsVectorAtCompileTime 00109 || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), 00110 AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits<Derived>::Flags&AlignedBit)==AlignedBit), 00111 ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value, 00112 MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch 00113 }; 00114 typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type; 00115 }; 00116 00117 }; 00118 00119 template<typename Derived> 00120 struct traits<RefBase<Derived> > : public traits<Derived> {}; 00121 00122 } 00123 00124 template<typename Derived> class RefBase 00125 : public MapBase<Derived> 00126 { 00127 typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType; 00128 typedef typename internal::traits<Derived>::StrideType StrideType; 00129 00130 public: 00131 00132 typedef MapBase<Derived> Base; 00133 EIGEN_DENSE_PUBLIC_INTERFACE(RefBase) 00134 00135 inline Index innerStride() const 00136 { 00137 return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; 00138 } 00139 00140 inline Index outerStride() const 00141 { 00142 return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() 00143 : IsVectorAtCompileTime ? this->size() 00144 : int(Flags)&RowMajorBit ? this->cols() 00145 : this->rows(); 00146 } 00147 00148 RefBase() 00149 : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), 00150 // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values: 00151 m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime, 00152 StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime) 00153 {} 00154 00155 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase) 00156 00157 protected: 00158 00159 typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase; 00160 00161 template<typename Expression> 00162 void construct(Expression& expr) 00163 { 00164 if(PlainObjectType::RowsAtCompileTime==1) 00165 { 00166 eigen_assert(expr.rows()==1 || expr.cols()==1); 00167 ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size()); 00168 } 00169 else if(PlainObjectType::ColsAtCompileTime==1) 00170 { 00171 eigen_assert(expr.rows()==1 || expr.cols()==1); 00172 ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1); 00173 } 00174 else 00175 ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols()); 00176 00177 if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit))) 00178 ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1); 00179 else 00180 ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), 00181 StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); 00182 } 00183 00184 StrideBase m_stride; 00185 }; 00186 00187 00188 template<typename PlainObjectType, int Options, typename StrideType> class Ref 00189 : public RefBase<Ref<PlainObjectType, Options, StrideType> > 00190 { 00191 private: 00192 typedef internal::traits<Ref> Traits; 00193 template<typename Derived> 00194 inline Ref(const PlainObjectBase<Derived>& expr, 00195 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0); 00196 public: 00197 00198 typedef RefBase<Ref> Base ; 00199 EIGEN_DENSE_PUBLIC_INTERFACE(Ref) 00200 00201 00202 #ifndef EIGEN_PARSED_BY_DOXYGEN 00203 template<typename Derived> 00204 inline Ref(PlainObjectBase<Derived>& expr, 00205 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0) 00206 { 00207 EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00208 Base::construct(expr.derived()); 00209 } 00210 template<typename Derived> 00211 inline Ref(const DenseBase<Derived> & expr, 00212 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0) 00213 #else 00214 template<typename Derived> 00215 inline Ref(DenseBase<Derived> & expr) 00216 #endif 00217 { 00218 EIGEN_STATIC_ASSERT(static_cast<bool>(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); 00219 EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00220 enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase}; 00221 Base::construct(expr.const_cast_derived()); 00222 } 00223 00224 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref) 00225 00226 }; 00227 00228 // this is the const ref version 00229 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType> 00230 : public RefBase<Ref<const TPlainObjectType, Options, StrideType> > 00231 { 00232 typedef internal::traits<Ref> Traits; 00233 public: 00234 00235 typedef RefBase<Ref> Base; 00236 EIGEN_DENSE_PUBLIC_INTERFACE(Ref) 00237 00238 template<typename Derived> 00239 inline Ref(const DenseBase<Derived>& expr, 00240 typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0) 00241 { 00242 // std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n"; 00243 // std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n"; 00244 // std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; 00245 construct(expr.derived(), typename Traits::template match<Derived>::type()); 00246 } 00247 00248 inline Ref(const Ref& other) : Base(other) { 00249 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy 00250 } 00251 00252 template<typename OtherRef> 00253 inline Ref(const RefBase<OtherRef>& other) { 00254 construct(other.derived(), typename Traits::template match<OtherRef>::type()); 00255 } 00256 00257 protected: 00258 00259 template<typename Expression> 00260 void construct(const Expression& expr,internal::true_type) 00261 { 00262 Base::construct(expr); 00263 } 00264 00265 template<typename Expression> 00266 void construct(const Expression& expr, internal::false_type) 00267 { 00268 m_object.lazyAssign(expr); 00269 Base::construct(m_object); 00270 } 00271 00272 protected: 00273 TPlainObjectType m_object; 00274 }; 00275 00276 } // end namespace Eigen 00277 00278 #endif // EIGEN_REF_H
Generated on Tue Jul 12 2022 17:46:59 by 1.7.2