MOAB  4.9.3pre
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 <[email protected]>
00005 // Copyright (C) 2006-2008 Benoit Jacob <[email protected]>
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 EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3)
00018   #define EIGEN_EMPTY_STRUCT_CTOR(X) \
00019     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
00020     EIGEN_DEVICE_FUNC 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 
00035 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
00036 
00037 namespace internal {
00038 
00039 template<typename IndexDest, typename IndexSrc>
00040 EIGEN_DEVICE_FUNC
00041 inline IndexDest convert_index(const IndexSrc& idx) {
00042   // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
00043   eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
00044   return IndexDest(idx);
00045 }
00046 
00047 
00048 //classes inheriting no_assignment_operator don't generate a default operator=.
00049 class no_assignment_operator
00050 {
00051   private:
00052     no_assignment_operator& operator=(const no_assignment_operator&);
00053 };
00054 
00056 template<typename I1, typename I2>
00057 struct promote_index_type
00058 {
00059   typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
00060 };
00061 
00066 template<typename T, int Value> class variable_if_dynamic
00067 {
00068   public:
00069     EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
00070     EIGEN_DEVICE_FUNC explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
00071     EIGEN_DEVICE_FUNC static T value() { return T(Value); }
00072     EIGEN_DEVICE_FUNC void setValue(T) {}
00073 };
00074 
00075 template<typename T> class variable_if_dynamic<T, Dynamic>
00076 {
00077     T m_value;
00078     EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); }
00079   public:
00080     EIGEN_DEVICE_FUNC explicit variable_if_dynamic(T value) : m_value(value) {}
00081     EIGEN_DEVICE_FUNC T value() const { return m_value; }
00082     EIGEN_DEVICE_FUNC void setValue(T value) { m_value = value; }
00083 };
00084 
00087 template<typename T, int Value> class variable_if_dynamicindex
00088 {
00089   public:
00090     EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
00091     EIGEN_DEVICE_FUNC explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
00092     EIGEN_DEVICE_FUNC static T value() { return T(Value); }
00093     EIGEN_DEVICE_FUNC void setValue(T) {}
00094 };
00095 
00096 template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
00097 {
00098     T m_value;
00099     EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
00100   public:
00101     EIGEN_DEVICE_FUNC explicit variable_if_dynamicindex(T value) : m_value(value) {}
00102     EIGEN_DEVICE_FUNC T value() const { return m_value; }
00103     EIGEN_DEVICE_FUNC void setValue(T value) { m_value = value; }
00104 };
00105 
00106 template<typename T> struct functor_traits
00107 {
00108   enum
00109   {
00110     Cost = 10,
00111     PacketAccess = false,
00112     IsRepeatable = false
00113   };
00114 };
00115 
00116 template<typename T> struct packet_traits;
00117 
00118 template<typename T> struct unpacket_traits
00119 {
00120   typedef T type;
00121   typedef T half;
00122   enum
00123   {
00124     size = 1,
00125     alignment = 1
00126   };
00127 };
00128 
00129 template<int Size, typename PacketType,
00130          bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
00131 struct find_best_packet_helper;
00132 
00133 template< int Size, typename PacketType>
00134 struct find_best_packet_helper<Size,PacketType,true>
00135 {
00136   typedef PacketType type;
00137 };
00138 
00139 template<int Size, typename PacketType>
00140 struct find_best_packet_helper<Size,PacketType,false>
00141 {
00142   typedef typename find_best_packet_helper<Size,typename unpacket_traits<PacketType>::half>::type type;
00143 };
00144 
00145 template<typename T, int Size>
00146 struct find_best_packet
00147 {
00148   typedef typename find_best_packet_helper<Size,typename packet_traits<T>::type>::type type;
00149 };
00150 
00151 #if EIGEN_MAX_STATIC_ALIGN_BYTES>0
00152 template<int ArrayBytes, int AlignmentBytes,
00153          bool Match     =  bool((ArrayBytes%AlignmentBytes)==0),
00154          bool TryHalf   =  bool(AlignmentBytes>EIGEN_MIN_ALIGN_BYTES) >
00155 struct compute_default_alignment_helper
00156 {
00157   enum { value = 0 };
00158 };
00159 
00160 template<int ArrayBytes, int AlignmentBytes, bool TryHalf>
00161 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
00162 {
00163   enum { value = AlignmentBytes };
00164 };
00165 
00166 template<int ArrayBytes, int AlignmentBytes>
00167 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
00168 {
00169   // current packet too large, try with an half-packet
00170   enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
00171 };
00172 #else
00173 // If static alignment is disabled, no need to bother.
00174 // This also avoids a division by zero in "bool Match =  bool((ArrayBytes%AlignmentBytes)==0)"
00175 template<int ArrayBytes, int AlignmentBytes>
00176 struct compute_default_alignment_helper
00177 {
00178   enum { value = 0 };
00179 };
00180 #endif
00181 
00182 template<typename T, int Size> struct compute_default_alignment {
00183   enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
00184 };
00185 
00186 template<typename T> struct compute_default_alignment<T,Dynamic> {
00187   enum { value = EIGEN_MAX_ALIGN_BYTES };
00188 };
00189 
00190 template<typename _Scalar, int _Rows, int _Cols,
00191          int _Options = AutoAlign |
00192                           ( (_Rows==1 && _Cols!=1) ? RowMajor
00193                           : (_Cols==1 && _Rows!=1) ? ColMajor
00194                           : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
00195          int _MaxRows = _Rows,
00196          int _MaxCols = _Cols
00197 > class make_proper_matrix_type
00198 {
00199     enum {
00200       IsColVector = _Cols==1 && _Rows!=1,
00201       IsRowVector = _Rows==1 && _Cols!=1,
00202       Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
00203               : IsRowVector ? (_Options | RowMajor) & ~ColMajor
00204               : _Options
00205     };
00206   public:
00207     typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
00208 };
00209 
00210 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
00211 class compute_matrix_flags
00212 {
00213     enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
00214   public:
00215     // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
00216     // and then propagate this information to the evaluator's flags.
00217     // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
00218     enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
00219 };
00220 
00221 template<int _Rows, int _Cols> struct size_at_compile_time
00222 {
00223   enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
00224 };
00225 
00226 template<typename XprType> struct size_of_xpr_at_compile_time
00227 {
00228   enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
00229 };
00230 
00231 /* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
00232  * whereas eval is a const reference in the case of a matrix
00233  */
00234 
00235 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
00236 template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
00237 template<typename T> struct plain_matrix_type<T,Dense>
00238 {
00239   typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, traits<T>::Flags>::type type;
00240 };
00241 template<typename T> struct plain_matrix_type<T,DiagonalShape>
00242 {
00243   typedef typename T::PlainObject type;
00244 };
00245 
00246 template<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
00247 {
00248   typedef Matrix<typename traits<T>::Scalar,
00249                 traits<T>::RowsAtCompileTime,
00250                 traits<T>::ColsAtCompileTime,
00251                 AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
00252                 traits<T>::MaxRowsAtCompileTime,
00253                 traits<T>::MaxColsAtCompileTime
00254           > type;
00255 };
00256 
00257 template<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags>
00258 {
00259   typedef Array<typename traits<T>::Scalar,
00260                 traits<T>::RowsAtCompileTime,
00261                 traits<T>::ColsAtCompileTime,
00262                 AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
00263                 traits<T>::MaxRowsAtCompileTime,
00264                 traits<T>::MaxColsAtCompileTime
00265           > type;
00266 };
00267 
00268 /* eval : the return type of eval(). For matrices, this is just a const reference
00269  * in order to avoid a useless copy
00270  */
00271 
00272 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
00273 
00274 template<typename T> struct eval<T,Dense>
00275 {
00276   typedef typename plain_matrix_type<T>::type type;
00277 //   typedef typename T::PlainObject type;
00278 //   typedef T::Matrix<typename traits<T>::Scalar,
00279 //                 traits<T>::RowsAtCompileTime,
00280 //                 traits<T>::ColsAtCompileTime,
00281 //                 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
00282 //                 traits<T>::MaxRowsAtCompileTime,
00283 //                 traits<T>::MaxColsAtCompileTime
00284 //           > type;
00285 };
00286 
00287 template<typename T> struct eval<T,DiagonalShape>
00288 {
00289   typedef typename plain_matrix_type<T>::type type;
00290 };
00291 
00292 // for matrices, no need to evaluate, just use a const reference to avoid a useless copy
00293 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00294 struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
00295 {
00296   typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
00297 };
00298 
00299 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00300 struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
00301 {
00302   typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
00303 };
00304 
00305 
00306 /* similar to plain_matrix_type, but using the evaluator's Flags */
00307 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval;
00308 
00309 template<typename T>
00310 struct plain_object_eval<T,Dense>
00311 {
00312   typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, evaluator<T>::Flags>::type type;
00313 };
00314 
00315 
00316 /* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
00317  */
00318 template<typename T> struct plain_matrix_type_column_major
00319 {
00320   enum { Rows = traits<T>::RowsAtCompileTime,
00321          Cols = traits<T>::ColsAtCompileTime,
00322          MaxRows = traits<T>::MaxRowsAtCompileTime,
00323          MaxCols = traits<T>::MaxColsAtCompileTime
00324   };
00325   typedef Matrix<typename traits<T>::Scalar,
00326                 Rows,
00327                 Cols,
00328                 (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
00329                 MaxRows,
00330                 MaxCols
00331           > type;
00332 };
00333 
00334 /* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
00335  */
00336 template<typename T> struct plain_matrix_type_row_major
00337 {
00338   enum { Rows = traits<T>::RowsAtCompileTime,
00339          Cols = traits<T>::ColsAtCompileTime,
00340          MaxRows = traits<T>::MaxRowsAtCompileTime,
00341          MaxCols = traits<T>::MaxColsAtCompileTime
00342   };
00343   typedef Matrix<typename traits<T>::Scalar,
00344                 Rows,
00345                 Cols,
00346                 (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
00347                 MaxRows,
00348                 MaxCols
00349           > type;
00350 };
00351 
00355 template <typename T>
00356 struct ref_selector
00357 {
00358   typedef typename conditional<
00359     bool(traits<T>::Flags & NestByRefBit),
00360     T const&,
00361     const T
00362   >::type type;
00363   
00364   typedef typename conditional<
00365     bool(traits<T>::Flags & NestByRefBit),
00366     T &,
00367     T
00368   >::type non_const_type;
00369 };
00370 
00372 template<typename T1, typename T2>
00373 struct transfer_constness
00374 {
00375   typedef typename conditional<
00376     bool(internal::is_const<T1>::value),
00377     typename internal::add_const_on_value_type<T2>::type,
00378     T2
00379   >::type type;
00380 };
00381 
00382 
00383 // However, we still need a mechanism to detect whether an expression which is evaluated multiple time
00384 // has to be evaluated into a temporary.
00385 // That's the purpose of this new nested_eval helper:
00397 template<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval
00398 {
00399   enum {
00400     ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
00401     CoeffReadCost = evaluator<T>::CoeffReadCost,  // NOTE What if an evaluator evaluate itself into a tempory?
00402                                                   //      Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
00403                                                   //      This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
00404                                                   //      for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
00405                                                   //      Another solution could be to count the number of temps?
00406     NAsInteger = n == Dynamic ? HugeCost : n,
00407     CostEval   = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
00408     CostNoEval = NAsInteger * CoeffReadCost
00409   };
00410 
00411   typedef typename conditional<
00412         ( (int(evaluator<T>::Flags) & EvalBeforeNestingBit) ||
00413           (int(CostEval) < int(CostNoEval)) ),
00414         PlainObject,
00415         typename ref_selector<T>::type
00416   >::type type;
00417 };
00418 
00419 template<typename T>
00420 EIGEN_DEVICE_FUNC
00421 inline T* const_cast_ptr(const T* ptr)
00422 {
00423   return const_cast<T*>(ptr);
00424 }
00425 
00426 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
00427 struct dense_xpr_base
00428 {
00429   /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
00430 };
00431 
00432 template<typename Derived>
00433 struct dense_xpr_base<Derived, MatrixXpr>
00434 {
00435   typedef MatrixBase<Derived> type;
00436 };
00437 
00438 template<typename Derived>
00439 struct dense_xpr_base<Derived, ArrayXpr>
00440 {
00441   typedef ArrayBase<Derived> type;
00442 };
00443 
00444 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
00445 struct generic_xpr_base;
00446 
00447 template<typename Derived, typename XprKind>
00448 struct generic_xpr_base<Derived, XprKind, Dense>
00449 {
00450   typedef typename dense_xpr_base<Derived,XprKind>::type type;
00451 };
00452 
00455 template<typename Derived, typename Scalar, typename OtherScalar, typename BaseType,
00456          bool EnableIt = !is_same<Scalar,OtherScalar>::value >
00457 struct special_scalar_op_base : public BaseType
00458 {
00459   // dummy operator* so that the
00460   // "using special_scalar_op_base::operator*" compiles
00461   struct dummy {};
00462   void operator*(dummy) const;
00463   void operator/(dummy) const;
00464 };
00465 
00466 template<typename Derived,typename Scalar,typename OtherScalar, typename BaseType>
00467 struct special_scalar_op_base<Derived,Scalar,OtherScalar,BaseType,true>  : public BaseType
00468 {
00469   const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, const Derived>
00470   operator*(const OtherScalar& scalar) const
00471   {
00472 #ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
00473     EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
00474 #endif
00475     return CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, const Derived>
00476       (*static_cast<const Derived*>(this), scalar_multiple2_op<Scalar,OtherScalar>(scalar));
00477   }
00478 
00479   inline friend const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, const Derived>
00480   operator*(const OtherScalar& scalar, const Derived& matrix)
00481   {
00482 #ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
00483     EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
00484 #endif
00485     return static_cast<const special_scalar_op_base&>(matrix).operator*(scalar);
00486   }
00487   
00488   const CwiseUnaryOp<scalar_quotient2_op<Scalar,OtherScalar>, const Derived>
00489   operator/(const OtherScalar& scalar) const
00490   {
00491 #ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
00492     EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
00493 #endif
00494     return CwiseUnaryOp<scalar_quotient2_op<Scalar,OtherScalar>, const Derived>
00495       (*static_cast<const Derived*>(this), scalar_quotient2_op<Scalar,OtherScalar>(scalar));
00496   }
00497 };
00498 
00499 template<typename XprType, typename CastType> struct cast_return_type
00500 {
00501   typedef typename XprType::Scalar CurrentScalarType;
00502   typedef typename remove_all<CastType>::type _CastType;
00503   typedef typename _CastType::Scalar NewScalarType;
00504   typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value,
00505                               const XprType&,CastType>::type type;
00506 };
00507 
00508 template <typename A, typename B> struct promote_storage_type;
00509 
00510 template <typename A> struct promote_storage_type<A,A>
00511 {
00512   typedef A ret;
00513 };
00514 template <typename A> struct promote_storage_type<A, const A>
00515 {
00516   typedef A ret;
00517 };
00518 template <typename A> struct promote_storage_type<const A, A>
00519 {
00520   typedef A ret;
00521 };
00522 
00536 template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
00537 
00538 template <typename A, typename Functor>                   struct cwise_promote_storage_type<A,A,Functor>                                      { typedef A      ret; };
00539 template <typename Functor>                               struct cwise_promote_storage_type<Dense,Dense,Functor>                              { typedef Dense  ret; };
00540 template <typename A, typename Functor>                   struct cwise_promote_storage_type<A,Dense,Functor>                                  { typedef Dense  ret; };
00541 template <typename B, typename Functor>                   struct cwise_promote_storage_type<Dense,B,Functor>                                  { typedef Dense  ret; };
00542 template <typename Functor>                               struct cwise_promote_storage_type<Sparse,Dense,Functor>                             { typedef Sparse ret; };
00543 template <typename Functor>                               struct cwise_promote_storage_type<Dense,Sparse,Functor>                             { typedef Sparse ret; };
00544 
00559 template <typename A, typename B, int ProductTag> struct product_promote_storage_type;
00560 
00561 template <typename A, int ProductTag> struct product_promote_storage_type<A,                  A,                  ProductTag> { typedef A     ret;};
00562 template <int ProductTag>             struct product_promote_storage_type<Dense,              Dense,              ProductTag> { typedef Dense ret;};
00563 template <typename A, int ProductTag> struct product_promote_storage_type<A,                  Dense,              ProductTag> { typedef Dense ret; };
00564 template <typename B, int ProductTag> struct product_promote_storage_type<Dense,              B,                  ProductTag> { typedef Dense ret; };
00565 
00566 template <typename A, int ProductTag> struct product_promote_storage_type<A,                  DiagonalShape,      ProductTag> { typedef A ret; };
00567 template <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape,      B,                  ProductTag> { typedef B ret; };
00568 template <int ProductTag>             struct product_promote_storage_type<Dense,              DiagonalShape,      ProductTag> { typedef Dense ret; };
00569 template <int ProductTag>             struct product_promote_storage_type<DiagonalShape,      Dense,              ProductTag> { typedef Dense ret; };
00570 
00571 template <typename A, int ProductTag> struct product_promote_storage_type<A,                  PermutationStorage, ProductTag> { typedef A ret; };
00572 template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B,                  ProductTag> { typedef B ret; };
00573 template <int ProductTag>             struct product_promote_storage_type<Dense,              PermutationStorage, ProductTag> { typedef Dense ret; };
00574 template <int ProductTag>             struct product_promote_storage_type<PermutationStorage, Dense,              ProductTag> { typedef Dense ret; };
00575 
00579 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
00580 struct plain_row_type
00581 {
00582   typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
00583                  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
00584   typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
00585                  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
00586 
00587   typedef typename conditional<
00588     is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
00589     MatrixRowType,
00590     ArrayRowType 
00591   >::type type;
00592 };
00593 
00594 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
00595 struct plain_col_type
00596 {
00597   typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
00598                  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
00599   typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
00600                  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
00601 
00602   typedef typename conditional<
00603     is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
00604     MatrixColType,
00605     ArrayColType 
00606   >::type type;
00607 };
00608 
00609 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
00610 struct plain_diag_type
00611 {
00612   enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
00613          max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
00614   };
00615   typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType;
00616   typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType;
00617 
00618   typedef typename conditional<
00619     is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
00620     MatrixDiagType,
00621     ArrayDiagType 
00622   >::type type;
00623 };
00624 
00625 template<typename ExpressionType>
00626 struct is_lvalue
00627 {
00628   enum { value = !bool(is_const<ExpressionType>::value) &&
00629                  bool(traits<ExpressionType>::Flags & LvalueBit) };
00630 };
00631 
00632 template<typename T> struct is_diagonal
00633 { enum { ret = false }; };
00634 
00635 template<typename T> struct is_diagonal<DiagonalBase<T> >
00636 { enum { ret = true }; };
00637 
00638 template<typename T> struct is_diagonal<DiagonalWrapper<T> >
00639 { enum { ret = true }; };
00640 
00641 template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
00642 { enum { ret = true }; };
00643 
00644 template<typename S1, typename S2> struct glue_shapes;
00645 template<> struct glue_shapes<DenseShape,TriangularShape> { typedef TriangularShape type;  };
00646 
00647 template<typename T1, typename T2>
00648 bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<has_direct_access<T1>::ret&&has_direct_access<T2>::ret, T1>::type * = 0)
00649 {
00650   return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
00651 }
00652 
00653 template<typename T1, typename T2>
00654 bool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
00655 {
00656   return false;
00657 }
00658 
00659 template<typename T, typename U> struct is_same_or_void { enum { value = is_same<T,U>::value }; };
00660 template<typename T> struct is_same_or_void<void,T>     { enum { value = 1 }; };
00661 template<typename T> struct is_same_or_void<T,void>     { enum { value = 1 }; };
00662 template<>           struct is_same_or_void<void,void>  { enum { value = 1 }; };
00663 
00664 #ifdef EIGEN_DEBUG_ASSIGN
00665 std::string demangle_traversal(int t)
00666 {
00667   if(t==DefaultTraversal) return "DefaultTraversal";
00668   if(t==LinearTraversal) return "LinearTraversal";
00669   if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
00670   if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
00671   if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
00672   return "?";
00673 }
00674 std::string demangle_unrolling(int t)
00675 {
00676   if(t==NoUnrolling) return "NoUnrolling";
00677   if(t==InnerUnrolling) return "InnerUnrolling";
00678   if(t==CompleteUnrolling) return "CompleteUnrolling";
00679   return "?";
00680 }
00681 std::string demangle_flags(int f)
00682 {
00683   std::string res;
00684   if(f&RowMajorBit)                 res += " | RowMajor";
00685   if(f&PacketAccessBit)             res += " | Packet";
00686   if(f&LinearAccessBit)             res += " | Linear";
00687   if(f&LvalueBit)                   res += " | Lvalue";
00688   if(f&DirectAccessBit)             res += " | Direct";
00689   if(f&NestByRefBit)                res += " | NestByRef";
00690   if(f&NoPreferredStorageOrderBit)  res += " | NoPreferredStorageOrderBit";
00691   
00692   return res;
00693 }
00694 #endif
00695 
00696 } // end namespace internal
00697 
00698 // we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor
00699 // that would take two operands of different types. If there were such an example, then this check should be
00700 // moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as
00701 // currently they take only one typename Scalar template parameter.
00702 // It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
00703 // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
00704 // add together a float matrix and a double matrix.
00705 #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
00706   EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \
00707                         ? int(internal::scalar_product_traits<LHS, RHS>::Defined) \
00708                         : int(internal::is_same_or_void<LHS, RHS>::value)), \
00709     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00710     
00711 } // end namespace Eigen
00712 
00713 #endif // EIGEN_XPRHELPER_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines