Path Tracer
XprHelper.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_XPRHELPER_H
12 #define EIGEN_XPRHELPER_H
13 
14 // just a workaround because GCC seems to not really like empty structs
15 // FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled
16 // so currently we simply disable this optimization for gcc 4.3
17 #if EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3)
18  #define EIGEN_EMPTY_STRUCT_CTOR(X) \
19  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
20  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
21 #else
22  #define EIGEN_EMPTY_STRUCT_CTOR(X)
23 #endif
24 
25 namespace Eigen {
26 
27 namespace internal {
28 
29 template<typename IndexDest, typename IndexSrc>
30 EIGEN_DEVICE_FUNC
31 inline IndexDest convert_index(const IndexSrc& idx) {
32  // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
33  eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
34  return IndexDest(idx);
35 }
36 
37 // true if T can be considered as an integral index (i.e., and integral type or enum)
38 template<typename T> struct is_valid_index_type
39 {
40  enum { value =
41 #if EIGEN_HAS_TYPE_TRAITS
42  internal::is_integral<T>::value || std::is_enum<T>::value
43 #elif EIGEN_COMP_MSVC
44  internal::is_integral<T>::value || __is_enum(T)
45 #else
46  // without C++11, we use is_convertible to Index instead of is_integral in order to treat enums as Index.
48 #endif
49  };
50 };
51 
52 // true if both types are not valid index types
53 template<typename RowIndices, typename ColIndices>
56 };
57 
58 // promote_scalar_arg is an helper used in operation between an expression and a scalar, like:
59 // expression * scalar
60 // Its role is to determine how the type T of the scalar operand should be promoted given the scalar type ExprScalar of the given expression.
61 // The IsSupported template parameter must be provided by the caller as: internal::has_ReturnType<ScalarBinaryOpTraits<ExprScalar,T,op> >::value using the proper order for ExprScalar and T.
62 // Then the logic is as follows:
63 // - if the operation is natively supported as defined by IsSupported, then the scalar type is not promoted, and T is returned.
64 // - otherwise, NumTraits<ExprScalar>::Literal is returned if T is implicitly convertible to NumTraits<ExprScalar>::Literal AND that this does not imply a float to integer conversion.
65 // - otherwise, ExprScalar is returned if T is implicitly convertible to ExprScalar AND that this does not imply a float to integer conversion.
66 // - In all other cases, the promoted type is not defined, and the respective operation is thus invalid and not available (SFINAE).
67 template<typename ExprScalar,typename T, bool IsSupported>
69 
70 template<typename S,typename T>
71 struct promote_scalar_arg<S,T,true>
72 {
73  typedef T type;
74 };
75 
76 // Recursively check safe conversion to PromotedType, and then ExprScalar if they are different.
77 template<typename ExprScalar,typename T,typename PromotedType,
78  bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value,
81 
82 // Start recursion with NumTraits<ExprScalar>::Literal
83 template<typename S,typename T>
84 struct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {};
85 
86 // We found a match!
87 template<typename S,typename T, typename PromotedType>
88 struct promote_scalar_arg_unsupported<S,T,PromotedType,true,true>
89 {
90  typedef PromotedType type;
91 };
92 
93 // No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different,
94 // so let's try to promote to ExprScalar
95 template<typename ExprScalar,typename T, typename PromotedType>
96 struct promote_scalar_arg_unsupported<ExprScalar,T,PromotedType,false,true>
97  : promote_scalar_arg_unsupported<ExprScalar,T,ExprScalar>
98 {};
99 
100 // Unsafe real-to-integer, let's stop.
101 template<typename S,typename T, typename PromotedType, bool ConvertibleToLiteral>
102 struct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {};
103 
104 // T is not even convertible to ExprScalar, let's stop.
105 template<typename S,typename T>
106 struct promote_scalar_arg_unsupported<S,T,S,false,true> {};
107 
108 //classes inheriting no_assignment_operator don't generate a default operator=.
110 {
111  private:
113  protected:
114  EIGEN_DEFAULT_COPY_CONSTRUCTOR(no_assignment_operator)
115  EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(no_assignment_operator)
116 };
117 
119 template<typename I1, typename I2>
121 {
122  typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
123 };
124 
129 template<typename T, int Value> class variable_if_dynamic
130 {
131  public:
132  EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
133  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
134  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
135  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return T(Value); }
136  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
137 };
138 
139 template<typename T> class variable_if_dynamic<T, Dynamic>
140 {
141  T m_value;
142  EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); }
143  public:
144  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value) : m_value(value) {}
145  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
146  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return m_value; }
147  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
148 };
149 
152 template<typename T, int Value> class variable_if_dynamicindex
153 {
154  public:
155  EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
156  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
157  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
158  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
159 };
160 
161 template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
162 {
163  T m_value;
164  EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
165  public:
166  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {}
167  EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; }
168  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
169 };
170 
171 template<typename T> struct functor_traits
172 {
173  enum
174  {
175  Cost = 10,
176  PacketAccess = false,
177  IsRepeatable = false
178  };
179 };
180 
181 template<typename T> struct packet_traits;
182 
183 template<typename T> struct unpacket_traits
184 {
185  typedef T type;
186  typedef T half;
187  enum
188  {
189  size = 1,
190  alignment = 1,
191  vectorizable = false,
192  masked_load_available=false,
193  masked_store_available=false
194  };
195 };
196 
197 template<int Size, typename PacketType,
198  bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
200 
201 template< int Size, typename PacketType>
203 {
204  typedef PacketType type;
205 };
206 
207 template<int Size, typename PacketType>
209 {
211 };
212 
213 template<typename T, int Size>
215 {
217 };
218 
219 #if EIGEN_MAX_STATIC_ALIGN_BYTES>0
220 template<int ArrayBytes, int AlignmentBytes,
221  bool Match = bool((ArrayBytes%AlignmentBytes)==0),
222  bool TryHalf = bool(EIGEN_MIN_ALIGN_BYTES<AlignmentBytes) >
224 {
225  enum { value = 0 };
226 };
227 
228 template<int ArrayBytes, int AlignmentBytes, bool TryHalf>
229 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
230 {
231  enum { value = AlignmentBytes };
232 };
233 
234 template<int ArrayBytes, int AlignmentBytes>
235 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
236 {
237  // current packet too large, try with an half-packet
238  enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
239 };
240 #else
241 // If static alignment is disabled, no need to bother.
242 // This also avoids a division by zero in "bool Match = bool((ArrayBytes%AlignmentBytes)==0)"
243 template<int ArrayBytes, int AlignmentBytes>
245 {
246  enum { value = 0 };
247 };
248 #endif
249 
250 template<typename T, int Size> struct compute_default_alignment {
251  enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
252 };
253 
254 template<typename T> struct compute_default_alignment<T,Dynamic> {
255  enum { value = EIGEN_MAX_ALIGN_BYTES };
256 };
257 
258 template<typename _Scalar, int _Rows, int _Cols,
259  int _Options = AutoAlign |
260  ( (_Rows==1 && _Cols!=1) ? RowMajor
261  : (_Cols==1 && _Rows!=1) ? ColMajor
262  : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
263  int _MaxRows = _Rows,
264  int _MaxCols = _Cols
266 {
267  enum {
268  IsColVector = _Cols==1 && _Rows!=1,
269  IsRowVector = _Rows==1 && _Cols!=1,
270  Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
271  : IsRowVector ? (_Options | RowMajor) & ~ColMajor
272  : _Options
273  };
274  public:
276 };
277 
278 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
280 {
281  enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
282  public:
283  // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
284  // and then propagate this information to the evaluator's flags.
285  // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
286  enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
287 };
288 
289 template<int _Rows, int _Cols> struct size_at_compile_time
290 {
291  enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
292 };
293 
294 template<typename XprType> struct size_of_xpr_at_compile_time
295 {
297 };
298 
299 /* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
300  * whereas eval is a const reference in the case of a matrix
301  */
302 
303 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
304 template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
305 template<typename T> struct plain_matrix_type<T,Dense>
306 {
308 };
309 template<typename T> struct plain_matrix_type<T,DiagonalShape>
310 {
311  typedef typename T::PlainObject type;
312 };
313 
314 template<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
315 {
319  AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
322  > type;
323 };
324 
325 template<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags>
326 {
330  AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
333  > type;
334 };
335 
336 /* eval : the return type of eval(). For matrices, this is just a const reference
337  * in order to avoid a useless copy
338  */
339 
340 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
341 
342 template<typename T> struct eval<T,Dense>
343 {
344  typedef typename plain_matrix_type<T>::type type;
345 // typedef typename T::PlainObject type;
346 // typedef T::Matrix<typename traits<T>::Scalar,
347 // traits<T>::RowsAtCompileTime,
348 // traits<T>::ColsAtCompileTime,
349 // AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
350 // traits<T>::MaxRowsAtCompileTime,
351 // traits<T>::MaxColsAtCompileTime
352 // > type;
353 };
354 
355 template<typename T> struct eval<T,DiagonalShape>
356 {
357  typedef typename plain_matrix_type<T>::type type;
358 };
359 
360 // for matrices, no need to evaluate, just use a const reference to avoid a useless copy
361 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
362 struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
363 {
365 };
366 
367 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
368 struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
369 {
371 };
372 
373 
374 /* similar to plain_matrix_type, but using the evaluator's Flags */
375 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval;
376 
377 template<typename T>
379 {
381 };
382 
383 
384 /* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
385  */
386 template<typename T> struct plain_matrix_type_column_major
387 {
388  enum { Rows = traits<T>::RowsAtCompileTime,
392  };
394  Rows,
395  Cols,
396  (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
397  MaxRows,
398  MaxCols
399  > type;
400 };
401 
402 /* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
403  */
404 template<typename T> struct plain_matrix_type_row_major
405 {
406  enum { Rows = traits<T>::RowsAtCompileTime,
410  };
412  Rows,
413  Cols,
414  (MaxCols==1&&MaxRows!=1) ? ColMajor : RowMajor,
415  MaxRows,
416  MaxCols
417  > type;
418 };
419 
423 template <typename T>
425 {
426  typedef typename conditional<
427  bool(traits<T>::Flags & NestByRefBit),
428  T const&,
429  const T
430  >::type type;
431 
432  typedef typename conditional<
433  bool(traits<T>::Flags & NestByRefBit),
434  T &,
435  T
437 };
438 
440 template<typename T1, typename T2>
442 {
443  typedef typename conditional<
445  typename internal::add_const_on_value_type<T2>::type,
446  T2
447  >::type type;
448 };
449 
450 
451 // However, we still need a mechanism to detect whether an expression which is evaluated multiple time
452 // has to be evaluated into a temporary.
453 // That's the purpose of this new nested_eval helper:
465 template<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval
466 {
467  enum {
468  ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
469  CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a temporary?
470  // Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
471  // This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
472  // for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
473  // Another solution could be to count the number of temps?
474  NAsInteger = n == Dynamic ? HugeCost : n,
475  CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
476  CostNoEval = NAsInteger * CoeffReadCost,
477  Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval))
478  };
479 
481 };
482 
483 template<typename T>
484 EIGEN_DEVICE_FUNC
485 inline T* const_cast_ptr(const T* ptr)
486 {
487  return const_cast<T*>(ptr);
488 }
489 
490 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
492 {
493  /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
494 };
495 
496 template<typename Derived>
497 struct dense_xpr_base<Derived, MatrixXpr>
498 {
499  typedef MatrixBase<Derived> type;
500 };
501 
502 template<typename Derived>
503 struct dense_xpr_base<Derived, ArrayXpr>
504 {
505  typedef ArrayBase<Derived> type;
506 };
507 
508 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
510 
511 template<typename Derived, typename XprKind>
512 struct generic_xpr_base<Derived, XprKind, Dense>
513 {
514  typedef typename dense_xpr_base<Derived,XprKind>::type type;
515 };
516 
517 template<typename XprType, typename CastType> struct cast_return_type
518 {
519  typedef typename XprType::Scalar CurrentScalarType;
520  typedef typename remove_all<CastType>::type _CastType;
521  typedef typename _CastType::Scalar NewScalarType;
523  const XprType&,CastType>::type type;
524 };
525 
526 template <typename A, typename B> struct promote_storage_type;
527 
528 template <typename A> struct promote_storage_type<A,A>
529 {
530  typedef A ret;
531 };
532 template <typename A> struct promote_storage_type<A, const A>
533 {
534  typedef A ret;
535 };
536 template <typename A> struct promote_storage_type<const A, A>
537 {
538  typedef A ret;
539 };
540 
554 template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
555 
556 template <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; };
557 template <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; };
558 template <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; };
559 template <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; };
560 template <typename Functor> struct cwise_promote_storage_type<Sparse,Dense,Functor> { typedef Sparse ret; };
561 template <typename Functor> struct cwise_promote_storage_type<Dense,Sparse,Functor> { typedef Sparse ret; };
562 
563 template <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order {
564  enum { value = LhsOrder };
565 };
566 
567 template <typename LhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder> { enum { value = RhsOrder }; };
568 template <typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder> { enum { value = LhsOrder }; };
569 template <int Order> struct cwise_promote_storage_order<Sparse,Sparse,Order,Order> { enum { value = Order }; };
570 
571 
586 template <typename A, typename B, int ProductTag> struct product_promote_storage_type;
587 
588 template <typename A, int ProductTag> struct product_promote_storage_type<A, A, ProductTag> { typedef A ret;};
589 template <int ProductTag> struct product_promote_storage_type<Dense, Dense, ProductTag> { typedef Dense ret;};
590 template <typename A, int ProductTag> struct product_promote_storage_type<A, Dense, ProductTag> { typedef Dense ret; };
591 template <typename B, int ProductTag> struct product_promote_storage_type<Dense, B, ProductTag> { typedef Dense ret; };
592 
593 template <typename A, int ProductTag> struct product_promote_storage_type<A, DiagonalShape, ProductTag> { typedef A ret; };
594 template <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape, B, ProductTag> { typedef B ret; };
595 template <int ProductTag> struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { typedef Dense ret; };
596 template <int ProductTag> struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { typedef Dense ret; };
597 
598 template <typename A, int ProductTag> struct product_promote_storage_type<A, PermutationStorage, ProductTag> { typedef A ret; };
599 template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B, ProductTag> { typedef B ret; };
600 template <int ProductTag> struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { typedef Dense ret; };
601 template <int ProductTag> struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { typedef Dense ret; };
602 
606 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
608 {
609  typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
610  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
611  typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
612  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
613 
614  typedef typename conditional<
617  ArrayRowType
618  >::type type;
619 };
620 
621 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
623 {
624  typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
625  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
626  typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
627  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
628 
629  typedef typename conditional<
632  ArrayColType
633  >::type type;
634 };
635 
636 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
638 {
639  enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
640  max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
641  };
644 
645  typedef typename conditional<
649  >::type type;
650 };
651 
652 template<typename Expr,typename Scalar = typename Expr::Scalar>
654 {
655  enum { Options = (traits<Expr>::Flags&RowMajorBit)?RowMajor:0 };
656 
659 
662 
664 };
665 
666 template<typename ExpressionType>
667 struct is_lvalue
668 {
669  enum { value = (!bool(is_const<ExpressionType>::value)) &&
671 };
672 
673 template<typename T> struct is_diagonal
674 { enum { ret = false }; };
675 
676 template<typename T> struct is_diagonal<DiagonalBase<T> >
677 { enum { ret = true }; };
678 
679 template<typename T> struct is_diagonal<DiagonalWrapper<T> >
680 { enum { ret = true }; };
681 
682 template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
683 { enum { ret = true }; };
684 
685 
686 template<typename T> struct is_identity
687 { enum { value = false }; };
688 
689 template<typename T> struct is_identity<CwiseNullaryOp<internal::scalar_identity_op<typename T::Scalar>, T> >
690 { enum { value = true }; };
691 
692 
693 template<typename S1, typename S2> struct glue_shapes;
695 
696 template<typename T1, typename T2>
699 };
700 
701 template<typename T1, typename T2>
702 EIGEN_DEVICE_FUNC
703 bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<possibly_same_dense<T1,T2>::value>::type * = 0)
704 {
705  return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
706 }
707 
708 template<typename T1, typename T2>
709 EIGEN_DEVICE_FUNC
710 bool is_same_dense(const T1 &, const T2 &, typename enable_if<!possibly_same_dense<T1,T2>::value>::type * = 0)
711 {
712  return false;
713 }
714 
715 // Internal helper defining the cost of a scalar division for the type T.
716 // The default heuristic can be specialized for each scalar type and architecture.
717 template<typename T,bool Vectorized=false,typename EnableIf = void>
719  enum { value = 8*NumTraits<T>::MulCost };
720 };
721 
722 template<typename T,bool Vectorized>
723 struct scalar_div_cost<std::complex<T>, Vectorized> {
724  enum { value = 2*scalar_div_cost<T>::value
727  };
728 };
729 
730 
731 template<bool Vectorized>
732 struct scalar_div_cost<signed long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 24 }; };
733 template<bool Vectorized>
734 struct scalar_div_cost<unsigned long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 21 }; };
735 
736 
737 #ifdef EIGEN_DEBUG_ASSIGN
738 std::string demangle_traversal(int t)
739 {
740  if(t==DefaultTraversal) return "DefaultTraversal";
741  if(t==LinearTraversal) return "LinearTraversal";
742  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
743  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
744  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
745  return "?";
746 }
747 std::string demangle_unrolling(int t)
748 {
749  if(t==NoUnrolling) return "NoUnrolling";
750  if(t==InnerUnrolling) return "InnerUnrolling";
751  if(t==CompleteUnrolling) return "CompleteUnrolling";
752  return "?";
753 }
754 std::string demangle_flags(int f)
755 {
756  std::string res;
757  if(f&RowMajorBit) res += " | RowMajor";
758  if(f&PacketAccessBit) res += " | Packet";
759  if(f&LinearAccessBit) res += " | Linear";
760  if(f&LvalueBit) res += " | Lvalue";
761  if(f&DirectAccessBit) res += " | Direct";
762  if(f&NestByRefBit) res += " | NestByRef";
763  if(f&NoPreferredStorageOrderBit) res += " | NoPreferredStorageOrderBit";
764 
765  return res;
766 }
767 #endif
768 
769 } // end namespace internal
770 
771 
808 template<typename ScalarA, typename ScalarB, typename BinaryOp=internal::scalar_product_op<ScalarA,ScalarB> >
810 #ifndef EIGEN_PARSED_BY_DOXYGEN
811  // for backward compatibility, use the hints given by the (deprecated) internal::scalar_product_traits class.
812  : internal::scalar_product_traits<ScalarA,ScalarB>
813 #endif // EIGEN_PARSED_BY_DOXYGEN
814 {};
815 
816 template<typename T, typename BinaryOp>
817 struct ScalarBinaryOpTraits<T,T,BinaryOp>
818 {
819  typedef T ReturnType;
820 };
821 
822 template <typename T, typename BinaryOp>
823 struct ScalarBinaryOpTraits<T, typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, BinaryOp>
824 {
825  typedef T ReturnType;
826 };
827 template <typename T, typename BinaryOp>
828 struct ScalarBinaryOpTraits<typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, T, BinaryOp>
829 {
830  typedef T ReturnType;
831 };
832 
833 // For Matrix * Permutation
834 template<typename T, typename BinaryOp>
835 struct ScalarBinaryOpTraits<T,void,BinaryOp>
836 {
837  typedef T ReturnType;
838 };
839 
840 // For Permutation * Matrix
841 template<typename T, typename BinaryOp>
842 struct ScalarBinaryOpTraits<void,T,BinaryOp>
843 {
844  typedef T ReturnType;
845 };
846 
847 // for Permutation*Permutation
848 template<typename BinaryOp>
849 struct ScalarBinaryOpTraits<void,void,BinaryOp>
850 {
851  typedef void ReturnType;
852 };
853 
854 // We require Lhs and Rhs to have "compatible" scalar types.
855 // It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
856 // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
857 // add together a float matrix and a double matrix.
858 #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
859  EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
860  YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
861 
862 } // end namespace Eigen
863 
864 #endif // EIGEN_XPRHELPER_H
Eigen::internal::variable_if_dynamic
Definition: XprHelper.h:130
Eigen::HugeCost
const int HugeCost
Definition: Constants.h:43
Eigen::MatrixXpr
Definition: Constants.h:518
Eigen::internal::is_diagonal
Definition: XprHelper.h:674
Eigen::internal::scalar_identity_op
Definition: NullaryFunctors.h:31
Eigen
Namespace containing all symbols from the Eigen library.
Definition: LDLT.h:16
Eigen::internal::cast_return_type
Definition: XprHelper.h:518
Eigen::DiagonalMatrix
Represents a diagonal matrix with its storage.
Definition: DiagonalMatrix.h:142
Eigen::internal::possibly_same_dense
Definition: XprHelper.h:697
Eigen::DenseShape
Definition: Constants.h:524
Eigen::Sparse
Definition: Constants.h:506
Eigen::internal::dense_xpr_base
Definition: XprHelper.h:492
Eigen::internal::is_lvalue
Definition: XprHelper.h:668
Eigen::RowMajorBit
const unsigned int RowMajorBit
Definition: Constants.h:65
Eigen::internal::false_type
Definition: Meta.h:64
Eigen::internal::promote_scalar_arg
Definition: XprHelper.h:68
Eigen::internal::packet_traits
Definition: GenericPacketMath.h:107
Eigen::internal::plain_object_eval
Definition: XprHelper.h:375
Eigen::Array
General-purpose arrays with easy API for coefficient-wise operations.
Definition: Array.h:47
Eigen::internal::glue_shapes
Definition: XprHelper.h:693
Eigen::internal::plain_row_type
Definition: XprHelper.h:608
Eigen::ScalarBinaryOpTraits
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:814
Eigen::internal::nested_eval
Definition: XprHelper.h:466
Eigen::RowMajor
@ RowMajor
Definition: Constants.h:320
Eigen::internal::scalar_product_traits
Definition: Meta.h:618
Eigen::internal::plain_matrix_type
Definition: XprHelper.h:303
Eigen::DirectAccessBit
const unsigned int DirectAccessBit
Definition: Constants.h:154
Eigen::internal::compute_matrix_flags
Definition: XprHelper.h:280
Eigen::CwiseNullaryOp
Generic expression of a matrix where all coefficients are defined by a functor.
Definition: CwiseNullaryOp.h:61
Eigen::PacketAccessBit
const unsigned int PacketAccessBit
Definition: Constants.h:93
Eigen::internal::size_of_xpr_at_compile_time
Definition: XprHelper.h:295
Eigen::ArrayXpr
Definition: Constants.h:521
Eigen::internal::is_convertible
Definition: Meta.h:219
Eigen::internal::true_type
Definition: Meta.h:63
Eigen::internal::plain_matrix_type_column_major
Definition: XprHelper.h:387
Eigen::internal::is_valid_index_type
Definition: XprHelper.h:39
Eigen::LvalueBit
const unsigned int LvalueBit
Definition: Constants.h:143
Eigen::internal::is_identity
Definition: XprHelper.h:687
Eigen::Dynamic
const int Dynamic
Definition: Constants.h:21
Eigen::internal::cwise_promote_storage_type
Definition: XprHelper.h:554
Eigen::internal::unpacket_traits
Definition: XprHelper.h:184
Eigen::internal::generic_xpr_base
Definition: XprHelper.h:509
Eigen::internal::plain_constant_type
Definition: XprHelper.h:654
Eigen::internal::valid_indexed_view_overload
Definition: XprHelper.h:54
Eigen::internal::promote_scalar_arg_unsupported
Definition: XprHelper.h:80
Eigen::internal::Packet
Definition: ZVector/PacketMath.h:53
Eigen::internal::promote_storage_type
Definition: XprHelper.h:526
Eigen::internal::product_promote_storage_type
Definition: XprHelper.h:586
Eigen::internal::plain_matrix_type_row_major
Definition: XprHelper.h:405
Eigen::AutoAlign
@ AutoAlign
Definition: Constants.h:322
Eigen::internal::evaluator
Definition: CoreEvaluators.h:91
Eigen::internal::variable_if_dynamicindex
Definition: XprHelper.h:153
Eigen::internal::ref_selector
Definition: XprHelper.h:425
Eigen::internal::is_integral
Definition: Meta.h:126
Eigen::DiagonalWrapper
Expression of a diagonal matrix.
Definition: DiagonalMatrix.h:295
Eigen::ArrayBase
Base class for all 1D and 2D array, and related expressions.
Definition: ArrayBase.h:41
Eigen::internal::find_best_packet_helper< Size, PacketType, true >
Definition: XprHelper.h:203
Eigen::LinearAccessBit
const unsigned int LinearAccessBit
Definition: Constants.h:129
Eigen::internal::find_best_packet
Definition: XprHelper.h:215
Eigen::internal::plain_matrix_type_dense
Definition: XprHelper.h:304
Eigen::internal::scalar_div_cost
Definition: XprHelper.h:718
Eigen::internal::plain_diag_type
Definition: XprHelper.h:638
Eigen::internal::traits
Definition: ForwardDeclarations.h:17
Eigen::PermutationStorage
Definition: Constants.h:512
Eigen::TriangularShape
Definition: Constants.h:529
Eigen::internal::conditional
Definition: Meta.h:76
Eigen::internal::make_proper_matrix_type
Definition: XprHelper.h:266
Eigen::internal::transfer_constness
Definition: XprHelper.h:442
Eigen::internal::compute_default_alignment_helper
Definition: XprHelper.h:245
Eigen::internal::find_best_packet_helper< Size, PacketType, false >
Definition: XprHelper.h:209
Eigen::internal::is_same
Definition: Meta.h:115
Eigen::internal::no_assignment_operator
Definition: XprHelper.h:110
Eigen::Matrix
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:180
Eigen::internal::functor_traits
Definition: XprHelper.h:172
Eigen::internal::is_const
Definition: Meta.h:172
Eigen::MatrixBase
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:50
Eigen::DynamicIndex
const int DynamicIndex
Definition: Constants.h:26
Eigen::internal::compute_default_alignment
Definition: XprHelper.h:250
Eigen::internal::enable_if
Definition: Meta.h:234
Eigen::ColMajor
@ ColMajor
Definition: Constants.h:318
Eigen::NoPreferredStorageOrderBit
const unsigned int NoPreferredStorageOrderBit
Definition: Constants.h:177
Eigen::EvalBeforeNestingBit
const unsigned int EvalBeforeNestingBit
Definition: Constants.h:69
Eigen::internal::promote_index_type
Definition: XprHelper.h:121
Eigen::internal::cwise_promote_storage_order
Definition: XprHelper.h:563
Eigen::internal::plain_col_type
Definition: XprHelper.h:623
Eigen::internal::eval
Definition: XprHelper.h:340
Eigen::DiagonalBase
Definition: DiagonalMatrix.h:19
Eigen::NumTraits
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:213
Eigen::internal::size_at_compile_time
Definition: XprHelper.h:290
Eigen::internal::has_direct_access
Definition: ForwardDeclarations.h:26
Eigen::Dense
Definition: Constants.h:503
Eigen::DiagonalShape
Definition: Constants.h:527
Eigen::internal::find_best_packet_helper
Definition: XprHelper.h:199