XprHelper.h
Go to the documentation of this file.
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 
00068 template<typename T> struct functor_traits
00069 {
00070   enum
00071   {
00072     Cost = 10,
00073     PacketAccess = false
00074   };
00075 };
00076 
00077 template<typename T> struct packet_traits;
00078 
00079 template<typename T> struct unpacket_traits
00080 {
00081   typedef T type;
00082   enum {size=1};
00083 };
00084 
00085 template<typename _Scalar, int _Rows, int _Cols,
00086          int _Options = AutoAlign |
00087                           ( (_Rows==1 && _Cols!=1) ? RowMajor
00088                           : (_Cols==1 && _Rows!=1) ? ColMajor
00089                           : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
00090          int _MaxRows = _Rows,
00091          int _MaxCols = _Cols
00092 > class make_proper_matrix_type
00093 {
00094     enum {
00095       IsColVector = _Cols==1 && _Rows!=1,
00096       IsRowVector = _Rows==1 && _Cols!=1,
00097       Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
00098               : IsRowVector ? (_Options | RowMajor) & ~ColMajor
00099               : _Options
00100     };
00101   public:
00102     typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
00103 };
00104 
00105 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
00106 class compute_matrix_flags
00107 {
00108     enum {
00109       row_major_bit = Options&RowMajor ? RowMajorBit : 0,
00110       is_dynamic_size_storage = MaxRows==Dynamic || MaxCols==Dynamic,
00111 
00112       aligned_bit =
00113       (
00114             ((Options&DontAlign)==0)
00115         && (
00116 #if EIGEN_ALIGN_STATICALLY
00117              ((!is_dynamic_size_storage) && (((MaxCols*MaxRows*int(sizeof(Scalar))) % 16) == 0))
00118 #else
00119              0
00120 #endif
00121 
00122           ||
00123 
00124 #if EIGEN_ALIGN
00125              is_dynamic_size_storage
00126 #else
00127              0
00128 #endif
00129 
00130           )
00131       ) ? AlignedBit : 0,
00132       packet_access_bit = packet_traits<Scalar>::Vectorizable && aligned_bit ? PacketAccessBit : 0
00133     };
00134 
00135   public:
00136     enum { ret = LinearAccessBit | LvalueBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit };
00137 };
00138 
00139 template<int _Rows, int _Cols> struct size_at_compile_time
00140 {
00141   enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
00142 };
00143 
00144 /* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
00145  * whereas eval is a const reference in the case of a matrix
00146  */
00147 
00148 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
00149 template<typename T, typename BaseClassType> struct plain_matrix_type_dense;
00150 template<typename T> struct plain_matrix_type<T,Dense>
00151 {
00152   typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind>::type type;
00153 };
00154 
00155 template<typename T> struct plain_matrix_type_dense<T,MatrixXpr>
00156 {
00157   typedef Matrix<typename traits<T>::Scalar,
00158                 traits<T>::RowsAtCompileTime,
00159                 traits<T>::ColsAtCompileTime,
00160                 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
00161                 traits<T>::MaxRowsAtCompileTime,
00162                 traits<T>::MaxColsAtCompileTime
00163           > type;
00164 };
00165 
00166 template<typename T> struct plain_matrix_type_dense<T,ArrayXpr>
00167 {
00168   typedef Array<typename traits<T>::Scalar,
00169                 traits<T>::RowsAtCompileTime,
00170                 traits<T>::ColsAtCompileTime,
00171                 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
00172                 traits<T>::MaxRowsAtCompileTime,
00173                 traits<T>::MaxColsAtCompileTime
00174           > type;
00175 };
00176 
00177 /* eval : the return type of eval(). For matrices, this is just a const reference
00178  * in order to avoid a useless copy
00179  */
00180 
00181 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
00182 
00183 template<typename T> struct eval<T,Dense>
00184 {
00185   typedef typename plain_matrix_type<T>::type type;
00186 //   typedef typename T::PlainObject type;
00187 //   typedef T::Matrix<typename traits<T>::Scalar,
00188 //                 traits<T>::RowsAtCompileTime,
00189 //                 traits<T>::ColsAtCompileTime,
00190 //                 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
00191 //                 traits<T>::MaxRowsAtCompileTime,
00192 //                 traits<T>::MaxColsAtCompileTime
00193 //           > type;
00194 };
00195 
00196 // for matrices, no need to evaluate, just use a const reference to avoid a useless copy
00197 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00198 struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
00199 {
00200   typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
00201 };
00202 
00203 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00204 struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
00205 {
00206   typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
00207 };
00208 
00209 
00210 
00211 /* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
00212  */
00213 template<typename T> struct plain_matrix_type_column_major
00214 {
00215   enum { Rows = traits<T>::RowsAtCompileTime,
00216          Cols = traits<T>::ColsAtCompileTime,
00217          MaxRows = traits<T>::MaxRowsAtCompileTime,
00218          MaxCols = traits<T>::MaxColsAtCompileTime
00219   };
00220   typedef Matrix<typename traits<T>::Scalar,
00221                 Rows,
00222                 Cols,
00223                 (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
00224                 MaxRows,
00225                 MaxCols
00226           > type;
00227 };
00228 
00229 /* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
00230  */
00231 template<typename T> struct plain_matrix_type_row_major
00232 {
00233   enum { Rows = traits<T>::RowsAtCompileTime,
00234          Cols = traits<T>::ColsAtCompileTime,
00235          MaxRows = traits<T>::MaxRowsAtCompileTime,
00236          MaxCols = traits<T>::MaxColsAtCompileTime
00237   };
00238   typedef Matrix<typename traits<T>::Scalar,
00239                 Rows,
00240                 Cols,
00241                 (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
00242                 MaxRows,
00243                 MaxCols
00244           > type;
00245 };
00246 
00247 // we should be able to get rid of this one too
00248 template<typename T> struct must_nest_by_value { enum { ret = false }; };
00249 
00253 template <typename T>
00254 struct ref_selector
00255 {
00256   typedef typename conditional<
00257     bool(traits<T>::Flags & NestByRefBit),
00258     T const&,
00259     const T
00260   >::type type;
00261 };
00262 
00264 template<typename T1, typename T2>
00265 struct transfer_constness
00266 {
00267   typedef typename conditional<
00268     bool(internal::is_const<T1>::value),
00269     typename internal::add_const_on_value_type<T2>::type,
00270     T2
00271   >::type type;
00272 };
00273 
00294 template<typename T, int n=1, typename PlainObject = typename eval<T>::type> struct nested
00295 {
00296   enum {
00297     // for the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values.
00298     // the choice of 10000 makes it larger than any practical fixed value and even most dynamic values.
00299     // in extreme cases where these assumptions would be wrong, we would still at worst suffer performance issues
00300     // (poor choice of temporaries).
00301     // it's important that this value can still be squared without integer overflowing.
00302     DynamicAsInteger = 10000,
00303     ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
00304     ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? int(DynamicAsInteger) : int(ScalarReadCost),
00305     CoeffReadCost = traits<T>::CoeffReadCost,
00306     CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? int(DynamicAsInteger) : int(CoeffReadCost),
00307     NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n,
00308     CostEvalAsInteger   = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger,
00309     CostNoEvalAsInteger = NAsInteger * CoeffReadCostAsInteger
00310   };
00311 
00312   typedef typename conditional<
00313       ( (int(traits<T>::Flags) & EvalBeforeNestingBit) ||
00314         int(CostEvalAsInteger) < int(CostNoEvalAsInteger)
00315       ),
00316       PlainObject,
00317       typename ref_selector<T>::type
00318   >::type type;
00319 };
00320 
00321 template<typename T>
00322 T* const_cast_ptr(const T* ptr)
00323 {
00324   return const_cast<T*>(ptr);
00325 }
00326 
00327 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
00328 struct dense_xpr_base
00329 {
00330   /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
00331 };
00332 
00333 template<typename Derived>
00334 struct dense_xpr_base<Derived, MatrixXpr>
00335 {
00336   typedef MatrixBase<Derived> type;
00337 };
00338 
00339 template<typename Derived>
00340 struct dense_xpr_base<Derived, ArrayXpr>
00341 {
00342   typedef ArrayBase<Derived> type;
00343 };
00344 
00347 template<typename Derived,typename Scalar,typename OtherScalar,
00348          bool EnableIt = !is_same<Scalar,OtherScalar>::value >
00349 struct special_scalar_op_base : public DenseCoeffsBase<Derived>
00350 {
00351   // dummy operator* so that the
00352   // "using special_scalar_op_base::operator*" compiles
00353   void operator*() const;
00354 };
00355 
00356 template<typename Derived,typename Scalar,typename OtherScalar>
00357 struct special_scalar_op_base<Derived,Scalar,OtherScalar,true>  : public DenseCoeffsBase<Derived>
00358 {
00359   const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
00360   operator*(const OtherScalar& scalar) const
00361   {
00362     return CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
00363       (*static_cast<const Derived*>(this), scalar_multiple2_op<Scalar,OtherScalar>(scalar));
00364   }
00365 
00366   inline friend const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
00367   operator*(const OtherScalar& scalar, const Derived& matrix)
00368   { return static_cast<const special_scalar_op_base&>(matrix).operator*(scalar); }
00369 };
00370 
00371 template<typename XprType, typename CastType> struct cast_return_type
00372 {
00373   typedef typename XprType::Scalar CurrentScalarType;
00374   typedef typename remove_all<CastType>::type _CastType;
00375   typedef typename _CastType::Scalar NewScalarType;
00376   typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value,
00377                               const XprType&,CastType>::type type;
00378 };
00379 
00380 template <typename A, typename B> struct promote_storage_type;
00381 
00382 template <typename A> struct promote_storage_type<A,A>
00383 {
00384   typedef A ret;
00385 };
00386 
00390 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
00391 struct plain_row_type
00392 {
00393   typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
00394                  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
00395   typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
00396                  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
00397 
00398   typedef typename conditional<
00399     is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
00400     MatrixRowType,
00401     ArrayRowType 
00402   >::type type;
00403 };
00404 
00405 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
00406 struct plain_col_type
00407 {
00408   typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
00409                  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
00410   typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
00411                  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
00412 
00413   typedef typename conditional<
00414     is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
00415     MatrixColType,
00416     ArrayColType 
00417   >::type type;
00418 };
00419 
00420 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
00421 struct plain_diag_type
00422 {
00423   enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
00424          max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
00425   };
00426   typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType;
00427   typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType;
00428 
00429   typedef typename conditional<
00430     is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
00431     MatrixDiagType,
00432     ArrayDiagType 
00433   >::type type;
00434 };
00435 
00436 template<typename ExpressionType>
00437 struct is_lvalue
00438 {
00439   enum { value = !bool(is_const<ExpressionType>::value) &&
00440                  bool(traits<ExpressionType>::Flags & LvalueBit) };
00441 };
00442 
00443 } // end namespace internal
00444 
00445 } // end namespace Eigen
00446 
00447 #endif // EIGEN_XPRHELPER_H


win_eigen
Author(s): Daniel Stonier
autogenerated on Wed Sep 16 2015 07:12:40