$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_XPRHELPER_H 00012 #define EIGEN_XPRHELPER_H 00013 00014 // just a workaround because GCC seems to not really like empty structs 00015 // FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled 00016 // so currently we simply disable this optimization for gcc 4.3 00017 #if (defined __GNUG__) && !((__GNUC__==4) && (__GNUC_MINOR__==3)) 00018 #define EIGEN_EMPTY_STRUCT_CTOR(X) \ 00019 EIGEN_STRONG_INLINE X() {} \ 00020 EIGEN_STRONG_INLINE X(const X& ) {} 00021 #else 00022 #define EIGEN_EMPTY_STRUCT_CTOR(X) 00023 #endif 00024 00025 namespace Eigen { 00026 00027 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex; 00028 00029 namespace internal { 00030 00031 //classes inheriting no_assignment_operator don't generate a default operator=. 00032 class no_assignment_operator 00033 { 00034 private: 00035 no_assignment_operator& operator=(const no_assignment_operator&); 00036 }; 00037 00039 template<typename I1, typename I2> 00040 struct promote_index_type 00041 { 00042 typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type; 00043 }; 00044 00049 template<typename T, int Value> class variable_if_dynamic 00050 { 00051 public: 00052 EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic) 00053 explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); assert(v == T(Value)); } 00054 static T value() { return T(Value); } 00055 void setValue(T) {} 00056 }; 00057 00058 template<typename T> class variable_if_dynamic<T, Dynamic> 00059 { 00060 T m_value; 00061 variable_if_dynamic() { assert(false); } 00062 public: 00063 explicit variable_if_dynamic(T value) : m_value(value) {} 00064 T value() const { return m_value; } 00065 void setValue(T value) { m_value = value; } 00066 }; 00067 00070 template<typename T, int Value> class variable_if_dynamicindex 00071 { 00072 public: 00073 EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex) 00074 explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); assert(v == T(Value)); } 00075 static T value() { return T(Value); } 00076 void setValue(T) {} 00077 }; 00078 00079 template<typename T> class variable_if_dynamicindex<T, DynamicIndex> 00080 { 00081 T m_value; 00082 variable_if_dynamicindex() { assert(false); } 00083 public: 00084 explicit variable_if_dynamicindex(T value) : m_value(value) {} 00085 T value() const { return m_value; } 00086 void setValue(T value) { m_value = value; } 00087 }; 00088 00089 template<typename T> struct functor_traits 00090 { 00091 enum 00092 { 00093 Cost = 10, 00094 PacketAccess = false, 00095 IsRepeatable = false 00096 }; 00097 }; 00098 00099 template<typename T> struct packet_traits; 00100 00101 template<typename T> struct unpacket_traits 00102 { 00103 typedef T type; 00104 enum {size=1}; 00105 }; 00106 00107 template<typename _Scalar, int _Rows, int _Cols, 00108 int _Options = AutoAlign | 00109 ( (_Rows==1 && _Cols!=1) ? RowMajor 00110 : (_Cols==1 && _Rows!=1) ? ColMajor 00111 : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ), 00112 int _MaxRows = _Rows, 00113 int _MaxCols = _Cols 00114 > class make_proper_matrix_type 00115 { 00116 enum { 00117 IsColVector = _Cols==1 && _Rows!=1, 00118 IsRowVector = _Rows==1 && _Cols!=1, 00119 Options = IsColVector ? (_Options | ColMajor) & ~RowMajor 00120 : IsRowVector ? (_Options | RowMajor) & ~ColMajor 00121 : _Options 00122 }; 00123 public: 00124 typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type; 00125 }; 00126 00127 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols> 00128 class compute_matrix_flags 00129 { 00130 enum { 00131 row_major_bit = Options&RowMajor ? RowMajorBit : 0, 00132 is_dynamic_size_storage = MaxRows==Dynamic || MaxCols==Dynamic, 00133 00134 aligned_bit = 00135 ( 00136 ((Options&DontAlign)==0) 00137 && ( 00138 #if EIGEN_ALIGN_STATICALLY 00139 ((!is_dynamic_size_storage) && (((MaxCols*MaxRows*int(sizeof(Scalar))) % 16) == 0)) 00140 #else 00141 0 00142 #endif 00143 00144 || 00145 00146 #if EIGEN_ALIGN 00147 is_dynamic_size_storage 00148 #else 00149 0 00150 #endif 00151 00152 ) 00153 ) ? AlignedBit : 0, 00154 packet_access_bit = packet_traits<Scalar>::Vectorizable && aligned_bit ? PacketAccessBit : 0 00155 }; 00156 00157 public: 00158 enum { ret = LinearAccessBit | LvalueBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit }; 00159 }; 00160 00161 template<int _Rows, int _Cols> struct size_at_compile_time 00162 { 00163 enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols }; 00164 }; 00165 00166 /* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type, 00167 * whereas eval is a const reference in the case of a matrix 00168 */ 00169 00170 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type; 00171 template<typename T, typename BaseClassType> struct plain_matrix_type_dense; 00172 template<typename T> struct plain_matrix_type<T,Dense> 00173 { 00174 typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind>::type type; 00175 }; 00176 00177 template<typename T> struct plain_matrix_type_dense<T,MatrixXpr> 00178 { 00179 typedef Matrix<typename traits<T>::Scalar, 00180 traits<T>::RowsAtCompileTime, 00181 traits<T>::ColsAtCompileTime, 00182 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor), 00183 traits<T>::MaxRowsAtCompileTime, 00184 traits<T>::MaxColsAtCompileTime 00185 > type; 00186 }; 00187 00188 template<typename T> struct plain_matrix_type_dense<T,ArrayXpr> 00189 { 00190 typedef Array<typename traits<T>::Scalar, 00191 traits<T>::RowsAtCompileTime, 00192 traits<T>::ColsAtCompileTime, 00193 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor), 00194 traits<T>::MaxRowsAtCompileTime, 00195 traits<T>::MaxColsAtCompileTime 00196 > type; 00197 }; 00198 00199 /* eval : the return type of eval(). For matrices, this is just a const reference 00200 * in order to avoid a useless copy 00201 */ 00202 00203 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval; 00204 00205 template<typename T> struct eval<T,Dense> 00206 { 00207 typedef typename plain_matrix_type<T>::type type; 00208 // typedef typename T::PlainObject type; 00209 // typedef T::Matrix<typename traits<T>::Scalar, 00210 // traits<T>::RowsAtCompileTime, 00211 // traits<T>::ColsAtCompileTime, 00212 // AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor), 00213 // traits<T>::MaxRowsAtCompileTime, 00214 // traits<T>::MaxColsAtCompileTime 00215 // > type; 00216 }; 00217 00218 // for matrices, no need to evaluate, just use a const reference to avoid a useless copy 00219 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00220 struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense> 00221 { 00222 typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type; 00223 }; 00224 00225 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00226 struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense> 00227 { 00228 typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type; 00229 }; 00230 00231 00232 00233 /* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major 00234 */ 00235 template<typename T> struct plain_matrix_type_column_major 00236 { 00237 enum { Rows = traits<T>::RowsAtCompileTime, 00238 Cols = traits<T>::ColsAtCompileTime, 00239 MaxRows = traits<T>::MaxRowsAtCompileTime, 00240 MaxCols = traits<T>::MaxColsAtCompileTime 00241 }; 00242 typedef Matrix<typename traits<T>::Scalar, 00243 Rows, 00244 Cols, 00245 (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor, 00246 MaxRows, 00247 MaxCols 00248 > type; 00249 }; 00250 00251 /* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major 00252 */ 00253 template<typename T> struct plain_matrix_type_row_major 00254 { 00255 enum { Rows = traits<T>::RowsAtCompileTime, 00256 Cols = traits<T>::ColsAtCompileTime, 00257 MaxRows = traits<T>::MaxRowsAtCompileTime, 00258 MaxCols = traits<T>::MaxColsAtCompileTime 00259 }; 00260 typedef Matrix<typename traits<T>::Scalar, 00261 Rows, 00262 Cols, 00263 (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor, 00264 MaxRows, 00265 MaxCols 00266 > type; 00267 }; 00268 00269 // we should be able to get rid of this one too 00270 template<typename T> struct must_nest_by_value { enum { ret = false }; }; 00271 00275 template <typename T> 00276 struct ref_selector 00277 { 00278 typedef typename conditional< 00279 bool(traits<T>::Flags & NestByRefBit), 00280 T const&, 00281 const T 00282 >::type type; 00283 }; 00284 00286 template<typename T1, typename T2> 00287 struct transfer_constness 00288 { 00289 typedef typename conditional< 00290 bool(internal::is_const<T1>::value), 00291 typename internal::add_const_on_value_type<T2>::type, 00292 T2 00293 >::type type; 00294 }; 00295 00316 template<typename T, int n=1, typename PlainObject = typename eval<T>::type> struct nested 00317 { 00318 enum { 00319 // for the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values. 00320 // the choice of 10000 makes it larger than any practical fixed value and even most dynamic values. 00321 // in extreme cases where these assumptions would be wrong, we would still at worst suffer performance issues 00322 // (poor choice of temporaries). 00323 // it's important that this value can still be squared without integer overflowing. 00324 DynamicAsInteger = 10000, 00325 ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost, 00326 ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? int(DynamicAsInteger) : int(ScalarReadCost), 00327 CoeffReadCost = traits<T>::CoeffReadCost, 00328 CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? int(DynamicAsInteger) : int(CoeffReadCost), 00329 NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n, 00330 CostEvalAsInteger = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger, 00331 CostNoEvalAsInteger = NAsInteger * CoeffReadCostAsInteger 00332 }; 00333 00334 typedef typename conditional< 00335 ( (int(traits<T>::Flags) & EvalBeforeNestingBit) || 00336 int(CostEvalAsInteger) < int(CostNoEvalAsInteger) 00337 ), 00338 PlainObject, 00339 typename ref_selector<T>::type 00340 >::type type; 00341 }; 00342 00343 template<typename T> 00344 inline T* const_cast_ptr(const T* ptr) 00345 { 00346 return const_cast<T*>(ptr); 00347 } 00348 00349 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind> 00350 struct dense_xpr_base 00351 { 00352 /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */ 00353 }; 00354 00355 template<typename Derived> 00356 struct dense_xpr_base<Derived, MatrixXpr> 00357 { 00358 typedef MatrixBase<Derived> type; 00359 }; 00360 00361 template<typename Derived> 00362 struct dense_xpr_base<Derived, ArrayXpr> 00363 { 00364 typedef ArrayBase<Derived> type; 00365 }; 00366 00369 template<typename Derived,typename Scalar,typename OtherScalar, 00370 bool EnableIt = !is_same<Scalar,OtherScalar>::value > 00371 struct special_scalar_op_base : public DenseCoeffsBase<Derived> 00372 { 00373 // dummy operator* so that the 00374 // "using special_scalar_op_base::operator*" compiles 00375 void operator*() const; 00376 }; 00377 00378 template<typename Derived,typename Scalar,typename OtherScalar> 00379 struct special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public DenseCoeffsBase<Derived> 00380 { 00381 const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived> 00382 operator*(const OtherScalar& scalar) const 00383 { 00384 return CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived> 00385 (*static_cast<const Derived*>(this), scalar_multiple2_op<Scalar,OtherScalar>(scalar)); 00386 } 00387 00388 inline friend const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived> 00389 operator*(const OtherScalar& scalar, const Derived& matrix) 00390 { return static_cast<const special_scalar_op_base&>(matrix).operator*(scalar); } 00391 }; 00392 00393 template<typename XprType, typename CastType> struct cast_return_type 00394 { 00395 typedef typename XprType::Scalar CurrentScalarType; 00396 typedef typename remove_all<CastType>::type _CastType; 00397 typedef typename _CastType::Scalar NewScalarType; 00398 typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value, 00399 const XprType&,CastType>::type type; 00400 }; 00401 00402 template <typename A, typename B> struct promote_storage_type; 00403 00404 template <typename A> struct promote_storage_type<A,A> 00405 { 00406 typedef A ret; 00407 }; 00408 00412 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> 00413 struct plain_row_type 00414 { 00415 typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime, 00416 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType; 00417 typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime, 00418 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType; 00419 00420 typedef typename conditional< 00421 is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value, 00422 MatrixRowType, 00423 ArrayRowType 00424 >::type type; 00425 }; 00426 00427 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> 00428 struct plain_col_type 00429 { 00430 typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1, 00431 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType; 00432 typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1, 00433 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType; 00434 00435 typedef typename conditional< 00436 is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value, 00437 MatrixColType, 00438 ArrayColType 00439 >::type type; 00440 }; 00441 00442 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> 00443 struct plain_diag_type 00444 { 00445 enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime), 00446 max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime) 00447 }; 00448 typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType; 00449 typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType; 00450 00451 typedef typename conditional< 00452 is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value, 00453 MatrixDiagType, 00454 ArrayDiagType 00455 >::type type; 00456 }; 00457 00458 template<typename ExpressionType> 00459 struct is_lvalue 00460 { 00461 enum { value = !bool(is_const<ExpressionType>::value) && 00462 bool(traits<ExpressionType>::Flags & LvalueBit) }; 00463 }; 00464 00465 } // end namespace internal 00466 00467 } // end namespace Eigen 00468 00469 #endif // EIGEN_XPRHELPER_H