Eigen  3.2.93
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 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
28 
35 typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
36 
37 namespace internal {
38 
39 template<typename IndexDest, typename IndexSrc>
40 EIGEN_DEVICE_FUNC
41 inline IndexDest convert_index(const IndexSrc& idx) {
42  // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
43  eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
44  return IndexDest(idx);
45 }
46 
47 
48 // promote_scalar_arg is an helper used in operation between an expression and a scalar, like:
49 // expression * scalar
50 // 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.
51 // 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.
52 // Then the logic is as follows:
53 // - if the operation is natively supported as defined by IsSupported, then the scalar type is not promoted, and T is returned.
54 // - 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.
55 // - otherwise, ExprScalar is returned if T is implicitly convertible to ExprScalar AND that this does not imply a float to integer conversion.
56 // - In all other cases, the promoted type is not defined, and the respective operation is thus invalid and not available (SFINAE).
57 template<typename ExprScalar,typename T, bool IsSupported>
58 struct promote_scalar_arg;
59 
60 template<typename S,typename T>
61 struct promote_scalar_arg<S,T,true>
62 {
63  typedef T type;
64 };
65 
66 // Recursively check safe conversion to PromotedType, and then ExprScalar if they are different.
67 template<typename ExprScalar,typename T,typename PromotedType,
68  bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value,
70 struct promote_scalar_arg_unsupported;
71 
72 // Start recursion with NumTraits<ExprScalar>::Literal
73 template<typename S,typename T>
74 struct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {};
75 
76 // We found a match!
77 template<typename S,typename T, typename PromotedType>
78 struct promote_scalar_arg_unsupported<S,T,PromotedType,true,true>
79 {
80  typedef PromotedType type;
81 };
82 
83 // No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different,
84 // so let's try to promote to ExprScalar
85 template<typename ExprScalar,typename T, typename PromotedType>
86 struct promote_scalar_arg_unsupported<ExprScalar,T,PromotedType,false,true>
87  : promote_scalar_arg_unsupported<ExprScalar,T,ExprScalar>
88 {};
89 
90 // Unsafe real-to-integer, let's stop.
91 template<typename S,typename T, typename PromotedType, bool ConvertibleToLiteral>
92 struct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {};
93 
94 // T is not even convertible to ExprScalar, let's stop.
95 template<typename S,typename T>
96 struct promote_scalar_arg_unsupported<S,T,S,false,true> {};
97 
98 //classes inheriting no_assignment_operator don't generate a default operator=.
99 class no_assignment_operator
100 {
101  private:
102  no_assignment_operator& operator=(const no_assignment_operator&);
103 };
104 
106 template<typename I1, typename I2>
107 struct promote_index_type
108 {
109  typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
110 };
111 
116 template<typename T, int Value> class variable_if_dynamic
117 {
118  public:
119  EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
120  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
121  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
122  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
123 };
124 
125 template<typename T> class variable_if_dynamic<T, Dynamic>
126 {
127  T m_value;
128  EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); }
129  public:
130  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value) : m_value(value) {}
131  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
132  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
133 };
134 
137 template<typename T, int Value> class variable_if_dynamicindex
138 {
139  public:
140  EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
141  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
142  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
143  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
144 };
145 
146 template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
147 {
148  T m_value;
149  EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
150  public:
151  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {}
152  EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; }
153  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
154 };
155 
156 template<typename T> struct functor_traits
157 {
158  enum
159  {
160  Cost = 10,
161  PacketAccess = false,
162  IsRepeatable = false
163  };
164 };
165 
166 template<typename T> struct packet_traits;
167 
168 template<typename T> struct unpacket_traits
169 {
170  typedef T type;
171  typedef T half;
172  enum
173  {
174  size = 1,
175  alignment = 1
176  };
177 };
178 
179 template<int Size, typename PacketType,
180  bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
181 struct find_best_packet_helper;
182 
183 template< int Size, typename PacketType>
184 struct find_best_packet_helper<Size,PacketType,true>
185 {
186  typedef PacketType type;
187 };
188 
189 template<int Size, typename PacketType>
190 struct find_best_packet_helper<Size,PacketType,false>
191 {
192  typedef typename find_best_packet_helper<Size,typename unpacket_traits<PacketType>::half>::type type;
193 };
194 
195 template<typename T, int Size>
196 struct find_best_packet
197 {
198  typedef typename find_best_packet_helper<Size,typename packet_traits<T>::type>::type type;
199 };
200 
201 #if EIGEN_MAX_STATIC_ALIGN_BYTES>0
202 template<int ArrayBytes, int AlignmentBytes,
203  bool Match = bool((ArrayBytes%AlignmentBytes)==0),
204  bool TryHalf = bool(AlignmentBytes>EIGEN_MIN_ALIGN_BYTES) >
205 struct compute_default_alignment_helper
206 {
207  enum { value = 0 };
208 };
209 
210 template<int ArrayBytes, int AlignmentBytes, bool TryHalf>
211 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
212 {
213  enum { value = AlignmentBytes };
214 };
215 
216 template<int ArrayBytes, int AlignmentBytes>
217 struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
218 {
219  // current packet too large, try with an half-packet
220  enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
221 };
222 #else
223 // If static alignment is disabled, no need to bother.
224 // This also avoids a division by zero in "bool Match = bool((ArrayBytes%AlignmentBytes)==0)"
225 template<int ArrayBytes, int AlignmentBytes>
226 struct compute_default_alignment_helper
227 {
228  enum { value = 0 };
229 };
230 #endif
231 
232 template<typename T, int Size> struct compute_default_alignment {
233  enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
234 };
235 
236 template<typename T> struct compute_default_alignment<T,Dynamic> {
237  enum { value = EIGEN_MAX_ALIGN_BYTES };
238 };
239 
240 template<typename _Scalar, int _Rows, int _Cols,
241  int _Options = AutoAlign |
242  ( (_Rows==1 && _Cols!=1) ? RowMajor
243  : (_Cols==1 && _Rows!=1) ? ColMajor
244  : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
245  int _MaxRows = _Rows,
246  int _MaxCols = _Cols
247 > class make_proper_matrix_type
248 {
249  enum {
250  IsColVector = _Cols==1 && _Rows!=1,
251  IsRowVector = _Rows==1 && _Cols!=1,
252  Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
253  : IsRowVector ? (_Options | RowMajor) & ~ColMajor
254  : _Options
255  };
256  public:
258 };
259 
260 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
261 class compute_matrix_flags
262 {
263  enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
264  public:
265  // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
266  // and then propagate this information to the evaluator's flags.
267  // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
268  enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
269 };
270 
271 template<int _Rows, int _Cols> struct size_at_compile_time
272 {
273  enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
274 };
275 
276 template<typename XprType> struct size_of_xpr_at_compile_time
277 {
278  enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
279 };
280 
281 /* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
282  * whereas eval is a const reference in the case of a matrix
283  */
284 
285 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
286 template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
287 template<typename T> struct plain_matrix_type<T,Dense>
288 {
289  typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, traits<T>::Flags>::type type;
290 };
291 template<typename T> struct plain_matrix_type<T,DiagonalShape>
292 {
293  typedef typename T::PlainObject type;
294 };
295 
296 template<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
297 {
299  traits<T>::RowsAtCompileTime,
300  traits<T>::ColsAtCompileTime,
301  AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
302  traits<T>::MaxRowsAtCompileTime,
303  traits<T>::MaxColsAtCompileTime
304  > type;
305 };
306 
307 template<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags>
308 {
310  traits<T>::RowsAtCompileTime,
311  traits<T>::ColsAtCompileTime,
312  AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
313  traits<T>::MaxRowsAtCompileTime,
314  traits<T>::MaxColsAtCompileTime
315  > type;
316 };
317 
318 /* eval : the return type of eval(). For matrices, this is just a const reference
319  * in order to avoid a useless copy
320  */
321 
322 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
323 
324 template<typename T> struct eval<T,Dense>
325 {
326  typedef typename plain_matrix_type<T>::type type;
327 // typedef typename T::PlainObject type;
328 // typedef T::Matrix<typename traits<T>::Scalar,
329 // traits<T>::RowsAtCompileTime,
330 // traits<T>::ColsAtCompileTime,
331 // AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
332 // traits<T>::MaxRowsAtCompileTime,
333 // traits<T>::MaxColsAtCompileTime
334 // > type;
335 };
336 
337 template<typename T> struct eval<T,DiagonalShape>
338 {
339  typedef typename plain_matrix_type<T>::type type;
340 };
341 
342 // for matrices, no need to evaluate, just use a const reference to avoid a useless copy
343 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
344 struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
345 {
347 };
348 
349 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
350 struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
351 {
353 };
354 
355 
356 /* similar to plain_matrix_type, but using the evaluator's Flags */
357 template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval;
358 
359 template<typename T>
360 struct plain_object_eval<T,Dense>
361 {
362  typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, evaluator<T>::Flags>::type type;
363 };
364 
365 
366 /* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
367  */
368 template<typename T> struct plain_matrix_type_column_major
369 {
370  enum { Rows = traits<T>::RowsAtCompileTime,
371  Cols = traits<T>::ColsAtCompileTime,
372  MaxRows = traits<T>::MaxRowsAtCompileTime,
373  MaxCols = traits<T>::MaxColsAtCompileTime
374  };
376  Rows,
377  Cols,
378  (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
379  MaxRows,
380  MaxCols
381  > type;
382 };
383 
384 /* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
385  */
386 template<typename T> struct plain_matrix_type_row_major
387 {
388  enum { Rows = traits<T>::RowsAtCompileTime,
389  Cols = traits<T>::ColsAtCompileTime,
390  MaxRows = traits<T>::MaxRowsAtCompileTime,
391  MaxCols = traits<T>::MaxColsAtCompileTime
392  };
394  Rows,
395  Cols,
396  (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
397  MaxRows,
398  MaxCols
399  > type;
400 };
401 
405 template <typename T>
406 struct ref_selector
407 {
408  typedef typename conditional<
409  bool(traits<T>::Flags & NestByRefBit),
410  T const&,
411  const T
412  >::type type;
413 
414  typedef typename conditional<
415  bool(traits<T>::Flags & NestByRefBit),
416  T &,
417  T
418  >::type non_const_type;
419 };
420 
422 template<typename T1, typename T2>
423 struct transfer_constness
424 {
425  typedef typename conditional<
426  bool(internal::is_const<T1>::value),
427  typename internal::add_const_on_value_type<T2>::type,
428  T2
429  >::type type;
430 };
431 
432 
433 // However, we still need a mechanism to detect whether an expression which is evaluated multiple time
434 // has to be evaluated into a temporary.
435 // That's the purpose of this new nested_eval helper:
447 template<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval
448 {
449  enum {
450  ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
451  CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a tempory?
452  // Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
453  // This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
454  // for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
455  // Another solution could be to count the number of temps?
456  NAsInteger = n == Dynamic ? HugeCost : n,
457  CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
458  CostNoEval = NAsInteger * CoeffReadCost
459  };
460 
461  typedef typename conditional<
462  ( (int(evaluator<T>::Flags) & EvalBeforeNestingBit) ||
463  (int(CostEval) < int(CostNoEval)) ),
464  PlainObject,
465  typename ref_selector<T>::type
466  >::type type;
467 };
468 
469 template<typename T>
470 EIGEN_DEVICE_FUNC
471 inline T* const_cast_ptr(const T* ptr)
472 {
473  return const_cast<T*>(ptr);
474 }
475 
476 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
477 struct dense_xpr_base
478 {
479  /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
480 };
481 
482 template<typename Derived>
483 struct dense_xpr_base<Derived, MatrixXpr>
484 {
485  typedef MatrixBase<Derived> type;
486 };
487 
488 template<typename Derived>
489 struct dense_xpr_base<Derived, ArrayXpr>
490 {
491  typedef ArrayBase<Derived> type;
492 };
493 
494 template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
495 struct generic_xpr_base;
496 
497 template<typename Derived, typename XprKind>
498 struct generic_xpr_base<Derived, XprKind, Dense>
499 {
500  typedef typename dense_xpr_base<Derived,XprKind>::type type;
501 };
502 
503 template<typename XprType, typename CastType> struct cast_return_type
504 {
505  typedef typename XprType::Scalar CurrentScalarType;
506  typedef typename remove_all<CastType>::type _CastType;
507  typedef typename _CastType::Scalar NewScalarType;
508  typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value,
509  const XprType&,CastType>::type type;
510 };
511 
512 template <typename A, typename B> struct promote_storage_type;
513 
514 template <typename A> struct promote_storage_type<A,A>
515 {
516  typedef A ret;
517 };
518 template <typename A> struct promote_storage_type<A, const A>
519 {
520  typedef A ret;
521 };
522 template <typename A> struct promote_storage_type<const A, A>
523 {
524  typedef A ret;
525 };
526 
540 template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
541 
542 template <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; };
543 template <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; };
544 template <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; };
545 template <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; };
546 template <typename Functor> struct cwise_promote_storage_type<Sparse,Dense,Functor> { typedef Sparse ret; };
547 template <typename Functor> struct cwise_promote_storage_type<Dense,Sparse,Functor> { typedef Sparse ret; };
548 
563 template <typename A, typename B, int ProductTag> struct product_promote_storage_type;
564 
565 template <typename A, int ProductTag> struct product_promote_storage_type<A, A, ProductTag> { typedef A ret;};
566 template <int ProductTag> struct product_promote_storage_type<Dense, Dense, ProductTag> { typedef Dense ret;};
567 template <typename A, int ProductTag> struct product_promote_storage_type<A, Dense, ProductTag> { typedef Dense ret; };
568 template <typename B, int ProductTag> struct product_promote_storage_type<Dense, B, ProductTag> { typedef Dense ret; };
569 
570 template <typename A, int ProductTag> struct product_promote_storage_type<A, DiagonalShape, ProductTag> { typedef A ret; };
571 template <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape, B, ProductTag> { typedef B ret; };
572 template <int ProductTag> struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { typedef Dense ret; };
573 template <int ProductTag> struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { typedef Dense ret; };
574 
575 template <typename A, int ProductTag> struct product_promote_storage_type<A, PermutationStorage, ProductTag> { typedef A ret; };
576 template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B, ProductTag> { typedef B ret; };
577 template <int ProductTag> struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { typedef Dense ret; };
578 template <int ProductTag> struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { typedef Dense ret; };
579 
583 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
584 struct plain_row_type
585 {
586  typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
587  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
588  typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
589  ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
590 
591  typedef typename conditional<
592  is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
593  MatrixRowType,
594  ArrayRowType
595  >::type type;
596 };
597 
598 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
599 struct plain_col_type
600 {
601  typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
602  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
603  typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
604  ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
605 
606  typedef typename conditional<
607  is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
608  MatrixColType,
609  ArrayColType
610  >::type type;
611 };
612 
613 template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
614 struct plain_diag_type
615 {
616  enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
617  max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
618  };
621 
622  typedef typename conditional<
623  is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
624  MatrixDiagType,
625  ArrayDiagType
626  >::type type;
627 };
628 
629 template<typename Expr,typename Scalar = typename Expr::Scalar>
630 struct plain_constant_type
631 {
632  enum { Options = (traits<Expr>::Flags&RowMajorBit)?RowMajor:0 };
633 
634  typedef Array<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime,
635  Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> array_type;
636 
637  typedef Matrix<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime,
638  Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> matrix_type;
639 
640  typedef CwiseNullaryOp<scalar_constant_op<Scalar>, const typename conditional<is_same< typename traits<Expr>::XprKind, MatrixXpr >::value, matrix_type, array_type>::type > type;
641 };
642 
643 template<typename ExpressionType>
644 struct is_lvalue
645 {
646  enum { value = !bool(is_const<ExpressionType>::value) &&
647  bool(traits<ExpressionType>::Flags & LvalueBit) };
648 };
649 
650 template<typename T> struct is_diagonal
651 { enum { ret = false }; };
652 
653 template<typename T> struct is_diagonal<DiagonalBase<T> >
654 { enum { ret = true }; };
655 
656 template<typename T> struct is_diagonal<DiagonalWrapper<T> >
657 { enum { ret = true }; };
658 
659 template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
660 { enum { ret = true }; };
661 
662 template<typename S1, typename S2> struct glue_shapes;
663 template<> struct glue_shapes<DenseShape,TriangularShape> { typedef TriangularShape type; };
664 
665 template<typename T1, typename T2>
666 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)
667 {
668  return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
669 }
670 
671 template<typename T1, typename T2>
672 bool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
673 {
674  return false;
675 }
676 
677 #ifdef EIGEN_DEBUG_ASSIGN
678 std::string demangle_traversal(int t)
679 {
680  if(t==DefaultTraversal) return "DefaultTraversal";
681  if(t==LinearTraversal) return "LinearTraversal";
682  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
683  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
684  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
685  return "?";
686 }
687 std::string demangle_unrolling(int t)
688 {
689  if(t==NoUnrolling) return "NoUnrolling";
690  if(t==InnerUnrolling) return "InnerUnrolling";
691  if(t==CompleteUnrolling) return "CompleteUnrolling";
692  return "?";
693 }
694 std::string demangle_flags(int f)
695 {
696  std::string res;
697  if(f&RowMajorBit) res += " | RowMajor";
698  if(f&PacketAccessBit) res += " | Packet";
699  if(f&LinearAccessBit) res += " | Linear";
700  if(f&LvalueBit) res += " | Lvalue";
701  if(f&DirectAccessBit) res += " | Direct";
702  if(f&NestByRefBit) res += " | NestByRef";
703  if(f&NoPreferredStorageOrderBit) res += " | NoPreferredStorageOrderBit";
704 
705  return res;
706 }
707 #endif
708 
709 } // end namespace internal
710 
711 
740 template<typename ScalarA, typename ScalarB, typename BinaryOp=internal::scalar_product_op<ScalarA,ScalarB> >
742 #ifndef EIGEN_PARSED_BY_DOXYGEN
743  // for backward compatibility, use the hints given by the (deprecated) internal::scalar_product_traits class.
744  : internal::scalar_product_traits<ScalarA,ScalarB>
745 #endif // EIGEN_PARSED_BY_DOXYGEN
746 {};
747 
748 template<typename T, typename BinaryOp>
749 struct ScalarBinaryOpTraits<T,T,BinaryOp>
750 {
751  typedef T ReturnType;
752 };
753 
754 // For Matrix * Permutation
755 template<typename T, typename BinaryOp>
756 struct ScalarBinaryOpTraits<T,void,BinaryOp>
757 {
758  typedef T ReturnType;
759 };
760 
761 // For Permutation * Matrix
762 template<typename T, typename BinaryOp>
763 struct ScalarBinaryOpTraits<void,T,BinaryOp>
764 {
765  typedef T ReturnType;
766 };
767 
768 // for Permutation*Permutation
769 template<typename BinaryOp>
770 struct ScalarBinaryOpTraits<void,void,BinaryOp>
771 {
772  typedef void ReturnType;
773 };
774 
775 template<typename T, typename BinaryOp>
776 struct ScalarBinaryOpTraits<T,std::complex<T>,BinaryOp>
777 {
778  typedef std::complex<T> ReturnType;
779 };
780 
781 template<typename T, typename BinaryOp>
782 struct ScalarBinaryOpTraits<std::complex<T>, T,BinaryOp>
783 {
784  typedef std::complex<T> ReturnType;
785 };
786 
787 // We require Lhs and Rhs to have "compatible" scalar types.
788 // It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
789 // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
790 // add together a float matrix and a double matrix.
791 #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
792  EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
793  YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
794 
795 } // end namespace Eigen
796 
797 #endif // EIGEN_XPRHELPER_H
Generic expression of a matrix where all coefficients are defined by a functor.
Definition: CwiseNullaryOp.h:43
Definition: Constants.h:320
const int HugeCost
Definition: Constants.h:39
const unsigned int DirectAccessBit
Definition: Constants.h:150
const unsigned int LvalueBit
Definition: Constants.h:139
Namespace containing all symbols from the Eigen library.
Definition: Core:271
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:167
const unsigned int RowMajorBit
Definition: Constants.h:61
const unsigned int PacketAccessBit
Definition: Constants.h:89
Definition: Constants.h:324
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: XprHelper.h:35
Base class for all 1D and 2D array, and related expressions.
Definition: ArrayBase.h:39
Definition: Eigen_Colamd.h:50
General-purpose arrays with easy API for coefficient-wise operations.
Definition: Array.h:45
Definition: Constants.h:322
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:741
const int Dynamic
Definition: Constants.h:21
const unsigned int EvalBeforeNestingBit
Definition: Constants.h:65
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:178
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
const unsigned int LinearAccessBit
Definition: Constants.h:125
const unsigned int NoPreferredStorageOrderBit
Definition: Constants.h:173