WPILibC++ 2023.4.3-108-ge5452e3
XprHelper.h
Go to the documentation of this file.
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
25namespace Eigen {
26
27namespace internal {
28
29template<typename IndexDest, typename IndexSrc>
31inline 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)
38template<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
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
53template<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).
67template<typename ExprScalar,typename T, bool IsSupported>
69
70template<typename S,typename T>
71struct 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.
77template<typename ExprScalar,typename T,typename PromotedType,
78 bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value,
81
82// Start recursion with NumTraits<ExprScalar>::Literal
83template<typename S,typename T>
84struct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {};
85
86// We found a match!
87template<typename S,typename T, typename PromotedType>
88struct 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
95template<typename ExprScalar,typename T, typename PromotedType>
96struct 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.
101template<typename S,typename T, typename PromotedType, bool ConvertibleToLiteral>
102struct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {};
103
104// T is not even convertible to ExprScalar, let's stop.
105template<typename S,typename T>
106struct 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:
116};
117
118/** \internal return the index type with the largest number of bits */
119template<typename I1, typename I2>
121{
122 typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
123};
124
125/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that
126 * can be accessed using value() and setValue().
127 * Otherwise, this class is an empty structure and value() just returns the template parameter Value.
128 */
129template<typename T, int Value> class variable_if_dynamic
130{
131 public:
135 T value() { return T(Value); }
137 operator T() const { return T(Value); }
139 void setValue(T v) const { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
140};
141
142template<typename T> class variable_if_dynamic<T, Dynamic>
143{
144 T m_value;
145 public:
147 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
148 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return m_value; }
150};
151
152/** \internal like variable_if_dynamic but for DynamicIndex
153 */
154template<typename T, int Value> class variable_if_dynamicindex
155{
156 public:
160 T value() { return T(Value); }
162 void setValue(T) {}
163};
164
165template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
166{
167 T m_value;
169 public:
171 EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; }
173};
174
175template<typename T> struct functor_traits
176{
177 enum
178 {
179 Cost = 10,
181 IsRepeatable = false
182 };
183};
184
185template<typename T> struct packet_traits;
186
187template<typename T> struct unpacket_traits;
188
189template<int Size, typename PacketType,
190 bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
192
193template< int Size, typename PacketType>
195{
196 typedef PacketType type;
197};
198
199template<int Size, typename PacketType>
201{
203};
204
205template<typename T, int Size>
207{
209};
210
211#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
212template<int ArrayBytes, int AlignmentBytes,
213 bool Match = bool((ArrayBytes%AlignmentBytes)==0),
214 bool TryHalf = bool(EIGEN_MIN_ALIGN_BYTES<AlignmentBytes) >
216{
217 enum { value = 0 };
218};
219
220template<int ArrayBytes, int AlignmentBytes, bool TryHalf>
221struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
222{
223 enum { value = AlignmentBytes };
224};
225
226template<int ArrayBytes, int AlignmentBytes>
227struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
228{
229 // current packet too large, try with an half-packet
230 enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
231};
232#else
233// If static alignment is disabled, no need to bother.
234// This also avoids a division by zero in "bool Match = bool((ArrayBytes%AlignmentBytes)==0)"
235template<int ArrayBytes, int AlignmentBytes>
237{
238 enum { value = 0 };
239};
240#endif
241
242template<typename T, int Size> struct compute_default_alignment {
244};
245
246template<typename T> struct compute_default_alignment<T,Dynamic> {
248};
249
250template<typename _Scalar, int _Rows, int _Cols,
251 int _Options = AutoAlign |
252 ( (_Rows==1 && _Cols!=1) ? RowMajor
253 : (_Cols==1 && _Rows!=1) ? ColMajor
255 int _MaxRows = _Rows,
256 int _MaxCols = _Cols
258{
259 enum {
260 IsColVector = _Cols==1 && _Rows!=1,
261 IsRowVector = _Rows==1 && _Cols!=1,
262 Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
263 : IsRowVector ? (_Options | RowMajor) & ~ColMajor
264 : _Options
265 };
266 public:
268};
269
270template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
272{
273 enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
274 public:
275 // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
276 // and then propagate this information to the evaluator's flags.
277 // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
278 enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
279};
280
281template<int _Rows, int _Cols> struct size_at_compile_time
282{
283 enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
284};
285
286template<typename XprType> struct size_of_xpr_at_compile_time
287{
289};
290
291/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
292 * whereas eval is a const reference in the case of a matrix
293 */
294
295template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
296template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
297template<typename T> struct plain_matrix_type<T,Dense>
298{
300};
301template<typename T> struct plain_matrix_type<T,DiagonalShape>
302{
303 typedef typename T::PlainObject type;
304};
305
306template<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
307{
315};
316
317template<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags>
318{
326};
327
328/* eval : the return type of eval(). For matrices, this is just a const reference
329 * in order to avoid a useless copy
330 */
331
332template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
333
334template<typename T> struct eval<T,Dense>
335{
337// typedef typename T::PlainObject type;
338// typedef T::Matrix<typename traits<T>::Scalar,
339// traits<T>::RowsAtCompileTime,
340// traits<T>::ColsAtCompileTime,
341// AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
342// traits<T>::MaxRowsAtCompileTime,
343// traits<T>::MaxColsAtCompileTime
344// > type;
345};
346
347template<typename T> struct eval<T,DiagonalShape>
348{
350};
351
352// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
353template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
354struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
355{
357};
358
359template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
360struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
361{
363};
364
365
366/* similar to plain_matrix_type, but using the evaluator's Flags */
367template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval;
368
369template<typename T>
371{
373};
374
375
376/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
377 */
378template<typename T> struct plain_matrix_type_column_major
379{
384 };
386 Rows,
387 Cols,
388 (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
389 MaxRows,
390 MaxCols
392};
393
394/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
395 */
396template<typename T> struct plain_matrix_type_row_major
397{
402 };
404 Rows,
405 Cols,
406 (MaxCols==1&&MaxRows!=1) ? ColMajor : RowMajor,
407 MaxRows,
408 MaxCols
410};
411
412/** \internal The reference selector for template expressions. The idea is that we don't
413 * need to use references for expressions since they are light weight proxy
414 * objects which should generate no copying overhead. */
415template <typename T>
417{
418 typedef typename conditional<
420 T const&,
421 const T
423
424 typedef typename conditional<
426 T &,
427 T
429};
430
431/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */
432template<typename T1, typename T2>
434{
435 typedef typename conditional<
438 T2
440};
441
442
443// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
444// has to be evaluated into a temporary.
445// That's the purpose of this new nested_eval helper:
446/** \internal Determines how a given expression should be nested when evaluated multiple times.
447 * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
448 * evaluated into the bigger product expression. The choice is between nesting the expression b+c as-is, or
449 * evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is
450 * a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
451 * many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
452 *
453 * \tparam T the type of the expression being nested.
454 * \tparam n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
455 * \tparam PlainObject the type of the temporary if needed.
456 */
458{
459 enum {
461 CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a temporary?
462 // Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
463 // This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
464 // for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
465 // Another solution could be to count the number of temps?
470 };
471
473};
474
475template<typename T>
477inline T* const_cast_ptr(const T* ptr)
478{
479 return const_cast<T*>(ptr);
480}
481
482template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
484{
485 /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
486};
487
488template<typename Derived>
489struct dense_xpr_base<Derived, MatrixXpr>
490{
492};
493
494template<typename Derived>
495struct dense_xpr_base<Derived, ArrayXpr>
496{
498};
499
500template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
502
503template<typename Derived, typename XprKind>
504struct generic_xpr_base<Derived, XprKind, Dense>
505{
507};
508
509template<typename XprType, typename CastType> struct cast_return_type
510{
511 typedef typename XprType::Scalar CurrentScalarType;
513 typedef typename _CastType::Scalar NewScalarType;
515 const XprType&,CastType>::type type;
516};
517
518template <typename A, typename B> struct promote_storage_type;
519
520template <typename A> struct promote_storage_type<A,A>
521{
522 typedef A ret;
523};
524template <typename A> struct promote_storage_type<A, const A>
525{
526 typedef A ret;
527};
528template <typename A> struct promote_storage_type<const A, A>
529{
530 typedef A ret;
531};
532
533/** \internal Specify the "storage kind" of applying a coefficient-wise
534 * binary operations between two expressions of kinds A and B respectively.
535 * The template parameter Functor permits to specialize the resulting storage kind wrt to
536 * the functor.
537 * The default rules are as follows:
538 * \code
539 * A op A -> A
540 * A op dense -> dense
541 * dense op B -> dense
542 * sparse op dense -> sparse
543 * dense op sparse -> sparse
544 * \endcode
545 */
546template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
547
548template <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; };
549template <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; };
550template <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; };
551template <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; };
552template <typename Functor> struct cwise_promote_storage_type<Sparse,Dense,Functor> { typedef Sparse ret; };
553template <typename Functor> struct cwise_promote_storage_type<Dense,Sparse,Functor> { typedef Sparse ret; };
554
555template <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order {
556 enum { value = LhsOrder };
557};
558
559template <typename LhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder> { enum { value = RhsOrder }; };
560template <typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder> { enum { value = LhsOrder }; };
561template <int Order> struct cwise_promote_storage_order<Sparse,Sparse,Order,Order> { enum { value = Order }; };
562
563
564/** \internal Specify the "storage kind" of multiplying an expression of kind A with kind B.
565 * The template parameter ProductTag permits to specialize the resulting storage kind wrt to
566 * some compile-time properties of the product: GemmProduct, GemvProduct, OuterProduct, InnerProduct.
567 * The default rules are as follows:
568 * \code
569 * K * K -> K
570 * dense * K -> dense
571 * K * dense -> dense
572 * diag * K -> K
573 * K * diag -> K
574 * Perm * K -> K
575 * K * Perm -> K
576 * \endcode
577 */
578template <typename A, typename B, int ProductTag> struct product_promote_storage_type;
579
580template <typename A, int ProductTag> struct product_promote_storage_type<A, A, ProductTag> { typedef A ret;};
581template <int ProductTag> struct product_promote_storage_type<Dense, Dense, ProductTag> { typedef Dense ret;};
582template <typename A, int ProductTag> struct product_promote_storage_type<A, Dense, ProductTag> { typedef Dense ret; };
583template <typename B, int ProductTag> struct product_promote_storage_type<Dense, B, ProductTag> { typedef Dense ret; };
584
585template <typename A, int ProductTag> struct product_promote_storage_type<A, DiagonalShape, ProductTag> { typedef A ret; };
586template <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape, B, ProductTag> { typedef B ret; };
587template <int ProductTag> struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { typedef Dense ret; };
588template <int ProductTag> struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { typedef Dense ret; };
589
590template <typename A, int ProductTag> struct product_promote_storage_type<A, PermutationStorage, ProductTag> { typedef A ret; };
591template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B, ProductTag> { typedef B ret; };
592template <int ProductTag> struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { typedef Dense ret; };
593template <int ProductTag> struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { typedef Dense ret; };
594
595/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type.
596 * \tparam Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType.
597 */
598template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
600{
601 typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
602 int(ExpressionType::PlainObject::Options) | int(RowMajor), 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
603 typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
604 int(ExpressionType::PlainObject::Options) | int(RowMajor), 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
605
606 typedef typename conditional<
611};
612
613template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
615{
616 typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
617 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
618 typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
619 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
620
621 typedef typename conditional<
626};
627
628template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
630{
631 enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
632 max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
633 };
636
637 typedef typename conditional<
642};
643
644template<typename Expr,typename Scalar = typename Expr::Scalar>
646{
648
651
654
656};
657
658template<typename ExpressionType>
660{
661 enum { value = (!bool(is_const<ExpressionType>::value)) &&
663};
664
665template<typename T> struct is_diagonal
666{ enum { ret = false }; };
667
668template<typename T> struct is_diagonal<DiagonalBase<T> >
669{ enum { ret = true }; };
670
671template<typename T> struct is_diagonal<DiagonalWrapper<T> >
672{ enum { ret = true }; };
673
674template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
675{ enum { ret = true }; };
676
677
678template<typename T> struct is_identity
679{ enum { value = false }; };
680
681template<typename T> struct is_identity<CwiseNullaryOp<internal::scalar_identity_op<typename T::Scalar>, T> >
682{ enum { value = true }; };
683
684
685template<typename S1, typename S2> struct glue_shapes;
687
688template<typename T1, typename T2>
691};
692
693template<typename T1, typename T2>
695bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<possibly_same_dense<T1,T2>::value>::type * = 0)
696{
697 return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
698}
699
700template<typename T1, typename T2>
702bool is_same_dense(const T1 &, const T2 &, typename enable_if<!possibly_same_dense<T1,T2>::value>::type * = 0)
703{
704 return false;
705}
706
707// Internal helper defining the cost of a scalar division for the type T.
708// The default heuristic can be specialized for each scalar type and architecture.
709template<typename T,bool Vectorized=false,typename EnableIf = void>
712};
713
714template<typename T,bool Vectorized>
715struct scalar_div_cost<std::complex<T>, Vectorized> {
719 };
720};
721
722
723template<bool Vectorized>
724struct scalar_div_cost<signed long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 24 }; };
725template<bool Vectorized>
726struct scalar_div_cost<unsigned long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 21 }; };
727
728
729#ifdef EIGEN_DEBUG_ASSIGN
730std::string demangle_traversal(int t)
731{
732 if(t==DefaultTraversal) return "DefaultTraversal";
733 if(t==LinearTraversal) return "LinearTraversal";
734 if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
735 if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
736 if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
737 return "?";
738}
739std::string demangle_unrolling(int t)
740{
741 if(t==NoUnrolling) return "NoUnrolling";
742 if(t==InnerUnrolling) return "InnerUnrolling";
743 if(t==CompleteUnrolling) return "CompleteUnrolling";
744 return "?";
745}
746std::string demangle_flags(int f)
747{
748 std::string res;
749 if(f&RowMajorBit) res += " | RowMajor";
750 if(f&PacketAccessBit) res += " | Packet";
751 if(f&LinearAccessBit) res += " | Linear";
752 if(f&LvalueBit) res += " | Lvalue";
753 if(f&DirectAccessBit) res += " | Direct";
754 if(f&NestByRefBit) res += " | NestByRef";
755 if(f&NoPreferredStorageOrderBit) res += " | NoPreferredStorageOrderBit";
756
757 return res;
758}
759#endif
760
761} // end namespace internal
762
763
764/** \class ScalarBinaryOpTraits
765 * \ingroup Core_Module
766 *
767 * \brief Determines whether the given binary operation of two numeric types is allowed and what the scalar return type is.
768 *
769 * This class permits to control the scalar return type of any binary operation performed on two different scalar types through (partial) template specializations.
770 *
771 * For instance, let \c U1, \c U2 and \c U3 be three user defined scalar types for which most operations between instances of \c U1 and \c U2 returns an \c U3.
772 * You can let %Eigen knows that by defining:
773 \code
774 template<typename BinaryOp>
775 struct ScalarBinaryOpTraits<U1,U2,BinaryOp> { typedef U3 ReturnType; };
776 template<typename BinaryOp>
777 struct ScalarBinaryOpTraits<U2,U1,BinaryOp> { typedef U3 ReturnType; };
778 \endcode
779 * You can then explicitly disable some particular operations to get more explicit error messages:
780 \code
781 template<>
782 struct ScalarBinaryOpTraits<U1,U2,internal::scalar_max_op<U1,U2> > {};
783 \endcode
784 * Or customize the return type for individual operation:
785 \code
786 template<>
787 struct ScalarBinaryOpTraits<U1,U2,internal::scalar_sum_op<U1,U2> > { typedef U1 ReturnType; };
788 \endcode
789 *
790 * By default, the following generic combinations are supported:
791 <table class="manual">
792 <tr><th>ScalarA</th><th>ScalarB</th><th>BinaryOp</th><th>ReturnType</th><th>Note</th></tr>
793 <tr ><td>\c T </td><td>\c T </td><td>\c * </td><td>\c T </td><td></td></tr>
794 <tr class="alt"><td>\c NumTraits<T>::Real </td><td>\c T </td><td>\c * </td><td>\c T </td><td>Only if \c NumTraits<T>::IsComplex </td></tr>
795 <tr ><td>\c T </td><td>\c NumTraits<T>::Real </td><td>\c * </td><td>\c T </td><td>Only if \c NumTraits<T>::IsComplex </td></tr>
796 </table>
797 *
798 * \sa CwiseBinaryOp
799 */
800template<typename ScalarA, typename ScalarB, typename BinaryOp=internal::scalar_product_op<ScalarA,ScalarB> >
802#ifndef EIGEN_PARSED_BY_DOXYGEN
803 // for backward compatibility, use the hints given by the (deprecated) internal::scalar_product_traits class.
804 : internal::scalar_product_traits<ScalarA,ScalarB>
805#endif // EIGEN_PARSED_BY_DOXYGEN
806{};
807
808template<typename T, typename BinaryOp>
809struct ScalarBinaryOpTraits<T,T,BinaryOp>
810{
811 typedef T ReturnType;
812};
813
814template <typename T, typename BinaryOp>
815struct ScalarBinaryOpTraits<T, typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, BinaryOp>
816{
817 typedef T ReturnType;
818};
819template <typename T, typename BinaryOp>
820struct ScalarBinaryOpTraits<typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, T, BinaryOp>
821{
822 typedef T ReturnType;
823};
824
825// For Matrix * Permutation
826template<typename T, typename BinaryOp>
827struct ScalarBinaryOpTraits<T,void,BinaryOp>
828{
829 typedef T ReturnType;
830};
831
832// For Permutation * Matrix
833template<typename T, typename BinaryOp>
834struct ScalarBinaryOpTraits<void,T,BinaryOp>
835{
836 typedef T ReturnType;
837};
838
839// for Permutation*Permutation
840template<typename BinaryOp>
841struct ScalarBinaryOpTraits<void,void,BinaryOp>
842{
843 typedef void ReturnType;
844};
845
846// We require Lhs and Rhs to have "compatible" scalar types.
847// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
848// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
849// add together a float matrix and a double matrix.
850#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
851 EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
852 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
853
854} // end namespace Eigen
855
856#endif // EIGEN_XPRHELPER_H
#define EIGEN_MIN_ALIGN_BYTES
Definition: ConfigureVectorization.h:77
#define EIGEN_MAX_STATIC_ALIGN_BYTES
Definition: ConfigureVectorization.h:128
#define EIGEN_MAX_ALIGN_BYTES
Definition: ConfigureVectorization.h:175
#define EIGEN_DEFAULT_COPY_CONSTRUCTOR(CLASS)
Definition: Macros.h:1231
#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a, b)
Definition: Macros.h:1304
#define eigen_internal_assert(x)
Definition: Macros.h:1053
#define EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(Derived)
Definition: Macros.h:1257
#define EIGEN_CONSTEXPR
Definition: Macros.h:797
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:986
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
Definition: Macros.h:1059
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION
Definition: Macros.h:29
#define eigen_assert(x)
Definition: Macros.h:1047
#define EIGEN_NO_THROW
Definition: Macros.h:1430
#define EIGEN_STRONG_INLINE
Definition: Macros.h:927
#define EIGEN_SIZE_MIN_PREFER_FIXED(a, b)
Definition: Macros.h:1312
#define EIGEN_EMPTY_STRUCT_CTOR(X)
Definition: XprHelper.h:22
Base class for all 1D and 2D array, and related expressions.
Definition: ArrayBase.h:41
General-purpose arrays with easy API for coefficient-wise operations.
Definition: Array.h:47
Generic expression of a matrix where all coefficients are defined by a functor.
Definition: CwiseNullaryOp.h:61
Definition: DiagonalMatrix.h:19
Represents a diagonal matrix with its storage.
Definition: DiagonalMatrix.h:142
Expression of a diagonal matrix.
Definition: DiagonalMatrix.h:295
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:50
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:180
Definition: XprHelper.h:272
Definition: XprHelper.h:258
Matrix< _Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols > type
Definition: XprHelper.h:267
Definition: XprHelper.h:110
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value)
Definition: XprHelper.h:149
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const
Definition: XprHelper.h:147
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE variable_if_dynamic(T value=0) EIGEN_NO_THROW
Definition: XprHelper.h:146
Definition: XprHelper.h:130
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T v) const
Definition: XprHelper.h:139
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR T value()
Definition: XprHelper.h:135
EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const
Definition: XprHelper.h:171
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value)
Definition: XprHelper.h:172
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE variable_if_dynamicindex(T value)
Definition: XprHelper.h:170
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T)
Definition: XprHelper.h:162
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR T value()
Definition: XprHelper.h:160
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE variable_if_dynamicindex(T v)
Definition: XprHelper.h:158
Definition: core.h:1240
type
Definition: core.h:575
auto ptr(T p) -> const void *
\rst Converts p to const void* for pointer formatting.
Definition: format.h:3823
@ ColMajor
Storage order is column major (see TopicStorageOrders).
Definition: Constants.h:319
@ RowMajor
Storage order is row major (see TopicStorageOrders).
Definition: Constants.h:321
@ AutoAlign
Align the matrix itself if it is vectorizable fixed-size.
Definition: Constants.h:323
const unsigned int PacketAccessBit
Short version: means the expression might be vectorized.
Definition: Constants.h:94
const unsigned int NoPreferredStorageOrderBit
for an expression, this means that the storage order can be either row-major or column-major.
Definition: Constants.h:178
const unsigned int LinearAccessBit
Short version: means the expression can be seen as 1D vector.
Definition: Constants.h:130
const unsigned int EvalBeforeNestingBit
means the expression should be evaluated by the calling expression
Definition: Constants.h:70
const unsigned int DirectAccessBit
Means that the underlying array of coefficients can be directly accessed as a plain strided array.
Definition: Constants.h:155
const unsigned int LvalueBit
Means the expression has a coeffRef() method, i.e.
Definition: Constants.h:144
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition: Constants.h:66
EIGEN_DEVICE_FUNC T * const_cast_ptr(const T *ptr)
Definition: XprHelper.h:477
EIGEN_DEVICE_FUNC IndexDest convert_index(const IndexSrc &idx)
Definition: XprHelper.h:31
EIGEN_DEVICE_FUNC bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if< possibly_same_dense< T1, T2 >::value >::type *=0)
Definition: XprHelper.h:695
Namespace containing all symbols from the Eigen library.
Definition: Core:141
const unsigned int NestByRefBit
Definition: Constants.h:169
const int HugeCost
This value means that the cost to evaluate an expression coefficient is either very expensive or cann...
Definition: Constants.h:44
@ InnerVectorizedTraversal
Definition: Constants.h:282
@ LinearVectorizedTraversal
Definition: Constants.h:285
@ DefaultTraversal
Definition: Constants.h:277
@ SliceVectorizedTraversal
Definition: Constants.h:288
@ LinearTraversal
Definition: Constants.h:279
const int DynamicIndex
This value means that a signed quantity (e.g., a signed index) is not known at compile-time,...
Definition: Constants.h:27
@ InnerUnrolling
Definition: Constants.h:301
@ CompleteUnrolling
Definition: Constants.h:304
@ NoUnrolling
Definition: Constants.h:299
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time,...
Definition: Constants.h:22
Definition: Eigen_Colamd.h:50
Definition: BFloat16.h:88
The type used to identify an array expression.
Definition: Constants.h:525
The type used to identify a dense storage.
Definition: Constants.h:507
Definition: Constants.h:528
Definition: Constants.h:531
The type used to identify a matrix expression.
Definition: Constants.h:522
Holds information about the various numeric (i.e.
Definition: NumTraits.h:233
The type used to identify a permutation storage.
Definition: Constants.h:516
T ReturnType
Definition: XprHelper.h:811
void ReturnType
Definition: XprHelper.h:843
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:806
The type used to identify a general sparse storage.
Definition: Constants.h:510
Definition: Constants.h:533
const T type
Definition: Meta.h:214
Definition: XprHelper.h:510
remove_all< CastType >::type _CastType
Definition: XprHelper.h:512
XprType::Scalar CurrentScalarType
Definition: XprHelper.h:511
_CastType::Scalar NewScalarType
Definition: XprHelper.h:513
conditional< is_same< CurrentScalarType, NewScalarType >::value, constXprType &, CastType >::type type
Definition: XprHelper.h:515
Definition: Meta.h:109
ArrayBase< Derived > type
Definition: XprHelper.h:497
MatrixBase< Derived > type
Definition: XprHelper.h:491
Definition: XprHelper.h:484
Definition: Meta.h:273
const Array< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > & type
Definition: XprHelper.h:362
const Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > & type
Definition: XprHelper.h:356
plain_matrix_type< T >::type type
Definition: XprHelper.h:336
plain_matrix_type< T >::type type
Definition: XprHelper.h:349
Definition: XprHelper.h:332
Definition: CoreEvaluators.h:91
Definition: Meta.h:97
find_best_packet_helper< Size, typenameunpacket_traits< PacketType >::half >::type type
Definition: XprHelper.h:202
Definition: XprHelper.h:191
Definition: XprHelper.h:207
find_best_packet_helper< Size, typenamepacket_traits< T >::type >::type type
Definition: XprHelper.h:208
Definition: XprHelper.h:176
@ PacketAccess
Definition: XprHelper.h:180
@ Cost
Definition: XprHelper.h:179
@ IsRepeatable
Definition: XprHelper.h:181
dense_xpr_base< Derived, XprKind >::type type
Definition: XprHelper.h:506
Definition: XprHelper.h:501
TriangularShape type
Definition: XprHelper.h:686
Definition: XprHelper.h:685
Definition: ForwardDeclarations.h:26
Definition: Meta.h:211
Definition: Meta.h:258
Definition: XprHelper.h:666
@ ret
Definition: XprHelper.h:666
Definition: XprHelper.h:679
Definition: Meta.h:159
Definition: XprHelper.h:660
Definition: Meta.h:148
Definition: XprHelper.h:39
Definition: XprHelper.h:458
conditional< Evaluate, PlainObject, typenameref_selector< T >::type >::type type
Definition: XprHelper.h:472
@ CoeffReadCost
Definition: XprHelper.h:461
@ CostNoEval
Definition: XprHelper.h:468
@ NAsInteger
Definition: XprHelper.h:466
@ ScalarReadCost
Definition: XprHelper.h:460
@ Evaluate
Definition: XprHelper.h:469
@ CostEval
Definition: XprHelper.h:467
Definition: XprHelper.h:615
Array< Scalar, ExpressionType::RowsAtCompileTime, 1, ExpressionType::PlainObject::Options &~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1 > ArrayColType
Definition: XprHelper.h:619
conditional< is_same< typenametraits< ExpressionType >::XprKind, MatrixXpr >::value, MatrixColType, ArrayColType >::type type
Definition: XprHelper.h:625
Matrix< Scalar, ExpressionType::RowsAtCompileTime, 1, ExpressionType::PlainObject::Options &~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1 > MatrixColType
Definition: XprHelper.h:617
Definition: XprHelper.h:646
Matrix< Scalar, traits< Expr >::RowsAtCompileTime, traits< Expr >::ColsAtCompileTime, Options, traits< Expr >::MaxRowsAtCompileTime, traits< Expr >::MaxColsAtCompileTime > matrix_type
Definition: XprHelper.h:653
CwiseNullaryOp< scalar_constant_op< Scalar >, const typename conditional< is_same< typename traits< Expr >::XprKind, MatrixXpr >::value, matrix_type, array_type >::type > type
Definition: XprHelper.h:655
@ Options
Definition: XprHelper.h:647
Array< Scalar, traits< Expr >::RowsAtCompileTime, traits< Expr >::ColsAtCompileTime, Options, traits< Expr >::MaxRowsAtCompileTime, traits< Expr >::MaxColsAtCompileTime > array_type
Definition: XprHelper.h:650
Definition: XprHelper.h:630
@ diag_size
Definition: XprHelper.h:631
@ max_diag_size
Definition: XprHelper.h:632
conditional< is_same< typenametraits< ExpressionType >::XprKind, MatrixXpr >::value, MatrixDiagType, ArrayDiagType >::type type
Definition: XprHelper.h:641
Matrix< Scalar, diag_size, 1, ExpressionType::PlainObject::Options &~RowMajor, max_diag_size, 1 > MatrixDiagType
Definition: XprHelper.h:634
Array< Scalar, diag_size, 1, ExpressionType::PlainObject::Options &~RowMajor, max_diag_size, 1 > ArrayDiagType
Definition: XprHelper.h:635
plain_matrix_type_dense< T, typenametraits< T >::XprKind, traits< T >::Flags >::type type
Definition: XprHelper.h:299
T::PlainObject type
Definition: XprHelper.h:303
Definition: XprHelper.h:296
@ MaxCols
Definition: XprHelper.h:401
@ MaxRows
Definition: XprHelper.h:400
Definition: XprHelper.h:295
plain_matrix_type_dense< T, typenametraits< T >::XprKind, evaluator< T >::Flags >::type type
Definition: XprHelper.h:372
Definition: XprHelper.h:367
Definition: XprHelper.h:600
conditional< is_same< typenametraits< ExpressionType >::XprKind, MatrixXpr >::value, MatrixRowType, ArrayRowType >::type type
Definition: XprHelper.h:610
Matrix< Scalar, 1, ExpressionType::ColsAtCompileTime, int(ExpressionType::PlainObject::Options)|int(RowMajor), 1, ExpressionType::MaxColsAtCompileTime > MatrixRowType
Definition: XprHelper.h:602
Array< Scalar, 1, ExpressionType::ColsAtCompileTime, int(ExpressionType::PlainObject::Options)|int(RowMajor), 1, ExpressionType::MaxColsAtCompileTime > ArrayRowType
Definition: XprHelper.h:604
Definition: XprHelper.h:689
Definition: XprHelper.h:121
Definition: XprHelper.h:68
Definition: XprHelper.h:518
Definition: XprHelper.h:417
conditional< bool(traits< T >::Flags &NestByRefBit), Tconst &, constT >::type type
Definition: XprHelper.h:422
conditional< bool(traits< T >::Flags &NestByRefBit), T &, T >::type non_const_type
Definition: XprHelper.h:428
T type
Definition: Meta.h:126
Definition: XprHelper.h:710
Definition: NullaryFunctors.h:31
Definition: XprHelper.h:282
Definition: ForwardDeclarations.h:17
Definition: XprHelper.h:434
conditional< bool(internal::is_const< T1 >::value), typenameinternal::add_const_on_value_type< T2 >::type, T2 >::type type
Definition: XprHelper.h:439
Definition: Meta.h:96
T half
Definition: GenericPacketMath.h:135
@ size
Definition: GenericPacketMath.h:138
#define S(label, offset, message)
Definition: Errors.h:119