1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_XPRHELPER_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_XPRHELPER_H 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// just a workaround because GCC seems to not really like empty structs 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// so currently we simply disable this optimization for gcc 4.3 172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3) 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #define EIGEN_EMPTY_STRUCT_CTOR(X) \ 192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \ 202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {} 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#else 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #define EIGEN_EMPTY_STRUCT_CTOR(X) 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename IndexDest, typename IndexSrc> 302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC 312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline IndexDest convert_index(const IndexSrc& idx) { 322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away: 332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type"); 342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return IndexDest(idx); 352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// promote_scalar_arg is an helper used in operation between an expression and a scalar, like: 392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// expression * scalar 402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// 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. 412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// 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. 422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Then the logic is as follows: 432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// - if the operation is natively supported as defined by IsSupported, then the scalar type is not promoted, and T is returned. 442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// - 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. 452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// - otherwise, ExprScalar is returned if T is implicitly convertible to ExprScalar AND that this does not imply a float to integer conversion. 462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// - In all other cases, the promoted type is not defined, and the respective operation is thus invalid and not available (SFINAE). 472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ExprScalar,typename T, bool IsSupported> 482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg; 492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T> 512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg<S,T,true> 522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef T type; 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Recursively check safe conversion to PromotedType, and then ExprScalar if they are different. 572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ExprScalar,typename T,typename PromotedType, 582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value, 592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool IsSafe = NumTraits<T>::IsInteger || !NumTraits<PromotedType>::IsInteger> 602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported; 612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Start recursion with NumTraits<ExprScalar>::Literal 632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T> 642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {}; 652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// We found a match! 672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T, typename PromotedType> 682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<S,T,PromotedType,true,true> 692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef PromotedType type; 712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different, 742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// so let's try to promote to ExprScalar 752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ExprScalar,typename T, typename PromotedType> 762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<ExprScalar,T,PromotedType,false,true> 772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : promote_scalar_arg_unsupported<ExprScalar,T,ExprScalar> 782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{}; 792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Unsafe real-to-integer, let's stop. 812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T, typename PromotedType, bool ConvertibleToLiteral> 822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {}; 832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// T is not even convertible to ExprScalar, let's stop. 852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T> 862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<S,T,S,false,true> {}; 872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//classes inheriting no_assignment_operator don't generate a default operator=. 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass no_assignment_operator 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath private: 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath no_assignment_operator& operator=(const no_assignment_operator&); 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal return the index type with the largest number of bits */ 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename I1, typename I2> 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct promote_index_type 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type; 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * can be accessed using value() and setValue(). 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Otherwise, this class is an empty structure and value() just returns the template parameter Value. 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, int Value> class variable_if_dynamic 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic) 1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); } 1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); } 1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {} 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> class variable_if_dynamic<T, Dynamic> 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath T m_value; 1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); } 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value) : m_value(value) {} 1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; } 1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; } 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/** \internal like variable_if_dynamic but for DynamicIndex 1267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez */ 1277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename T, int Value> class variable_if_dynamicindex 1287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 1297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public: 1307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex) 1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); } 1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); } 1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {} 1347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}; 1357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename T> class variable_if_dynamicindex<T, DynamicIndex> 1377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 1387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez T m_value; 1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); } 1407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez public: 1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {} 1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; } 1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; } 1447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}; 1457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct functor_traits 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Cost = 10, 1517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez PacketAccess = false, 1527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez IsRepeatable = false 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct packet_traits; 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct unpacket_traits 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef T type; 1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef T half; 1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum 1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang size = 1, 1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang alignment = 1 1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int Size, typename PacketType, 1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value> 1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet_helper; 1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate< int Size, typename PacketType> 1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet_helper<Size,PacketType,true> 1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef PacketType type; 1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int Size, typename PacketType> 1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet_helper<Size,PacketType,false> 1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename find_best_packet_helper<Size,typename unpacket_traits<PacketType>::half>::type type; 1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Size> 1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet 1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename find_best_packet_helper<Size,typename packet_traits<T>::type>::type type; 1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if EIGEN_MAX_STATIC_ALIGN_BYTES>0 1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes, 1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool Match = bool((ArrayBytes%AlignmentBytes)==0), 1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool TryHalf = bool(EIGEN_MIN_ALIGN_BYTES<AlignmentBytes) > 1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper 1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = 0 }; 1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes, bool TryHalf> 2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match 2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = AlignmentBytes }; 2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes> 2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half 2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // current packet too large, try with an half-packet 2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value }; 2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#else 2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// If static alignment is disabled, no need to bother. 2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This also avoids a division by zero in "bool Match = bool((ArrayBytes%AlignmentBytes)==0)" 2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes> 2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper 2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = 0 }; 2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif 2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Size> struct compute_default_alignment { 2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value }; 2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct compute_default_alignment<T,Dynamic> { 2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = EIGEN_MAX_ALIGN_BYTES }; 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Rows, int _Cols, 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int _Options = AutoAlign | 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ( (_Rows==1 && _Cols!=1) ? RowMajor 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : (_Cols==1 && _Rows!=1) ? ColMajor 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ), 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int _MaxRows = _Rows, 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int _MaxCols = _Cols 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath> class make_proper_matrix_type 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath IsColVector = _Cols==1 && _Rows!=1, 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath IsRowVector = _Rows==1 && _Cols!=1, 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Options = IsColVector ? (_Options | ColMajor) & ~RowMajor 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : IsRowVector ? (_Options | RowMajor) & ~ColMajor 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : _Options 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type; 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols> 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass compute_matrix_flags 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 }; 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<> 2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // and then propagate this information to the evaluator's flags. 2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage. 2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit }; 259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int _Rows, int _Cols> struct size_at_compile_time 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols }; 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 2662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename XprType> struct size_of_xpr_at_compile_time 2672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret }; 2692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type, 272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * whereas eval is a const reference in the case of a matrix 273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type; 2762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense; 277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct plain_matrix_type<T,Dense> 278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 2792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, traits<T>::Flags>::type type; 2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 2812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct plain_matrix_type<T,DiagonalShape> 2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename T::PlainObject type; 284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags> 287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<typename traits<T>::Scalar, 289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::RowsAtCompileTime, 290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::ColsAtCompileTime, 2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor), 292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::MaxRowsAtCompileTime, 293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::MaxColsAtCompileTime 294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath > type; 295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 2972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags> 298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Array<typename traits<T>::Scalar, 300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::RowsAtCompileTime, 301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::ColsAtCompileTime, 3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor), 303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::MaxRowsAtCompileTime, 304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath traits<T>::MaxColsAtCompileTime 305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath > type; 306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* eval : the return type of eval(). For matrices, this is just a const reference 309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * in order to avoid a useless copy 310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval; 313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct eval<T,Dense> 315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename plain_matrix_type<T>::type type; 317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// typedef typename T::PlainObject type; 318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// typedef T::Matrix<typename traits<T>::Scalar, 319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// traits<T>::RowsAtCompileTime, 320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// traits<T>::ColsAtCompileTime, 321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor), 322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// traits<T>::MaxRowsAtCompileTime, 323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// traits<T>::MaxColsAtCompileTime 324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// > type; 325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 3272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct eval<T,DiagonalShape> 3282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 3292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename plain_matrix_type<T>::type type; 3302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 3312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for matrices, no need to evaluate, just use a const reference to avoid a useless copy 333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense> 335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type; 337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense> 341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type; 343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 3462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/* similar to plain_matrix_type, but using the evaluator's Flags */ 3472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval; 3482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 3492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> 3502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct plain_object_eval<T,Dense> 3512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 3522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, evaluator<T>::Flags>::type type; 3532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 3542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major 357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct plain_matrix_type_column_major 359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { Rows = traits<T>::RowsAtCompileTime, 361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Cols = traits<T>::ColsAtCompileTime, 362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRows = traits<T>::MaxRowsAtCompileTime, 363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxCols = traits<T>::MaxColsAtCompileTime 364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<typename traits<T>::Scalar, 366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Rows, 367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Cols, 368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor, 369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRows, 370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxCols 371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath > type; 372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major 375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct plain_matrix_type_row_major 377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { Rows = traits<T>::RowsAtCompileTime, 379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Cols = traits<T>::ColsAtCompileTime, 380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRows = traits<T>::MaxRowsAtCompileTime, 381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxCols = traits<T>::MaxColsAtCompileTime 382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<typename traits<T>::Scalar, 384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Rows, 385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Cols, 386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor, 387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRows, 388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxCols 389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath > type; 390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal The reference selector for template expressions. The idea is that we don't 393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * need to use references for expressions since they are light weight proxy 394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * objects which should generate no copying overhead. */ 395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename T> 396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct ref_selector 397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename conditional< 399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool(traits<T>::Flags & NestByRefBit), 400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath T const&, 401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const T 402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath >::type type; 4032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename conditional< 4052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool(traits<T>::Flags & NestByRefBit), 4062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang T &, 4072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang T 4082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang >::type non_const_type; 409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */ 412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T1, typename T2> 413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct transfer_constness 414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename conditional< 416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool(internal::is_const<T1>::value), 417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename internal::add_const_on_value_type<T2>::type, 418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath T2 419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath >::type type; 420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 4222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 4232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// However, we still need a mechanism to detect whether an expression which is evaluated multiple time 4242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// has to be evaluated into a temporary. 4252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// That's the purpose of this new nested_eval helper: 4262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal Determines how a given expression should be nested when evaluated multiple times. 427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be 4282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * evaluated into the bigger product expression. The choice is between nesting the expression b+c as-is, or 429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is 430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes 431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * many coefficient accesses in the nested expressions -- as is the case with matrix product for example. 432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 4332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam T the type of the expression being nested. 4342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression. 4352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam PlainObject the type of the temporary if needed. 436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 4372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval 438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost, 4412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a tempory? 4422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1. 4432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON 4442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // for all evaluator creating a temporary. This flag is then propagated by the parent evaluators. 4452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // Another solution could be to count the number of temps? 4462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang NAsInteger = n == Dynamic ? HugeCost : n, 4472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost, 4482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CostNoEval = NAsInteger * CoeffReadCost, 4492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval)) 450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 4522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename conditional<Evaluate, PlainObject, typename ref_selector<T>::type>::type type; 453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> 4562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC 457615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murrayinline T* const_cast_ptr(const T* ptr) 458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return const_cast<T*>(ptr); 460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename XprKind = typename traits<Derived>::XprKind> 463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct dense_xpr_base 464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */ 466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct dense_xpr_base<Derived, MatrixXpr> 470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef MatrixBase<Derived> type; 472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct dense_xpr_base<Derived, ArrayXpr> 476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef ArrayBase<Derived> type; 478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 479c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 4802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind> 4812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct generic_xpr_base; 482c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 4832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Derived, typename XprKind> 4842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct generic_xpr_base<Derived, XprKind, Dense> 485c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 4862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename dense_xpr_base<Derived,XprKind>::type type; 487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename XprType, typename CastType> struct cast_return_type 490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename XprType::Scalar CurrentScalarType; 492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<CastType>::type _CastType; 493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename _CastType::Scalar NewScalarType; 494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value, 495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const XprType&,CastType>::type type; 496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename A, typename B> struct promote_storage_type; 499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename A> struct promote_storage_type<A,A> 501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef A ret; 503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 5042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A> struct promote_storage_type<A, const A> 5052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 5062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef A ret; 5072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 5082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A> struct promote_storage_type<const A, A> 5092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 5102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef A ret; 5112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 5122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal Specify the "storage kind" of applying a coefficient-wise 5142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * binary operations between two expressions of kinds A and B respectively. 5152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * The template parameter Functor permits to specialize the resulting storage kind wrt to 5162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * the functor. 5172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * The default rules are as follows: 5182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \code 5192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * A op A -> A 5202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * A op dense -> dense 5212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * dense op B -> dense 5222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * sparse op dense -> sparse 5232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * dense op sparse -> sparse 5242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \endcode 5252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 5262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename B, typename Functor> struct cwise_promote_storage_type; 5272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; }; 5292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; }; 5302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; }; 5312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; }; 5322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Functor> struct cwise_promote_storage_type<Sparse,Dense,Functor> { typedef Sparse ret; }; 5332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Functor> struct cwise_promote_storage_type<Dense,Sparse,Functor> { typedef Sparse ret; }; 5342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order { 5362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = LhsOrder }; 5372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 5382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename LhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder> { enum { value = RhsOrder }; }; 5402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder> { enum { value = LhsOrder }; }; 5412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int Order> struct cwise_promote_storage_order<Sparse,Sparse,Order,Order> { enum { value = Order }; }; 5422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal Specify the "storage kind" of multiplying an expression of kind A with kind B. 5452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * The template parameter ProductTag permits to specialize the resulting storage kind wrt to 5462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * some compile-time properties of the product: GemmProduct, GemvProduct, OuterProduct, InnerProduct. 5472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * The default rules are as follows: 5482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \code 5492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * K * K -> K 5502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * dense * K -> dense 5512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * K * dense -> dense 5522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * diag * K -> K 5532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * K * diag -> K 5542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Perm * K -> K 5552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * K * Perm -> K 5562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \endcode 5572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 5582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename B, int ProductTag> struct product_promote_storage_type; 5592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A, A, ProductTag> { typedef A ret;}; 5612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag> struct product_promote_storage_type<Dense, Dense, ProductTag> { typedef Dense ret;}; 5622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A, Dense, ProductTag> { typedef Dense ret; }; 5632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, int ProductTag> struct product_promote_storage_type<Dense, B, ProductTag> { typedef Dense ret; }; 5642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A, DiagonalShape, ProductTag> { typedef A ret; }; 5662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape, B, ProductTag> { typedef B ret; }; 5672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag> struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { typedef Dense ret; }; 5682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag> struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { typedef Dense ret; }; 5692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 5702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A, PermutationStorage, ProductTag> { typedef A ret; }; 5712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B, ProductTag> { typedef B ret; }; 5722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag> struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { typedef Dense ret; }; 5732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag> struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { typedef Dense ret; }; 574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type. 5762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \tparam Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType. 577c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 578c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> 579c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct plain_row_type 580c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 581c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime, 582c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType; 583c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime, 584c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType; 585c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 586c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename conditional< 587c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value, 588c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixRowType, 589c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ArrayRowType 590c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath >::type type; 591c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 592c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> 594c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct plain_col_type 595c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 596c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1, 597c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType; 598c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1, 599c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType; 600c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 601c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename conditional< 602c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value, 603c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixColType, 604c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ArrayColType 605c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath >::type type; 606c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 607c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 608c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar> 609c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct plain_diag_type 610c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 611c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime), 612c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime) 613c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 614c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType; 615c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType; 616c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 617c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename conditional< 618c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value, 619c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixDiagType, 620c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ArrayDiagType 621c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath >::type type; 622c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 623c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 6242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Expr,typename Scalar = typename Expr::Scalar> 6252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct plain_constant_type 6262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { Options = (traits<Expr>::Flags&RowMajorBit)?RowMajor:0 }; 6282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Array<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime, 6302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> array_type; 6312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Matrix<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime, 6332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> matrix_type; 6342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef CwiseNullaryOp<scalar_constant_op<Scalar>, const typename conditional<is_same< typename traits<Expr>::XprKind, MatrixXpr >::value, matrix_type, array_type>::type > type; 6362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 638c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType> 639c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct is_lvalue 640c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 6412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = (!bool(is_const<ExpressionType>::value)) && 642c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool(traits<ExpressionType>::Flags & LvalueBit) }; 643c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 644c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 6452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct is_diagonal 6462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = false }; }; 6472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct is_diagonal<DiagonalBase<T> > 6492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = true }; }; 6502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct is_diagonal<DiagonalWrapper<T> > 6522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = true }; }; 6532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> > 6552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = true }; }; 6562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S1, typename S2> struct glue_shapes; 6582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<> struct glue_shapes<DenseShape,TriangularShape> { typedef TriangularShape type; }; 6592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T1, typename T2> 6612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangbool 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) 6622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride()); 6642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 6652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T1, typename T2> 6672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangbool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0) 6682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return false; 6702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 6712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Internal helper defining the cost of a scalar division for the type T. 6732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// The default heuristic can be specialized for each scalar type and architecture. 6742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T,bool Vectorized=false,typename EnaleIf = void> 6752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost { 6762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = 8*NumTraits<T>::MulCost }; 6772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T,bool Vectorized> 6802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost<std::complex<T>, Vectorized> { 6812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { value = 2*scalar_div_cost<T>::value 6822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang + 6*NumTraits<T>::MulCost 6832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang + 3*NumTraits<T>::AddCost 6842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 6852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 6862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<bool Vectorized> 6892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost<signed long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 24 }; }; 6902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<bool Vectorized> 6912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost<unsigned long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 21 }; }; 6922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 6942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifdef EIGEN_DEBUG_ASSIGN 6952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstd::string demangle_traversal(int t) 6962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 6972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==DefaultTraversal) return "DefaultTraversal"; 6982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==LinearTraversal) return "LinearTraversal"; 6992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal"; 7002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal"; 7012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal"; 7022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return "?"; 7032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 7042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstd::string demangle_unrolling(int t) 7052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 7062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==NoUnrolling) return "NoUnrolling"; 7072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==InnerUnrolling) return "InnerUnrolling"; 7082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(t==CompleteUnrolling) return "CompleteUnrolling"; 7092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return "?"; 7102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 7112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstd::string demangle_flags(int f) 7122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 7132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang std::string res; 7142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(f&RowMajorBit) res += " | RowMajor"; 7152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(f&PacketAccessBit) res += " | Packet"; 7162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(f&LinearAccessBit) res += " | Linear"; 7172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(f&LvalueBit) res += " | Lvalue"; 7182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(f&DirectAccessBit) res += " | Direct"; 7192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(f&NestByRefBit) res += " | NestByRef"; 7202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(f&NoPreferredStorageOrderBit) res += " | NoPreferredStorageOrderBit"; 7212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return res; 7232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} 7242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif 7252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 726c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 727c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 7282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \class ScalarBinaryOpTraits 7302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \ingroup Core_Module 7312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 7322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \brief Determines whether the given binary operation of two numeric types is allowed and what the scalar return type is. 7332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 7342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * This class permits to control the scalar return type of any binary operation performed on two different scalar types through (partial) template specializations. 7352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 7362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 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. 7372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * You can let %Eigen knows that by defining: 7382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \code 7392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename BinaryOp> 7402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct ScalarBinaryOpTraits<U1,U2,BinaryOp> { typedef U3 ReturnType; }; 7412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename BinaryOp> 7422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct ScalarBinaryOpTraits<U2,U1,BinaryOp> { typedef U3 ReturnType; }; 7432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \endcode 7442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * You can then explicitly disable some particular operations to get more explicit error messages: 7452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \code 7462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<> 7472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct ScalarBinaryOpTraits<U1,U2,internal::scalar_max_op<U1,U2> > {}; 7482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \endcode 7492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * Or customize the return type for individual operation: 7502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \code 7512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<> 7522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang struct ScalarBinaryOpTraits<U1,U2,internal::scalar_sum_op<U1,U2> > { typedef U1 ReturnType; }; 7532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang \endcode 7542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 7552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * By default, the following generic combinations are supported: 7562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang <table class="manual"> 7572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang <tr><th>ScalarA</th><th>ScalarB</th><th>BinaryOp</th><th>ReturnType</th><th>Note</th></tr> 7582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang <tr ><td>\c T </td><td>\c T </td><td>\c * </td><td>\c T </td><td></td></tr> 7592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang <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> 7602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang <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> 7612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang </table> 7622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 7632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \sa CwiseBinaryOp 7642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 7652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ScalarA, typename ScalarB, typename BinaryOp=internal::scalar_product_op<ScalarA,ScalarB> > 7662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits 7672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_PARSED_BY_DOXYGEN 7682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // for backward compatibility, use the hints given by the (deprecated) internal::scalar_product_traits class. 7692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : internal::scalar_product_traits<ScalarA,ScalarB> 7702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_PARSED_BY_DOXYGEN 7712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{}; 7722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BinaryOp> 7742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<T,T,BinaryOp> 7752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 7762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef T ReturnType; 7772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 7782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename T, typename BinaryOp> 7802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<T, typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, BinaryOp> 7812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 7822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef T ReturnType; 7832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 7842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename T, typename BinaryOp> 7852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, T, BinaryOp> 7862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 7872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef T ReturnType; 7882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 7892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// For Matrix * Permutation 7912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BinaryOp> 7922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<T,void,BinaryOp> 7932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 7942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef T ReturnType; 7952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 7962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 7972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// For Permutation * Matrix 7982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BinaryOp> 7992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<void,T,BinaryOp> 8002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 8012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef T ReturnType; 8022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 8032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// for Permutation*Permutation 8052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename BinaryOp> 8062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<void,void,BinaryOp> 8072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ 8082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef void ReturnType; 8092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}; 8102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 8112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// We require Lhs and Rhs to have "compatible" scalar types. 8122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths. 8132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to 8142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// add together a float matrix and a double matrix. 8152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \ 8162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \ 8172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) 8182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 819c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 820c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 821c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_XPRHELPER_H 822