Add preliminary PhysX 4.0 backend for PyBullet
Add inverse dynamics / mass matrix code from DeepMimic, thanks to Xue Bin (Jason) Peng Add example how to use stable PD control for humanoid with spherical joints (see humanoidMotionCapture.py) Fix related to TinyRenderer object transforms not updating when using collision filtering
This commit is contained in:
403
examples/ThirdPartyLibs/Eigen/src/Core/util/BlasUtil.h
Normal file
403
examples/ThirdPartyLibs/Eigen/src/Core/util/BlasUtil.h
Normal file
@@ -0,0 +1,403 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_BLASUTIL_H
|
||||
#define EIGEN_BLASUTIL_H
|
||||
|
||||
// This file contains many lightweight helper classes used to
|
||||
// implement and control fast level 2 and level 3 BLAS-like routines.
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// forward declarations
|
||||
template<typename LhsScalar, typename RhsScalar, typename Index, typename DataMapper, int mr, int nr, bool ConjugateLhs=false, bool ConjugateRhs=false>
|
||||
struct gebp_kernel;
|
||||
|
||||
template<typename Scalar, typename Index, typename DataMapper, int nr, int StorageOrder, bool Conjugate = false, bool PanelMode=false>
|
||||
struct gemm_pack_rhs;
|
||||
|
||||
template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, int StorageOrder, bool Conjugate = false, bool PanelMode = false>
|
||||
struct gemm_pack_lhs;
|
||||
|
||||
template<
|
||||
typename Index,
|
||||
typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
|
||||
typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs,
|
||||
int ResStorageOrder>
|
||||
struct general_matrix_matrix_product;
|
||||
|
||||
template<typename Index,
|
||||
typename LhsScalar, typename LhsMapper, int LhsStorageOrder, bool ConjugateLhs,
|
||||
typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version=Specialized>
|
||||
struct general_matrix_vector_product;
|
||||
|
||||
|
||||
template<bool Conjugate> struct conj_if;
|
||||
|
||||
template<> struct conj_if<true> {
|
||||
template<typename T>
|
||||
inline T operator()(const T& x) const { return numext::conj(x); }
|
||||
template<typename T>
|
||||
inline T pconj(const T& x) const { return internal::pconj(x); }
|
||||
};
|
||||
|
||||
template<> struct conj_if<false> {
|
||||
template<typename T>
|
||||
inline const T& operator()(const T& x) const { return x; }
|
||||
template<typename T>
|
||||
inline const T& pconj(const T& x) const { return x; }
|
||||
};
|
||||
|
||||
// Generic implementation for custom complex types.
|
||||
template<typename LhsScalar, typename RhsScalar, bool ConjLhs, bool ConjRhs>
|
||||
struct conj_helper
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar>::ReturnType Scalar;
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar pmadd(const LhsScalar& x, const RhsScalar& y, const Scalar& c) const
|
||||
{ return padd(c, pmul(x,y)); }
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar pmul(const LhsScalar& x, const RhsScalar& y) const
|
||||
{ return conj_if<ConjLhs>()(x) * conj_if<ConjRhs>()(y); }
|
||||
};
|
||||
|
||||
template<typename Scalar> struct conj_helper<Scalar,Scalar,false,false>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const { return internal::pmadd(x,y,c); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const { return internal::pmul(x,y); }
|
||||
};
|
||||
|
||||
template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, false,true>
|
||||
{
|
||||
typedef std::complex<RealScalar> Scalar;
|
||||
EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
|
||||
{ return c + pmul(x,y); }
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
|
||||
{ return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::imag(x)*numext::real(y) - numext::real(x)*numext::imag(y)); }
|
||||
};
|
||||
|
||||
template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,false>
|
||||
{
|
||||
typedef std::complex<RealScalar> Scalar;
|
||||
EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
|
||||
{ return c + pmul(x,y); }
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
|
||||
{ return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
|
||||
};
|
||||
|
||||
template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,true>
|
||||
{
|
||||
typedef std::complex<RealScalar> Scalar;
|
||||
EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
|
||||
{ return c + pmul(x,y); }
|
||||
|
||||
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
|
||||
{ return Scalar(numext::real(x)*numext::real(y) - numext::imag(x)*numext::imag(y), - numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
|
||||
};
|
||||
|
||||
template<typename RealScalar,bool Conj> struct conj_helper<std::complex<RealScalar>, RealScalar, Conj,false>
|
||||
{
|
||||
typedef std::complex<RealScalar> Scalar;
|
||||
EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const RealScalar& y, const Scalar& c) const
|
||||
{ return padd(c, pmul(x,y)); }
|
||||
EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const RealScalar& y) const
|
||||
{ return conj_if<Conj>()(x)*y; }
|
||||
};
|
||||
|
||||
template<typename RealScalar,bool Conj> struct conj_helper<RealScalar, std::complex<RealScalar>, false,Conj>
|
||||
{
|
||||
typedef std::complex<RealScalar> Scalar;
|
||||
EIGEN_STRONG_INLINE Scalar pmadd(const RealScalar& x, const Scalar& y, const Scalar& c) const
|
||||
{ return padd(c, pmul(x,y)); }
|
||||
EIGEN_STRONG_INLINE Scalar pmul(const RealScalar& x, const Scalar& y) const
|
||||
{ return x*conj_if<Conj>()(y); }
|
||||
};
|
||||
|
||||
template<typename From,typename To> struct get_factor {
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE To run(const From& x) { return To(x); }
|
||||
};
|
||||
|
||||
template<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::Real> {
|
||||
EIGEN_DEVICE_FUNC
|
||||
static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return numext::real(x); }
|
||||
};
|
||||
|
||||
|
||||
template<typename Scalar, typename Index>
|
||||
class BlasVectorMapper {
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasVectorMapper(Scalar *data) : m_data(data) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const {
|
||||
return m_data[i];
|
||||
}
|
||||
template <typename Packet, int AlignmentType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet load(Index i) const {
|
||||
return ploadt<Packet, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC bool aligned(Index i) const {
|
||||
return (UIntPtr(m_data+i)%sizeof(Packet))==0;
|
||||
}
|
||||
|
||||
protected:
|
||||
Scalar* m_data;
|
||||
};
|
||||
|
||||
template<typename Scalar, typename Index, int AlignmentType>
|
||||
class BlasLinearMapper {
|
||||
public:
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
typedef typename packet_traits<Scalar>::half HalfPacket;
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data) : m_data(data) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const {
|
||||
internal::prefetch(&operator()(i));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const {
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const {
|
||||
return ploadt<Packet, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const {
|
||||
return ploadt<HalfPacket, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const Packet &p) const {
|
||||
pstoret<Scalar, Packet, AlignmentType>(m_data + i, p);
|
||||
}
|
||||
|
||||
protected:
|
||||
Scalar *m_data;
|
||||
};
|
||||
|
||||
// Lightweight helper class to access matrix coefficients.
|
||||
template<typename Scalar, typename Index, int StorageOrder, int AlignmentType = Unaligned>
|
||||
class blas_data_mapper {
|
||||
public:
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
typedef typename packet_traits<Scalar>::half HalfPacket;
|
||||
|
||||
typedef BlasLinearMapper<Scalar, Index, AlignmentType> LinearMapper;
|
||||
typedef BlasVectorMapper<Scalar, Index> VectorMapper;
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType>
|
||||
getSubMapper(Index i, Index j) const {
|
||||
return blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType>(&operator()(i, j), m_stride);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
|
||||
return LinearMapper(&operator()(i, j));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE VectorMapper getVectorMapper(Index i, Index j) const {
|
||||
return VectorMapper(&operator()(i, j));
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
|
||||
return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const {
|
||||
return ploadt<Packet, AlignmentType>(&operator()(i, j));
|
||||
}
|
||||
|
||||
template <typename PacketT, int AlignmentT>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT load(Index i, Index j) const {
|
||||
return ploadt<PacketT, AlignmentT>(&operator()(i, j));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i, Index j) const {
|
||||
return ploadt<HalfPacket, AlignmentType>(&operator()(i, j));
|
||||
}
|
||||
|
||||
template<typename SubPacket>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const {
|
||||
pscatter<Scalar, SubPacket>(&operator()(i, j), p, m_stride);
|
||||
}
|
||||
|
||||
template<typename SubPacket>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubPacket gatherPacket(Index i, Index j) const {
|
||||
return pgather<Scalar, SubPacket>(&operator()(i, j), m_stride);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC const Index stride() const { return m_stride; }
|
||||
EIGEN_DEVICE_FUNC const Scalar* data() const { return m_data; }
|
||||
|
||||
EIGEN_DEVICE_FUNC Index firstAligned(Index size) const {
|
||||
if (UIntPtr(m_data)%sizeof(Scalar)) {
|
||||
return -1;
|
||||
}
|
||||
return internal::first_default_aligned(m_data, size);
|
||||
}
|
||||
|
||||
protected:
|
||||
Scalar* EIGEN_RESTRICT m_data;
|
||||
const Index m_stride;
|
||||
};
|
||||
|
||||
// lightweight helper class to access matrix coefficients (const version)
|
||||
template<typename Scalar, typename Index, int StorageOrder>
|
||||
class const_blas_data_mapper : public blas_data_mapper<const Scalar, Index, StorageOrder> {
|
||||
public:
|
||||
EIGEN_ALWAYS_INLINE const_blas_data_mapper(const Scalar *data, Index stride) : blas_data_mapper<const Scalar, Index, StorageOrder>(data, stride) {}
|
||||
|
||||
EIGEN_ALWAYS_INLINE const_blas_data_mapper<Scalar, Index, StorageOrder> getSubMapper(Index i, Index j) const {
|
||||
return const_blas_data_mapper<Scalar, Index, StorageOrder>(&(this->operator()(i, j)), this->m_stride);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* Helper class to analyze the factors of a Product expression.
|
||||
* In particular it allows to pop out operator-, scalar multiples,
|
||||
* and conjugate */
|
||||
template<typename XprType> struct blas_traits
|
||||
{
|
||||
typedef typename traits<XprType>::Scalar Scalar;
|
||||
typedef const XprType& ExtractType;
|
||||
typedef XprType _ExtractType;
|
||||
enum {
|
||||
IsComplex = NumTraits<Scalar>::IsComplex,
|
||||
IsTransposed = false,
|
||||
NeedToConjugate = false,
|
||||
HasUsableDirectAccess = ( (int(XprType::Flags)&DirectAccessBit)
|
||||
&& ( bool(XprType::IsVectorAtCompileTime)
|
||||
|| int(inner_stride_at_compile_time<XprType>::ret) == 1)
|
||||
) ? 1 : 0
|
||||
};
|
||||
typedef typename conditional<bool(HasUsableDirectAccess),
|
||||
ExtractType,
|
||||
typename _ExtractType::PlainObject
|
||||
>::type DirectLinearAccessType;
|
||||
static inline ExtractType extract(const XprType& x) { return x; }
|
||||
static inline const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
|
||||
};
|
||||
|
||||
// pop conjugate
|
||||
template<typename Scalar, typename NestedXpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
{
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
|
||||
enum {
|
||||
IsComplex = NumTraits<Scalar>::IsComplex,
|
||||
NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex
|
||||
};
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x) { return conj(Base::extractScalarFactor(x.nestedExpression())); }
|
||||
};
|
||||
|
||||
// pop scalar multiple
|
||||
template<typename Scalar, typename NestedXpr, typename Plain>
|
||||
struct blas_traits<CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain>, NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
{
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain>, NestedXpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.rhs()); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x)
|
||||
{ return x.lhs().functor().m_other * Base::extractScalarFactor(x.rhs()); }
|
||||
};
|
||||
template<typename Scalar, typename NestedXpr, typename Plain>
|
||||
struct blas_traits<CwiseBinaryOp<scalar_product_op<Scalar>, NestedXpr, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain> > >
|
||||
: blas_traits<NestedXpr>
|
||||
{
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseBinaryOp<scalar_product_op<Scalar>, NestedXpr, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain> > XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.lhs()); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x)
|
||||
{ return Base::extractScalarFactor(x.lhs()) * x.rhs().functor().m_other; }
|
||||
};
|
||||
template<typename Scalar, typename Plain1, typename Plain2>
|
||||
struct blas_traits<CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain1>,
|
||||
const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain2> > >
|
||||
: blas_traits<CwiseNullaryOp<scalar_constant_op<Scalar>,Plain1> >
|
||||
{};
|
||||
|
||||
// pop opposite
|
||||
template<typename Scalar, typename NestedXpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
{
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x)
|
||||
{ return - Base::extractScalarFactor(x.nestedExpression()); }
|
||||
};
|
||||
|
||||
// pop/push transpose
|
||||
template<typename NestedXpr>
|
||||
struct blas_traits<Transpose<NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
{
|
||||
typedef typename NestedXpr::Scalar Scalar;
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef Transpose<NestedXpr> XprType;
|
||||
typedef Transpose<const typename Base::_ExtractType> ExtractType; // const to get rid of a compile error; anyway blas traits are only used on the RHS
|
||||
typedef Transpose<const typename Base::_ExtractType> _ExtractType;
|
||||
typedef typename conditional<bool(Base::HasUsableDirectAccess),
|
||||
ExtractType,
|
||||
typename ExtractType::PlainObject
|
||||
>::type DirectLinearAccessType;
|
||||
enum {
|
||||
IsTransposed = Base::IsTransposed ? 0 : 1
|
||||
};
|
||||
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()); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct blas_traits<const T>
|
||||
: blas_traits<T>
|
||||
{};
|
||||
|
||||
template<typename T, bool HasUsableDirectAccess=blas_traits<T>::HasUsableDirectAccess>
|
||||
struct extract_data_selector {
|
||||
static const typename T::Scalar* run(const T& m)
|
||||
{
|
||||
return blas_traits<T>::extract(m).data();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct extract_data_selector<T,false> {
|
||||
static typename T::Scalar* run(const T&) { return 0; }
|
||||
};
|
||||
|
||||
template<typename T> const typename T::Scalar* extract_data(const T& m)
|
||||
{
|
||||
return extract_data_selector<T>::run(m);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_BLASUTIL_H
|
||||
551
examples/ThirdPartyLibs/Eigen/src/Core/util/Constants.h
Normal file
551
examples/ThirdPartyLibs/Eigen/src/Core/util/Constants.h
Normal file
@@ -0,0 +1,551 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_CONSTANTS_H
|
||||
#define EIGEN_CONSTANTS_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is
|
||||
* stored in some runtime variable.
|
||||
*
|
||||
* Changing the value of Dynamic breaks the ABI, as Dynamic is often used as a template parameter for Matrix.
|
||||
*/
|
||||
const int Dynamic = -1;
|
||||
|
||||
/** This value means that a signed quantity (e.g., a signed index) is not known at compile-time, and that instead its value
|
||||
* has to be specified at runtime.
|
||||
*/
|
||||
const int DynamicIndex = 0xffffff;
|
||||
|
||||
/** This value means that the increment to go from one value to another in a sequence is not constant for each step.
|
||||
*/
|
||||
const int UndefinedIncr = 0xfffffe;
|
||||
|
||||
/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>().
|
||||
* The value Infinity there means the L-infinity norm.
|
||||
*/
|
||||
const int Infinity = -1;
|
||||
|
||||
/** This value means that the cost to evaluate an expression coefficient is either very expensive or
|
||||
* cannot be known at compile time.
|
||||
*
|
||||
* This value has to be positive to (1) simplify cost computation, and (2) allow to distinguish between a very expensive and very very expensive expressions.
|
||||
* It thus must also be large enough to make sure unrolling won't happen and that sub expressions will be evaluated, but not too large to avoid overflow.
|
||||
*/
|
||||
const int HugeCost = 10000;
|
||||
|
||||
/** \defgroup flags Flags
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* These are the possible bits which can be OR'ed to constitute the flags of a matrix or
|
||||
* expression.
|
||||
*
|
||||
* It is important to note that these flags are a purely compile-time notion. They are a compile-time property of
|
||||
* an expression type, implemented as enum's. They are not stored in memory at runtime, and they do not incur any
|
||||
* runtime overhead.
|
||||
*
|
||||
* \sa MatrixBase::Flags
|
||||
*/
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* for a matrix, this means that the storage order is row-major.
|
||||
* If this bit is not set, the storage order is column-major.
|
||||
* For an expression, this determines the storage order of
|
||||
* the matrix created by evaluation of that expression.
|
||||
* \sa \blank \ref TopicStorageOrders */
|
||||
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 */
|
||||
EIGEN_DEPRECATED
|
||||
const unsigned int EvalBeforeAssigningBit = 0x4; // FIXME deprecated
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* Short version: means the expression might be vectorized
|
||||
*
|
||||
* Long version: means that the coefficients can be handled by packets
|
||||
* and start at a memory location whose alignment meets the requirements
|
||||
* of the present CPU architecture for optimized packet access. In the fixed-size
|
||||
* case, there is the additional condition that it be possible to access all the
|
||||
* coefficients by packets (this implies the requirement that the size be a multiple of 16 bytes,
|
||||
* and that any nontrivial strides don't break the alignment). In the dynamic-size case,
|
||||
* there is no such condition on the total size and strides, so it might not be possible to access
|
||||
* all coeffs by packets.
|
||||
*
|
||||
* \note This bit can be set regardless of whether vectorization is actually enabled.
|
||||
* To check for actual vectorizability, see \a ActualPacketAccessBit.
|
||||
*/
|
||||
const unsigned int PacketAccessBit = 0x8;
|
||||
|
||||
#ifdef EIGEN_VECTORIZE
|
||||
/** \ingroup flags
|
||||
*
|
||||
* If vectorization is enabled (EIGEN_VECTORIZE is defined) this constant
|
||||
* is set to the value \a PacketAccessBit.
|
||||
*
|
||||
* If vectorization is not enabled (EIGEN_VECTORIZE is not defined) this constant
|
||||
* is set to the value 0.
|
||||
*/
|
||||
const unsigned int ActualPacketAccessBit = PacketAccessBit;
|
||||
#else
|
||||
const unsigned int ActualPacketAccessBit = 0x0;
|
||||
#endif
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* Short version: means the expression can be seen as 1D vector.
|
||||
*
|
||||
* Long version: means that one can access the coefficients
|
||||
* of this expression by coeff(int), and coeffRef(int) in the case of a lvalue expression. These
|
||||
* index-based access methods are guaranteed
|
||||
* to not have to do any runtime computation of a (row, col)-pair from the index, so that it
|
||||
* is guaranteed that whenever it is available, index-based access is at least as fast as
|
||||
* (row,col)-based access. Expressions for which that isn't possible don't have the LinearAccessBit.
|
||||
*
|
||||
* If both PacketAccessBit and LinearAccessBit are set, then the
|
||||
* packets of this expression can be accessed by packet(int), and writePacket(int) in the case of a
|
||||
* lvalue expression.
|
||||
*
|
||||
* Typically, all vector expressions have the LinearAccessBit, but there is one exception:
|
||||
* Product expressions don't have it, because it would be troublesome for vectorization, even when the
|
||||
* Product is a vector expression. Thus, vector Product expressions allow index-based coefficient access but
|
||||
* not index-based packet access, so they don't have the LinearAccessBit.
|
||||
*/
|
||||
const unsigned int LinearAccessBit = 0x10;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* Means the expression has a coeffRef() method, i.e. is writable as its individual coefficients are directly addressable.
|
||||
* This rules out read-only expressions.
|
||||
*
|
||||
* Note that DirectAccessBit and LvalueBit are mutually orthogonal, as there are examples of expression having one but note
|
||||
* the other:
|
||||
* \li writable expressions that don't have a very simple memory layout as a strided array, have LvalueBit but not DirectAccessBit
|
||||
* \li Map-to-const expressions, for example Map<const Matrix>, have DirectAccessBit but not LvalueBit
|
||||
*
|
||||
* Expressions having LvalueBit also have their coeff() method returning a const reference instead of returning a new value.
|
||||
*/
|
||||
const unsigned int LvalueBit = 0x20;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* Means that the underlying array of coefficients can be directly accessed as a plain strided array. The memory layout
|
||||
* of the array of coefficients must be exactly the natural one suggested by rows(), cols(),
|
||||
* outerStride(), innerStride(), and the RowMajorBit. This rules out expressions such as Diagonal, whose coefficients,
|
||||
* though referencable, do not have such a regular memory layout.
|
||||
*
|
||||
* See the comment on LvalueBit for an explanation of how LvalueBit and DirectAccessBit are mutually orthogonal.
|
||||
*/
|
||||
const unsigned int DirectAccessBit = 0x40;
|
||||
|
||||
/** \deprecated \ingroup flags
|
||||
*
|
||||
* means the first coefficient packet is guaranteed to be aligned.
|
||||
* An expression cannot has the AlignedBit without the PacketAccessBit flag.
|
||||
* In other words, this means we are allow to perform an aligned packet access to the first element regardless
|
||||
* of the expression kind:
|
||||
* \code
|
||||
* expression.packet<Aligned>(0);
|
||||
* \endcode
|
||||
*/
|
||||
EIGEN_DEPRECATED 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 \blank \ref RowMajorBit, \ref TopicStorageOrders */
|
||||
const unsigned int NoPreferredStorageOrderBit = 0x200;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* Means that the underlying coefficients can be accessed through pointers to the sparse (un)compressed storage format,
|
||||
* that is, the expression provides:
|
||||
* \code
|
||||
inline const Scalar* valuePtr() const;
|
||||
inline const Index* innerIndexPtr() const;
|
||||
inline const Index* outerIndexPtr() const;
|
||||
inline const Index* innerNonZeroPtr() const;
|
||||
\endcode
|
||||
*/
|
||||
const unsigned int CompressedAccessBit = 0x400;
|
||||
|
||||
|
||||
// list of flags that are inherited by default
|
||||
const unsigned int HereditaryBits = RowMajorBit
|
||||
| EvalBeforeNestingBit;
|
||||
|
||||
/** \defgroup enums Enumerations
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* Various enumerations used in %Eigen. Many of these are used as template parameters.
|
||||
*/
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum containing possible values for the \c Mode or \c UpLo parameter of
|
||||
* MatrixBase::selfadjointView() and MatrixBase::triangularView(), and selfadjoint solvers. */
|
||||
enum UpLoType {
|
||||
/** View matrix as a lower triangular matrix. */
|
||||
Lower=0x1,
|
||||
/** View matrix as an upper triangular matrix. */
|
||||
Upper=0x2,
|
||||
/** %Matrix has ones on the diagonal; to be used in combination with #Lower or #Upper. */
|
||||
UnitDiag=0x4,
|
||||
/** %Matrix has zeros on the diagonal; to be used in combination with #Lower or #Upper. */
|
||||
ZeroDiag=0x8,
|
||||
/** View matrix as a lower triangular matrix with ones on the diagonal. */
|
||||
UnitLower=UnitDiag|Lower,
|
||||
/** View matrix as an upper triangular matrix with ones on the diagonal. */
|
||||
UnitUpper=UnitDiag|Upper,
|
||||
/** View matrix as a lower triangular matrix with zeros on the diagonal. */
|
||||
StrictlyLower=ZeroDiag|Lower,
|
||||
/** View matrix as an upper triangular matrix with zeros on the diagonal. */
|
||||
StrictlyUpper=ZeroDiag|Upper,
|
||||
/** Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint. */
|
||||
SelfAdjoint=0x10,
|
||||
/** Used to support symmetric, non-selfadjoint, complex matrices. */
|
||||
Symmetric=0x20
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for indicating whether a buffer is aligned or not. */
|
||||
enum AlignmentType {
|
||||
Unaligned=0, /**< Data pointer has no specific alignment. */
|
||||
Aligned8=8, /**< Data pointer is aligned on a 8 bytes boundary. */
|
||||
Aligned16=16, /**< Data pointer is aligned on a 16 bytes boundary. */
|
||||
Aligned32=32, /**< Data pointer is aligned on a 32 bytes boundary. */
|
||||
Aligned64=64, /**< Data pointer is aligned on a 64 bytes boundary. */
|
||||
Aligned128=128, /**< Data pointer is aligned on a 128 bytes boundary. */
|
||||
AlignedMask=255,
|
||||
Aligned=16, /**< \deprecated Synonym for Aligned16. */
|
||||
#if EIGEN_MAX_ALIGN_BYTES==128
|
||||
AlignedMax = Aligned128
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==64
|
||||
AlignedMax = Aligned64
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==32
|
||||
AlignedMax = Aligned32
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==16
|
||||
AlignedMax = Aligned16
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==8
|
||||
AlignedMax = Aligned8
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==0
|
||||
AlignedMax = Unaligned
|
||||
#else
|
||||
#error Invalid value for EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum used by DenseBase::corner() in Eigen2 compatibility mode. */
|
||||
// FIXME after the corner() API change, this was not needed anymore, except by AlignedBox
|
||||
// TODO: find out what to do with that. Adapt the AlignedBox API ?
|
||||
enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum containing possible values for the \p Direction parameter of
|
||||
* Reverse, PartialReduxExpr and VectorwiseOp. */
|
||||
enum DirectionType {
|
||||
/** For Reverse, all columns are reversed;
|
||||
* for PartialReduxExpr and VectorwiseOp, act on columns. */
|
||||
Vertical,
|
||||
/** For Reverse, all rows are reversed;
|
||||
* for PartialReduxExpr and VectorwiseOp, act on rows. */
|
||||
Horizontal,
|
||||
/** For Reverse, both rows and columns are reversed;
|
||||
* not used for PartialReduxExpr and VectorwiseOp. */
|
||||
BothDirections
|
||||
};
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum to specify how to traverse the entries of a matrix. */
|
||||
enum TraversalType {
|
||||
/** \internal Default traversal, no vectorization, no index-based access */
|
||||
DefaultTraversal,
|
||||
/** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */
|
||||
LinearTraversal,
|
||||
/** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment
|
||||
* and good size */
|
||||
InnerVectorizedTraversal,
|
||||
/** \internal Vectorization path using a single loop plus scalar loops for the
|
||||
* unaligned boundaries */
|
||||
LinearVectorizedTraversal,
|
||||
/** \internal Generic vectorization path using one vectorized loop per row/column with some
|
||||
* scalar loops to handle the unaligned boundaries */
|
||||
SliceVectorizedTraversal,
|
||||
/** \internal Special case to properly handle incompatible scalar types or other defecting cases*/
|
||||
InvalidTraversal,
|
||||
/** \internal Evaluate all entries at once */
|
||||
AllAtOnceTraversal
|
||||
};
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum to specify whether to unroll loops when traversing over the entries of a matrix. */
|
||||
enum UnrollingType {
|
||||
/** \internal Do not unroll loops. */
|
||||
NoUnrolling,
|
||||
/** \internal Unroll only the inner loop, but not the outer loop. */
|
||||
InnerUnrolling,
|
||||
/** \internal Unroll both the inner and the outer loop. If there is only one loop,
|
||||
* because linear traversal is used, then unroll that loop. */
|
||||
CompleteUnrolling
|
||||
};
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum to specify whether to use the default (built-in) implementation or the specialization. */
|
||||
enum SpecializedType {
|
||||
Specialized,
|
||||
BuiltIn
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum containing possible values for the \p _Options template parameter of
|
||||
* Matrix, Array and BandMatrix. */
|
||||
enum StorageOptions {
|
||||
/** Storage order is column major (see \ref TopicStorageOrders). */
|
||||
ColMajor = 0,
|
||||
/** Storage order is row major (see \ref TopicStorageOrders). */
|
||||
RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
|
||||
/** Align the matrix itself if it is vectorizable fixed-size */
|
||||
AutoAlign = 0,
|
||||
/** Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation
|
||||
DontAlign = 0x2
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for specifying whether to apply or solve on the left or right. */
|
||||
enum SideType {
|
||||
/** Apply transformation on the left. */
|
||||
OnTheLeft = 1,
|
||||
/** Apply transformation on the right. */
|
||||
OnTheRight = 2
|
||||
};
|
||||
|
||||
/* the following used to be written as:
|
||||
*
|
||||
* struct NoChange_t {};
|
||||
* namespace {
|
||||
* EIGEN_UNUSED NoChange_t NoChange;
|
||||
* }
|
||||
*
|
||||
* on the ground that it feels dangerous to disambiguate overloaded functions on enum/integer types.
|
||||
* However, this leads to "variable declared but never referenced" warnings on Intel Composer XE,
|
||||
* and we do not know how to get rid of them (bug 450).
|
||||
*/
|
||||
|
||||
enum NoChange_t { NoChange };
|
||||
enum Sequential_t { Sequential };
|
||||
enum Default_t { Default };
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Used in AmbiVector. */
|
||||
enum AmbiVectorMode {
|
||||
IsDense = 0,
|
||||
IsSparse
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Used as template parameter in DenseCoeffBase and MapBase to indicate
|
||||
* which accessors should be provided. */
|
||||
enum AccessorLevels {
|
||||
/** Read-only access via a member function. */
|
||||
ReadOnlyAccessors,
|
||||
/** Read/write access via member functions. */
|
||||
WriteAccessors,
|
||||
/** Direct read-only access to the coefficients. */
|
||||
DirectAccessors,
|
||||
/** Direct read/write access to the coefficients. */
|
||||
DirectWriteAccessors
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum with options to give to various decompositions. */
|
||||
enum DecompositionOptions {
|
||||
/** \internal Not used (meant for LDLT?). */
|
||||
Pivoting = 0x01,
|
||||
/** \internal Not used (meant for LDLT?). */
|
||||
NoPivoting = 0x02,
|
||||
/** Used in JacobiSVD to indicate that the square matrix U is to be computed. */
|
||||
ComputeFullU = 0x04,
|
||||
/** Used in JacobiSVD to indicate that the thin matrix U is to be computed. */
|
||||
ComputeThinU = 0x08,
|
||||
/** Used in JacobiSVD to indicate that the square matrix V is to be computed. */
|
||||
ComputeFullV = 0x10,
|
||||
/** Used in JacobiSVD to indicate that the thin matrix V is to be computed. */
|
||||
ComputeThinV = 0x20,
|
||||
/** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify
|
||||
* that only the eigenvalues are to be computed and not the eigenvectors. */
|
||||
EigenvaluesOnly = 0x40,
|
||||
/** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify
|
||||
* that both the eigenvalues and the eigenvectors are to be computed. */
|
||||
ComputeEigenvectors = 0x80,
|
||||
/** \internal */
|
||||
EigVecMask = EigenvaluesOnly | ComputeEigenvectors,
|
||||
/** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
|
||||
* solve the generalized eigenproblem \f$ Ax = \lambda B x \f$. */
|
||||
Ax_lBx = 0x100,
|
||||
/** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
|
||||
* solve the generalized eigenproblem \f$ ABx = \lambda x \f$. */
|
||||
ABx_lx = 0x200,
|
||||
/** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
|
||||
* solve the generalized eigenproblem \f$ BAx = \lambda x \f$. */
|
||||
BAx_lx = 0x400,
|
||||
/** \internal */
|
||||
GenEigMask = Ax_lBx | ABx_lx | BAx_lx
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Possible values for the \p QRPreconditioner template parameter of JacobiSVD. */
|
||||
enum QRPreconditioners {
|
||||
/** Do not specify what is to be done if the SVD of a non-square matrix is asked for. */
|
||||
NoQRPreconditioner,
|
||||
/** Use a QR decomposition without pivoting as the first step. */
|
||||
HouseholderQRPreconditioner,
|
||||
/** Use a QR decomposition with column pivoting as the first step. */
|
||||
ColPivHouseholderQRPreconditioner,
|
||||
/** Use a QR decomposition with full pivoting as the first step. */
|
||||
FullPivHouseholderQRPreconditioner
|
||||
};
|
||||
|
||||
#ifdef Success
|
||||
#error The preprocessor symbol 'Success' is defined, possibly by the X11 header file X.h
|
||||
#endif
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for reporting the status of a computation. */
|
||||
enum ComputationInfo {
|
||||
/** Computation was successful. */
|
||||
Success = 0,
|
||||
/** The provided data did not satisfy the prerequisites. */
|
||||
NumericalIssue = 1,
|
||||
/** Iterative procedure did not converge. */
|
||||
NoConvergence = 2,
|
||||
/** The inputs are invalid, or the algorithm has been improperly called.
|
||||
* When assertions are enabled, such errors trigger an assert. */
|
||||
InvalidInput = 3
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum used to specify how a particular transformation is stored in a matrix.
|
||||
* \sa Transform, Hyperplane::transform(). */
|
||||
enum TransformTraits {
|
||||
/** Transformation is an isometry. */
|
||||
Isometry = 0x1,
|
||||
/** Transformation is an affine transformation stored as a (Dim+1)^2 matrix whose last row is
|
||||
* assumed to be [0 ... 0 1]. */
|
||||
Affine = 0x2,
|
||||
/** Transformation is an affine transformation stored as a (Dim) x (Dim+1) matrix. */
|
||||
AffineCompact = 0x10 | Affine,
|
||||
/** Transformation is a general projective transformation stored as a (Dim+1)^2 matrix. */
|
||||
Projective = 0x20
|
||||
};
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum used to choose between implementation depending on the computer architecture. */
|
||||
namespace Architecture
|
||||
{
|
||||
enum Type {
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum used as template parameter in Product and product evaluators. */
|
||||
enum ProductImplType
|
||||
{ DefaultProduct=0, LazyProduct, AliasFreeProduct, CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum used in experimental parallel implementation. */
|
||||
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 general solver (factored) storage. */
|
||||
struct SolverStorage {};
|
||||
|
||||
/** The type used to identify a permutation storage. */
|
||||
struct PermutationStorage {};
|
||||
|
||||
/** The type used to identify a permutation storage. */
|
||||
struct TranspositionsStorage {};
|
||||
|
||||
/** 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 SolverShape { static std::string debugName() { return "SolverShape"; } };
|
||||
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 TranspositionsShape { static std::string debugName() { return "TranspositionsShape"; } };
|
||||
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 {};
|
||||
|
||||
/** \internal
|
||||
* Constants for comparison functors
|
||||
*/
|
||||
enum ComparisonName {
|
||||
cmp_EQ = 0,
|
||||
cmp_LT = 1,
|
||||
cmp_LE = 2,
|
||||
cmp_UNORD = 3,
|
||||
cmp_NEQ = 4,
|
||||
cmp_GT = 5,
|
||||
cmp_GE = 6
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_CONSTANTS_H
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef EIGEN_WARNINGS_DISABLED
|
||||
#define EIGEN_WARNINGS_DISABLED
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
|
||||
// 4101 - unreferenced local variable
|
||||
// 4181 - qualifier applied to reference type ignored
|
||||
// 4211 - nonstandard extension used : redefined extern to static
|
||||
// 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data
|
||||
// 4273 - QtAlignedMalloc, inconsistent DLL linkage
|
||||
// 4324 - structure was padded due to declspec(align())
|
||||
// 4503 - decorated name length exceeded, name was truncated
|
||||
// 4512 - assignment operator could not be generated
|
||||
// 4522 - 'class' : multiple assignment operators specified
|
||||
// 4700 - uninitialized local variable 'xyz' used
|
||||
// 4714 - function marked as __forceinline not inlined
|
||||
// 4717 - 'function' : recursive on all control paths, function will cause runtime stack overflow
|
||||
// 4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma warning( push )
|
||||
#endif
|
||||
#pragma warning( disable : 4100 4101 4181 4211 4244 4273 4324 4503 4512 4522 4700 4714 4717 4800)
|
||||
|
||||
#elif defined __INTEL_COMPILER
|
||||
// 2196 - routine is both "inline" and "noinline" ("noinline" assumed)
|
||||
// ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body
|
||||
// typedef that may be a reference type.
|
||||
// 279 - controlling expression is constant
|
||||
// ICC 12 generates this warning on assert(constant_expression_depending_on_template_params) and frankly this is a legitimate use case.
|
||||
// 1684 - conversion from pointer to same-sized integral type (potential portability problem)
|
||||
// 2259 - non-pointer conversion from "Eigen::Index={ptrdiff_t={long}}" to "int" may lose significant bits
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma warning push
|
||||
#endif
|
||||
#pragma warning disable 2196 279 1684 2259
|
||||
|
||||
#elif defined __clang__
|
||||
// -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant
|
||||
// this is really a stupid warning as it warns on compile-time expressions involving enums
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma clang diagnostic push
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
||||
#if __clang_major__ >= 3 && __clang_minor__ >= 5
|
||||
#pragma clang diagnostic ignored "-Wabsolute-value"
|
||||
#endif
|
||||
|
||||
#elif defined __GNUC__ && __GNUC__>=6
|
||||
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__
|
||||
#pragma diag_suppress boolean_controlling_expr_is_constant
|
||||
// Disable the "statement is unreachable" message
|
||||
#pragma diag_suppress code_is_unreachable
|
||||
// Disable the "dynamic initialization in unreachable code" message
|
||||
#pragma diag_suppress initialization_not_reachable
|
||||
// Disable the "invalid error number" message that we get with older versions of nvcc
|
||||
#pragma diag_suppress 1222
|
||||
// Disable the "calling a __host__ function from a __host__ __device__ function is not allowed" messages (yes, there are many of them and they seem to change with every version of the compiler)
|
||||
#pragma diag_suppress 2527
|
||||
#pragma diag_suppress 2529
|
||||
#pragma diag_suppress 2651
|
||||
#pragma diag_suppress 2653
|
||||
#pragma diag_suppress 2668
|
||||
#pragma diag_suppress 2669
|
||||
#pragma diag_suppress 2670
|
||||
#pragma diag_suppress 2671
|
||||
#pragma diag_suppress 2735
|
||||
#pragma diag_suppress 2737
|
||||
#pragma diag_suppress 2739
|
||||
#endif
|
||||
|
||||
#endif // not EIGEN_WARNINGS_DISABLED
|
||||
@@ -0,0 +1,303 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_FORWARDDECLARATIONS_H
|
||||
#define EIGEN_FORWARDDECLARATIONS_H
|
||||
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
template<typename T> struct traits;
|
||||
|
||||
// here we say once and for all that traits<const T> == traits<T>
|
||||
// When constness must affect traits, it has to be constness on template parameters on which T itself depends.
|
||||
// For example, traits<Map<const T> > != traits<Map<T> >, but
|
||||
// traits<const Map<T> > == traits<Map<T> >
|
||||
template<typename T> struct traits<const T> : traits<T> {};
|
||||
|
||||
template<typename Derived> struct has_direct_access
|
||||
{
|
||||
enum { ret = (traits<Derived>::Flags & DirectAccessBit) ? 1 : 0 };
|
||||
};
|
||||
|
||||
template<typename Derived> struct accessors_level
|
||||
{
|
||||
enum { has_direct_access = (traits<Derived>::Flags & DirectAccessBit) ? 1 : 0,
|
||||
has_write_access = (traits<Derived>::Flags & LvalueBit) ? 1 : 0,
|
||||
value = has_direct_access ? (has_write_access ? DirectWriteAccessors : DirectAccessors)
|
||||
: (has_write_access ? WriteAccessors : ReadOnlyAccessors)
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T> struct evaluator_traits;
|
||||
|
||||
template< typename T> struct evaluator;
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
template<typename T> struct NumTraits;
|
||||
|
||||
template<typename Derived> struct EigenBase;
|
||||
template<typename Derived> class DenseBase;
|
||||
template<typename Derived> class PlainObjectBase;
|
||||
|
||||
|
||||
template<typename Derived,
|
||||
int Level = internal::accessors_level<Derived>::value >
|
||||
class DenseCoeffsBase;
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols,
|
||||
int _Options = AutoAlign |
|
||||
#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.
|
||||
// The error would only show up with EIGEN_DEFAULT_TO_ROW_MAJOR is defined
|
||||
// (when EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION is RowMajor)
|
||||
( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
|
||||
: !(_Cols==1 && _Rows!=1) ? EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION
|
||||
: Eigen::ColMajor ),
|
||||
#else
|
||||
( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
|
||||
: (_Cols==1 && _Rows!=1) ? Eigen::ColMajor
|
||||
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
|
||||
#endif
|
||||
int _MaxRows = _Rows,
|
||||
int _MaxCols = _Cols
|
||||
> class Matrix;
|
||||
|
||||
template<typename Derived> class MatrixBase;
|
||||
template<typename Derived> class ArrayBase;
|
||||
|
||||
template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged;
|
||||
template<typename ExpressionType, template <typename> class StorageBase > class NoAlias;
|
||||
template<typename ExpressionType> class NestByValue;
|
||||
template<typename ExpressionType> class ForceAlignedAccess;
|
||||
template<typename ExpressionType> class SwapWrapper;
|
||||
|
||||
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false> class Block;
|
||||
template<typename XprType, typename RowIndices, typename ColIndices> class IndexedView;
|
||||
|
||||
template<typename MatrixType, int Size=Dynamic> class VectorBlock;
|
||||
template<typename MatrixType> class Transpose;
|
||||
template<typename MatrixType> class Conjugate;
|
||||
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 TernaryOp, typename Arg1, typename Arg2, typename Arg3> class CwiseTernaryOp;
|
||||
template<typename Decomposition, typename Rhstype> class Solve;
|
||||
template<typename XprType> class Inverse;
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option = DefaultProduct> class Product;
|
||||
|
||||
template<typename Derived> class DiagonalBase;
|
||||
template<typename _DiagonalVectorType> class DiagonalWrapper;
|
||||
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime=SizeAtCompileTime> class DiagonalMatrix;
|
||||
template<typename MatrixType, typename DiagonalType, int ProductOrder> class DiagonalProduct;
|
||||
template<typename MatrixType, int Index = 0> class Diagonal;
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime = SizeAtCompileTime, typename IndexType=int> class PermutationMatrix;
|
||||
template<int SizeAtCompileTime, int MaxSizeAtCompileTime = SizeAtCompileTime, typename IndexType=int> class Transpositions;
|
||||
template<typename Derived> class PermutationBase;
|
||||
template<typename Derived> class TranspositionsBase;
|
||||
template<typename _IndicesType> class PermutationWrapper;
|
||||
template<typename _IndicesType> class TranspositionsWrapper;
|
||||
|
||||
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;
|
||||
template<typename MatrixType, unsigned int Mode> class SelfAdjointView;
|
||||
template<typename MatrixType> class SparseView;
|
||||
template<typename ExpressionType> class WithFormat;
|
||||
template<typename MatrixType> struct CommaInitializer;
|
||||
template<typename Derived> class ReturnByValue;
|
||||
template<typename ExpressionType> class ArrayWrapper;
|
||||
template<typename ExpressionType> class MatrixWrapper;
|
||||
template<typename Derived> class SolverBase;
|
||||
template<typename XprType> class InnerIterator;
|
||||
|
||||
namespace internal {
|
||||
template<typename DecompositionType> struct kernel_retval_base;
|
||||
template<typename DecompositionType> struct kernel_retval;
|
||||
template<typename DecompositionType> struct image_retval_base;
|
||||
template<typename DecompositionType> struct image_retval;
|
||||
} // end namespace internal
|
||||
|
||||
namespace internal {
|
||||
template<typename _Scalar, int Rows=Dynamic, int Cols=Dynamic, int Supers=Dynamic, int Subs=Dynamic, int Options=0> class BandMatrix;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs> struct product_type;
|
||||
|
||||
template<bool> struct EnableIf;
|
||||
|
||||
/** \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,
|
||||
int ProductType = internal::product_type<Lhs,Rhs>::value>
|
||||
struct ProductReturnType;
|
||||
|
||||
// this is a workaround for sun CC
|
||||
template<typename Lhs, typename Rhs> struct LazyProductReturnType;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Provides scalar/packet-wise product and product with accumulation
|
||||
// with optional conjugation of the arguments.
|
||||
template<typename LhsScalar, typename RhsScalar, bool ConjLhs=false, bool ConjRhs=false> struct conj_helper;
|
||||
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_sum_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_difference_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_conj_product_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_min_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_max_op;
|
||||
template<typename Scalar> struct scalar_opposite_op;
|
||||
template<typename Scalar> struct scalar_conjugate_op;
|
||||
template<typename Scalar> struct scalar_real_op;
|
||||
template<typename Scalar> struct scalar_imag_op;
|
||||
template<typename Scalar> struct scalar_abs_op;
|
||||
template<typename Scalar> struct scalar_abs2_op;
|
||||
template<typename Scalar> struct scalar_sqrt_op;
|
||||
template<typename Scalar> struct scalar_rsqrt_op;
|
||||
template<typename Scalar> struct scalar_exp_op;
|
||||
template<typename Scalar> struct scalar_log_op;
|
||||
template<typename Scalar> struct scalar_cos_op;
|
||||
template<typename Scalar> struct scalar_sin_op;
|
||||
template<typename Scalar> struct scalar_acos_op;
|
||||
template<typename Scalar> struct scalar_asin_op;
|
||||
template<typename Scalar> struct scalar_tan_op;
|
||||
template<typename Scalar> struct scalar_inverse_op;
|
||||
template<typename Scalar> struct scalar_square_op;
|
||||
template<typename Scalar> struct scalar_cube_op;
|
||||
template<typename Scalar, typename NewType> struct scalar_cast_op;
|
||||
template<typename Scalar> struct scalar_random_op;
|
||||
template<typename Scalar> struct scalar_constant_op;
|
||||
template<typename Scalar> struct scalar_identity_op;
|
||||
template<typename Scalar,bool iscpx> struct scalar_sign_op;
|
||||
template<typename Scalar,typename ScalarExponent> struct scalar_pow_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_hypot_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_product_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_quotient_op;
|
||||
|
||||
// SpecialFunctions module
|
||||
template<typename Scalar> struct scalar_lgamma_op;
|
||||
template<typename Scalar> struct scalar_digamma_op;
|
||||
template<typename Scalar> struct scalar_erf_op;
|
||||
template<typename Scalar> struct scalar_erfc_op;
|
||||
template<typename Scalar> struct scalar_igamma_op;
|
||||
template<typename Scalar> struct scalar_igammac_op;
|
||||
template<typename Scalar> struct scalar_zeta_op;
|
||||
template<typename Scalar> struct scalar_betainc_op;
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
struct IOFormat;
|
||||
|
||||
// Array module
|
||||
template<typename _Scalar, int _Rows, int _Cols,
|
||||
int _Options = AutoAlign |
|
||||
#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.
|
||||
// The error would only show up with EIGEN_DEFAULT_TO_ROW_MAJOR is defined
|
||||
// (when EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION is RowMajor)
|
||||
( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
|
||||
: !(_Cols==1 && _Rows!=1) ? EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION
|
||||
: Eigen::ColMajor ),
|
||||
#else
|
||||
( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
|
||||
: (_Cols==1 && _Rows!=1) ? Eigen::ColMajor
|
||||
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
|
||||
#endif
|
||||
int _MaxRows = _Rows, int _MaxCols = _Cols> class Array;
|
||||
template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> class Select;
|
||||
template<typename MatrixType, typename BinaryOp, int Direction> class PartialReduxExpr;
|
||||
template<typename ExpressionType, int Direction> class VectorwiseOp;
|
||||
template<typename MatrixType,int RowFactor,int ColFactor> class Replicate;
|
||||
template<typename MatrixType, int Direction = BothDirections> class Reverse;
|
||||
|
||||
template<typename MatrixType> class FullPivLU;
|
||||
template<typename MatrixType> class PartialPivLU;
|
||||
namespace internal {
|
||||
template<typename MatrixType> struct inverse_impl;
|
||||
}
|
||||
template<typename MatrixType> class HouseholderQR;
|
||||
template<typename MatrixType> class ColPivHouseholderQR;
|
||||
template<typename MatrixType> class FullPivHouseholderQR;
|
||||
template<typename MatrixType> class CompleteOrthogonalDecomposition;
|
||||
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;
|
||||
template<typename Scalar> class JacobiRotation;
|
||||
|
||||
// Geometry module:
|
||||
template<typename Derived, int _Dim> class RotationBase;
|
||||
template<typename Lhs, typename Rhs> class Cross;
|
||||
template<typename Derived> class QuaternionBase;
|
||||
template<typename Scalar> class Rotation2D;
|
||||
template<typename Scalar> class AngleAxis;
|
||||
template<typename Scalar,int Dim> class Translation;
|
||||
template<typename Scalar,int Dim> class AlignedBox;
|
||||
template<typename Scalar, int Options = AutoAlign> class Quaternion;
|
||||
template<typename Scalar,int Dim,int Mode,int _Options=AutoAlign> class Transform;
|
||||
template <typename _Scalar, int _AmbientDim, int Options=AutoAlign> class ParametrizedLine;
|
||||
template <typename _Scalar, int _AmbientDim, int Options=AutoAlign> class Hyperplane;
|
||||
template<typename Scalar> class UniformScaling;
|
||||
template<typename MatrixType,int Direction> class Homogeneous;
|
||||
|
||||
// Sparse module:
|
||||
template<typename Derived> class SparseMatrixBase;
|
||||
|
||||
// MatrixFunctions module
|
||||
template<typename Derived> struct MatrixExponentialReturnValue;
|
||||
template<typename Derived> class MatrixFunctionReturnValue;
|
||||
template<typename Derived> class MatrixSquareRootReturnValue;
|
||||
template<typename Derived> class MatrixLogarithmReturnValue;
|
||||
template<typename Derived> class MatrixPowerReturnValue;
|
||||
template<typename Derived> class MatrixComplexPowerReturnValue;
|
||||
|
||||
namespace internal {
|
||||
template <typename Scalar>
|
||||
struct stem_function
|
||||
{
|
||||
typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
|
||||
typedef ComplexScalar type(ComplexScalar, int);
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_FORWARDDECLARATIONS_H
|
||||
187
examples/ThirdPartyLibs/Eigen/src/Core/util/IndexedViewHelper.h
Normal file
187
examples/ThirdPartyLibs/Eigen/src/Core/util/IndexedViewHelper.h
Normal file
@@ -0,0 +1,187 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
#ifndef EIGEN_INDEXED_VIEW_HELPER_H
|
||||
#define EIGEN_INDEXED_VIEW_HELPER_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \namespace Eigen::placeholders
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* Namespace containing symbolic placeholder and identifiers
|
||||
*/
|
||||
namespace placeholders {
|
||||
|
||||
namespace internal {
|
||||
struct symbolic_last_tag {};
|
||||
}
|
||||
|
||||
/** \var last
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last element/row/columns
|
||||
* of the underlying vector or matrix once passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
|
||||
*
|
||||
* This symbolic placeholder support standard arithmetic operation.
|
||||
*
|
||||
* A typical usage example would be:
|
||||
* \code
|
||||
* using namespace Eigen;
|
||||
* using Eigen::placeholders::last;
|
||||
* VectorXd v(n);
|
||||
* v(seq(2,last-2)).setOnes();
|
||||
* \endcode
|
||||
*
|
||||
* \sa end
|
||||
*/
|
||||
static const Symbolic::SymbolExpr<internal::symbolic_last_tag> last;
|
||||
|
||||
/** \var end
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* Can be used as a parameter to Eigen::seq and Eigen::seqN functions to symbolically reference the last+1 element/row/columns
|
||||
* of the underlying vector or matrix once passed to DenseBase::operator()(const RowIndices&, const ColIndices&).
|
||||
*
|
||||
* This symbolic placeholder support standard arithmetic operation.
|
||||
* It is essentially an alias to last+1
|
||||
*
|
||||
* \sa last
|
||||
*/
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
static const auto end = last+1;
|
||||
#else
|
||||
// Using a FixedExpr<1> expression is important here to make sure the compiler
|
||||
// can fully optimize the computation starting indices with zero overhead.
|
||||
static const Symbolic::AddExpr<Symbolic::SymbolExpr<internal::symbolic_last_tag>,Symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > end(last+fix<1>());
|
||||
#endif
|
||||
|
||||
} // end namespace placeholders
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Replace symbolic last/end "keywords" by their true runtime value
|
||||
inline Index eval_expr_given_size(Index x, Index /* size */) { return x; }
|
||||
|
||||
template<int N>
|
||||
FixedInt<N> eval_expr_given_size(FixedInt<N> x, Index /*size*/) { return x; }
|
||||
|
||||
template<typename Derived>
|
||||
Index eval_expr_given_size(const Symbolic::BaseExpr<Derived> &x, Index size)
|
||||
{
|
||||
return x.derived().eval(placeholders::last=size-1);
|
||||
}
|
||||
|
||||
// Extract increment/step at compile time
|
||||
template<typename T, typename EnableIf = void> struct get_compile_time_incr {
|
||||
enum { value = UndefinedIncr };
|
||||
};
|
||||
|
||||
// Analogue of std::get<0>(x), but tailored for our needs.
|
||||
template<typename T>
|
||||
Index first(const T& x) { return x.first(); }
|
||||
|
||||
// IndexedViewCompatibleType/makeIndexedViewCompatible turn an arbitrary object of type T into something usable by MatrixSlice
|
||||
// The generic implementation is a no-op
|
||||
template<typename T,int XprSize,typename EnableIf=void>
|
||||
struct IndexedViewCompatibleType {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T,typename Q>
|
||||
const T& makeIndexedViewCompatible(const T& x, Index /*size*/, Q) { return x; }
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Handling of a single Index
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
struct SingleRange {
|
||||
enum {
|
||||
SizeAtCompileTime = 1
|
||||
};
|
||||
SingleRange(Index val) : m_value(val) {}
|
||||
Index operator[](Index) const { return m_value; }
|
||||
Index size() const { return 1; }
|
||||
Index first() const { return m_value; }
|
||||
Index m_value;
|
||||
};
|
||||
|
||||
template<> struct get_compile_time_incr<SingleRange> {
|
||||
enum { value = 1 }; // 1 or 0 ??
|
||||
};
|
||||
|
||||
// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operatro[](int) methods)
|
||||
template<typename T, int XprSize>
|
||||
struct IndexedViewCompatibleType<T,XprSize,typename internal::enable_if<internal::is_integral<T>::value>::type> {
|
||||
// Here we could simply use Array, but maybe it's less work for the compiler to use
|
||||
// a simpler wrapper as SingleRange
|
||||
//typedef Eigen::Array<Index,1,1> type;
|
||||
typedef SingleRange type;
|
||||
};
|
||||
|
||||
template<typename T, int XprSize>
|
||||
struct IndexedViewCompatibleType<T, XprSize, typename enable_if<Symbolic::is_symbolic<T>::value>::type> {
|
||||
typedef SingleRange type;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
typename enable_if<Symbolic::is_symbolic<T>::value,SingleRange>::type
|
||||
makeIndexedViewCompatible(const T& id, Index size, SpecializedType) {
|
||||
return eval_expr_given_size(id,size);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Handling of all
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
struct all_t { all_t() {} };
|
||||
|
||||
// Convert a symbolic 'all' into a usable range type
|
||||
template<int XprSize>
|
||||
struct AllRange {
|
||||
enum { SizeAtCompileTime = XprSize };
|
||||
AllRange(Index size = XprSize) : m_size(size) {}
|
||||
Index operator[](Index i) const { return i; }
|
||||
Index size() const { return m_size.value(); }
|
||||
Index first() const { return 0; }
|
||||
variable_if_dynamic<Index,XprSize> m_size;
|
||||
};
|
||||
|
||||
template<int XprSize>
|
||||
struct IndexedViewCompatibleType<all_t,XprSize> {
|
||||
typedef AllRange<XprSize> type;
|
||||
};
|
||||
|
||||
template<typename XprSizeType>
|
||||
inline AllRange<get_fixed_value<XprSizeType>::value> makeIndexedViewCompatible(all_t , XprSizeType size, SpecializedType) {
|
||||
return AllRange<get_fixed_value<XprSizeType>::value>(size);
|
||||
}
|
||||
|
||||
template<int Size> struct get_compile_time_incr<AllRange<Size> > {
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
namespace placeholders {
|
||||
|
||||
/** \var all
|
||||
* \ingroup Core_Module
|
||||
* Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns
|
||||
*/
|
||||
static const Eigen::internal::all_t all;
|
||||
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_INDEXED_VIEW_HELPER_H
|
||||
270
examples/ThirdPartyLibs/Eigen/src/Core/util/IntegralConstant.h
Normal file
270
examples/ThirdPartyLibs/Eigen/src/Core/util/IntegralConstant.h
Normal file
@@ -0,0 +1,270 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
#ifndef EIGEN_INTEGRAL_CONSTANT_H
|
||||
#define EIGEN_INTEGRAL_CONSTANT_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<int N> class FixedInt;
|
||||
template<int N> class VariableAndFixedInt;
|
||||
|
||||
/** \internal
|
||||
* \class FixedInt
|
||||
*
|
||||
* This class embeds a compile-time integer \c N.
|
||||
*
|
||||
* It is similar to c++11 std::integral_constant<int,N> but with some additional features
|
||||
* such as:
|
||||
* - implicit conversion to int
|
||||
* - arithmetic and some bitwise operators: -, +, *, /, %, &, |
|
||||
* - c++98/14 compatibility with fix<N> and fix<N>() syntax to define integral constants.
|
||||
*
|
||||
* It is strongly discouraged to directly deal with this class FixedInt. Instances are expcected to
|
||||
* be created by the user using Eigen::fix<N> or Eigen::fix<N>(). In C++98-11, the former syntax does
|
||||
* not create a FixedInt<N> instance but rather a point to function that needs to be \em cleaned-up
|
||||
* using the generic helper:
|
||||
* \code
|
||||
* internal::cleanup_index_type<T>::type
|
||||
* internal::cleanup_index_type<T,DynamicKey>::type
|
||||
* \endcode
|
||||
* where T can a FixedInt<N>, a pointer to function FixedInt<N> (*)(), or numerous other integer-like representations.
|
||||
* \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
|
||||
*
|
||||
* For convenience, you can extract the compile-time value \c N in a generic way using the following helper:
|
||||
* \code
|
||||
* internal::get_fixed_value<T,DefaultVal>::value
|
||||
* \endcode
|
||||
* that will give you \c N if T equals FixedInt<N> or FixedInt<N> (*)(), and \c DefaultVal if T does not embed any compile-time value (e.g., T==int).
|
||||
*
|
||||
* \sa fix<N>, class VariableAndFixedInt
|
||||
*/
|
||||
template<int N> class FixedInt
|
||||
{
|
||||
public:
|
||||
static const int value = N;
|
||||
operator int() const { return value; }
|
||||
FixedInt() {}
|
||||
FixedInt( VariableAndFixedInt<N> other) {
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(other);
|
||||
eigen_internal_assert(int(other)==N);
|
||||
}
|
||||
|
||||
FixedInt<-N> operator-() const { return FixedInt<-N>(); }
|
||||
template<int M>
|
||||
FixedInt<N+M> operator+( FixedInt<M>) const { return FixedInt<N+M>(); }
|
||||
template<int M>
|
||||
FixedInt<N-M> operator-( FixedInt<M>) const { return FixedInt<N-M>(); }
|
||||
template<int M>
|
||||
FixedInt<N*M> operator*( FixedInt<M>) const { return FixedInt<N*M>(); }
|
||||
template<int M>
|
||||
FixedInt<N/M> operator/( FixedInt<M>) const { return FixedInt<N/M>(); }
|
||||
template<int M>
|
||||
FixedInt<N%M> operator%( FixedInt<M>) const { return FixedInt<N%M>(); }
|
||||
template<int M>
|
||||
FixedInt<N|M> operator|( FixedInt<M>) const { return FixedInt<N|M>(); }
|
||||
template<int M>
|
||||
FixedInt<N&M> operator&( FixedInt<M>) const { return FixedInt<N&M>(); }
|
||||
|
||||
#if EIGEN_HAS_CXX14
|
||||
// Needed in C++14 to allow fix<N>():
|
||||
FixedInt operator() () const { return *this; }
|
||||
|
||||
VariableAndFixedInt<N> operator() (int val) const { return VariableAndFixedInt<N>(val); }
|
||||
#else
|
||||
FixedInt ( FixedInt<N> (*)() ) {}
|
||||
#endif
|
||||
|
||||
#if EIGEN_HAS_CXX11
|
||||
FixedInt(std::integral_constant<int,N>) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \class VariableAndFixedInt
|
||||
*
|
||||
* This class embeds both a compile-time integer \c N and a runtime integer.
|
||||
* Both values are supposed to be equal unless the compile-time value \c N has a special
|
||||
* value meaning that the runtime-value should be used. Depending on the context, this special
|
||||
* value can be either Eigen::Dynamic (for positive quantities) or Eigen::DynamicIndex (for
|
||||
* quantities that can be negative).
|
||||
*
|
||||
* It is the return-type of the function Eigen::fix<N>(int), and most of the time this is the only
|
||||
* way it is used. It is strongly discouraged to directly deal with instances of VariableAndFixedInt.
|
||||
* Indeed, in order to write generic code, it is the responsibility of the callee to properly convert
|
||||
* it to either a true compile-time quantity (i.e. a FixedInt<N>), or to a runtime quantity (e.g., an Index)
|
||||
* using the following generic helper:
|
||||
* \code
|
||||
* internal::cleanup_index_type<T>::type
|
||||
* internal::cleanup_index_type<T,DynamicKey>::type
|
||||
* \endcode
|
||||
* where T can be a template instantiation of VariableAndFixedInt or numerous other integer-like representations.
|
||||
* \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
|
||||
*
|
||||
* For convenience, you can also extract the compile-time value \c N using the following helper:
|
||||
* \code
|
||||
* internal::get_fixed_value<T,DefaultVal>::value
|
||||
* \endcode
|
||||
* that will give you \c N if T equals VariableAndFixedInt<N>, and \c DefaultVal if T does not embed any compile-time value (e.g., T==int).
|
||||
*
|
||||
* \sa fix<N>(int), class FixedInt
|
||||
*/
|
||||
template<int N> class VariableAndFixedInt
|
||||
{
|
||||
public:
|
||||
static const int value = N;
|
||||
operator int() const { return m_value; }
|
||||
VariableAndFixedInt(int val) { m_value = val; }
|
||||
protected:
|
||||
int m_value;
|
||||
};
|
||||
|
||||
template<typename T, int Default=Dynamic> struct get_fixed_value {
|
||||
static const int value = Default;
|
||||
};
|
||||
|
||||
template<int N,int Default> struct get_fixed_value<FixedInt<N>,Default> {
|
||||
static const int value = N;
|
||||
};
|
||||
|
||||
#if !EIGEN_HAS_CXX14
|
||||
template<int N,int Default> struct get_fixed_value<FixedInt<N> (*)(),Default> {
|
||||
static const int value = N;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<int N,int Default> struct get_fixed_value<VariableAndFixedInt<N>,Default> {
|
||||
static const int value = N ;
|
||||
};
|
||||
|
||||
template<typename T, int N, int Default>
|
||||
struct get_fixed_value<variable_if_dynamic<T,N>,Default> {
|
||||
static const int value = N;
|
||||
};
|
||||
|
||||
template<typename T> EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) { return x; }
|
||||
#if !EIGEN_HAS_CXX14
|
||||
template<int N> EIGEN_DEVICE_FUNC Index get_runtime_value(FixedInt<N> (*)()) { return N; }
|
||||
#endif
|
||||
|
||||
// Cleanup integer/FixedInt/VariableAndFixedInt/etc types:
|
||||
|
||||
// By default, no cleanup:
|
||||
template<typename T, int DynamicKey=Dynamic, typename EnableIf=void> struct cleanup_index_type { typedef T type; };
|
||||
|
||||
// Convert any integral type (e.g., short, int, unsigned int, etc.) to Eigen::Index
|
||||
template<typename T, int DynamicKey> struct cleanup_index_type<T,DynamicKey,typename internal::enable_if<internal::is_integral<T>::value>::type> { typedef Index type; };
|
||||
|
||||
#if !EIGEN_HAS_CXX14
|
||||
// In c++98/c++11, fix<N> is a pointer to function that we better cleanup to a true FixedInt<N>:
|
||||
template<int N, int DynamicKey> struct cleanup_index_type<FixedInt<N> (*)(), DynamicKey> { typedef FixedInt<N> type; };
|
||||
#endif
|
||||
|
||||
// If VariableAndFixedInt does not match DynamicKey, then we turn it to a pure compile-time value:
|
||||
template<int N, int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<N>, DynamicKey> { typedef FixedInt<N> type; };
|
||||
// If VariableAndFixedInt matches DynamicKey, then we turn it to a pure runtime-value (aka Index):
|
||||
template<int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<DynamicKey>, DynamicKey> { typedef Index type; };
|
||||
|
||||
#if EIGEN_HAS_CXX11
|
||||
template<int N, int DynamicKey> struct cleanup_index_type<std::integral_constant<int,N>, DynamicKey> { typedef FixedInt<N> type; };
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
#if EIGEN_HAS_CXX14
|
||||
template<int N>
|
||||
static const internal::FixedInt<N> fix{};
|
||||
#else
|
||||
template<int N>
|
||||
inline internal::FixedInt<N> fix() { return internal::FixedInt<N>(); }
|
||||
|
||||
// The generic typename T is mandatory. Otherwise, a code like fix<N> could refer to either the function above or this next overload.
|
||||
// This way a code like fix<N> can only refer to the previous function.
|
||||
template<int N,typename T>
|
||||
inline internal::VariableAndFixedInt<N> fix(T val) { return internal::VariableAndFixedInt<N>(val); }
|
||||
#endif
|
||||
|
||||
#else // EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
/** \var fix<N>()
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* This \em identifier permits to construct an object embedding a compile-time integer \c N.
|
||||
*
|
||||
* \tparam N the compile-time integer value
|
||||
*
|
||||
* It is typically used in conjunction with the Eigen::seq and Eigen::seqN functions to pass compile-time values to them:
|
||||
* \code
|
||||
* seqN(10,fix<4>,fix<-3>) // <=> [10 7 4 1]
|
||||
* \endcode
|
||||
*
|
||||
* See also the function fix(int) to pass both a compile-time and runtime value.
|
||||
*
|
||||
* In c++14, it is implemented as:
|
||||
* \code
|
||||
* template<int N> static const internal::FixedInt<N> fix{};
|
||||
* \endcode
|
||||
* where internal::FixedInt<N> is an internal template class similar to
|
||||
* <a href="http://en.cppreference.com/w/cpp/types/integral_constant">\c std::integral_constant </a><tt> <int,N> </tt>
|
||||
* Here, \c fix<N> is thus an object of type \c internal::FixedInt<N>.
|
||||
*
|
||||
* In c++98/11, it is implemented as a function:
|
||||
* \code
|
||||
* template<int N> inline internal::FixedInt<N> fix();
|
||||
* \endcode
|
||||
* Here internal::FixedInt<N> is thus a pointer to function.
|
||||
*
|
||||
* If for some reason you want a true object in c++98 then you can write: \code fix<N>() \endcode which is also valid in c++14.
|
||||
*
|
||||
* \sa fix<N>(int), seq, seqN
|
||||
*/
|
||||
template<int N>
|
||||
static const auto fix();
|
||||
|
||||
/** \fn fix<N>(int)
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* This function returns an object embedding both a compile-time integer \c N, and a fallback runtime value \a val.
|
||||
*
|
||||
* \tparam N the compile-time integer value
|
||||
* \param val the fallback runtime integer value
|
||||
*
|
||||
* This function is a more general version of the \ref fix identifier/function that can be used in template code
|
||||
* where the compile-time value could turn out to actually mean "undefined at compile-time". For positive integers
|
||||
* such as a size or a dimension, this case is identified by Eigen::Dynamic, whereas runtime signed integers
|
||||
* (e.g., an increment/stride) are identified as Eigen::DynamicIndex. In such a case, the runtime value \a val
|
||||
* will be used as a fallback.
|
||||
*
|
||||
* A typical use case would be:
|
||||
* \code
|
||||
* template<typename Derived> void foo(const MatrixBase<Derived> &mat) {
|
||||
* const int N = Derived::RowsAtCompileTime==Dynamic ? Dynamic : Derived::RowsAtCompileTime/2;
|
||||
* const int n = mat.rows()/2;
|
||||
* ... mat( seqN(0,fix<N>(n) ) ...;
|
||||
* }
|
||||
* \endcode
|
||||
* In this example, the function Eigen::seqN knows that the second argument is expected to be a size.
|
||||
* If the passed compile-time value N equals Eigen::Dynamic, then the proxy object returned by fix will be dissmissed, and converted to an Eigen::Index of value \c n.
|
||||
* Otherwise, the runtime-value \c n will be dissmissed, and the returned ArithmeticSequence will be of the exact same type as <tt> seqN(0,fix<N>) </tt>.
|
||||
*
|
||||
* \sa fix, seqN, class ArithmeticSequence
|
||||
*/
|
||||
template<int N>
|
||||
static const auto fix(int val);
|
||||
|
||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_INTEGRAL_CONSTANT_H
|
||||
130
examples/ThirdPartyLibs/Eigen/src/Core/util/MKL_support.h
Normal file
130
examples/ThirdPartyLibs/Eigen/src/Core/util/MKL_support.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (c) 2011, Intel Corporation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of Intel Corporation nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
********************************************************************************
|
||||
* Content : Eigen bindings to Intel(R) MKL
|
||||
* Include file with common MKL declarations
|
||||
********************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef EIGEN_MKL_SUPPORT_H
|
||||
#define EIGEN_MKL_SUPPORT_H
|
||||
|
||||
#ifdef EIGEN_USE_MKL_ALL
|
||||
#ifndef EIGEN_USE_BLAS
|
||||
#define EIGEN_USE_BLAS
|
||||
#endif
|
||||
#ifndef EIGEN_USE_LAPACKE
|
||||
#define EIGEN_USE_LAPACKE
|
||||
#endif
|
||||
#ifndef EIGEN_USE_MKL_VML
|
||||
#define EIGEN_USE_MKL_VML
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_USE_LAPACKE_STRICT
|
||||
#define EIGEN_USE_LAPACKE
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_USE_MKL_VML) && !defined(EIGEN_USE_MKL)
|
||||
#define EIGEN_USE_MKL
|
||||
#endif
|
||||
|
||||
|
||||
#if defined EIGEN_USE_MKL
|
||||
# include <mkl.h>
|
||||
/*Check IMKL version for compatibility: < 10.3 is not usable with Eigen*/
|
||||
# ifndef INTEL_MKL_VERSION
|
||||
# undef EIGEN_USE_MKL /* INTEL_MKL_VERSION is not even defined on older versions */
|
||||
# elif INTEL_MKL_VERSION < 100305 /* the intel-mkl-103-release-notes say this was when the lapacke.h interface was added*/
|
||||
# undef EIGEN_USE_MKL
|
||||
# endif
|
||||
# ifndef EIGEN_USE_MKL
|
||||
/*If the MKL version is too old, undef everything*/
|
||||
# undef EIGEN_USE_MKL_ALL
|
||||
# undef EIGEN_USE_LAPACKE
|
||||
# undef EIGEN_USE_MKL_VML
|
||||
# undef EIGEN_USE_LAPACKE_STRICT
|
||||
# undef EIGEN_USE_LAPACKE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined EIGEN_USE_MKL
|
||||
|
||||
#define EIGEN_MKL_VML_THRESHOLD 128
|
||||
|
||||
/* MKL_DOMAIN_BLAS, etc are defined only in 10.3 update 7 */
|
||||
/* MKL_BLAS, etc are not defined in 11.2 */
|
||||
#ifdef MKL_DOMAIN_ALL
|
||||
#define EIGEN_MKL_DOMAIN_ALL MKL_DOMAIN_ALL
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_ALL MKL_ALL
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_BLAS
|
||||
#define EIGEN_MKL_DOMAIN_BLAS MKL_DOMAIN_BLAS
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_BLAS MKL_BLAS
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_FFT
|
||||
#define EIGEN_MKL_DOMAIN_FFT MKL_DOMAIN_FFT
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_FFT MKL_FFT
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_VML
|
||||
#define EIGEN_MKL_DOMAIN_VML MKL_DOMAIN_VML
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_VML MKL_VML
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_PARDISO
|
||||
#define EIGEN_MKL_DOMAIN_PARDISO MKL_DOMAIN_PARDISO
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_PARDISO MKL_PARDISO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_USE_BLAS) && !defined(EIGEN_USE_MKL)
|
||||
#include "../../misc/blas.h"
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
typedef std::complex<double> dcomplex;
|
||||
typedef std::complex<float> scomplex;
|
||||
|
||||
#if defined(EIGEN_USE_MKL)
|
||||
typedef MKL_INT BlasIndex;
|
||||
#else
|
||||
typedef int BlasIndex;
|
||||
#endif
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
#endif // EIGEN_MKL_SUPPORT_H
|
||||
1029
examples/ThirdPartyLibs/Eigen/src/Core/util/Macros.h
Normal file
1029
examples/ThirdPartyLibs/Eigen/src/Core/util/Macros.h
Normal file
File diff suppressed because it is too large
Load Diff
985
examples/ThirdPartyLibs/Eigen/src/Core/util/Memory.h
Normal file
985
examples/ThirdPartyLibs/Eigen/src/Core/util/Memory.h
Normal file
@@ -0,0 +1,985 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2015 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>
|
||||
// Copyright (C) 2010 Thomas Capricelli <orzel@freehackers.org>
|
||||
// Copyright (C) 2013 Pavel Holoborodko <pavel@holoborodko.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*** Platform checks for aligned malloc functions ***
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef EIGEN_MEMORY_H
|
||||
#define EIGEN_MEMORY_H
|
||||
|
||||
#ifndef EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
|
||||
// Try to determine automatically if malloc is already aligned.
|
||||
|
||||
// On 64-bit systems, glibc's malloc returns 16-byte-aligned pointers, see:
|
||||
// http://www.gnu.org/s/libc/manual/html_node/Aligned-Memory-Blocks.html
|
||||
// This is true at least since glibc 2.8.
|
||||
// This leaves the question how to detect 64-bit. According to this document,
|
||||
// http://gcc.fyxm.net/summit/2003/Porting%20to%2064%20bit.pdf
|
||||
// page 114, "[The] LP64 model [...] is used by all 64-bit UNIX ports" so it's indeed
|
||||
// quite safe, at least within the context of glibc, to equate 64-bit with LP64.
|
||||
#if defined(__GLIBC__) && ((__GLIBC__>=2 && __GLIBC_MINOR__ >= 8) || __GLIBC__>2) \
|
||||
&& defined(__LP64__) && ! defined( __SANITIZE_ADDRESS__ ) && (EIGEN_DEFAULT_ALIGN_BYTES == 16)
|
||||
#define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 1
|
||||
#else
|
||||
#define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 0
|
||||
#endif
|
||||
|
||||
// FreeBSD 6 seems to have 16-byte aligned malloc
|
||||
// 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__) && !(EIGEN_ARCH_ARM || EIGEN_ARCH_MIPS) && (EIGEN_DEFAULT_ALIGN_BYTES == 16)
|
||||
#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1
|
||||
#else
|
||||
#define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 0
|
||||
#endif
|
||||
|
||||
#if (EIGEN_OS_MAC && (EIGEN_DEFAULT_ALIGN_BYTES == 16)) \
|
||||
|| (EIGEN_OS_WIN64 && (EIGEN_DEFAULT_ALIGN_BYTES == 16)) \
|
||||
|| EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED \
|
||||
|| EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED
|
||||
#define EIGEN_MALLOC_ALREADY_ALIGNED 1
|
||||
#else
|
||||
#define EIGEN_MALLOC_ALREADY_ALIGNED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline void throw_std_bad_alloc()
|
||||
{
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
throw std::bad_alloc();
|
||||
#else
|
||||
std::size_t huge = static_cast<std::size_t>(-1);
|
||||
new int[huge];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of handmade aligned functions ***
|
||||
*****************************************************************************/
|
||||
|
||||
/* ----- Hand made implementations of aligned malloc/free and realloc ----- */
|
||||
|
||||
/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned.
|
||||
* Fast, but wastes 16 additional bytes of memory. Does not throw any exception.
|
||||
*/
|
||||
inline void* handmade_aligned_malloc(std::size_t size)
|
||||
{
|
||||
void *original = std::malloc(size+EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
if (original == 0) return 0;
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1))) + EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
*(reinterpret_cast<void**>(aligned) - 1) = original;
|
||||
return aligned;
|
||||
}
|
||||
|
||||
/** \internal Frees memory allocated with handmade_aligned_malloc */
|
||||
inline void handmade_aligned_free(void *ptr)
|
||||
{
|
||||
if (ptr) std::free(*(reinterpret_cast<void**>(ptr) - 1));
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Reallocates aligned memory.
|
||||
* Since we know that our handmade version is based on std::malloc
|
||||
* we can use std::realloc to implement efficient reallocation.
|
||||
*/
|
||||
inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0)
|
||||
{
|
||||
if (ptr == 0) return handmade_aligned_malloc(size);
|
||||
void *original = *(reinterpret_cast<void**>(ptr) - 1);
|
||||
std::ptrdiff_t previous_offset = static_cast<char *>(ptr)-static_cast<char *>(original);
|
||||
original = std::realloc(original,size+EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
if (original == 0) return 0;
|
||||
void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1))) + EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
void *previous_aligned = static_cast<char *>(original)+previous_offset;
|
||||
if(aligned!=previous_aligned)
|
||||
std::memmove(aligned, previous_aligned, size);
|
||||
|
||||
*(reinterpret_cast<void**>(aligned) - 1) = original;
|
||||
return aligned;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of portable aligned versions of malloc/free/realloc ***
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef EIGEN_NO_MALLOC
|
||||
EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
|
||||
{
|
||||
eigen_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
|
||||
}
|
||||
#elif defined EIGEN_RUNTIME_NO_MALLOC
|
||||
EIGEN_DEVICE_FUNC inline bool is_malloc_allowed_impl(bool update, bool new_value = false)
|
||||
{
|
||||
static bool value = true;
|
||||
if (update == 1)
|
||||
value = new_value;
|
||||
return value;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC inline bool is_malloc_allowed() { return is_malloc_allowed_impl(false); }
|
||||
EIGEN_DEVICE_FUNC inline bool set_is_malloc_allowed(bool new_value) { return is_malloc_allowed_impl(true, new_value); }
|
||||
EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
|
||||
{
|
||||
eigen_assert(is_malloc_allowed() && "heap allocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and g_is_malloc_allowed is false)");
|
||||
}
|
||||
#else
|
||||
EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
|
||||
{}
|
||||
#endif
|
||||
|
||||
/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 or 32 bytes alignment depending on the requirements.
|
||||
* On allocation error, the returned pointer is null, and std::bad_alloc is thrown.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC inline void* aligned_malloc(std::size_t size)
|
||||
{
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
void *result;
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::malloc(size);
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==16
|
||||
eigen_assert((size<16 || (std::size_t(result)%16)==0) && "System's malloc returned an unaligned pointer. Compile with EIGEN_MALLOC_ALREADY_ALIGNED=0 to fallback to handmade alignd memory allocator.");
|
||||
#endif
|
||||
#else
|
||||
result = handmade_aligned_malloc(size);
|
||||
#endif
|
||||
|
||||
if(!result && size)
|
||||
throw_std_bad_alloc();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \internal Frees memory allocated with aligned_malloc. */
|
||||
EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
|
||||
{
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
std::free(ptr);
|
||||
#else
|
||||
handmade_aligned_free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \brief Reallocates an aligned block of memory.
|
||||
* \throws std::bad_alloc on allocation failure
|
||||
*/
|
||||
inline void* aligned_realloc(void *ptr, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(old_size);
|
||||
|
||||
void *result;
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::realloc(ptr,new_size);
|
||||
#else
|
||||
result = handmade_aligned_realloc(ptr,new_size,old_size);
|
||||
#endif
|
||||
|
||||
if (!result && new_size)
|
||||
throw_std_bad_alloc();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of conditionally aligned functions ***
|
||||
*****************************************************************************/
|
||||
|
||||
/** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
|
||||
* On allocation error, the returned pointer is null, and a std::bad_alloc is thrown.
|
||||
*/
|
||||
template<bool Align> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(std::size_t size)
|
||||
{
|
||||
return aligned_malloc(size);
|
||||
}
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc<false>(std::size_t size)
|
||||
{
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
void *result = std::malloc(size);
|
||||
if(!result && size)
|
||||
throw_std_bad_alloc();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \internal Frees memory allocated with conditional_aligned_malloc */
|
||||
template<bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_free(void *ptr)
|
||||
{
|
||||
aligned_free(ptr);
|
||||
}
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline void conditional_aligned_free<false>(void *ptr)
|
||||
{
|
||||
std::free(ptr);
|
||||
}
|
||||
|
||||
template<bool Align> inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
return aligned_realloc(ptr, new_size, old_size);
|
||||
}
|
||||
|
||||
template<> inline void* conditional_aligned_realloc<false>(void* ptr, std::size_t new_size, std::size_t)
|
||||
{
|
||||
return std::realloc(ptr, new_size);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Construction/destruction of array elements ***
|
||||
*****************************************************************************/
|
||||
|
||||
/** \internal Destructs the elements of an array.
|
||||
* The \a size parameters tells on how many objects to call the destructor of T.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T *ptr, std::size_t size)
|
||||
{
|
||||
// always destruct an array starting from the end.
|
||||
if(ptr)
|
||||
while(size) ptr[--size].~T();
|
||||
}
|
||||
|
||||
/** \internal Constructs the elements of an array.
|
||||
* The \a size parameter tells on how many objects to call the constructor of T.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *ptr, std::size_t size)
|
||||
{
|
||||
std::size_t i;
|
||||
EIGEN_TRY
|
||||
{
|
||||
for (i = 0; i < size; ++i) ::new (ptr + i) T;
|
||||
return ptr;
|
||||
}
|
||||
EIGEN_CATCH(...)
|
||||
{
|
||||
destruct_elements_of_array(ptr, i);
|
||||
EIGEN_THROW;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of aligned new/delete-like functions ***
|
||||
*****************************************************************************/
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(std::size_t size)
|
||||
{
|
||||
if(size > std::size_t(-1) / sizeof(T))
|
||||
throw_std_bad_alloc();
|
||||
}
|
||||
|
||||
/** \internal Allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.
|
||||
* On allocation error, the returned pointer is undefined, but a std::bad_alloc is thrown.
|
||||
* The default constructor of T is called.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline T* aligned_new(std::size_t size)
|
||||
{
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
|
||||
EIGEN_TRY
|
||||
{
|
||||
return construct_elements_of_array(result, size);
|
||||
}
|
||||
EIGEN_CATCH(...)
|
||||
{
|
||||
aligned_free(result);
|
||||
EIGEN_THROW;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new(std::size_t size)
|
||||
{
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||
EIGEN_TRY
|
||||
{
|
||||
return construct_elements_of_array(result, size);
|
||||
}
|
||||
EIGEN_CATCH(...)
|
||||
{
|
||||
conditional_aligned_free<Align>(result);
|
||||
EIGEN_THROW;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \internal Deletes objects constructed with aligned_new
|
||||
* The \a size parameters tells on how many objects to call the destructor of T.
|
||||
*/
|
||||
template<typename T> EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, std::size_t size)
|
||||
{
|
||||
destruct_elements_of_array<T>(ptr, size);
|
||||
aligned_free(ptr);
|
||||
}
|
||||
|
||||
/** \internal Deletes objects constructed with conditional_aligned_new
|
||||
* The \a size parameters tells on how many objects to call the destructor of T.
|
||||
*/
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete(T *ptr, std::size_t size)
|
||||
{
|
||||
destruct_elements_of_array<T>(ptr, size);
|
||||
conditional_aligned_free<Align>(ptr);
|
||||
}
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_realloc_new(T* pts, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
check_size_for_overflow<T>(new_size);
|
||||
check_size_for_overflow<T>(old_size);
|
||||
if(new_size < old_size)
|
||||
destruct_elements_of_array(pts+new_size, old_size-new_size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
||||
if(new_size > old_size)
|
||||
{
|
||||
EIGEN_TRY
|
||||
{
|
||||
construct_elements_of_array(result+old_size, new_size-old_size);
|
||||
}
|
||||
EIGEN_CATCH(...)
|
||||
{
|
||||
conditional_aligned_free<Align>(result);
|
||||
EIGEN_THROW;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new_auto(std::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)
|
||||
{
|
||||
EIGEN_TRY
|
||||
{
|
||||
construct_elements_of_array(result, size);
|
||||
}
|
||||
EIGEN_CATCH(...)
|
||||
{
|
||||
conditional_aligned_free<Align>(result);
|
||||
EIGEN_THROW;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(T* pts, std::size_t new_size, std::size_t old_size)
|
||||
{
|
||||
check_size_for_overflow<T>(new_size);
|
||||
check_size_for_overflow<T>(old_size);
|
||||
if(NumTraits<T>::RequireInitialization && (new_size < old_size))
|
||||
destruct_elements_of_array(pts+new_size, old_size-new_size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
|
||||
if(NumTraits<T>::RequireInitialization && (new_size > old_size))
|
||||
{
|
||||
EIGEN_TRY
|
||||
{
|
||||
construct_elements_of_array(result+old_size, new_size-old_size);
|
||||
}
|
||||
EIGEN_CATCH(...)
|
||||
{
|
||||
conditional_aligned_free<Align>(result);
|
||||
EIGEN_THROW;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete_auto(T *ptr, std::size_t size)
|
||||
{
|
||||
if(NumTraits<T>::RequireInitialization)
|
||||
destruct_elements_of_array<T>(ptr, size);
|
||||
conditional_aligned_free<Align>(ptr);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/** \internal Returns the index of the first element of the array that is well aligned with respect to the requested \a Alignment.
|
||||
*
|
||||
* \tparam Alignment requested alignment in Bytes.
|
||||
* \param array the address of the start of the array
|
||||
* \param size the size of the array
|
||||
*
|
||||
* \note If no element of the array is well aligned or the requested alignment is not a multiple of a scalar,
|
||||
* the size of the array is returned. For example with SSE, the requested alignment is typically 16-bytes. If
|
||||
* packet size for the given scalar type is 1, then everything is considered well-aligned.
|
||||
*
|
||||
* \note Otherwise, if the Alignment is larger that the scalar size, we rely on the assumptions that sizeof(Scalar) is a
|
||||
* power of 2. On the other hand, we do not assume that the array address is a multiple of sizeof(Scalar), as that fails for
|
||||
* example with Scalar=double on certain 32-bit platforms, see bug #79.
|
||||
*
|
||||
* There is also the variant first_aligned(const MatrixBase&) defined in DenseCoeffsBase.h.
|
||||
* \sa first_default_aligned()
|
||||
*/
|
||||
template<int Alignment, typename Scalar, typename Index>
|
||||
EIGEN_DEVICE_FUNC inline Index first_aligned(const Scalar* array, Index size)
|
||||
{
|
||||
const Index ScalarSize = sizeof(Scalar);
|
||||
const Index AlignmentSize = Alignment / ScalarSize;
|
||||
const Index AlignmentMask = AlignmentSize-1;
|
||||
|
||||
if(AlignmentSize<=1)
|
||||
{
|
||||
// Either the requested alignment if smaller than a scalar, or it exactly match a 1 scalar
|
||||
// so that all elements of the array have the same alignment.
|
||||
return 0;
|
||||
}
|
||||
else if( (UIntPtr(array) & (sizeof(Scalar)-1)) || (Alignment%ScalarSize)!=0)
|
||||
{
|
||||
// The array is not aligned to the size of a single scalar, or the requested alignment is not a multiple of the scalar size.
|
||||
// Consequently, no element of the array is well aligned.
|
||||
return size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Index first = (AlignmentSize - (Index((UIntPtr(array)/sizeof(Scalar))) & AlignmentMask)) & AlignmentMask;
|
||||
return (first < size) ? first : size;
|
||||
}
|
||||
}
|
||||
|
||||
/** \internal Returns the index of the first element of the array that is well aligned with respect the largest packet requirement.
|
||||
* \sa first_aligned(Scalar*,Index) and first_default_aligned(DenseBase<Derived>) */
|
||||
template<typename Scalar, typename Index>
|
||||
EIGEN_DEVICE_FUNC inline Index first_default_aligned(const Scalar* array, Index size)
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type DefaultPacketType;
|
||||
return first_aligned<unpacket_traits<DefaultPacketType>::alignment>(array, size);
|
||||
}
|
||||
|
||||
/** \internal Returns the smallest integer multiple of \a base and greater or equal to \a size
|
||||
*/
|
||||
template<typename Index>
|
||||
inline Index first_multiple(Index size, Index base)
|
||||
{
|
||||
return ((size+base-1)/base)*base;
|
||||
}
|
||||
|
||||
// std::copy is much slower than memcpy, so let's introduce a smart_copy which
|
||||
// use memcpy on trivial types, i.e., on types that does not require an initialization ctor.
|
||||
template<typename T, bool UseMemcpy> struct smart_copy_helper;
|
||||
|
||||
template<typename T> EIGEN_DEVICE_FUNC void smart_copy(const T* start, const T* end, T* target)
|
||||
{
|
||||
smart_copy_helper<T,!NumTraits<T>::RequireInitialization>::run(start, end, target);
|
||||
}
|
||||
|
||||
template<typename T> struct smart_copy_helper<T,true> {
|
||||
EIGEN_DEVICE_FUNC static inline void run(const T* start, const T* end, T* target)
|
||||
{
|
||||
IntPtr size = IntPtr(end)-IntPtr(start);
|
||||
if(size==0) return;
|
||||
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||
std::memcpy(target, start, size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct smart_copy_helper<T,false> {
|
||||
EIGEN_DEVICE_FUNC static inline void run(const T* start, const T* end, T* target)
|
||||
{ std::copy(start, end, target); }
|
||||
};
|
||||
|
||||
// intelligent memmove. falls back to std::memmove for POD types, uses std::copy otherwise.
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T> struct smart_memmove_helper<T,true> {
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{
|
||||
IntPtr size = IntPtr(end)-IntPtr(start);
|
||||
if(size==0) return;
|
||||
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||
std::memmove(target, start, size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct smart_memmove_helper<T,false> {
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{
|
||||
if (UIntPtr(target) < UIntPtr(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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of runtime stack allocation (falling back to malloc) ***
|
||||
*****************************************************************************/
|
||||
|
||||
// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA
|
||||
// to the appropriate stack allocation function
|
||||
#ifndef EIGEN_ALLOCA
|
||||
#if EIGEN_OS_LINUX || EIGEN_OS_MAC || (defined alloca)
|
||||
#define EIGEN_ALLOCA alloca
|
||||
#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 : noncopyable
|
||||
{
|
||||
public:
|
||||
/* Creates a stack_memory_handler responsible for the buffer \a ptr of size \a size.
|
||||
* Note that \a ptr can be 0 regardless of the other parameters.
|
||||
* This constructor takes care of constructing/initializing the elements of the buffer if required by the scalar type T (see NumTraits<T>::RequireInitialization).
|
||||
* In this case, the buffer elements will also be destructed when this handler will be destructed.
|
||||
* Finally, if \a dealloc is true, then the pointer \a ptr is freed.
|
||||
**/
|
||||
aligned_stack_memory_handler(T* ptr, std::size_t size, bool dealloc)
|
||||
: m_ptr(ptr), m_size(size), m_deallocate(dealloc)
|
||||
{
|
||||
if(NumTraits<T>::RequireInitialization && m_ptr)
|
||||
Eigen::internal::construct_elements_of_array(m_ptr, size);
|
||||
}
|
||||
~aligned_stack_memory_handler()
|
||||
{
|
||||
if(NumTraits<T>::RequireInitialization && m_ptr)
|
||||
Eigen::internal::destruct_elements_of_array<T>(m_ptr, m_size);
|
||||
if(m_deallocate)
|
||||
Eigen::internal::aligned_free(m_ptr);
|
||||
}
|
||||
protected:
|
||||
T* m_ptr;
|
||||
std::size_t m_size;
|
||||
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
|
||||
* Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack
|
||||
* if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
|
||||
* (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap.
|
||||
* The allocated buffer is automatically deleted when exiting the scope of this declaration.
|
||||
* If BUFFER is non null, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs.
|
||||
* Here is an example:
|
||||
* \code
|
||||
* {
|
||||
* ei_declare_aligned_stack_constructed_variable(float,data,size,0);
|
||||
* // use data[0] to data[size-1]
|
||||
* }
|
||||
* \endcode
|
||||
* The underlying stack allocation function can controlled with the EIGEN_ALLOCA preprocessor token.
|
||||
*/
|
||||
#ifdef EIGEN_ALLOCA
|
||||
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES>0
|
||||
// We always manually re-align the result of EIGEN_ALLOCA.
|
||||
// If alloca is already aligned, the compiler should be smart enough to optimize away the re-alignment.
|
||||
#define EIGEN_ALIGNED_ALLOCA(SIZE) reinterpret_cast<void*>((internal::UIntPtr(EIGEN_ALLOCA(SIZE+EIGEN_DEFAULT_ALIGN_BYTES-1)) + EIGEN_DEFAULT_ALIGN_BYTES-1) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1)))
|
||||
#else
|
||||
#define EIGEN_ALIGNED_ALLOCA(SIZE) EIGEN_ALLOCA(SIZE)
|
||||
#endif
|
||||
|
||||
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
|
||||
Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
|
||||
TYPE* NAME = (BUFFER)!=0 ? (BUFFER) \
|
||||
: reinterpret_cast<TYPE*>( \
|
||||
(sizeof(TYPE)*SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) ? EIGEN_ALIGNED_ALLOCA(sizeof(TYPE)*SIZE) \
|
||||
: Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE) ); \
|
||||
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,sizeof(TYPE)*SIZE>EIGEN_STACK_ALLOCATION_LIMIT)
|
||||
|
||||
#else
|
||||
|
||||
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
|
||||
Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
|
||||
TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \
|
||||
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of EIGEN_MAKE_ALIGNED_OPERATOR_NEW [_IF] ***
|
||||
*****************************************************************************/
|
||||
|
||||
#if EIGEN_MAX_ALIGN_BYTES!=0
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
|
||||
void* operator new(std::size_t size, const std::nothrow_t&) EIGEN_NO_THROW { \
|
||||
EIGEN_TRY { return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); } \
|
||||
EIGEN_CATCH (...) { return 0; } \
|
||||
}
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
|
||||
void *operator new(std::size_t size) { \
|
||||
return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
|
||||
} \
|
||||
void *operator new[](std::size_t size) { \
|
||||
return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
|
||||
} \
|
||||
void operator delete(void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
void operator delete[](void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
void operator delete(void * ptr, std::size_t /* sz */) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
void operator delete[](void * ptr, std::size_t /* sz */) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
/* in-place new and delete. since (at least afaik) there is no actual */ \
|
||||
/* memory allocated we can safely let the default implementation handle */ \
|
||||
/* this particular case. */ \
|
||||
static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \
|
||||
static void *operator new[](std::size_t size, void* ptr) { return ::operator new[](size,ptr); } \
|
||||
void operator delete(void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete(memory,ptr); } \
|
||||
void operator delete[](void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete[](memory,ptr); } \
|
||||
/* nothrow-new (returns zero instead of std::bad_alloc) */ \
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
|
||||
void operator delete(void *ptr, const std::nothrow_t&) EIGEN_NO_THROW { \
|
||||
Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); \
|
||||
} \
|
||||
typedef void eigen_aligned_operator_new_marker_type;
|
||||
#else
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
||||
#endif
|
||||
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true)
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%EIGEN_MAX_ALIGN_BYTES==0)))
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/** \class aligned_allocator
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief STL compatible allocator to use with types requiring a non standrad alignment.
|
||||
*
|
||||
* The memory is aligned as for dynamically aligned matrix/array types such as MatrixXd.
|
||||
* By default, it will thus provide at least 16 bytes alignment and more in following cases:
|
||||
* - 32 bytes alignment if AVX is enabled.
|
||||
* - 64 bytes alignment if AVX512 is enabled.
|
||||
*
|
||||
* This can be controled using the \c EIGEN_MAX_ALIGN_BYTES macro as documented
|
||||
* \link TopicPreprocessorDirectivesPerformance there \endlink.
|
||||
*
|
||||
* Example:
|
||||
* \code
|
||||
* // Matrix4f requires 16 bytes alignment:
|
||||
* std::map< int, Matrix4f, std::less<int>,
|
||||
* aligned_allocator<std::pair<const int, Matrix4f> > > my_map_mat4;
|
||||
* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator:
|
||||
* std::map< int, Vector3f > my_map_vec3;
|
||||
* \endcode
|
||||
*
|
||||
* \sa \blank \ref TopicStlContainers.
|
||||
*/
|
||||
template<class T>
|
||||
class aligned_allocator : public std::allocator<T>
|
||||
{
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef aligned_allocator<U> other;
|
||||
};
|
||||
|
||||
aligned_allocator() : std::allocator<T>() {}
|
||||
|
||||
aligned_allocator(const aligned_allocator& other) : std::allocator<T>(other) {}
|
||||
|
||||
template<class U>
|
||||
aligned_allocator(const aligned_allocator<U>& other) : std::allocator<T>(other) {}
|
||||
|
||||
~aligned_allocator() {}
|
||||
|
||||
pointer allocate(size_type num, const void* /*hint*/ = 0)
|
||||
{
|
||||
internal::check_size_for_overflow<T>(num);
|
||||
return static_cast<pointer>( internal::aligned_malloc(num * sizeof(T)) );
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type /*num*/)
|
||||
{
|
||||
internal::aligned_free(p);
|
||||
}
|
||||
};
|
||||
|
||||
//---------- Cache sizes ----------
|
||||
|
||||
#if !defined(EIGEN_NO_CPUID)
|
||||
# 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__) && 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) \
|
||||
__asm__ __volatile__ ("xchg{q}\t{%%}rbx, %q1; cpuid; xchg{q}\t{%%}rbx, %q1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id));
|
||||
# else
|
||||
// Case for x86_64 or x86 w/o PIC
|
||||
# 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 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
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
|
||||
#ifdef EIGEN_CPUID
|
||||
|
||||
inline bool cpuid_is_vendor(int abcd[4], const int vendor[3])
|
||||
{
|
||||
return abcd[1]==vendor[0] && abcd[3]==vendor[1] && abcd[2]==vendor[2];
|
||||
}
|
||||
|
||||
inline void queryCacheSizes_intel_direct(int& l1, int& l2, int& l3)
|
||||
{
|
||||
int abcd[4];
|
||||
l1 = l2 = l3 = 0;
|
||||
int cache_id = 0;
|
||||
int cache_type = 0;
|
||||
do {
|
||||
abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
|
||||
EIGEN_CPUID(abcd,0x4,cache_id);
|
||||
cache_type = (abcd[0] & 0x0F) >> 0;
|
||||
if(cache_type==1||cache_type==3) // data or unified cache
|
||||
{
|
||||
int cache_level = (abcd[0] & 0xE0) >> 5; // A[7:5]
|
||||
int ways = (abcd[1] & 0xFFC00000) >> 22; // B[31:22]
|
||||
int partitions = (abcd[1] & 0x003FF000) >> 12; // B[21:12]
|
||||
int line_size = (abcd[1] & 0x00000FFF) >> 0; // B[11:0]
|
||||
int sets = (abcd[2]); // C[31:0]
|
||||
|
||||
int cache_size = (ways+1) * (partitions+1) * (line_size+1) * (sets+1);
|
||||
|
||||
switch(cache_level)
|
||||
{
|
||||
case 1: l1 = cache_size; break;
|
||||
case 2: l2 = cache_size; break;
|
||||
case 3: l3 = cache_size; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
cache_id++;
|
||||
} while(cache_type>0 && cache_id<16);
|
||||
}
|
||||
|
||||
inline void queryCacheSizes_intel_codes(int& l1, int& l2, int& l3)
|
||||
{
|
||||
int abcd[4];
|
||||
abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
|
||||
l1 = l2 = l3 = 0;
|
||||
EIGEN_CPUID(abcd,0x00000002,0);
|
||||
unsigned char * bytes = reinterpret_cast<unsigned char *>(abcd)+2;
|
||||
bool check_for_p2_core2 = false;
|
||||
for(int i=0; i<14; ++i)
|
||||
{
|
||||
switch(bytes[i])
|
||||
{
|
||||
case 0x0A: l1 = 8; break; // 0Ah data L1 cache, 8 KB, 2 ways, 32 byte lines
|
||||
case 0x0C: l1 = 16; break; // 0Ch data L1 cache, 16 KB, 4 ways, 32 byte lines
|
||||
case 0x0E: l1 = 24; break; // 0Eh data L1 cache, 24 KB, 6 ways, 64 byte lines
|
||||
case 0x10: l1 = 16; break; // 10h data L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
|
||||
case 0x15: l1 = 16; break; // 15h code L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
|
||||
case 0x2C: l1 = 32; break; // 2Ch data L1 cache, 32 KB, 8 ways, 64 byte lines
|
||||
case 0x30: l1 = 32; break; // 30h code L1 cache, 32 KB, 8 ways, 64 byte lines
|
||||
case 0x60: l1 = 16; break; // 60h data L1 cache, 16 KB, 8 ways, 64 byte lines, sectored
|
||||
case 0x66: l1 = 8; break; // 66h data L1 cache, 8 KB, 4 ways, 64 byte lines, sectored
|
||||
case 0x67: l1 = 16; break; // 67h data L1 cache, 16 KB, 4 ways, 64 byte lines, sectored
|
||||
case 0x68: l1 = 32; break; // 68h data L1 cache, 32 KB, 4 ways, 64 byte lines, sectored
|
||||
case 0x1A: l2 = 96; break; // code and data L2 cache, 96 KB, 6 ways, 64 byte lines (IA-64)
|
||||
case 0x22: l3 = 512; break; // code and data L3 cache, 512 KB, 4 ways (!), 64 byte lines, dual-sectored
|
||||
case 0x23: l3 = 1024; break; // code and data L3 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
|
||||
case 0x25: l3 = 2048; break; // code and data L3 cache, 2048 KB, 8 ways, 64 byte lines, dual-sectored
|
||||
case 0x29: l3 = 4096; break; // code and data L3 cache, 4096 KB, 8 ways, 64 byte lines, dual-sectored
|
||||
case 0x39: l2 = 128; break; // code and data L2 cache, 128 KB, 4 ways, 64 byte lines, sectored
|
||||
case 0x3A: l2 = 192; break; // code and data L2 cache, 192 KB, 6 ways, 64 byte lines, sectored
|
||||
case 0x3B: l2 = 128; break; // code and data L2 cache, 128 KB, 2 ways, 64 byte lines, sectored
|
||||
case 0x3C: l2 = 256; break; // code and data L2 cache, 256 KB, 4 ways, 64 byte lines, sectored
|
||||
case 0x3D: l2 = 384; break; // code and data L2 cache, 384 KB, 6 ways, 64 byte lines, sectored
|
||||
case 0x3E: l2 = 512; break; // code and data L2 cache, 512 KB, 4 ways, 64 byte lines, sectored
|
||||
case 0x40: l2 = 0; break; // no integrated L2 cache (P6 core) or L3 cache (P4 core)
|
||||
case 0x41: l2 = 128; break; // code and data L2 cache, 128 KB, 4 ways, 32 byte lines
|
||||
case 0x42: l2 = 256; break; // code and data L2 cache, 256 KB, 4 ways, 32 byte lines
|
||||
case 0x43: l2 = 512; break; // code and data L2 cache, 512 KB, 4 ways, 32 byte lines
|
||||
case 0x44: l2 = 1024; break; // code and data L2 cache, 1024 KB, 4 ways, 32 byte lines
|
||||
case 0x45: l2 = 2048; break; // code and data L2 cache, 2048 KB, 4 ways, 32 byte lines
|
||||
case 0x46: l3 = 4096; break; // code and data L3 cache, 4096 KB, 4 ways, 64 byte lines
|
||||
case 0x47: l3 = 8192; break; // code and data L3 cache, 8192 KB, 8 ways, 64 byte lines
|
||||
case 0x48: l2 = 3072; break; // code and data L2 cache, 3072 KB, 12 ways, 64 byte lines
|
||||
case 0x49: if(l2!=0) l3 = 4096; else {check_for_p2_core2=true; l3 = l2 = 4096;} break;// code and data L3 cache, 4096 KB, 16 ways, 64 byte lines (P4) or L2 for core2
|
||||
case 0x4A: l3 = 6144; break; // code and data L3 cache, 6144 KB, 12 ways, 64 byte lines
|
||||
case 0x4B: l3 = 8192; break; // code and data L3 cache, 8192 KB, 16 ways, 64 byte lines
|
||||
case 0x4C: l3 = 12288; break; // code and data L3 cache, 12288 KB, 12 ways, 64 byte lines
|
||||
case 0x4D: l3 = 16384; break; // code and data L3 cache, 16384 KB, 16 ways, 64 byte lines
|
||||
case 0x4E: l2 = 6144; break; // code and data L2 cache, 6144 KB, 24 ways, 64 byte lines
|
||||
case 0x78: l2 = 1024; break; // code and data L2 cache, 1024 KB, 4 ways, 64 byte lines
|
||||
case 0x79: l2 = 128; break; // code and data L2 cache, 128 KB, 8 ways, 64 byte lines, dual-sectored
|
||||
case 0x7A: l2 = 256; break; // code and data L2 cache, 256 KB, 8 ways, 64 byte lines, dual-sectored
|
||||
case 0x7B: l2 = 512; break; // code and data L2 cache, 512 KB, 8 ways, 64 byte lines, dual-sectored
|
||||
case 0x7C: l2 = 1024; break; // code and data L2 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
|
||||
case 0x7D: l2 = 2048; break; // code and data L2 cache, 2048 KB, 8 ways, 64 byte lines
|
||||
case 0x7E: l2 = 256; break; // code and data L2 cache, 256 KB, 8 ways, 128 byte lines, sect. (IA-64)
|
||||
case 0x7F: l2 = 512; break; // code and data L2 cache, 512 KB, 2 ways, 64 byte lines
|
||||
case 0x80: l2 = 512; break; // code and data L2 cache, 512 KB, 8 ways, 64 byte lines
|
||||
case 0x81: l2 = 128; break; // code and data L2 cache, 128 KB, 8 ways, 32 byte lines
|
||||
case 0x82: l2 = 256; break; // code and data L2 cache, 256 KB, 8 ways, 32 byte lines
|
||||
case 0x83: l2 = 512; break; // code and data L2 cache, 512 KB, 8 ways, 32 byte lines
|
||||
case 0x84: l2 = 1024; break; // code and data L2 cache, 1024 KB, 8 ways, 32 byte lines
|
||||
case 0x85: l2 = 2048; break; // code and data L2 cache, 2048 KB, 8 ways, 32 byte lines
|
||||
case 0x86: l2 = 512; break; // code and data L2 cache, 512 KB, 4 ways, 64 byte lines
|
||||
case 0x87: l2 = 1024; break; // code and data L2 cache, 1024 KB, 8 ways, 64 byte lines
|
||||
case 0x88: l3 = 2048; break; // code and data L3 cache, 2048 KB, 4 ways, 64 byte lines (IA-64)
|
||||
case 0x89: l3 = 4096; break; // code and data L3 cache, 4096 KB, 4 ways, 64 byte lines (IA-64)
|
||||
case 0x8A: l3 = 8192; break; // code and data L3 cache, 8192 KB, 4 ways, 64 byte lines (IA-64)
|
||||
case 0x8D: l3 = 3072; break; // code and data L3 cache, 3072 KB, 12 ways, 128 byte lines (IA-64)
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if(check_for_p2_core2 && l2 == l3)
|
||||
l3 = 0;
|
||||
l1 *= 1024;
|
||||
l2 *= 1024;
|
||||
l3 *= 1024;
|
||||
}
|
||||
|
||||
inline void queryCacheSizes_intel(int& l1, int& l2, int& l3, int max_std_funcs)
|
||||
{
|
||||
if(max_std_funcs>=4)
|
||||
queryCacheSizes_intel_direct(l1,l2,l3);
|
||||
else
|
||||
queryCacheSizes_intel_codes(l1,l2,l3);
|
||||
}
|
||||
|
||||
inline void queryCacheSizes_amd(int& l1, int& l2, int& l3)
|
||||
{
|
||||
int abcd[4];
|
||||
abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
|
||||
EIGEN_CPUID(abcd,0x80000005,0);
|
||||
l1 = (abcd[2] >> 24) * 1024; // C[31:24] = L1 size in KB
|
||||
abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
|
||||
EIGEN_CPUID(abcd,0x80000006,0);
|
||||
l2 = (abcd[2] >> 16) * 1024; // C[31;16] = l2 cache size in KB
|
||||
l3 = ((abcd[3] & 0xFFFC000) >> 18) * 512 * 1024; // D[31;18] = l3 cache size in 512KB
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \internal
|
||||
* Queries and returns the cache sizes in Bytes of the L1, L2, and L3 data caches respectively */
|
||||
inline void queryCacheSizes(int& l1, int& l2, int& l3)
|
||||
{
|
||||
#ifdef EIGEN_CPUID
|
||||
int abcd[4];
|
||||
const int GenuineIntel[] = {0x756e6547, 0x49656e69, 0x6c65746e};
|
||||
const int AuthenticAMD[] = {0x68747541, 0x69746e65, 0x444d4163};
|
||||
const int AMDisbetter_[] = {0x69444d41, 0x74656273, 0x21726574}; // "AMDisbetter!"
|
||||
|
||||
// identify the CPU vendor
|
||||
EIGEN_CPUID(abcd,0x0,0);
|
||||
int max_std_funcs = abcd[1];
|
||||
if(cpuid_is_vendor(abcd,GenuineIntel))
|
||||
queryCacheSizes_intel(l1,l2,l3,max_std_funcs);
|
||||
else if(cpuid_is_vendor(abcd,AuthenticAMD) || cpuid_is_vendor(abcd,AMDisbetter_))
|
||||
queryCacheSizes_amd(l1,l2,l3);
|
||||
else
|
||||
// by default let's use Intel's API
|
||||
queryCacheSizes_intel(l1,l2,l3,max_std_funcs);
|
||||
|
||||
// here is the list of other vendors:
|
||||
// ||cpuid_is_vendor(abcd,"VIA VIA VIA ")
|
||||
// ||cpuid_is_vendor(abcd,"CyrixInstead")
|
||||
// ||cpuid_is_vendor(abcd,"CentaurHauls")
|
||||
// ||cpuid_is_vendor(abcd,"GenuineTMx86")
|
||||
// ||cpuid_is_vendor(abcd,"TransmetaCPU")
|
||||
// ||cpuid_is_vendor(abcd,"RiseRiseRise")
|
||||
// ||cpuid_is_vendor(abcd,"Geode by NSC")
|
||||
// ||cpuid_is_vendor(abcd,"SiS SiS SiS ")
|
||||
// ||cpuid_is_vendor(abcd,"UMC UMC UMC ")
|
||||
// ||cpuid_is_vendor(abcd,"NexGenDriven")
|
||||
#else
|
||||
l1 = l2 = l3 = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \returns the size in Bytes of the L1 data cache */
|
||||
inline int queryL1CacheSize()
|
||||
{
|
||||
int l1(-1), l2, l3;
|
||||
queryCacheSizes(l1,l2,l3);
|
||||
return l1;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \returns the size in Bytes of the L2 or L3 cache if this later is present */
|
||||
inline int queryTopLevelCacheSize()
|
||||
{
|
||||
int l1, l2(-1), l3(-1);
|
||||
queryCacheSizes(l1,l2,l3);
|
||||
return (std::max)(l2,l3);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_MEMORY_H
|
||||
550
examples/ThirdPartyLibs/Eigen/src/Core/util/Meta.h
Normal file
550
examples/ThirdPartyLibs/Eigen/src/Core/util/Meta.h
Normal file
@@ -0,0 +1,550 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_META_H
|
||||
#define EIGEN_META_H
|
||||
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
#include <cfloat>
|
||||
#include <math_constants.h>
|
||||
#endif
|
||||
|
||||
#if EIGEN_COMP_ICC>=1600 && __cplusplus >= 201103L
|
||||
#include <cstdint>
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
|
||||
|
||||
/**
|
||||
* \brief The Index type as used for the API.
|
||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||
* \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
|
||||
*/
|
||||
|
||||
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
|
||||
|
||||
namespace internal {
|
||||
|
||||
/** \internal
|
||||
* \file Meta.h
|
||||
* This file contains generic metaprogramming classes which are not specifically related to Eigen.
|
||||
* \note In case you wonder, yes we're aware that Boost already provides all these features,
|
||||
* we however don't want to add a dependency to Boost.
|
||||
*/
|
||||
|
||||
// Only recent versions of ICC complain about using ptrdiff_t to hold pointers,
|
||||
// and older versions do not provide *intptr_t types.
|
||||
#if EIGEN_COMP_ICC>=1600 && __cplusplus >= 201103L
|
||||
typedef std::intptr_t IntPtr;
|
||||
typedef std::uintptr_t UIntPtr;
|
||||
#else
|
||||
typedef std::ptrdiff_t IntPtr;
|
||||
typedef std::size_t UIntPtr;
|
||||
#endif
|
||||
|
||||
struct true_type { enum { value = 1 }; };
|
||||
struct false_type { enum { value = 0 }; };
|
||||
|
||||
template<bool Condition, typename Then, typename Else>
|
||||
struct conditional { typedef Then type; };
|
||||
|
||||
template<typename Then, typename Else>
|
||||
struct conditional <false, Then, Else> { typedef Else type; };
|
||||
|
||||
template<typename T, typename U> struct is_same { enum { value = 0 }; };
|
||||
template<typename T> struct is_same<T,T> { enum { value = 1 }; };
|
||||
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*const> { typedef T type; };
|
||||
|
||||
template <class T> struct remove_const { typedef T type; };
|
||||
template <class T> struct remove_const<const T> { typedef T type; };
|
||||
template <class T> struct remove_const<const T[]> { typedef T type[]; };
|
||||
template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; };
|
||||
|
||||
template<typename T> struct remove_all { typedef T type; };
|
||||
template<typename T> struct remove_all<const T> { typedef typename remove_all<T>::type type; };
|
||||
template<typename T> struct remove_all<T const&> { typedef typename remove_all<T>::type type; };
|
||||
template<typename T> struct remove_all<T&> { typedef typename remove_all<T>::type type; };
|
||||
template<typename T> struct remove_all<T const*> { typedef typename remove_all<T>::type type; };
|
||||
template<typename T> struct remove_all<T*> { typedef typename remove_all<T>::type type; };
|
||||
|
||||
template<typename T> struct is_arithmetic { enum { value = false }; };
|
||||
template<> struct is_arithmetic<float> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<double> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<long double> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<bool> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<char> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<signed char> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<unsigned char> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<signed short> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<unsigned short>{ enum { value = true }; };
|
||||
template<> struct is_arithmetic<signed int> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<unsigned int> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<signed long> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
|
||||
|
||||
#if EIGEN_HAS_CXX11
|
||||
using std::is_integral;
|
||||
#else
|
||||
template<typename T> struct is_integral { enum { value = false }; };
|
||||
template<> struct is_integral<bool> { enum { value = true }; };
|
||||
template<> struct is_integral<char> { enum { value = true }; };
|
||||
template<> struct is_integral<signed char> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned char> { enum { value = true }; };
|
||||
template<> struct is_integral<signed short> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned short> { enum { value = true }; };
|
||||
template<> struct is_integral<signed int> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned int> { enum { value = true }; };
|
||||
template<> struct is_integral<signed long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long> { enum { value = true }; };
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T> struct add_const { typedef const T type; };
|
||||
template <typename T> struct add_const<T&> { typedef T& type; };
|
||||
|
||||
template <typename T> struct is_const { enum { value = 0 }; };
|
||||
template <typename T> struct is_const<T const> { enum { value = 1 }; };
|
||||
|
||||
template<typename T> struct add_const_on_value_type { typedef const T type; };
|
||||
template<typename T> struct add_const_on_value_type<T&> { typedef T const& type; };
|
||||
template<typename T> struct add_const_on_value_type<T*> { typedef T const* type; };
|
||||
template<typename T> struct add_const_on_value_type<T* const> { typedef T const* const type; };
|
||||
template<typename T> struct add_const_on_value_type<T const* const> { typedef T const* const type; };
|
||||
|
||||
|
||||
template<typename From, typename To>
|
||||
struct is_convertible_impl
|
||||
{
|
||||
private:
|
||||
struct any_conversion
|
||||
{
|
||||
template <typename T> any_conversion(const volatile T&);
|
||||
template <typename T> any_conversion(T&);
|
||||
};
|
||||
struct yes {int a[1];};
|
||||
struct no {int a[2];};
|
||||
|
||||
static yes test(const To&, int);
|
||||
static no test(any_conversion, ...);
|
||||
|
||||
public:
|
||||
static From ms_from;
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning push
|
||||
#pragma warning ( disable : 2259 )
|
||||
#endif
|
||||
enum { value = sizeof(test(ms_from, 0))==sizeof(yes) };
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning pop
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename From, typename To>
|
||||
struct is_convertible
|
||||
{
|
||||
enum { value = is_convertible_impl<typename remove_all<From>::type,
|
||||
typename remove_all<To >::type>::value };
|
||||
};
|
||||
|
||||
/** \internal Allows to enable/disable an overload
|
||||
* according to a compile time condition.
|
||||
*/
|
||||
template<bool Condition, typename T=void> struct enable_if;
|
||||
|
||||
template<typename T> struct enable_if<true,T>
|
||||
{ typedef T type; };
|
||||
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
#if !defined(__FLT_EPSILON__)
|
||||
#define __FLT_EPSILON__ FLT_EPSILON
|
||||
#define __DBL_EPSILON__ DBL_EPSILON
|
||||
#endif
|
||||
|
||||
namespace device {
|
||||
|
||||
template<typename T> struct numeric_limits
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static T epsilon() { return 0; }
|
||||
static T (max)() { assert(false && "Highest not supported for this type"); }
|
||||
static T (min)() { assert(false && "Lowest not supported for this type"); }
|
||||
static T infinity() { assert(false && "Infinity not supported for this type"); }
|
||||
static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); }
|
||||
};
|
||||
template<> struct numeric_limits<float>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float epsilon() { return __FLT_EPSILON__; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float (max)() { return CUDART_MAX_NORMAL_F; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float (min)() { return FLT_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float infinity() { return CUDART_INF_F; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float quiet_NaN() { return CUDART_NAN_F; }
|
||||
};
|
||||
template<> struct numeric_limits<double>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double epsilon() { return __DBL_EPSILON__; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double (max)() { return DBL_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double (min)() { return DBL_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double infinity() { return CUDART_INF; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double quiet_NaN() { return CUDART_NAN; }
|
||||
};
|
||||
template<> struct numeric_limits<int>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static int epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static int (max)() { return INT_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static int (min)() { return INT_MIN; }
|
||||
};
|
||||
template<> struct numeric_limits<unsigned int>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned int epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned int (max)() { return UINT_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned int (min)() { return 0; }
|
||||
};
|
||||
template<> struct numeric_limits<long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static long (max)() { return LONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static long (min)() { return LONG_MIN; }
|
||||
};
|
||||
template<> struct numeric_limits<unsigned long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned long (max)() { return ULONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned long (min)() { return 0; }
|
||||
};
|
||||
template<> struct numeric_limits<long long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static long long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static long long (max)() { return LLONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static long long (min)() { return LLONG_MIN; }
|
||||
};
|
||||
template<> struct numeric_limits<unsigned long long>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned long long epsilon() { return 0; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned long long (max)() { return ULLONG_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static unsigned long long (min)() { return 0; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** \internal
|
||||
* A base class do disable default copy ctor and copy assignement operator.
|
||||
*/
|
||||
class noncopyable
|
||||
{
|
||||
EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
|
||||
EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
|
||||
protected:
|
||||
EIGEN_DEVICE_FUNC noncopyable() {}
|
||||
EIGEN_DEVICE_FUNC ~noncopyable() {}
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* Provides access to the number of elements in the object of as a compile-time constant expression.
|
||||
* It "returns" Eigen::Dynamic if the size cannot be resolved at compile-time (default).
|
||||
*
|
||||
* Similar to std::tuple_size, but more general.
|
||||
*
|
||||
* It currently supports:
|
||||
* - any types T defining T::SizeAtCompileTime
|
||||
* - plain C arrays as T[N]
|
||||
* - std::array (c++11)
|
||||
* - some internal types such as SingleRange and AllRange
|
||||
*
|
||||
* The second template parameter eases SFINAE-based specializations.
|
||||
*/
|
||||
template<typename T, typename EnableIf = void> struct array_size {
|
||||
enum { value = Dynamic };
|
||||
};
|
||||
|
||||
template<typename T> struct array_size<T,typename internal::enable_if<((T::SizeAtCompileTime&0)==0)>::type> {
|
||||
enum { value = T::SizeAtCompileTime };
|
||||
};
|
||||
|
||||
template<typename T, int N> struct array_size<const T (&)[N]> {
|
||||
enum { value = N };
|
||||
};
|
||||
template<typename T, int N> struct array_size<T (&)[N]> {
|
||||
enum { value = N };
|
||||
};
|
||||
|
||||
#if EIGEN_HAS_CXX11
|
||||
template<typename T, std::size_t N> struct array_size<const std::array<T,N> > {
|
||||
enum { value = N };
|
||||
};
|
||||
template<typename T, std::size_t N> struct array_size<std::array<T,N> > {
|
||||
enum { value = N };
|
||||
};
|
||||
#endif
|
||||
|
||||
/** \internal
|
||||
* Analogue of the std::size free function.
|
||||
* It returns the size of the container or view \a x of type \c T
|
||||
*
|
||||
* It currently supports:
|
||||
* - any types T defining a member T::size() const
|
||||
* - plain C arrays as T[N]
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
Index size(const T& x) { return x.size(); }
|
||||
|
||||
template<typename T,std::size_t N>
|
||||
Index size(const T (&) [N]) { return N; }
|
||||
|
||||
/** \internal
|
||||
* Convenient struct to get the result type of a unary or binary functor.
|
||||
*
|
||||
* It supports both the current STL mechanism (using the result_type member) as well as
|
||||
* upcoming next STL generation (using a templated result member).
|
||||
* If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack.
|
||||
*/
|
||||
#if EIGEN_HAS_STD_RESULT_OF
|
||||
template<typename T> struct result_of {
|
||||
typedef typename std::result_of<T>::type type1;
|
||||
typedef typename remove_all<type1>::type type;
|
||||
};
|
||||
#else
|
||||
template<typename T> struct result_of { };
|
||||
|
||||
struct has_none {int a[1];};
|
||||
struct has_std_result_type {int a[2];};
|
||||
struct has_tr1_result {int a[3];};
|
||||
|
||||
template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
|
||||
struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType>
|
||||
struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
|
||||
|
||||
template<typename Func, typename ArgType>
|
||||
struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType>
|
||||
struct result_of<Func(ArgType)> {
|
||||
template<typename T>
|
||||
static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
|
||||
template<typename T>
|
||||
static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
|
||||
static has_none testFunctor(...);
|
||||
|
||||
// note that the following indirection is needed for gcc-3.3
|
||||
enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
|
||||
typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type;
|
||||
};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
|
||||
struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1>
|
||||
struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
|
||||
{typedef typename Func::result_type type;};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1>
|
||||
struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)>
|
||||
{typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1>
|
||||
struct result_of<Func(ArgType0,ArgType1)> {
|
||||
template<typename T>
|
||||
static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
|
||||
template<typename T>
|
||||
static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
|
||||
static has_none testFunctor(...);
|
||||
|
||||
// note that the following indirection is needed for gcc-3.3
|
||||
enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
|
||||
typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
|
||||
};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)>
|
||||
struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
|
||||
struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)>
|
||||
{typedef typename Func::result_type type;};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
|
||||
struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)>
|
||||
{typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
|
||||
struct result_of<Func(ArgType0,ArgType1,ArgType2)> {
|
||||
template<typename T>
|
||||
static has_std_result_type testFunctor(T const *, typename T::result_type const * = 0);
|
||||
template<typename T>
|
||||
static has_tr1_result testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0);
|
||||
static has_none testFunctor(...);
|
||||
|
||||
// note that the following indirection is needed for gcc-3.3
|
||||
enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
|
||||
typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct meta_yes { char a[1]; };
|
||||
struct meta_no { char a[2]; };
|
||||
|
||||
// Check whether T::ReturnType does exist
|
||||
template <typename T>
|
||||
struct has_ReturnType
|
||||
{
|
||||
template <typename C> static meta_yes testFunctor(C const *, typename C::ReturnType const * = 0);
|
||||
template <typename C> static meta_no testFunctor(...);
|
||||
|
||||
enum { value = sizeof(testFunctor<T>(static_cast<T*>(0))) == sizeof(meta_yes) };
|
||||
};
|
||||
|
||||
template<typename T> const T* return_ptr();
|
||||
|
||||
template <typename T, typename IndexType=Index>
|
||||
struct has_nullary_operator
|
||||
{
|
||||
template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0);
|
||||
static meta_no testFunctor(...);
|
||||
|
||||
enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
|
||||
};
|
||||
|
||||
template <typename T, typename IndexType=Index>
|
||||
struct has_unary_operator
|
||||
{
|
||||
template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0);
|
||||
static meta_no testFunctor(...);
|
||||
|
||||
enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
|
||||
};
|
||||
|
||||
template <typename T, typename IndexType=Index>
|
||||
struct has_binary_operator
|
||||
{
|
||||
template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0);
|
||||
static meta_no testFunctor(...);
|
||||
|
||||
enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
|
||||
};
|
||||
|
||||
/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
|
||||
* Usage example: \code meta_sqrt<1023>::ret \endcode
|
||||
*/
|
||||
template<int Y,
|
||||
int InfX = 0,
|
||||
int SupX = ((Y==1) ? 1 : Y/2),
|
||||
bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
|
||||
// use ?: instead of || just to shut up a stupid gcc 4.3 warning
|
||||
class meta_sqrt
|
||||
{
|
||||
enum {
|
||||
MidX = (InfX+SupX)/2,
|
||||
TakeInf = MidX*MidX > Y ? 1 : 0,
|
||||
NewInf = int(TakeInf) ? InfX : int(MidX),
|
||||
NewSup = int(TakeInf) ? int(MidX) : SupX
|
||||
};
|
||||
public:
|
||||
enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret };
|
||||
};
|
||||
|
||||
template<int Y, int InfX, int SupX>
|
||||
class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
|
||||
|
||||
|
||||
/** \internal Computes the least common multiple of two positive integer A and B
|
||||
* at compile-time. It implements a naive algorithm testing all multiples of A.
|
||||
* It thus works better if A>=B.
|
||||
*/
|
||||
template<int A, int B, int K=1, bool Done = ((A*K)%B)==0>
|
||||
struct meta_least_common_multiple
|
||||
{
|
||||
enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
|
||||
};
|
||||
template<int A, int B, int K>
|
||||
struct meta_least_common_multiple<A,B,K,true>
|
||||
{
|
||||
enum { ret = A*K };
|
||||
};
|
||||
|
||||
/** \internal determines whether the product of two numeric types is allowed and what the return type is */
|
||||
template<typename T, typename U> struct scalar_product_traits
|
||||
{
|
||||
enum { Defined = 0 };
|
||||
};
|
||||
|
||||
// FIXME quick workaround around current limitation of result_of
|
||||
// template<typename Scalar, typename ArgType0, typename ArgType1>
|
||||
// struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
|
||||
// typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
|
||||
// };
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
namespace numext {
|
||||
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
|
||||
#else
|
||||
template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
using internal::device::numeric_limits;
|
||||
#else
|
||||
using std::numeric_limits;
|
||||
#endif
|
||||
|
||||
// Integer division with rounding up.
|
||||
// T is assumed to be an integer type with a>=0, and b>0
|
||||
template<typename T>
|
||||
T div_ceil(const T &a, const T &b)
|
||||
{
|
||||
return (a+b-1) / b;
|
||||
}
|
||||
|
||||
} // end namespace numext
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_META_H
|
||||
3
examples/ThirdPartyLibs/Eigen/src/Core/util/NonMPL2.h
Normal file
3
examples/ThirdPartyLibs/Eigen/src/Core/util/NonMPL2.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#ifdef EIGEN_MPL2_ONLY
|
||||
#error Including non-MPL2 code in EIGEN_MPL2_ONLY mode
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifdef EIGEN_WARNINGS_DISABLED
|
||||
#undef EIGEN_WARNINGS_DISABLED
|
||||
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
#elif defined __INTEL_COMPILER
|
||||
#pragma warning pop
|
||||
#elif defined __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined __GNUC__ && __GNUC__>=6
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__
|
||||
// Don't reenable the diagnostic messages, as it turns out these messages need
|
||||
// to be disabled at the point of the template instantiation (i.e the user code)
|
||||
// otherwise they'll be triggered by nvcc.
|
||||
// #pragma diag_default code_is_unreachable
|
||||
// #pragma diag_default initialization_not_reachable
|
||||
// #pragma diag_default 2651
|
||||
// #pragma diag_default 2653
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_WARNINGS_DISABLED
|
||||
216
examples/ThirdPartyLibs/Eigen/src/Core/util/StaticAssert.h
Normal file
216
examples/ThirdPartyLibs/Eigen/src/Core/util/StaticAssert.h
Normal file
@@ -0,0 +1,216 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_STATIC_ASSERT_H
|
||||
#define EIGEN_STATIC_ASSERT_H
|
||||
|
||||
/* Some notes on Eigen's static assertion mechanism:
|
||||
*
|
||||
* - in EIGEN_STATIC_ASSERT(CONDITION,MSG) the parameter CONDITION must be a compile time boolean
|
||||
* expression, and MSG an enum listed in struct internal::static_assertion<true>
|
||||
*
|
||||
* - define EIGEN_NO_STATIC_ASSERT to disable them (and save compilation time)
|
||||
* in that case, the static assertion is converted to the following runtime assert:
|
||||
* eigen_assert(CONDITION && "MSG")
|
||||
*
|
||||
* - currently EIGEN_STATIC_ASSERT can only be used in function scope
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600))
|
||||
|
||||
// if native static_assert is enabled, let's use it
|
||||
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
||||
|
||||
#else // not CXX0X
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<bool condition>
|
||||
struct static_assertion {};
|
||||
|
||||
template<>
|
||||
struct static_assertion<true>
|
||||
{
|
||||
enum {
|
||||
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX=1,
|
||||
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES=1,
|
||||
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE=1,
|
||||
OUT_OF_RANGE_ACCESS=1,
|
||||
YOU_MADE_A_PROGRAMMING_MISTAKE=1,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT=1,
|
||||
EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE=1,
|
||||
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR=1,
|
||||
YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR=1,
|
||||
UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC=1,
|
||||
THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES=1,
|
||||
FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED=1,
|
||||
NUMERIC_TYPE_MUST_BE_REAL=1,
|
||||
COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED=1,
|
||||
WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE=1,
|
||||
INVALID_MATRIX_PRODUCT=1,
|
||||
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS=1,
|
||||
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION=1,
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES=1,
|
||||
INVALID_MATRIX_TEMPLATE_PARAMETERS=1,
|
||||
INVALID_MATRIXBASE_TEMPLATE_PARAMETERS=1,
|
||||
BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX=1,
|
||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES=1,
|
||||
YOU_ALREADY_SPECIFIED_THIS_STRIDE=1,
|
||||
INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION=1,
|
||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD=1,
|
||||
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS=1,
|
||||
YOU_CANNOT_MIX_ARRAYS_AND_MATRICES=1,
|
||||
YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION=1,
|
||||
THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY=1,
|
||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL=1,
|
||||
THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES=1,
|
||||
YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED=1,
|
||||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED=1,
|
||||
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE=1,
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH=1,
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG=1,
|
||||
IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY=1,
|
||||
STORAGE_LAYOUT_DOES_NOT_MATCH=1,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE=1,
|
||||
THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS=1,
|
||||
MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY=1,
|
||||
THIS_TYPE_IS_NOT_SUPPORTED=1,
|
||||
STORAGE_KIND_MUST_MATCH=1,
|
||||
STORAGE_INDEX_MUST_MATCH=1,
|
||||
CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY=1
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
// Specialized implementation for MSVC to avoid "conditional
|
||||
// expression is constant" warnings. This implementation doesn't
|
||||
// appear to work under GCC, hence the multiple implementations.
|
||||
#if EIGEN_COMP_MSVC
|
||||
|
||||
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
|
||||
{Eigen::internal::static_assertion<bool(CONDITION)>::MSG;}
|
||||
|
||||
#else
|
||||
// In some cases clang interprets bool(CONDITION) as function declaration
|
||||
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
|
||||
if (Eigen::internal::static_assertion<static_cast<bool>(CONDITION)>::MSG) {}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // not CXX0X
|
||||
|
||||
#else // EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);
|
||||
|
||||
#endif // EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
|
||||
// static assertion failing if the type \a TYPE is not a vector type
|
||||
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \
|
||||
EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime, \
|
||||
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX)
|
||||
|
||||
// static assertion failing if the type \a TYPE is not fixed-size
|
||||
#define EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) \
|
||||
EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime!=Eigen::Dynamic, \
|
||||
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR)
|
||||
|
||||
// static assertion failing if the type \a TYPE is not dynamic-size
|
||||
#define EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(TYPE) \
|
||||
EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime==Eigen::Dynamic, \
|
||||
YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR)
|
||||
|
||||
// static assertion failing if the type \a TYPE is not a vector type of the given size
|
||||
#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) \
|
||||
EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime && TYPE::SizeAtCompileTime==SIZE, \
|
||||
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE)
|
||||
|
||||
// static assertion failing if the type \a TYPE is not a vector type of the given size
|
||||
#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) \
|
||||
EIGEN_STATIC_ASSERT(TYPE::RowsAtCompileTime==ROWS && TYPE::ColsAtCompileTime==COLS, \
|
||||
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
|
||||
|
||||
// static assertion failing if the two vector expression types are not compatible (same fixed-size or dynamic size)
|
||||
#define EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) \
|
||||
EIGEN_STATIC_ASSERT( \
|
||||
(int(TYPE0::SizeAtCompileTime)==Eigen::Dynamic \
|
||||
|| int(TYPE1::SizeAtCompileTime)==Eigen::Dynamic \
|
||||
|| int(TYPE0::SizeAtCompileTime)==int(TYPE1::SizeAtCompileTime)),\
|
||||
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES)
|
||||
|
||||
#define EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
|
||||
( \
|
||||
(int(Eigen::internal::size_of_xpr_at_compile_time<TYPE0>::ret)==0 && int(Eigen::internal::size_of_xpr_at_compile_time<TYPE1>::ret)==0) \
|
||||
|| (\
|
||||
(int(TYPE0::RowsAtCompileTime)==Eigen::Dynamic \
|
||||
|| int(TYPE1::RowsAtCompileTime)==Eigen::Dynamic \
|
||||
|| int(TYPE0::RowsAtCompileTime)==int(TYPE1::RowsAtCompileTime)) \
|
||||
&& (int(TYPE0::ColsAtCompileTime)==Eigen::Dynamic \
|
||||
|| int(TYPE1::ColsAtCompileTime)==Eigen::Dynamic \
|
||||
|| int(TYPE0::ColsAtCompileTime)==int(TYPE1::ColsAtCompileTime))\
|
||||
) \
|
||||
)
|
||||
|
||||
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE) \
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<TYPE>::IsInteger, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES)
|
||||
|
||||
|
||||
// static assertion failing if it is guaranteed at compile-time that the two matrix expression types have different sizes
|
||||
#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
|
||||
EIGEN_STATIC_ASSERT( \
|
||||
EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1),\
|
||||
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES)
|
||||
|
||||
#define EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) \
|
||||
EIGEN_STATIC_ASSERT((TYPE::RowsAtCompileTime == 1 || TYPE::RowsAtCompileTime == Dynamic) && \
|
||||
(TYPE::ColsAtCompileTime == 1 || TYPE::ColsAtCompileTime == Dynamic), \
|
||||
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS)
|
||||
|
||||
#define EIGEN_STATIC_ASSERT_LVALUE(Derived) \
|
||||
EIGEN_STATIC_ASSERT(Eigen::internal::is_lvalue<Derived>::value, \
|
||||
THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY)
|
||||
|
||||
#define EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) \
|
||||
EIGEN_STATIC_ASSERT((Eigen::internal::is_same<typename Eigen::internal::traits<Derived>::XprKind, ArrayXpr>::value), \
|
||||
THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES)
|
||||
|
||||
#define EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2) \
|
||||
EIGEN_STATIC_ASSERT((Eigen::internal::is_same<typename Eigen::internal::traits<Derived1>::XprKind, \
|
||||
typename Eigen::internal::traits<Derived2>::XprKind \
|
||||
>::value), \
|
||||
YOU_CANNOT_MIX_ARRAYS_AND_MATRICES)
|
||||
|
||||
// Check that a cost value is positive, and that is stay within a reasonable range
|
||||
// TODO this check could be enabled for internal debugging only
|
||||
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C) \
|
||||
EIGEN_STATIC_ASSERT((C)>=0 && (C)<=HugeCost*HugeCost, EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE);
|
||||
|
||||
#endif // EIGEN_STATIC_ASSERT_H
|
||||
300
examples/ThirdPartyLibs/Eigen/src/Core/util/SymbolicIndex.h
Normal file
300
examples/ThirdPartyLibs/Eigen/src/Core/util/SymbolicIndex.h
Normal file
@@ -0,0 +1,300 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_SYMBOLIC_INDEX_H
|
||||
#define EIGEN_SYMBOLIC_INDEX_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \namespace Eigen::Symbolic
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index.
|
||||
* Here is a simple example:
|
||||
*
|
||||
* \code
|
||||
* // First step, defines symbols:
|
||||
* struct x_tag {}; static const Symbolic::SymbolExpr<x_tag> x;
|
||||
* struct y_tag {}; static const Symbolic::SymbolExpr<y_tag> y;
|
||||
* struct z_tag {}; static const Symbolic::SymbolExpr<z_tag> z;
|
||||
*
|
||||
* // Defines an expression:
|
||||
* auto expr = (x+3)/y+z;
|
||||
*
|
||||
* // And evaluate it: (c++14)
|
||||
* std::cout << expr.eval(x=6,y=3,z=-13) << "\n";
|
||||
*
|
||||
* // In c++98/11, only one symbol per expression is supported for now:
|
||||
* auto expr98 = (3-x)/2;
|
||||
* std::cout << expr98.eval(x=6) << "\n";
|
||||
* \endcode
|
||||
*
|
||||
* It is currently only used internally to define and minipulate the placeholders::last and placeholders::end symbols in Eigen::seq and Eigen::seqN.
|
||||
*
|
||||
*/
|
||||
namespace Symbolic {
|
||||
|
||||
template<typename Tag> class Symbol;
|
||||
template<typename Arg0> class NegateExpr;
|
||||
template<typename Arg1,typename Arg2> class AddExpr;
|
||||
template<typename Arg1,typename Arg2> class ProductExpr;
|
||||
template<typename Arg1,typename Arg2> class QuotientExpr;
|
||||
|
||||
// A simple wrapper around an integral value to provide the eval method.
|
||||
// We could also use a free-function symbolic_eval...
|
||||
template<typename IndexType=Index>
|
||||
class ValueExpr {
|
||||
public:
|
||||
ValueExpr(IndexType val) : m_value(val) {}
|
||||
template<typename T>
|
||||
IndexType eval_impl(const T&) const { return m_value; }
|
||||
protected:
|
||||
IndexType m_value;
|
||||
};
|
||||
|
||||
// Specialization for compile-time value,
|
||||
// It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
|
||||
template<int N>
|
||||
class ValueExpr<internal::FixedInt<N> > {
|
||||
public:
|
||||
ValueExpr() {}
|
||||
template<typename T>
|
||||
Index eval_impl(const T&) const { return N; }
|
||||
};
|
||||
|
||||
|
||||
/** \class BaseExpr
|
||||
* \ingroup Core_Module
|
||||
* Common base class of any symbolic expressions
|
||||
*/
|
||||
template<typename Derived>
|
||||
class BaseExpr
|
||||
{
|
||||
public:
|
||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||
|
||||
/** Evaluate the expression given the \a values of the symbols.
|
||||
*
|
||||
* \param values defines the values of the symbols, it can either be a SymbolValue or a std::tuple of SymbolValue
|
||||
* as constructed by SymbolExpr::operator= operator.
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
Index eval(const T& values) const { return derived().eval_impl(values); }
|
||||
|
||||
#if EIGEN_HAS_CXX14
|
||||
template<typename... Types>
|
||||
Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); }
|
||||
#endif
|
||||
|
||||
NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }
|
||||
|
||||
AddExpr<Derived,ValueExpr<> > operator+(Index b) const
|
||||
{ return AddExpr<Derived,ValueExpr<> >(derived(), b); }
|
||||
AddExpr<Derived,ValueExpr<> > operator-(Index a) const
|
||||
{ return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
|
||||
ProductExpr<Derived,ValueExpr<> > operator*(Index a) const
|
||||
{ return ProductExpr<Derived,ValueExpr<> >(derived(),a); }
|
||||
QuotientExpr<Derived,ValueExpr<> > operator/(Index a) const
|
||||
{ return QuotientExpr<Derived,ValueExpr<> >(derived(),a); }
|
||||
|
||||
friend AddExpr<Derived,ValueExpr<> > operator+(Index a, const BaseExpr& b)
|
||||
{ return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
|
||||
friend AddExpr<NegateExpr<Derived>,ValueExpr<> > operator-(Index a, const BaseExpr& b)
|
||||
{ return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
|
||||
friend ProductExpr<ValueExpr<>,Derived> operator*(Index a, const BaseExpr& b)
|
||||
{ return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
|
||||
friend QuotientExpr<ValueExpr<>,Derived> operator/(Index a, const BaseExpr& b)
|
||||
{ return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }
|
||||
|
||||
template<int N>
|
||||
AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>) const
|
||||
{ return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N>) const
|
||||
{ return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
|
||||
template<int N>
|
||||
ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N>) const
|
||||
{ return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N>) const
|
||||
{ return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
|
||||
|
||||
template<int N>
|
||||
friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>, const BaseExpr& b)
|
||||
{ return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N>, const BaseExpr& b)
|
||||
{ return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N>, const BaseExpr& b)
|
||||
{ return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
|
||||
template<int N>
|
||||
friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N>, const BaseExpr& b)
|
||||
{ return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
|
||||
|
||||
#if (!EIGEN_HAS_CXX14)
|
||||
template<int N>
|
||||
AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)()) const
|
||||
{ return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N> (*)()) const
|
||||
{ return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
|
||||
template<int N>
|
||||
ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N> (*)()) const
|
||||
{ return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N> (*)()) const
|
||||
{ return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
|
||||
|
||||
template<int N>
|
||||
friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)(), const BaseExpr& b)
|
||||
{ return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N> (*)(), const BaseExpr& b)
|
||||
{ return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
|
||||
template<int N>
|
||||
friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N> (*)(), const BaseExpr& b)
|
||||
{ return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
|
||||
template<int N>
|
||||
friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N> (*)(), const BaseExpr& b)
|
||||
{ return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
|
||||
#endif
|
||||
|
||||
|
||||
template<typename OtherDerived>
|
||||
AddExpr<Derived,OtherDerived> operator+(const BaseExpr<OtherDerived> &b) const
|
||||
{ return AddExpr<Derived,OtherDerived>(derived(), b.derived()); }
|
||||
|
||||
template<typename OtherDerived>
|
||||
AddExpr<Derived,NegateExpr<OtherDerived> > operator-(const BaseExpr<OtherDerived> &b) const
|
||||
{ return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); }
|
||||
|
||||
template<typename OtherDerived>
|
||||
ProductExpr<Derived,OtherDerived> operator*(const BaseExpr<OtherDerived> &b) const
|
||||
{ return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); }
|
||||
|
||||
template<typename OtherDerived>
|
||||
QuotientExpr<Derived,OtherDerived> operator/(const BaseExpr<OtherDerived> &b) const
|
||||
{ return QuotientExpr<Derived,OtherDerived>(derived(), b.derived()); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_symbolic {
|
||||
// BaseExpr has no conversion ctor, so we only have to check whether T can be staticaly cast to its base class BaseExpr<T>.
|
||||
enum { value = internal::is_convertible<T,BaseExpr<T> >::value };
|
||||
};
|
||||
|
||||
// Specialization for functions, because is_convertible fails in this case.
|
||||
// Useful in c++98/11 mode when testing is_symbolic<decltype(fix<N>)>
|
||||
template<typename T>
|
||||
struct is_symbolic<T (*)()> {
|
||||
enum { value = false };
|
||||
};
|
||||
|
||||
/** Represents the actual value of a symbol identified by its tag
|
||||
*
|
||||
* It is the return type of SymbolValue::operator=, and most of the time this is only way it is used.
|
||||
*/
|
||||
template<typename Tag>
|
||||
class SymbolValue
|
||||
{
|
||||
public:
|
||||
/** Default constructor from the value \a val */
|
||||
SymbolValue(Index val) : m_value(val) {}
|
||||
|
||||
/** \returns the stored value of the symbol */
|
||||
Index value() const { return m_value; }
|
||||
protected:
|
||||
Index m_value;
|
||||
};
|
||||
|
||||
/** Expression of a symbol uniquely identified by the template parameter type \c tag */
|
||||
template<typename tag>
|
||||
class SymbolExpr : public BaseExpr<SymbolExpr<tag> >
|
||||
{
|
||||
public:
|
||||
/** Alias to the template parameter \c tag */
|
||||
typedef tag Tag;
|
||||
|
||||
SymbolExpr() {}
|
||||
|
||||
/** Associate the value \a val to the given symbol \c *this, uniquely identified by its \c Tag.
|
||||
*
|
||||
* The returned object should be passed to ExprBase::eval() to evaluate a given expression with this specified runtime-time value.
|
||||
*/
|
||||
SymbolValue<Tag> operator=(Index val) const {
|
||||
return SymbolValue<Tag>(val);
|
||||
}
|
||||
|
||||
Index eval_impl(const SymbolValue<Tag> &values) const { return values.value(); }
|
||||
|
||||
#if EIGEN_HAS_CXX14
|
||||
// C++14 versions suitable for multiple symbols
|
||||
template<typename... Types>
|
||||
Index eval_impl(const std::tuple<Types...>& values) const { return std::get<SymbolValue<Tag> >(values).value(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename Arg0>
|
||||
class NegateExpr : public BaseExpr<NegateExpr<Arg0> >
|
||||
{
|
||||
public:
|
||||
NegateExpr(const Arg0& arg0) : m_arg0(arg0) {}
|
||||
|
||||
template<typename T>
|
||||
Index eval_impl(const T& values) const { return -m_arg0.eval_impl(values); }
|
||||
protected:
|
||||
Arg0 m_arg0;
|
||||
};
|
||||
|
||||
template<typename Arg0, typename Arg1>
|
||||
class AddExpr : public BaseExpr<AddExpr<Arg0,Arg1> >
|
||||
{
|
||||
public:
|
||||
AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
|
||||
|
||||
template<typename T>
|
||||
Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) + m_arg1.eval_impl(values); }
|
||||
protected:
|
||||
Arg0 m_arg0;
|
||||
Arg1 m_arg1;
|
||||
};
|
||||
|
||||
template<typename Arg0, typename Arg1>
|
||||
class ProductExpr : public BaseExpr<ProductExpr<Arg0,Arg1> >
|
||||
{
|
||||
public:
|
||||
ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
|
||||
|
||||
template<typename T>
|
||||
Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) * m_arg1.eval_impl(values); }
|
||||
protected:
|
||||
Arg0 m_arg0;
|
||||
Arg1 m_arg1;
|
||||
};
|
||||
|
||||
template<typename Arg0, typename Arg1>
|
||||
class QuotientExpr : public BaseExpr<QuotientExpr<Arg0,Arg1> >
|
||||
{
|
||||
public:
|
||||
QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
|
||||
|
||||
template<typename T>
|
||||
Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) / m_arg1.eval_impl(values); }
|
||||
protected:
|
||||
Arg0 m_arg0;
|
||||
Arg1 m_arg1;
|
||||
};
|
||||
|
||||
} // end namespace Symbolic
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SYMBOLIC_INDEX_H
|
||||
835
examples/ThirdPartyLibs/Eigen/src/Core/util/XprHelper.h
Normal file
835
examples/ThirdPartyLibs/Eigen/src/Core/util/XprHelper.h
Normal file
@@ -0,0 +1,835 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_XPRHELPER_H
|
||||
#define EIGEN_XPRHELPER_H
|
||||
|
||||
// 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 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& ) {}
|
||||
#else
|
||||
#define EIGEN_EMPTY_STRUCT_CTOR(X)
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename IndexDest, typename IndexSrc>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline IndexDest convert_index(const IndexSrc& idx) {
|
||||
// for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
|
||||
eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
|
||||
return IndexDest(idx);
|
||||
}
|
||||
|
||||
// true if T can be considered as an integral index (i.e., and integral type or enum)
|
||||
template<typename T> struct is_valid_index_type
|
||||
{
|
||||
enum { value =
|
||||
#if EIGEN_HAS_TYPE_TRAITS
|
||||
internal::is_integral<T>::value || std::is_enum<T>::value
|
||||
#else
|
||||
// without C++11, we use is_convertible to Index instead of is_integral in order to treat enums as Index.
|
||||
internal::is_convertible<T,Index>::value
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
// promote_scalar_arg is an helper used in operation between an expression and a scalar, like:
|
||||
// expression * scalar
|
||||
// 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.
|
||||
// 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.
|
||||
// Then the logic is as follows:
|
||||
// - if the operation is natively supported as defined by IsSupported, then the scalar type is not promoted, and T is returned.
|
||||
// - 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.
|
||||
// - otherwise, ExprScalar is returned if T is implicitly convertible to ExprScalar AND that this does not imply a float to integer conversion.
|
||||
// - In all other cases, the promoted type is not defined, and the respective operation is thus invalid and not available (SFINAE).
|
||||
template<typename ExprScalar,typename T, bool IsSupported>
|
||||
struct promote_scalar_arg;
|
||||
|
||||
template<typename S,typename T>
|
||||
struct promote_scalar_arg<S,T,true>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// Recursively check safe conversion to PromotedType, and then ExprScalar if they are different.
|
||||
template<typename ExprScalar,typename T,typename PromotedType,
|
||||
bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value,
|
||||
bool IsSafe = NumTraits<T>::IsInteger || !NumTraits<PromotedType>::IsInteger>
|
||||
struct promote_scalar_arg_unsupported;
|
||||
|
||||
// Start recursion with NumTraits<ExprScalar>::Literal
|
||||
template<typename S,typename T>
|
||||
struct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {};
|
||||
|
||||
// We found a match!
|
||||
template<typename S,typename T, typename PromotedType>
|
||||
struct promote_scalar_arg_unsupported<S,T,PromotedType,true,true>
|
||||
{
|
||||
typedef PromotedType type;
|
||||
};
|
||||
|
||||
// No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different,
|
||||
// so let's try to promote to ExprScalar
|
||||
template<typename ExprScalar,typename T, typename PromotedType>
|
||||
struct promote_scalar_arg_unsupported<ExprScalar,T,PromotedType,false,true>
|
||||
: promote_scalar_arg_unsupported<ExprScalar,T,ExprScalar>
|
||||
{};
|
||||
|
||||
// Unsafe real-to-integer, let's stop.
|
||||
template<typename S,typename T, typename PromotedType, bool ConvertibleToLiteral>
|
||||
struct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {};
|
||||
|
||||
// T is not even convertible to ExprScalar, let's stop.
|
||||
template<typename S,typename T>
|
||||
struct promote_scalar_arg_unsupported<S,T,S,false,true> {};
|
||||
|
||||
//classes inheriting no_assignment_operator don't generate a default operator=.
|
||||
class no_assignment_operator
|
||||
{
|
||||
private:
|
||||
no_assignment_operator& operator=(const no_assignment_operator&);
|
||||
};
|
||||
|
||||
/** \internal return the index type with the largest number of bits */
|
||||
template<typename I1, typename I2>
|
||||
struct promote_index_type
|
||||
{
|
||||
typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
|
||||
};
|
||||
|
||||
/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that
|
||||
* can be accessed using value() and setValue().
|
||||
* Otherwise, this class is an empty structure and value() just returns the template parameter Value.
|
||||
*/
|
||||
template<typename T, int Value> class variable_if_dynamic
|
||||
{
|
||||
public:
|
||||
EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
|
||||
};
|
||||
|
||||
template<typename T> class variable_if_dynamic<T, Dynamic>
|
||||
{
|
||||
T m_value;
|
||||
EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); }
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value) : m_value(value) {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return m_value; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
|
||||
};
|
||||
|
||||
/** \internal like variable_if_dynamic but for DynamicIndex
|
||||
*/
|
||||
template<typename T, int Value> class variable_if_dynamicindex
|
||||
{
|
||||
public:
|
||||
EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
|
||||
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
|
||||
};
|
||||
|
||||
template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
|
||||
{
|
||||
T m_value;
|
||||
EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {}
|
||||
EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
|
||||
};
|
||||
|
||||
template<typename T> struct functor_traits
|
||||
{
|
||||
enum
|
||||
{
|
||||
Cost = 10,
|
||||
PacketAccess = false,
|
||||
IsRepeatable = false
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T> struct packet_traits;
|
||||
|
||||
template<typename T> struct unpacket_traits
|
||||
{
|
||||
typedef T type;
|
||||
typedef T half;
|
||||
enum
|
||||
{
|
||||
size = 1,
|
||||
alignment = 1
|
||||
};
|
||||
};
|
||||
|
||||
template<int Size, typename PacketType,
|
||||
bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
|
||||
struct find_best_packet_helper;
|
||||
|
||||
template< int Size, typename PacketType>
|
||||
struct find_best_packet_helper<Size,PacketType,true>
|
||||
{
|
||||
typedef PacketType type;
|
||||
};
|
||||
|
||||
template<int Size, typename PacketType>
|
||||
struct find_best_packet_helper<Size,PacketType,false>
|
||||
{
|
||||
typedef typename find_best_packet_helper<Size,typename unpacket_traits<PacketType>::half>::type type;
|
||||
};
|
||||
|
||||
template<typename T, int Size>
|
||||
struct find_best_packet
|
||||
{
|
||||
typedef typename find_best_packet_helper<Size,typename packet_traits<T>::type>::type type;
|
||||
};
|
||||
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
|
||||
template<int ArrayBytes, int AlignmentBytes,
|
||||
bool Match = bool((ArrayBytes%AlignmentBytes)==0),
|
||||
bool TryHalf = bool(EIGEN_MIN_ALIGN_BYTES<AlignmentBytes) >
|
||||
struct compute_default_alignment_helper
|
||||
{
|
||||
enum { value = 0 };
|
||||
};
|
||||
|
||||
template<int ArrayBytes, int AlignmentBytes, bool TryHalf>
|
||||
struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
|
||||
{
|
||||
enum { value = AlignmentBytes };
|
||||
};
|
||||
|
||||
template<int ArrayBytes, int AlignmentBytes>
|
||||
struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
|
||||
{
|
||||
// current packet too large, try with an half-packet
|
||||
enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
|
||||
};
|
||||
#else
|
||||
// If static alignment is disabled, no need to bother.
|
||||
// This also avoids a division by zero in "bool Match = bool((ArrayBytes%AlignmentBytes)==0)"
|
||||
template<int ArrayBytes, int AlignmentBytes>
|
||||
struct compute_default_alignment_helper
|
||||
{
|
||||
enum { value = 0 };
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename T, int Size> struct compute_default_alignment {
|
||||
enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct compute_default_alignment<T,Dynamic> {
|
||||
enum { value = EIGEN_MAX_ALIGN_BYTES };
|
||||
};
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols,
|
||||
int _Options = AutoAlign |
|
||||
( (_Rows==1 && _Cols!=1) ? RowMajor
|
||||
: (_Cols==1 && _Rows!=1) ? ColMajor
|
||||
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
|
||||
int _MaxRows = _Rows,
|
||||
int _MaxCols = _Cols
|
||||
> class make_proper_matrix_type
|
||||
{
|
||||
enum {
|
||||
IsColVector = _Cols==1 && _Rows!=1,
|
||||
IsRowVector = _Rows==1 && _Cols!=1,
|
||||
Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
|
||||
: IsRowVector ? (_Options | RowMajor) & ~ColMajor
|
||||
: _Options
|
||||
};
|
||||
public:
|
||||
typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
|
||||
};
|
||||
|
||||
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<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
|
||||
*/
|
||||
|
||||
template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
|
||||
template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
|
||||
template<typename T> struct plain_matrix_type<T,Dense>
|
||||
{
|
||||
typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, traits<T>::Flags>::type type;
|
||||
};
|
||||
template<typename T> struct plain_matrix_type<T,DiagonalShape>
|
||||
{
|
||||
typedef typename T::PlainObject type;
|
||||
};
|
||||
|
||||
template<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
|
||||
{
|
||||
typedef Matrix<typename traits<T>::Scalar,
|
||||
traits<T>::RowsAtCompileTime,
|
||||
traits<T>::ColsAtCompileTime,
|
||||
AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||
traits<T>::MaxRowsAtCompileTime,
|
||||
traits<T>::MaxColsAtCompileTime
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags>
|
||||
{
|
||||
typedef Array<typename traits<T>::Scalar,
|
||||
traits<T>::RowsAtCompileTime,
|
||||
traits<T>::ColsAtCompileTime,
|
||||
AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||
traits<T>::MaxRowsAtCompileTime,
|
||||
traits<T>::MaxColsAtCompileTime
|
||||
> type;
|
||||
};
|
||||
|
||||
/* eval : the return type of eval(). For matrices, this is just a const reference
|
||||
* in order to avoid a useless copy
|
||||
*/
|
||||
|
||||
template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
|
||||
|
||||
template<typename T> struct eval<T,Dense>
|
||||
{
|
||||
typedef typename plain_matrix_type<T>::type type;
|
||||
// typedef typename T::PlainObject type;
|
||||
// typedef T::Matrix<typename traits<T>::Scalar,
|
||||
// traits<T>::RowsAtCompileTime,
|
||||
// traits<T>::ColsAtCompileTime,
|
||||
// AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
|
||||
// traits<T>::MaxRowsAtCompileTime,
|
||||
// traits<T>::MaxColsAtCompileTime
|
||||
// > 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>
|
||||
{
|
||||
typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
|
||||
};
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
|
||||
{
|
||||
typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
|
||||
};
|
||||
|
||||
|
||||
/* similar to plain_matrix_type, but using the evaluator's Flags */
|
||||
template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval;
|
||||
|
||||
template<typename T>
|
||||
struct plain_object_eval<T,Dense>
|
||||
{
|
||||
typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, evaluator<T>::Flags>::type type;
|
||||
};
|
||||
|
||||
|
||||
/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
|
||||
*/
|
||||
template<typename T> struct plain_matrix_type_column_major
|
||||
{
|
||||
enum { Rows = traits<T>::RowsAtCompileTime,
|
||||
Cols = traits<T>::ColsAtCompileTime,
|
||||
MaxRows = traits<T>::MaxRowsAtCompileTime,
|
||||
MaxCols = traits<T>::MaxColsAtCompileTime
|
||||
};
|
||||
typedef Matrix<typename traits<T>::Scalar,
|
||||
Rows,
|
||||
Cols,
|
||||
(MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
|
||||
MaxRows,
|
||||
MaxCols
|
||||
> type;
|
||||
};
|
||||
|
||||
/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
|
||||
*/
|
||||
template<typename T> struct plain_matrix_type_row_major
|
||||
{
|
||||
enum { Rows = traits<T>::RowsAtCompileTime,
|
||||
Cols = traits<T>::ColsAtCompileTime,
|
||||
MaxRows = traits<T>::MaxRowsAtCompileTime,
|
||||
MaxCols = traits<T>::MaxColsAtCompileTime
|
||||
};
|
||||
typedef Matrix<typename traits<T>::Scalar,
|
||||
Rows,
|
||||
Cols,
|
||||
(MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
|
||||
MaxRows,
|
||||
MaxCols
|
||||
> type;
|
||||
};
|
||||
|
||||
/** \internal The reference selector for template expressions. The idea is that we don't
|
||||
* need to use references for expressions since they are light weight proxy
|
||||
* objects which should generate no copying overhead. */
|
||||
template <typename T>
|
||||
struct ref_selector
|
||||
{
|
||||
typedef typename conditional<
|
||||
bool(traits<T>::Flags & NestByRefBit),
|
||||
T const&,
|
||||
const T
|
||||
>::type type;
|
||||
|
||||
typedef typename conditional<
|
||||
bool(traits<T>::Flags & NestByRefBit),
|
||||
T &,
|
||||
T
|
||||
>::type non_const_type;
|
||||
};
|
||||
|
||||
/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */
|
||||
template<typename T1, typename T2>
|
||||
struct transfer_constness
|
||||
{
|
||||
typedef typename conditional<
|
||||
bool(internal::is_const<T1>::value),
|
||||
typename internal::add_const_on_value_type<T2>::type,
|
||||
T2
|
||||
>::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
|
||||
* 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.
|
||||
*
|
||||
* \tparam T the type of the expression being nested.
|
||||
* \tparam n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
|
||||
* \tparam PlainObject the type of the temporary if needed.
|
||||
*/
|
||||
template<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval
|
||||
{
|
||||
enum {
|
||||
ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
|
||||
CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a tempory?
|
||||
// Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
|
||||
// This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
|
||||
// for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
|
||||
// Another solution could be to count the number of temps?
|
||||
NAsInteger = n == Dynamic ? HugeCost : n,
|
||||
CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
|
||||
CostNoEval = NAsInteger * CoeffReadCost,
|
||||
Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval))
|
||||
};
|
||||
|
||||
typedef typename conditional<Evaluate, PlainObject, typename ref_selector<T>::type>::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline T* const_cast_ptr(const T* ptr)
|
||||
{
|
||||
return const_cast<T*>(ptr);
|
||||
}
|
||||
|
||||
template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
|
||||
struct dense_xpr_base
|
||||
{
|
||||
/* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
struct dense_xpr_base<Derived, MatrixXpr>
|
||||
{
|
||||
typedef MatrixBase<Derived> type;
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
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;
|
||||
};
|
||||
|
||||
template<typename XprType, typename CastType> struct cast_return_type
|
||||
{
|
||||
typedef typename XprType::Scalar CurrentScalarType;
|
||||
typedef typename remove_all<CastType>::type _CastType;
|
||||
typedef typename _CastType::Scalar NewScalarType;
|
||||
typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value,
|
||||
const XprType&,CastType>::type type;
|
||||
};
|
||||
|
||||
template <typename A, typename B> struct promote_storage_type;
|
||||
|
||||
template <typename A> struct promote_storage_type<A,A>
|
||||
{
|
||||
typedef A ret;
|
||||
};
|
||||
template <typename A> struct promote_storage_type<A, const A>
|
||||
{
|
||||
typedef A ret;
|
||||
};
|
||||
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
|
||||
* sparse op dense -> sparse
|
||||
* dense op sparse -> sparse
|
||||
* \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 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 Functor> struct cwise_promote_storage_type<Sparse,Dense,Functor> { typedef Sparse ret; };
|
||||
template <typename Functor> struct cwise_promote_storage_type<Dense,Sparse,Functor> { typedef Sparse ret; };
|
||||
|
||||
template <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order {
|
||||
enum { value = LhsOrder };
|
||||
};
|
||||
|
||||
template <typename LhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder> { enum { value = RhsOrder }; };
|
||||
template <typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder> { enum { value = LhsOrder }; };
|
||||
template <int Order> struct cwise_promote_storage_order<Sparse,Sparse,Order,Order> { enum { value = Order }; };
|
||||
|
||||
|
||||
/** \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.
|
||||
* \tparam Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType.
|
||||
*/
|
||||
template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
|
||||
struct plain_row_type
|
||||
{
|
||||
typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
|
||||
ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
|
||||
typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
|
||||
ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
|
||||
|
||||
typedef typename conditional<
|
||||
is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
|
||||
MatrixRowType,
|
||||
ArrayRowType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
|
||||
struct plain_col_type
|
||||
{
|
||||
typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
|
||||
ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
|
||||
typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
|
||||
ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
|
||||
|
||||
typedef typename conditional<
|
||||
is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
|
||||
MatrixColType,
|
||||
ArrayColType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
|
||||
struct plain_diag_type
|
||||
{
|
||||
enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
|
||||
max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
|
||||
};
|
||||
typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType;
|
||||
typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType;
|
||||
|
||||
typedef typename conditional<
|
||||
is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
|
||||
MatrixDiagType,
|
||||
ArrayDiagType
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename Expr,typename Scalar = typename Expr::Scalar>
|
||||
struct plain_constant_type
|
||||
{
|
||||
enum { Options = (traits<Expr>::Flags&RowMajorBit)?RowMajor:0 };
|
||||
|
||||
typedef Array<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime,
|
||||
Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> array_type;
|
||||
|
||||
typedef Matrix<Scalar, traits<Expr>::RowsAtCompileTime, traits<Expr>::ColsAtCompileTime,
|
||||
Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> matrix_type;
|
||||
|
||||
typedef CwiseNullaryOp<scalar_constant_op<Scalar>, const typename conditional<is_same< typename traits<Expr>::XprKind, MatrixXpr >::value, matrix_type, array_type>::type > type;
|
||||
};
|
||||
|
||||
template<typename ExpressionType>
|
||||
struct is_lvalue
|
||||
{
|
||||
enum { value = (!bool(is_const<ExpressionType>::value)) &&
|
||||
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; };
|
||||
|
||||
template<typename T1, typename T2>
|
||||
bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<has_direct_access<T1>::ret&&has_direct_access<T2>::ret, T1>::type * = 0)
|
||||
{
|
||||
return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
bool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Internal helper defining the cost of a scalar division for the type T.
|
||||
// The default heuristic can be specialized for each scalar type and architecture.
|
||||
template<typename T,bool Vectorized=false,typename EnableIf = void>
|
||||
struct scalar_div_cost {
|
||||
enum { value = 8*NumTraits<T>::MulCost };
|
||||
};
|
||||
|
||||
template<typename T,bool Vectorized>
|
||||
struct scalar_div_cost<std::complex<T>, Vectorized> {
|
||||
enum { value = 2*scalar_div_cost<T>::value
|
||||
+ 6*NumTraits<T>::MulCost
|
||||
+ 3*NumTraits<T>::AddCost
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<bool Vectorized>
|
||||
struct scalar_div_cost<signed long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 24 }; };
|
||||
template<bool Vectorized>
|
||||
struct scalar_div_cost<unsigned long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 21 }; };
|
||||
|
||||
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
std::string demangle_traversal(int t)
|
||||
{
|
||||
if(t==DefaultTraversal) return "DefaultTraversal";
|
||||
if(t==LinearTraversal) return "LinearTraversal";
|
||||
if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
|
||||
if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
|
||||
if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
|
||||
return "?";
|
||||
}
|
||||
std::string demangle_unrolling(int t)
|
||||
{
|
||||
if(t==NoUnrolling) return "NoUnrolling";
|
||||
if(t==InnerUnrolling) return "InnerUnrolling";
|
||||
if(t==CompleteUnrolling) return "CompleteUnrolling";
|
||||
return "?";
|
||||
}
|
||||
std::string demangle_flags(int f)
|
||||
{
|
||||
std::string res;
|
||||
if(f&RowMajorBit) res += " | RowMajor";
|
||||
if(f&PacketAccessBit) res += " | Packet";
|
||||
if(f&LinearAccessBit) res += " | Linear";
|
||||
if(f&LvalueBit) res += " | Lvalue";
|
||||
if(f&DirectAccessBit) res += " | Direct";
|
||||
if(f&NestByRefBit) res += " | NestByRef";
|
||||
if(f&NoPreferredStorageOrderBit) res += " | NoPreferredStorageOrderBit";
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
/** \class ScalarBinaryOpTraits
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief Determines whether the given binary operation of two numeric types is allowed and what the scalar return type is.
|
||||
*
|
||||
* This class permits to control the scalar return type of any binary operation performed on two different scalar types through (partial) template specializations.
|
||||
*
|
||||
* 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.
|
||||
* You can let %Eigen knows that by defining:
|
||||
\code
|
||||
template<typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<U1,U2,BinaryOp> { typedef U3 ReturnType; };
|
||||
template<typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<U2,U1,BinaryOp> { typedef U3 ReturnType; };
|
||||
\endcode
|
||||
* You can then explicitly disable some particular operations to get more explicit error messages:
|
||||
\code
|
||||
template<>
|
||||
struct ScalarBinaryOpTraits<U1,U2,internal::scalar_max_op<U1,U2> > {};
|
||||
\endcode
|
||||
* Or customize the return type for individual operation:
|
||||
\code
|
||||
template<>
|
||||
struct ScalarBinaryOpTraits<U1,U2,internal::scalar_sum_op<U1,U2> > { typedef U1 ReturnType; };
|
||||
\endcode
|
||||
*
|
||||
* By default, the following generic combinations are supported:
|
||||
<table class="manual">
|
||||
<tr><th>ScalarA</th><th>ScalarB</th><th>BinaryOp</th><th>ReturnType</th><th>Note</th></tr>
|
||||
<tr ><td>\c T </td><td>\c T </td><td>\c * </td><td>\c T </td><td></td></tr>
|
||||
<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>
|
||||
<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>
|
||||
</table>
|
||||
*
|
||||
* \sa CwiseBinaryOp
|
||||
*/
|
||||
template<typename ScalarA, typename ScalarB, typename BinaryOp=internal::scalar_product_op<ScalarA,ScalarB> >
|
||||
struct ScalarBinaryOpTraits
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
// for backward compatibility, use the hints given by the (deprecated) internal::scalar_product_traits class.
|
||||
: internal::scalar_product_traits<ScalarA,ScalarB>
|
||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||
{};
|
||||
|
||||
template<typename T, typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<T,T,BinaryOp>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
};
|
||||
|
||||
template <typename T, typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<T, typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, BinaryOp>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
};
|
||||
template <typename T, typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, T, BinaryOp>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
};
|
||||
|
||||
// For Matrix * Permutation
|
||||
template<typename T, typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<T,void,BinaryOp>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
};
|
||||
|
||||
// For Permutation * Matrix
|
||||
template<typename T, typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<void,T,BinaryOp>
|
||||
{
|
||||
typedef T ReturnType;
|
||||
};
|
||||
|
||||
// for Permutation*Permutation
|
||||
template<typename BinaryOp>
|
||||
struct ScalarBinaryOpTraits<void,void,BinaryOp>
|
||||
{
|
||||
typedef void ReturnType;
|
||||
};
|
||||
|
||||
// We require Lhs and Rhs to have "compatible" scalar types.
|
||||
// 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((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::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