mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Pulled the latest changes from the trunk
This commit is contained in:
@@ -334,7 +334,7 @@ struct blas_traits<Transpose<NestedXpr> >
|
||||
enum {
|
||||
IsTransposed = Base::IsTransposed ? 0 : 1
|
||||
};
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
|
||||
static inline ExtractType extract(const XprType& x) { return ExtractType(Base::extract(x.nestedExpression())); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); }
|
||||
};
|
||||
|
||||
|
||||
@@ -53,14 +53,13 @@ const int Infinity = -1;
|
||||
const unsigned int RowMajorBit = 0x1;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* means the expression should be evaluated by the calling expression */
|
||||
const unsigned int EvalBeforeNestingBit = 0x2;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* \deprecated
|
||||
* means the expression should be evaluated before any assignment */
|
||||
const unsigned int EvalBeforeAssigningBit = 0x4;
|
||||
const unsigned int EvalBeforeAssigningBit = 0x4; // FIXME deprecated
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
@@ -155,6 +154,16 @@ const unsigned int AlignedBit = 0x80;
|
||||
|
||||
const unsigned int NestByRefBit = 0x100;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* for an expression, this means that the storage order
|
||||
* can be either row-major or column-major.
|
||||
* The precise choice will be decided at evaluation time or when
|
||||
* combined with other expressions.
|
||||
* \sa \ref RowMajorBit, \ref TopicStorageOrders */
|
||||
const unsigned int NoPreferredStorageOrderBit = 0x200;
|
||||
|
||||
|
||||
// list of flags that are inherited by default
|
||||
const unsigned int HereditaryBits = RowMajorBit
|
||||
| EvalBeforeNestingBit
|
||||
@@ -413,10 +422,16 @@ namespace Architecture
|
||||
Generic = 0x0,
|
||||
SSE = 0x1,
|
||||
AltiVec = 0x2,
|
||||
VSX = 0x3,
|
||||
NEON = 0x4,
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
Target = SSE
|
||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||
Target = AltiVec
|
||||
#elif defined EIGEN_VECTORIZE_VSX
|
||||
Target = VSX
|
||||
#elif defined EIGEN_VECTORIZE_NEON
|
||||
Target = NEON
|
||||
#else
|
||||
Target = Generic
|
||||
#endif
|
||||
@@ -425,7 +440,7 @@ namespace Architecture
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum used as template parameter in GeneralProduct. */
|
||||
enum { CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
|
||||
enum { DefaultProduct=0, CoeffBasedProductMode, LazyCoeffBasedProductMode, LazyProduct, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum used in experimental parallel implementation. */
|
||||
@@ -434,12 +449,38 @@ enum Action {GetAction, SetAction};
|
||||
/** The type used to identify a dense storage. */
|
||||
struct Dense {};
|
||||
|
||||
/** The type used to identify a general sparse storage. */
|
||||
struct Sparse {};
|
||||
|
||||
/** The type used to identify a permutation storage. */
|
||||
struct PermutationStorage {};
|
||||
|
||||
/** The type used to identify a matrix expression */
|
||||
struct MatrixXpr {};
|
||||
|
||||
/** The type used to identify an array expression */
|
||||
struct ArrayXpr {};
|
||||
|
||||
// An evaluator must define its shape. By default, it can be one of the following:
|
||||
struct DenseShape { static std::string debugName() { return "DenseShape"; } };
|
||||
struct HomogeneousShape { static std::string debugName() { return "HomogeneousShape"; } };
|
||||
struct DiagonalShape { static std::string debugName() { return "DiagonalShape"; } };
|
||||
struct BandShape { static std::string debugName() { return "BandShape"; } };
|
||||
struct TriangularShape { static std::string debugName() { return "TriangularShape"; } };
|
||||
struct SelfAdjointShape { static std::string debugName() { return "SelfAdjointShape"; } };
|
||||
struct PermutationShape { static std::string debugName() { return "PermutationShape"; } };
|
||||
struct SparseShape { static std::string debugName() { return "SparseShape"; } };
|
||||
|
||||
namespace internal {
|
||||
|
||||
// random access iterators based on coeff*() accessors.
|
||||
struct IndexBased {};
|
||||
|
||||
// evaluator based on iterators to access coefficients.
|
||||
struct IteratorBased {};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_CONSTANTS_H
|
||||
|
||||
@@ -36,6 +36,10 @@ template<typename Derived> struct accessors_level
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T> struct evaluator_traits;
|
||||
|
||||
template< typename T> struct evaluator;
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename T> struct NumTraits;
|
||||
@@ -51,7 +55,7 @@ class DenseCoeffsBase;
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols,
|
||||
int _Options = AutoAlign |
|
||||
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==4
|
||||
#if EIGEN_GNUC_AT(3,4)
|
||||
// workaround a bug in at least gcc 3.4.6
|
||||
// the innermost ?: ternary operator is misparsed. We write it slightly
|
||||
// differently and this makes gcc 3.4.6 happy, but it's ugly.
|
||||
@@ -87,11 +91,19 @@ template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp;
|
||||
template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp;
|
||||
template<typename ViewOp, typename MatrixType> class CwiseUnaryView;
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp;
|
||||
template<typename BinOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp;
|
||||
template<typename Derived, typename Lhs, typename Rhs> class ProductBase;
|
||||
template<typename Lhs, typename Rhs> class Product;
|
||||
template<typename Lhs, typename Rhs, int Mode> class GeneralProduct;
|
||||
template<typename Lhs, typename Rhs, int NestingFlags> class CoeffBasedProduct;
|
||||
template<typename BinOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp; // TODO deprecated
|
||||
template<typename Derived, typename Lhs, typename Rhs> class ProductBase; // TODO deprecated
|
||||
template<typename Decomposition, typename Rhstype> class Solve;
|
||||
template<typename XprType> class Inverse;
|
||||
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs> struct product_tag;
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option = DefaultProduct> class Product;
|
||||
|
||||
template<typename Lhs, typename Rhs, int Mode> class GeneralProduct; // TODO deprecated
|
||||
template<typename Lhs, typename Rhs, int NestingFlags> class CoeffBasedProduct; // TODO deprecated
|
||||
|
||||
template<typename Derived> class DiagonalBase;
|
||||
template<typename _DiagonalVectorType> class DiagonalWrapper;
|
||||
@@ -109,7 +121,12 @@ template<typename Derived,
|
||||
int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors
|
||||
> class MapBase;
|
||||
template<int InnerStrideAtCompileTime, int OuterStrideAtCompileTime> class Stride;
|
||||
template<int Value = Dynamic> class InnerStride;
|
||||
template<int Value = Dynamic> class OuterStride;
|
||||
template<typename MatrixType, int MapOptions=Unaligned, typename StrideType = Stride<0,0> > class Map;
|
||||
template<typename Derived> class RefBase;
|
||||
template<typename PlainObjectType, int Options = 0,
|
||||
typename StrideType = typename internal::conditional<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> >::type > class Ref;
|
||||
|
||||
template<typename Derived> class TriangularBase;
|
||||
template<typename MatrixType, unsigned int Mode> class TriangularView;
|
||||
@@ -120,10 +137,9 @@ template<typename MatrixType> struct CommaInitializer;
|
||||
template<typename Derived> class ReturnByValue;
|
||||
template<typename ExpressionType> class ArrayWrapper;
|
||||
template<typename ExpressionType> class MatrixWrapper;
|
||||
template<typename XprType> class InnerIterator;
|
||||
|
||||
namespace internal {
|
||||
template<typename DecompositionType, typename Rhs> struct solve_retval_base;
|
||||
template<typename DecompositionType, typename Rhs> struct solve_retval;
|
||||
template<typename DecompositionType> struct kernel_retval_base;
|
||||
template<typename DecompositionType> struct kernel_retval;
|
||||
template<typename DecompositionType> struct image_retval_base;
|
||||
@@ -136,6 +152,18 @@ template<typename _Scalar, int Rows=Dynamic, int Cols=Dynamic, int Supers=Dynami
|
||||
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs> struct product_type;
|
||||
/** \internal
|
||||
* \class product_evaluator
|
||||
* Products need their own evaluator with more template arguments allowing for
|
||||
* easier partial template specializations.
|
||||
*/
|
||||
template< typename T,
|
||||
int ProductTag = internal::product_type<typename T::Lhs,typename T::Rhs>::ret,
|
||||
typename LhsShape = typename evaluator_traits<typename T::Lhs>::Shape,
|
||||
typename RhsShape = typename evaluator_traits<typename T::Rhs>::Shape,
|
||||
typename LhsScalar = typename traits<typename T::Lhs>::Scalar,
|
||||
typename RhsScalar = typename traits<typename T::Rhs>::Scalar
|
||||
> struct product_evaluator;
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs,
|
||||
@@ -193,7 +221,7 @@ struct IOFormat;
|
||||
// Array module
|
||||
template<typename _Scalar, int _Rows, int _Cols,
|
||||
int _Options = AutoAlign |
|
||||
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==4
|
||||
#if EIGEN_GNUC_AT(3,4)
|
||||
// workaround a bug in at least gcc 3.4.6
|
||||
// the innermost ?: ternary operator is misparsed. We write it slightly
|
||||
// differently and this makes gcc 3.4.6 happy, but it's ugly.
|
||||
@@ -223,6 +251,7 @@ template<typename MatrixType> class HouseholderQR;
|
||||
template<typename MatrixType> class ColPivHouseholderQR;
|
||||
template<typename MatrixType> class FullPivHouseholderQR;
|
||||
template<typename MatrixType, int QRPreconditioner = ColPivHouseholderQRPreconditioner> class JacobiSVD;
|
||||
template<typename MatrixType> class BDCSVD;
|
||||
template<typename MatrixType, int UpLo = Lower> class LLT;
|
||||
template<typename MatrixType, int UpLo = Lower> class LDLT;
|
||||
template<typename VectorsType, typename CoeffsType, int Side=OnTheLeft> class HouseholderSequence;
|
||||
|
||||
@@ -18,31 +18,280 @@
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
EIGEN_MINOR_VERSION>=z))))
|
||||
|
||||
// Compiler identification, EIGEN_COMP_*
|
||||
|
||||
/// \internal EIGEN_COMP_GNUC set to 1 for all compilers compatible with GCC
|
||||
#ifdef __GNUC__
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||
#define EIGEN_COMP_GNUC 1
|
||||
#else
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__<x)
|
||||
#else
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) 0
|
||||
#define EIGEN_COMP_GNUC 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_GNUC_AT_MOST(4,3) && !defined(__clang__)
|
||||
/// \internal EIGEN_COMP_CLANG set to 1 if the compiler is clang (alias for __clang__)
|
||||
#if defined(__clang__)
|
||||
#define EIGEN_COMP_CLANG 1
|
||||
#else
|
||||
#define EIGEN_COMP_CLANG 0
|
||||
#endif
|
||||
|
||||
|
||||
/// \internal EIGEN_COMP_LLVM set to 1 if the compiler backend is llvm
|
||||
#if defined(__llvm__)
|
||||
#define EIGEN_COMP_LLVM 1
|
||||
#else
|
||||
#define EIGEN_COMP_LLVM 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_ICC set to __INTEL_COMPILER if the compiler is Intel compiler, 0 otherwise
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#define EIGEN_COMP_ICC __INTEL_COMPILER
|
||||
#else
|
||||
#define EIGEN_COMP_ICC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_MINGW set to 1 if the compiler is mingw
|
||||
#if defined(__MINGW32__)
|
||||
#define EIGEN_COMP_MINGW 1
|
||||
#else
|
||||
#define EIGEN_COMP_MINGW 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_SUNCC set to 1 if the compiler is Solaris Studio
|
||||
#if defined(__SUNPRO_CC)
|
||||
#define EIGEN_COMP_SUNCC 1
|
||||
#else
|
||||
#define EIGEN_COMP_SUNCC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_MSVC set to _MSC_VER if the compiler is Microsoft Visual C++, 0 otherwise.
|
||||
#if defined(_MSC_VER)
|
||||
#define EIGEN_COMP_MSVC _MSC_VER
|
||||
#else
|
||||
#define EIGEN_COMP_MSVC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC
|
||||
#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC)
|
||||
#define EIGEN_COMP_MSVC_STRICT _MSC_VER
|
||||
#else
|
||||
#define EIGEN_COMP_MSVC_STRICT 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_IBM set to 1 if the compiler is IBM XL C++
|
||||
#if defined(__IBMCPP__) || defined(__xlc__)
|
||||
#define EIGEN_COMP_IBM 1
|
||||
#else
|
||||
#define EIGEN_COMP_IBM 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_PGI set to 1 if the compiler is Portland Group Compiler
|
||||
#if defined(__PGI)
|
||||
#define EIGEN_COMP_PGI 1
|
||||
#else
|
||||
#define EIGEN_COMP_PGI 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_ARM set to 1 if the compiler is ARM Compiler
|
||||
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||
#define EIGEN_COMP_ARM 1
|
||||
#else
|
||||
#define EIGEN_COMP_ARM 0
|
||||
#endif
|
||||
|
||||
|
||||
/// \internal EIGEN_GNUC_STRICT set to 1 if the compiler is really GCC and not a compatible compiler (e.g., ICC, clang, mingw, etc.)
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_COMP_CLANG || EIGEN_COMP_CLANG || EIGEN_COMP_MINGW || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM )
|
||||
#define EIGEN_COMP_GNUC_STRICT 1
|
||||
#else
|
||||
#define EIGEN_COMP_GNUC_STRICT 0
|
||||
#endif
|
||||
|
||||
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__<x)
|
||||
#define EIGEN_GNUC_AT(x,y) ( __GNUC__==x && __GNUC_MINOR__==y )
|
||||
#else
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) 0
|
||||
#define EIGEN_GNUC_AT(x,y) 0
|
||||
#endif
|
||||
|
||||
// FIXME: could probably be removed as we do not support gcc 3.x anymore
|
||||
#if EIGEN_COMP_GNUC && (__GNUC__ <= 3)
|
||||
#define EIGEN_GCC3_OR_OLDER 1
|
||||
#else
|
||||
#define EIGEN_GCC3_OR_OLDER 0
|
||||
#endif
|
||||
|
||||
|
||||
// Architecture identification, EIGEN_ARCH_*
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64)
|
||||
#define EIGEN_ARCH_x86_64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_x86_64 0
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__i386)
|
||||
#define EIGEN_ARCH_i386 1
|
||||
#else
|
||||
#define EIGEN_ARCH_i386 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_ARCH_x86_64 || EIGEN_ARCH_i386
|
||||
#define EIGEN_ARCH_i386_OR_x86_64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_i386_OR_x86_64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_ARM set to 1 if the architecture is ARM
|
||||
#if defined(__arm__)
|
||||
#define EIGEN_ARCH_ARM 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARM 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_ARM64 set to 1 if the architecture is ARM64
|
||||
#if defined(__aarch64__)
|
||||
#define EIGEN_ARCH_ARM64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARM64 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_ARCH_ARM || EIGEN_ARCH_ARM64
|
||||
#define EIGEN_ARCH_ARM_OR_ARM64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARM_OR_ARM64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_MIPS set to 1 if the architecture is MIPS
|
||||
#if defined(__mips__) || defined(__mips)
|
||||
#define EIGEN_ARCH_MIPS 1
|
||||
#else
|
||||
#define EIGEN_ARCH_MIPS 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_SPARC set to 1 if the architecture is SPARC
|
||||
#if defined(__sparc__) || defined(__sparc)
|
||||
#define EIGEN_ARCH_SPARC 1
|
||||
#else
|
||||
#define EIGEN_ARCH_SPARC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_IA64 set to 1 if the architecture is Intel Itanium
|
||||
#if defined(__ia64__)
|
||||
#define EIGEN_ARCH_IA64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_IA64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_PPC set to 1 if the architecture is PowerPC
|
||||
#if defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
|
||||
#define EIGEN_ARCH_PPC 1
|
||||
#else
|
||||
#define EIGEN_ARCH_PPC 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Operating system identification, EIGEN_OS_*
|
||||
|
||||
/// \internal EIGEN_OS_UNIX set to 1 if the OS is a unix variant
|
||||
#if defined(__unix__) || defined(__unix)
|
||||
#define EIGEN_OS_UNIX 1
|
||||
#else
|
||||
#define EIGEN_OS_UNIX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_LINUX set to 1 if the OS is based on Linux kernel
|
||||
#if defined(__linux__)
|
||||
#define EIGEN_OS_LINUX 1
|
||||
#else
|
||||
#define EIGEN_OS_LINUX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_ANDROID set to 1 if the OS is Android
|
||||
#if defined(__ANDROID__)
|
||||
#define EIGEN_OS_ANDROID 1
|
||||
#else
|
||||
#define EIGEN_OS_ANDROID 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_GNULINUX set to 1 if the OS is GNU Linux and not Linux-based OS (e.g., not android)
|
||||
#if defined(__gnu_linux__) && !(EIGEN_OS_ANDROID)
|
||||
#define EIGEN_OS_GNULINUX 1
|
||||
#else
|
||||
#define EIGEN_OS_GNULINUX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_BSD set to 1 if the OS is a BSD variant
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
|
||||
#define EIGEN_OS_BSD 1
|
||||
#else
|
||||
#define EIGEN_OS_BSD 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_MAC set to 1 if the OS is MacOS
|
||||
#if defined(__APPLE__)
|
||||
#define EIGEN_OS_MAC 1
|
||||
#else
|
||||
#define EIGEN_OS_MAC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_QNX set to 1 if the OS is QNX
|
||||
#if defined(__QNX__)
|
||||
#define EIGEN_OS_QNX 1
|
||||
#else
|
||||
#define EIGEN_OS_QNX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WIN set to 1 if the OS is Windows based
|
||||
#if defined(_WIN32)
|
||||
#define EIGEN_OS_WIN 1
|
||||
#else
|
||||
#define EIGEN_OS_WIN 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WIN64 set to 1 if the OS is Windows 64bits
|
||||
#if defined(_WIN64)
|
||||
#define EIGEN_OS_WIN64 1
|
||||
#else
|
||||
#define EIGEN_OS_WIN64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WINCE set to 1 if the OS is Windows CE
|
||||
#if defined(_WIN32_WCE)
|
||||
#define EIGEN_OS_WINCE 1
|
||||
#else
|
||||
#define EIGEN_OS_WINCE 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_CYGWIN set to 1 if the OS is Windows/Cygwin
|
||||
#if defined(__CYGWIN__)
|
||||
#define EIGEN_OS_CYGWIN 1
|
||||
#else
|
||||
#define EIGEN_OS_CYGWIN 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WIN_STRICT set to 1 if the OS is really Windows and not some variants
|
||||
#if EIGEN_OS_WIN && !( EIGEN_OS_WINCE || EIGEN_OS_CYGWIN )
|
||||
#define EIGEN_OS_WIN_STRICT 1
|
||||
#else
|
||||
#define EIGEN_OS_WIN_STRICT 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if EIGEN_GNUC_AT_MOST(4,3) && !EIGEN_COMP_CLANG
|
||||
// see bug 89
|
||||
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 0
|
||||
#else
|
||||
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 1
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
||||
#define EIGEN_GCC3_OR_OLDER 1
|
||||
#else
|
||||
#define EIGEN_GCC3_OR_OLDER 0
|
||||
#endif
|
||||
|
||||
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
|
||||
// 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
|
||||
// enable alignment, but it can be a cause of problems on some platforms, so we just disable it in
|
||||
@@ -50,7 +299,7 @@
|
||||
// Only static alignment is really problematic (relies on nonstandard compiler extensions that don't
|
||||
// work everywhere, for example don't work on GCC/ARM), try to keep heap alignment even
|
||||
// when we have to disable static alignment.
|
||||
#if defined(__GNUC__) && !(defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__ppc__) || defined(__ia64__))
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_PPC || EIGEN_ARCH_IA64)
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
|
||||
@@ -59,8 +308,8 @@
|
||||
// static alignment is completely disabled with GCC 3, Sun Studio, and QCC/QNX
|
||||
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT \
|
||||
&& !EIGEN_GCC3_OR_OLDER \
|
||||
&& !defined(__SUNPRO_CC) \
|
||||
&& !defined(__QNXNTO__)
|
||||
&& !EIGEN_COMP_SUNCC \
|
||||
&& !EIGEN_OS_QNX
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 0
|
||||
@@ -86,6 +335,11 @@
|
||||
#define EIGEN_ALIGN 0
|
||||
#endif
|
||||
|
||||
|
||||
// This macro can be used to prevent from macro expansion, e.g.:
|
||||
// std::max EIGEN_NOT_A_MACRO(a,b)
|
||||
#define EIGEN_NOT_A_MACRO
|
||||
|
||||
// EIGEN_ALIGN_STATICALLY is the true test whether we want to align arrays on the stack or not. It takes into account both the user choice to explicitly disable
|
||||
// alignment (EIGEN_DONT_ALIGN_STATICALLY) and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT). Henceforth, only EIGEN_ALIGN_STATICALLY should be used.
|
||||
#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT && !defined(EIGEN_DONT_ALIGN_STATICALLY)
|
||||
@@ -124,7 +378,7 @@
|
||||
#if (__has_feature(cxx_rvalue_references) || \
|
||||
(defined(__cplusplus) && __cplusplus >= 201103L) || \
|
||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || \
|
||||
(defined(_MSC_VER) && _MSC_VER >= 1600))
|
||||
(EIGEN_COMP_MSVC >= 1600))
|
||||
#define EIGEN_HAVE_RVALUE_REFERENCES
|
||||
#endif
|
||||
|
||||
@@ -161,7 +415,7 @@
|
||||
// EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC,
|
||||
// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline
|
||||
// but GCC is still doing fine with just inline.
|
||||
#if (defined _MSC_VER) || (defined __INTEL_COMPILER)
|
||||
#if EIGEN_COMP_MSVC || EIGEN_COMP_ICC
|
||||
#define EIGEN_STRONG_INLINE __forceinline
|
||||
#else
|
||||
#define EIGEN_STRONG_INLINE inline
|
||||
@@ -180,15 +434,15 @@
|
||||
#define EIGEN_ALWAYS_INLINE EIGEN_STRONG_INLINE
|
||||
#endif
|
||||
|
||||
#if (defined __GNUC__)
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_DONT_INLINE __attribute__((noinline))
|
||||
#elif (defined _MSC_VER)
|
||||
#elif EIGEN_COMP_MSVC
|
||||
#define EIGEN_DONT_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define EIGEN_DONT_INLINE
|
||||
#endif
|
||||
|
||||
#if (defined __GNUC__)
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_PERMISSIVE_EXPR __extension__
|
||||
#else
|
||||
#define EIGEN_PERMISSIVE_EXPR
|
||||
@@ -257,15 +511,15 @@
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_NO_DEBUG
|
||||
#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x
|
||||
#define EIGEN_ONLY_USED_FOR_DEBUG(x) EIGEN_UNUSED_VARIABLE(x)
|
||||
#else
|
||||
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_NO_DEPRECATED_WARNING
|
||||
#if (defined __GNUC__)
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_DEPRECATED __attribute__((deprecated))
|
||||
#elif (defined _MSC_VER)
|
||||
#elif EIGEN_COMP_MSVC
|
||||
#define EIGEN_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#define EIGEN_DEPRECATED
|
||||
@@ -274,7 +528,7 @@
|
||||
#define EIGEN_DEPRECATED
|
||||
#endif
|
||||
|
||||
#if (defined __GNUC__)
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define EIGEN_UNUSED
|
||||
@@ -283,13 +537,13 @@
|
||||
// Suppresses 'unused variable' warnings.
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
template<typename T> void ignore_unused_variable(const T&) {}
|
||||
template<typename T> EIGEN_DEVICE_FUNC void ignore_unused_variable(const T&) {}
|
||||
}
|
||||
}
|
||||
#define EIGEN_UNUSED_VARIABLE(var) Eigen::internal::ignore_unused_variable(var);
|
||||
|
||||
#if !defined(EIGEN_ASM_COMMENT)
|
||||
#if (defined __GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
|
||||
#if EIGEN_COMP_GNUC && (EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM_OR_ARM64)
|
||||
#define EIGEN_ASM_COMMENT(X) __asm__("#" X)
|
||||
#else
|
||||
#define EIGEN_ASM_COMMENT(X)
|
||||
@@ -304,12 +558,12 @@ namespace Eigen {
|
||||
* vectorized and non-vectorized code.
|
||||
*/
|
||||
#if (defined __CUDACC__)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __align__(n)
|
||||
#elif (defined __GNUC__) || (defined __PGI) || (defined __IBMCPP__) || (defined __ARMCC_VERSION)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __align__(n)
|
||||
#elif EIGEN_COMP_GNUC || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
#elif (defined _MSC_VER)
|
||||
#elif EIGEN_COMP_MSVC
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
|
||||
#elif (defined __SUNPRO_CC)
|
||||
#elif EIGEN_COMP_SUNCC
|
||||
// FIXME not sure about this one:
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
|
||||
#else
|
||||
@@ -357,27 +611,26 @@ namespace Eigen {
|
||||
// just an empty macro !
|
||||
#define EIGEN_EMPTY
|
||||
|
||||
#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =;
|
||||
#elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =; \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \
|
||||
template <typename OtherDerived> \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const DenseBase<OtherDerived>& other) { Base::operator=(other.derived()); return *this; }
|
||||
#if EIGEN_COMP_MSVC_STRICT && EIGEN_COMP_MSVC < 1900
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =;
|
||||
#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =; \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \
|
||||
template <typename OtherDerived> \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const DenseBase<OtherDerived>& other) { Base::operator=(other.derived()); return *this; }
|
||||
#else
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =; \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \
|
||||
{ \
|
||||
Base::operator=(other); \
|
||||
return *this; \
|
||||
}
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =; \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \
|
||||
{ \
|
||||
Base::operator=(other); \
|
||||
return *this; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \
|
||||
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)
|
||||
|
||||
/**
|
||||
* Just a side note. Commenting within defines works only by documenting
|
||||
@@ -387,6 +640,8 @@ namespace Eigen {
|
||||
* documentation in a single line.
|
||||
**/
|
||||
|
||||
// TODO The EIGEN_DENSE_PUBLIC_INTERFACE should not exists anymore
|
||||
|
||||
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
|
||||
typedef typename Eigen::internal::traits<Derived>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \
|
||||
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \
|
||||
@@ -397,7 +652,6 @@ namespace Eigen {
|
||||
enum { RowsAtCompileTime = Eigen::internal::traits<Derived>::RowsAtCompileTime, \
|
||||
ColsAtCompileTime = Eigen::internal::traits<Derived>::ColsAtCompileTime, \
|
||||
Flags = Eigen::internal::traits<Derived>::Flags, \
|
||||
CoeffReadCost = Eigen::internal::traits<Derived>::CoeffReadCost, \
|
||||
SizeAtCompileTime = Base::SizeAtCompileTime, \
|
||||
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
|
||||
IsVectorAtCompileTime = Base::IsVectorAtCompileTime };
|
||||
@@ -416,13 +670,11 @@ namespace Eigen {
|
||||
MaxRowsAtCompileTime = Eigen::internal::traits<Derived>::MaxRowsAtCompileTime, \
|
||||
MaxColsAtCompileTime = Eigen::internal::traits<Derived>::MaxColsAtCompileTime, \
|
||||
Flags = Eigen::internal::traits<Derived>::Flags, \
|
||||
CoeffReadCost = Eigen::internal::traits<Derived>::CoeffReadCost, \
|
||||
SizeAtCompileTime = Base::SizeAtCompileTime, \
|
||||
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
|
||||
IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \
|
||||
using Base::derived; \
|
||||
using Base::const_cast_derived;
|
||||
|
||||
using Base::const_cast_derived;
|
||||
|
||||
#define EIGEN_PLAIN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
|
||||
#define EIGEN_PLAIN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2009 Kenneth Riddile <kfriddile@yahoo.com>
|
||||
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
|
||||
@@ -42,15 +42,15 @@
|
||||
// See http://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup
|
||||
// FreeBSD 7 seems to have 16-byte aligned malloc except on ARM and MIPS architectures
|
||||
// See http://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup
|
||||
#if defined(__FreeBSD__) && !defined(__arm__) && !defined(__mips__) && (EIGEN_ALIGN_BYTES == 16)
|
||||
#if defined(__FreeBSD__) && !(EIGEN_ARCH_ARM || EIGEN_ARCH_MIPS) && (EIGEN_ALIGN_BYTES == 16)
|
||||
#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1
|
||||
#else
|
||||
#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 0
|
||||
#endif
|
||||
|
||||
#if (defined(__APPLE__) && (EIGEN_ALIGN_BYTES == 16)) \
|
||||
|| (defined(_WIN64) && (EIGEN_ALIGN_BYTES == 16)) \
|
||||
|| EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED \
|
||||
#if (EIGEN_OS_MAC && (EIGEN_ALIGN_BYTES == 16)) \
|
||||
|| (EIGEN_OS_WIN64 && (EIGEN_ALIGN_BYTES == 16)) \
|
||||
|| EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED \
|
||||
|| EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED
|
||||
#define EIGEN_MALLOC_ALREADY_ALIGNED 1
|
||||
#else
|
||||
@@ -62,9 +62,9 @@
|
||||
// See bug 554 (http://eigen.tuxfamily.org/bz/show_bug.cgi?id=554)
|
||||
// It seems to be unsafe to check _POSIX_ADVISORY_INFO without including unistd.h first.
|
||||
// Currently, let's include it only on unix systems:
|
||||
#if defined(__unix__) || defined(__unix)
|
||||
#if EIGEN_OS_UNIX
|
||||
#include <unistd.h>
|
||||
#if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || (defined __PGI) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
|
||||
#if (EIGEN_OS_QNX || (defined _GNU_SOURCE) || EIGEN_COMP_PGI || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
|
||||
#define EIGEN_HAS_POSIX_MEMALIGN 1
|
||||
#endif
|
||||
#endif
|
||||
@@ -224,7 +224,7 @@ inline void* aligned_malloc(size_t size)
|
||||
if(posix_memalign(&result, EIGEN_ALIGN_BYTES, size)) result = 0;
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
result = _mm_malloc(size, EIGEN_ALIGN_BYTES);
|
||||
#elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
result = _aligned_malloc(size, EIGEN_ALIGN_BYTES);
|
||||
#else
|
||||
result = handmade_aligned_malloc(size);
|
||||
@@ -247,7 +247,7 @@ inline void aligned_free(void *ptr)
|
||||
std::free(ptr);
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
_mm_free(ptr);
|
||||
#elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
handmade_aligned_free(ptr);
|
||||
@@ -274,12 +274,12 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
// The defined(_mm_free) is just here to verify that this MSVC version
|
||||
// implements _mm_malloc/_mm_free based on the corresponding _aligned_
|
||||
// functions. This may not always be the case and we just try to be safe.
|
||||
#if defined(_MSC_VER) && (!defined(_WIN32_WCE)) && defined(_mm_free)
|
||||
#if EIGEN_OS_WIN_STRICT && defined(_mm_free)
|
||||
result = _aligned_realloc(ptr,new_size,EIGEN_ALIGN_BYTES);
|
||||
#else
|
||||
result = generic_aligned_realloc(ptr,new_size,old_size);
|
||||
#endif
|
||||
#elif defined(_MSC_VER) && (!defined(_WIN32_WCE))
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
result = _aligned_realloc(ptr,new_size,EIGEN_ALIGN_BYTES);
|
||||
#else
|
||||
result = handmade_aligned_realloc(ptr,new_size,old_size);
|
||||
@@ -454,6 +454,8 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pt
|
||||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t size)
|
||||
{
|
||||
if(size==0)
|
||||
return 0; // short-cut. Also fixes Bug 884
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||
if(NumTraits<T>::RequireInitialization)
|
||||
@@ -521,9 +523,8 @@ template<typename T, bool Align> inline void conditional_aligned_delete_auto(T *
|
||||
template<typename Scalar, typename Index>
|
||||
inline Index first_aligned(const Scalar* array, Index size)
|
||||
{
|
||||
enum { PacketSize = packet_traits<Scalar>::size,
|
||||
PacketAlignedMask = PacketSize-1
|
||||
};
|
||||
static const Index PacketSize = packet_traits<Scalar>::size;
|
||||
static const Index PacketAlignedMask = PacketSize-1;
|
||||
|
||||
if(PacketSize==1)
|
||||
{
|
||||
@@ -576,27 +577,27 @@ template<typename T, bool UseMemmove> struct smart_memmove_helper;
|
||||
|
||||
template<typename T> void smart_memmove(const T* start, const T* end, T* target)
|
||||
{
|
||||
smart_memmove_helper<T,!NumTraits<T>::RequireInitialization>::run(start, end, target);
|
||||
smart_memmove_helper<T,!NumTraits<T>::RequireInitialization>::run(start, end, target);
|
||||
}
|
||||
|
||||
template<typename T> struct smart_memmove_helper<T,true> {
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{ std::memmove(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); }
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{ std::memmove(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); }
|
||||
};
|
||||
|
||||
template<typename T> struct smart_memmove_helper<T,false> {
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{
|
||||
if (uintptr_t(target) < uintptr_t(start))
|
||||
{
|
||||
std::copy(start, end, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ptrdiff_t count = (std::ptrdiff_t(end)-std::ptrdiff_t(start)) / sizeof(T);
|
||||
std::copy_backward(start, end, target + count);
|
||||
}
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{
|
||||
if (uintptr_t(target) < uintptr_t(start))
|
||||
{
|
||||
std::copy(start, end, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ptrdiff_t count = (std::ptrdiff_t(end)-std::ptrdiff_t(start)) / sizeof(T);
|
||||
std::copy_backward(start, end, target + count);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -607,16 +608,16 @@ template<typename T> struct smart_memmove_helper<T,false> {
|
||||
// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA
|
||||
// to the appropriate stack allocation function
|
||||
#ifndef EIGEN_ALLOCA
|
||||
#if (defined __linux__) || (defined __APPLE__) || (defined alloca)
|
||||
#if EIGEN_OS_LINUX || EIGEN_OS_MAC || (defined alloca)
|
||||
#define EIGEN_ALLOCA alloca
|
||||
#elif defined(_MSC_VER)
|
||||
#elif EIGEN_COMP_MSVC
|
||||
#define EIGEN_ALLOCA _alloca
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This helper class construct the allocated memory, and takes care of destructing and freeing the handled data
|
||||
// at destruction time. In practice this helper class is mainly useful to avoid memory leak in case of exceptions.
|
||||
template<typename T> class aligned_stack_memory_handler
|
||||
template<typename T> class aligned_stack_memory_handler : noncopyable
|
||||
{
|
||||
public:
|
||||
/* Creates a stack_memory_handler responsible for the buffer \a ptr of size \a size.
|
||||
@@ -644,6 +645,30 @@ template<typename T> class aligned_stack_memory_handler
|
||||
bool m_deallocate;
|
||||
};
|
||||
|
||||
template<typename T> class scoped_array : noncopyable
|
||||
{
|
||||
T* m_ptr;
|
||||
public:
|
||||
explicit scoped_array(std::ptrdiff_t size)
|
||||
{
|
||||
m_ptr = new T[size];
|
||||
}
|
||||
~scoped_array()
|
||||
{
|
||||
delete[] m_ptr;
|
||||
}
|
||||
T& operator[](std::ptrdiff_t i) { return m_ptr[i]; }
|
||||
const T& operator[](std::ptrdiff_t i) const { return m_ptr[i]; }
|
||||
T* &ptr() { return m_ptr; }
|
||||
const T* ptr() const { return m_ptr; }
|
||||
operator const T*() const { return m_ptr; }
|
||||
};
|
||||
|
||||
template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
{
|
||||
std::swap(a.ptr(),b.ptr());
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \internal
|
||||
@@ -786,12 +811,12 @@ public:
|
||||
//---------- Cache sizes ----------
|
||||
|
||||
#if !defined(EIGEN_NO_CPUID)
|
||||
# if defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
|
||||
# if defined(__PIC__) && defined(__i386__)
|
||||
# if EIGEN_COMP_GNUC && EIGEN_ARCH_i386_OR_x86_64
|
||||
# if defined(__PIC__) && EIGEN_ARCH_i386
|
||||
// Case for x86 with PIC
|
||||
# define EIGEN_CPUID(abcd,func,id) \
|
||||
__asm__ __volatile__ ("xchgl %%ebx, %k1;cpuid; xchgl %%ebx,%k1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id));
|
||||
# elif defined(__PIC__) && defined(__x86_64__)
|
||||
# elif defined(__PIC__) && EIGEN_ARCH_x86_64
|
||||
// Case for x64 with PIC. In theory this is only a problem with recent gcc and with medium or large code model, not with the default small code model.
|
||||
// However, we cannot detect which code model is used, and the xchg overhead is negligible anyway.
|
||||
# define EIGEN_CPUID(abcd,func,id) \
|
||||
@@ -801,8 +826,8 @@ public:
|
||||
# define EIGEN_CPUID(abcd,func,id) \
|
||||
__asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id) );
|
||||
# endif
|
||||
# elif defined(_MSC_VER)
|
||||
# if (_MSC_VER > 1500) && ( defined(_M_IX86) || defined(_M_X64) )
|
||||
# elif EIGEN_COMP_MSVC
|
||||
# if (EIGEN_COMP_MSVC > 1500) && EIGEN_ARCH_i386_OR_x86_64
|
||||
# define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
@@ -274,18 +274,6 @@ template<typename T> struct scalar_product_traits<std::complex<T>, T>
|
||||
// typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
|
||||
// };
|
||||
|
||||
template<typename T> struct is_diagonal
|
||||
{ enum { ret = false }; };
|
||||
|
||||
template<typename T> struct is_diagonal<DiagonalBase<T> >
|
||||
{ enum { ret = true }; };
|
||||
|
||||
template<typename T> struct is_diagonal<DiagonalWrapper<T> >
|
||||
{ enum { ret = true }; };
|
||||
|
||||
template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
|
||||
{ enum { ret = true }; };
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
namespace numext {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#ifndef EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (EIGEN_COMP_MSVC >= 1600)
|
||||
|
||||
// if native static_assert is enabled, let's use it
|
||||
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
||||
@@ -84,13 +84,16 @@
|
||||
THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY,
|
||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT,
|
||||
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS,
|
||||
THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS,
|
||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL,
|
||||
THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES,
|
||||
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED,
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
|
||||
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
|
||||
IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY,
|
||||
STORAGE_LAYOUT_DOES_NOT_MATCH
|
||||
};
|
||||
};
|
||||
|
||||
@@ -101,7 +104,7 @@
|
||||
// Specialized implementation for MSVC to avoid "conditional
|
||||
// expression is constant" warnings. This implementation doesn't
|
||||
// appear to work under GCC, hence the multiple implementations.
|
||||
#ifdef _MSC_VER
|
||||
#if EIGEN_COMP_MSVC
|
||||
|
||||
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
|
||||
{Eigen::internal::static_assertion<bool(CONDITION)>::MSG;}
|
||||
@@ -157,7 +160,7 @@
|
||||
|
||||
#define EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
|
||||
( \
|
||||
(int(TYPE0::SizeAtCompileTime)==0 && int(TYPE1::SizeAtCompileTime)==0) \
|
||||
(int(internal::size_of_xpr_at_compile_time<TYPE0>::ret)==0 && int(internal::size_of_xpr_at_compile_time<TYPE1>::ret)==0) \
|
||||
|| (\
|
||||
(int(TYPE0::RowsAtCompileTime)==Eigen::Dynamic \
|
||||
|| int(TYPE1::RowsAtCompileTime)==Eigen::Dynamic \
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// just a workaround because GCC seems to not really like empty structs
|
||||
// FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled
|
||||
// so currently we simply disable this optimization for gcc 4.3
|
||||
#if (defined __GNUG__) && !((__GNUC__==4) && (__GNUC_MINOR__==3))
|
||||
#if EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3)
|
||||
#define EIGEN_EMPTY_STRUCT_CTOR(X) \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
|
||||
@@ -127,6 +127,17 @@ template<typename _Scalar, int _Rows, int _Cols,
|
||||
|
||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
class compute_matrix_flags
|
||||
{
|
||||
enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
|
||||
public:
|
||||
// FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
|
||||
// and then propagate this information to the evaluator's flags.
|
||||
// However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
|
||||
enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
|
||||
};
|
||||
|
||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
class compute_matrix_evaluator_flags
|
||||
{
|
||||
enum {
|
||||
row_major_bit = Options&RowMajor ? RowMajorBit : 0,
|
||||
@@ -156,7 +167,7 @@ class compute_matrix_flags
|
||||
};
|
||||
|
||||
public:
|
||||
enum { ret = LinearAccessBit | LvalueBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit };
|
||||
enum { ret = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit };
|
||||
};
|
||||
|
||||
template<int _Rows, int _Cols> struct size_at_compile_time
|
||||
@@ -164,6 +175,11 @@ template<int _Rows, int _Cols> struct size_at_compile_time
|
||||
enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
|
||||
};
|
||||
|
||||
template<typename XprType> struct size_of_xpr_at_compile_time
|
||||
{
|
||||
enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
|
||||
};
|
||||
|
||||
/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
|
||||
* whereas eval is a const reference in the case of a matrix
|
||||
*/
|
||||
@@ -174,6 +190,10 @@ template<typename T> struct plain_matrix_type<T,Dense>
|
||||
{
|
||||
typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind>::type type;
|
||||
};
|
||||
template<typename T> struct plain_matrix_type<T,DiagonalShape>
|
||||
{
|
||||
typedef typename T::PlainObject type;
|
||||
};
|
||||
|
||||
template<typename T> struct plain_matrix_type_dense<T,MatrixXpr>
|
||||
{
|
||||
@@ -216,6 +236,11 @@ template<typename T> struct eval<T,Dense>
|
||||
// > type;
|
||||
};
|
||||
|
||||
template<typename T> struct eval<T,DiagonalShape>
|
||||
{
|
||||
typedef typename plain_matrix_type<T>::type type;
|
||||
};
|
||||
|
||||
// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
|
||||
@@ -294,38 +319,42 @@ struct transfer_constness
|
||||
>::type type;
|
||||
};
|
||||
|
||||
/** \internal Determines how a given expression should be nested into another one.
|
||||
|
||||
// When using evaluators, we never evaluate when assembling the expression!!
|
||||
// TODO: get rid of this nested class since it's just an alias for ref_selector.
|
||||
template<typename T, int n=1, typename PlainObject = void> struct nested
|
||||
{
|
||||
typedef typename ref_selector<T>::type type;
|
||||
};
|
||||
|
||||
// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
|
||||
// has to be evaluated into a temporary.
|
||||
// That's the purpose of this new nested_eval helper:
|
||||
/** \internal Determines how a given expression should be nested when evaluated multiple times.
|
||||
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
|
||||
* nested into the bigger product expression. The choice is between nesting the expression b+c as-is, or
|
||||
* evaluated into the bigger product expression. The choice is between nesting the expression b+c as-is, or
|
||||
* evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is
|
||||
* a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
|
||||
* many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
|
||||
*
|
||||
* \param T the type of the expression being nested
|
||||
* \param T the type of the expression being nested.
|
||||
* \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
|
||||
*
|
||||
* Note that if no evaluation occur, then the constness of T is preserved.
|
||||
*
|
||||
* Example. Suppose that a, b, and c are of type Matrix3d. The user forms the expression a*(b+c).
|
||||
* b+c is an expression "sum of matrices", which we will denote by S. In order to determine how to nest it,
|
||||
* the Product expression uses: nested<S, 3>::type, which turns out to be Matrix3d because the internal logic of
|
||||
* nested determined that in this case it was better to evaluate the expression b+c into a temporary. On the other hand,
|
||||
* since a is of type Matrix3d, the Product expression nests it as nested<Matrix3d, 3>::type, which turns out to be
|
||||
* const Matrix3d&, because the internal logic of nested determined that since a was already a matrix, there was no point
|
||||
* in copying it into another matrix.
|
||||
* \param PlainObject the type of the temporary if needed.
|
||||
*/
|
||||
template<typename T, int n=1, typename PlainObject = typename eval<T>::type> struct nested
|
||||
template<typename T, int n, typename PlainObject = typename eval<T>::type> struct nested_eval
|
||||
{
|
||||
enum {
|
||||
// for the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values.
|
||||
// For the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values.
|
||||
// the choice of 10000 makes it larger than any practical fixed value and even most dynamic values.
|
||||
// in extreme cases where these assumptions would be wrong, we would still at worst suffer performance issues
|
||||
// (poor choice of temporaries).
|
||||
// it's important that this value can still be squared without integer overflowing.
|
||||
// It's important that this value can still be squared without integer overflowing.
|
||||
DynamicAsInteger = 10000,
|
||||
ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
|
||||
ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? int(DynamicAsInteger) : int(ScalarReadCost),
|
||||
CoeffReadCost = traits<T>::CoeffReadCost,
|
||||
CoeffReadCost = evaluator<T>::CoeffReadCost, // TODO What if an evaluator evaluate itself into a tempory?
|
||||
// Then CoeffReadCost will be small but we still have to evaluate if n>1...
|
||||
// The solution might be to ask the evaluator if it creates a temp. Perhaps we could even ask the number of temps?
|
||||
CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? int(DynamicAsInteger) : int(CoeffReadCost),
|
||||
NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n,
|
||||
CostEvalAsInteger = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger,
|
||||
@@ -333,17 +362,16 @@ template<typename T, int n=1, typename PlainObject = typename eval<T>::type> str
|
||||
};
|
||||
|
||||
typedef typename conditional<
|
||||
( (int(traits<T>::Flags) & EvalBeforeNestingBit) ||
|
||||
int(CostEvalAsInteger) < int(CostNoEvalAsInteger)
|
||||
),
|
||||
PlainObject,
|
||||
typename ref_selector<T>::type
|
||||
( (int(evaluator<T>::Flags) & EvalBeforeNestingBit) ||
|
||||
(int(CostEvalAsInteger) < int(CostNoEvalAsInteger)) ),
|
||||
PlainObject,
|
||||
typename ref_selector<T>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
T* const_cast_ptr(const T* ptr)
|
||||
inline T* const_cast_ptr(const T* ptr)
|
||||
{
|
||||
return const_cast<T*>(ptr);
|
||||
}
|
||||
@@ -366,6 +394,15 @@ struct dense_xpr_base<Derived, ArrayXpr>
|
||||
typedef ArrayBase<Derived> type;
|
||||
};
|
||||
|
||||
template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
|
||||
struct generic_xpr_base;
|
||||
|
||||
template<typename Derived, typename XprKind>
|
||||
struct generic_xpr_base<Derived, XprKind, Dense>
|
||||
{
|
||||
typedef typename dense_xpr_base<Derived,XprKind>::type type;
|
||||
};
|
||||
|
||||
/** \internal Helper base class to add a scalar multiple operator
|
||||
* overloads for complex types */
|
||||
template<typename Derived,typename Scalar,typename OtherScalar,
|
||||
@@ -424,6 +461,60 @@ template <typename A> struct promote_storage_type<const A, A>
|
||||
typedef A ret;
|
||||
};
|
||||
|
||||
/** \internal Specify the "storage kind" of applying a coefficient-wise
|
||||
* binary operations between two expressions of kinds A and B respectively.
|
||||
* The template parameter Functor permits to specialize the resulting storage kind wrt to
|
||||
* the functor.
|
||||
* The default rules are as follows:
|
||||
* \code
|
||||
* A op A -> A
|
||||
* A op dense -> dense
|
||||
* dense op B -> dense
|
||||
* A * dense -> A
|
||||
* dense * B -> B
|
||||
* \endcode
|
||||
*/
|
||||
template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
|
||||
|
||||
template <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; };
|
||||
template <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; };
|
||||
template <typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<Dense,Dense,scalar_product_op<ScalarA,ScalarB> > { typedef Dense ret; };
|
||||
template <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; };
|
||||
template <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; };
|
||||
template <typename A, typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<A,Dense,scalar_product_op<ScalarA,ScalarB> > { typedef A ret; };
|
||||
template <typename B, typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<Dense,B,scalar_product_op<ScalarA,ScalarB> > { typedef B ret; };
|
||||
|
||||
/** \internal Specify the "storage kind" of multiplying an expression of kind A with kind B.
|
||||
* The template parameter ProductTag permits to specialize the resulting storage kind wrt to
|
||||
* some compile-time properties of the product: GemmProduct, GemvProduct, OuterProduct, InnerProduct.
|
||||
* The default rules are as follows:
|
||||
* \code
|
||||
* K * K -> K
|
||||
* dense * K -> dense
|
||||
* K * dense -> dense
|
||||
* diag * K -> K
|
||||
* K * diag -> K
|
||||
* Perm * K -> K
|
||||
* K * Perm -> K
|
||||
* \endcode
|
||||
*/
|
||||
template <typename A, typename B, int ProductTag> struct product_promote_storage_type;
|
||||
|
||||
template <typename A, int ProductTag> struct product_promote_storage_type<A, A, ProductTag> { typedef A ret;};
|
||||
template <int ProductTag> struct product_promote_storage_type<Dense, Dense, ProductTag> { typedef Dense ret;};
|
||||
template <typename A, int ProductTag> struct product_promote_storage_type<A, Dense, ProductTag> { typedef Dense ret; };
|
||||
template <typename B, int ProductTag> struct product_promote_storage_type<Dense, B, ProductTag> { typedef Dense ret; };
|
||||
|
||||
template <typename A, int ProductTag> struct product_promote_storage_type<A, DiagonalShape, ProductTag> { typedef A ret; };
|
||||
template <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape, B, ProductTag> { typedef B ret; };
|
||||
template <int ProductTag> struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { typedef Dense ret; };
|
||||
template <int ProductTag> struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { typedef Dense ret; };
|
||||
|
||||
template <typename A, int ProductTag> struct product_promote_storage_type<A, PermutationStorage, ProductTag> { typedef A ret; };
|
||||
template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B, ProductTag> { typedef B ret; };
|
||||
template <int ProductTag> struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { typedef Dense ret; };
|
||||
template <int ProductTag> struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { typedef Dense ret; };
|
||||
|
||||
/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type.
|
||||
* \param Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType.
|
||||
*/
|
||||
@@ -480,8 +571,36 @@ struct is_lvalue
|
||||
bool(traits<ExpressionType>::Flags & LvalueBit) };
|
||||
};
|
||||
|
||||
template<typename T> struct is_diagonal
|
||||
{ enum { ret = false }; };
|
||||
|
||||
template<typename T> struct is_diagonal<DiagonalBase<T> >
|
||||
{ enum { ret = true }; };
|
||||
|
||||
template<typename T> struct is_diagonal<DiagonalWrapper<T> >
|
||||
{ enum { ret = true }; };
|
||||
|
||||
template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
|
||||
{ enum { ret = true }; };
|
||||
|
||||
template<typename S1, typename S2> struct glue_shapes;
|
||||
template<> struct glue_shapes<DenseShape,TriangularShape> { typedef TriangularShape type; };
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
// we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor
|
||||
// that would take two operands of different types. If there were such an example, then this check should be
|
||||
// moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as
|
||||
// currently they take only one typename Scalar template parameter.
|
||||
// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
|
||||
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
|
||||
// add together a float matrix and a double matrix.
|
||||
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
|
||||
EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \
|
||||
? int(internal::scalar_product_traits<LHS, RHS>::Defined) \
|
||||
: int(internal::is_same<LHS, RHS>::value)), \
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_XPRHELPER_H
|
||||
|
||||
Reference in New Issue
Block a user