MOAB
4.9.3pre
|
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