mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Apply clang-format
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
|
||||
#ifndef EIGEN_USE_CUSTOM_PLAIN_ASSERT
|
||||
// Disable new custom asserts by default for now.
|
||||
#define EIGEN_USE_CUSTOM_PLAIN_ASSERT 0
|
||||
#define EIGEN_USE_CUSTOM_PLAIN_ASSERT 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_USE_CUSTOM_PLAIN_ASSERT
|
||||
@@ -41,11 +41,11 @@
|
||||
#ifndef EIGEN_HAS_BUILTIN_FILE
|
||||
// Clang can check if __builtin_FILE() is supported.
|
||||
// GCC > 5, MSVC 2019 14.26 (1926) all have __builtin_FILE().
|
||||
//
|
||||
//
|
||||
// For NVCC, it's more complicated. Through trial-and-error:
|
||||
// - nvcc+gcc supports __builtin_FILE() on host, and on device after CUDA 11.
|
||||
// - nvcc+msvc supports __builtin_FILE() only after CUDA 11.
|
||||
#if (EIGEN_HAS_BUILTIN(__builtin_FILE) && (EIGEN_COMP_CLANG || !defined(EIGEN_CUDA_ARCH))) || \
|
||||
#if (EIGEN_HAS_BUILTIN(__builtin_FILE) && (EIGEN_COMP_CLANG || !defined(EIGEN_CUDA_ARCH))) || \
|
||||
(EIGEN_GNUC_STRICT_AT_LEAST(5, 0, 0) && (EIGEN_COMP_NVCC >= 110000 || !defined(EIGEN_CUDA_ARCH))) || \
|
||||
(EIGEN_COMP_MSVC >= 1926 && (!EIGEN_COMP_NVCC || EIGEN_COMP_NVCC >= 110000))
|
||||
#define EIGEN_HAS_BUILTIN_FILE 1
|
||||
@@ -55,12 +55,12 @@
|
||||
#endif // EIGEN_HAS_BUILTIN_FILE
|
||||
|
||||
#if EIGEN_HAS_BUILTIN_FILE
|
||||
# define EIGEN_BUILTIN_FILE __builtin_FILE()
|
||||
# define EIGEN_BUILTIN_LINE __builtin_LINE()
|
||||
#define EIGEN_BUILTIN_FILE __builtin_FILE()
|
||||
#define EIGEN_BUILTIN_LINE __builtin_LINE()
|
||||
#else
|
||||
// Default (potentially unsafe) values.
|
||||
# define EIGEN_BUILTIN_FILE __FILE__
|
||||
# define EIGEN_BUILTIN_LINE __LINE__
|
||||
#define EIGEN_BUILTIN_FILE __FILE__
|
||||
#define EIGEN_BUILTIN_LINE __LINE__
|
||||
#endif
|
||||
|
||||
// Use __PRETTY_FUNCTION__ when available, since it is more descriptive, as
|
||||
@@ -68,45 +68,39 @@
|
||||
// This should still be okay ODR-wise since it is a compiler-specific fixed
|
||||
// value. Mixing compilers will likely lead to ODR violations anyways.
|
||||
#if EIGEN_COMP_MSVC
|
||||
# define EIGEN_BUILTIN_FUNCTION __FUNCSIG__
|
||||
#define EIGEN_BUILTIN_FUNCTION __FUNCSIG__
|
||||
#elif EIGEN_COMP_GNUC
|
||||
# define EIGEN_BUILTIN_FUNCTION __PRETTY_FUNCTION__
|
||||
#define EIGEN_BUILTIN_FUNCTION __PRETTY_FUNCTION__
|
||||
#else
|
||||
# define EIGEN_BUILTIN_FUNCTION __func__
|
||||
#define EIGEN_BUILTIN_FUNCTION __func__
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
// Generic default assert handler.
|
||||
template<typename EnableIf = void, typename... EmptyArgs>
|
||||
template <typename EnableIf = void, typename... EmptyArgs>
|
||||
struct assert_handler_impl {
|
||||
EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE
|
||||
static inline void run(const char* expression, const char* file, unsigned line, const char* function) {
|
||||
EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE static inline void run(const char* expression, const char* file, unsigned line,
|
||||
const char* function) {
|
||||
#ifdef EIGEN_GPU_COMPILE_PHASE
|
||||
// GPU device code doesn't allow stderr or abort, so use printf and raise an
|
||||
// illegal instruction exception to trigger a kernel failure.
|
||||
#ifndef EIGEN_NO_IO
|
||||
printf("Assertion failed at %s:%u in %s: %s\n",
|
||||
file == nullptr ? "<file>" : file,
|
||||
line,
|
||||
function == nullptr ? "<function>" : function,
|
||||
expression);
|
||||
printf("Assertion failed at %s:%u in %s: %s\n", file == nullptr ? "<file>" : file, line,
|
||||
function == nullptr ? "<function>" : function, expression);
|
||||
#endif
|
||||
__trap();
|
||||
|
||||
|
||||
#else // EIGEN_GPU_COMPILE_PHASE
|
||||
|
||||
// Print to stderr and abort, as specified in <cassert>.
|
||||
#ifndef EIGEN_NO_IO
|
||||
fprintf(stderr, "Assertion failed at %s:%u in %s: %s\n",
|
||||
file == nullptr ? "<file>" : file,
|
||||
line,
|
||||
function == nullptr ? "<function>" : function,
|
||||
expression);
|
||||
fprintf(stderr, "Assertion failed at %s:%u in %s: %s\n", file == nullptr ? "<file>" : file, line,
|
||||
function == nullptr ? "<function>" : function, expression);
|
||||
#endif
|
||||
std::abort();
|
||||
|
||||
|
||||
#endif // EIGEN_GPU_COMPILE_PHASE
|
||||
}
|
||||
};
|
||||
@@ -119,36 +113,34 @@ struct assert_handler_impl {
|
||||
// we could simply test for __unix__ or similar). The handler function name
|
||||
// seems to depend on the specific toolchain implementation, and differs between
|
||||
// compilers, platforms, OSes, etc. Hence, we detect support via SFINAE.
|
||||
template<typename... EmptyArgs>
|
||||
struct assert_handler_impl<
|
||||
void_t<decltype(__assert_fail(
|
||||
(const char*)nullptr, // expression
|
||||
(const char*)nullptr, // file
|
||||
0, // line
|
||||
(const char*)nullptr, // function
|
||||
std::declval<EmptyArgs>()... // Empty substitution required for SFINAE.
|
||||
))>, EmptyArgs... > {
|
||||
EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE
|
||||
static inline void run(const char* expression, const char* file, unsigned line, const char* function) {
|
||||
template <typename... EmptyArgs>
|
||||
struct assert_handler_impl<void_t<decltype(__assert_fail((const char*)nullptr, // expression
|
||||
(const char*)nullptr, // file
|
||||
0, // line
|
||||
(const char*)nullptr, // function
|
||||
std::declval<EmptyArgs>()... // Empty substitution required
|
||||
// for SFINAE.
|
||||
))>,
|
||||
EmptyArgs...> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE static inline void run(const char* expression, const char* file, unsigned line,
|
||||
const char* function) {
|
||||
// GCC requires this call to be dependent on the template parameters.
|
||||
__assert_fail(expression, file, line, function, std::declval<EmptyArgs>()...);
|
||||
}
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE
|
||||
inline void __assert_handler(const char* expression, const char* file, unsigned line, const char* function) {
|
||||
EIGEN_DEVICE_FUNC EIGEN_DONT_INLINE inline void __assert_handler(const char* expression, const char* file,
|
||||
unsigned line, const char* function) {
|
||||
assert_handler_impl<>::run(expression, file, line, function);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Eigen
|
||||
|
||||
#define eigen_plain_assert(expression) \
|
||||
(EIGEN_PREDICT_FALSE(!(expression)) ? \
|
||||
Eigen::internal::__assert_handler(#expression, \
|
||||
EIGEN_BUILTIN_FILE, \
|
||||
EIGEN_BUILTIN_LINE, \
|
||||
EIGEN_BUILTIN_FUNCTION) : (void)0)
|
||||
#define eigen_plain_assert(expression) \
|
||||
(EIGEN_PREDICT_FALSE(!(expression)) ? Eigen::internal::__assert_handler(#expression, EIGEN_BUILTIN_FILE, \
|
||||
EIGEN_BUILTIN_LINE, EIGEN_BUILTIN_FUNCTION) \
|
||||
: (void)0)
|
||||
|
||||
#else // EIGEN_USE_CUSTOM_PLAIN_ASSERT
|
||||
|
||||
@@ -157,7 +149,7 @@ inline void __assert_handler(const char* expression, const char* file, unsigned
|
||||
|
||||
#endif // EIGEN_USE_CUSTOM_PLAIN_ASSERT
|
||||
|
||||
#else // EIGEN_NO_DEBUG
|
||||
#else // EIGEN_NO_DEBUG
|
||||
|
||||
#define eigen_plain_assert(condition) ((void)0)
|
||||
|
||||
|
||||
@@ -21,45 +21,44 @@ 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>
|
||||
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>
|
||||
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, typename Packet, int StorageOrder, bool Conjugate = false, bool PanelMode = false>
|
||||
template <typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, typename Packet, 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, int ResInnerStride>
|
||||
template <typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, typename RhsScalar,
|
||||
int RhsStorageOrder, bool ConjugateRhs, int ResStorageOrder, int ResInnerStride>
|
||||
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>
|
||||
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<typename From,typename To> struct get_factor {
|
||||
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>
|
||||
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>
|
||||
template <typename Scalar, typename Index>
|
||||
class BlasVectorMapper {
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasVectorMapper(Scalar *data) : m_data(data) {}
|
||||
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];
|
||||
}
|
||||
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);
|
||||
@@ -67,97 +66,91 @@ class BlasVectorMapper {
|
||||
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC bool aligned(Index i) const {
|
||||
return (std::uintptr_t(m_data+i)%sizeof(Packet))==0;
|
||||
return (std::uintptr_t(m_data + i) % sizeof(Packet)) == 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
Scalar* m_data;
|
||||
};
|
||||
|
||||
template<typename Scalar, typename Index, int AlignmentType, int Incr=1>
|
||||
template <typename Scalar, typename Index, int AlignmentType, int Incr = 1>
|
||||
class BlasLinearMapper;
|
||||
|
||||
template<typename Scalar, typename Index, int AlignmentType>
|
||||
class BlasLinearMapper<Scalar,Index,AlignmentType>
|
||||
{
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data, Index incr=1)
|
||||
: m_data(data)
|
||||
{
|
||||
template <typename Scalar, typename Index, int AlignmentType>
|
||||
class BlasLinearMapper<Scalar, Index, AlignmentType> {
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar* data, Index incr = 1) : m_data(data) {
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(incr);
|
||||
eigen_assert(incr==1);
|
||||
eigen_assert(incr == 1);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i) const {
|
||||
internal::prefetch(&operator()(i));
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index 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 Scalar& operator()(Index i) const { return m_data[i]; }
|
||||
|
||||
template<typename PacketType>
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i) const {
|
||||
return ploadt<PacketType, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index n, Index offset = 0) const {
|
||||
return ploadt_partial<PacketType, AlignmentType>(m_data + i, n, offset);
|
||||
}
|
||||
|
||||
template<typename PacketType, int AlignmentT>
|
||||
template <typename PacketType, int AlignmentT>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType load(Index i) const {
|
||||
return ploadt<PacketType, AlignmentT>(m_data + i);
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const PacketType &p) const {
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const PacketType& p) const {
|
||||
pstoret<Scalar, PacketType, AlignmentType>(m_data + i, p);
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, const PacketType &p, Index n, Index offset = 0) const {
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, const PacketType& p, Index n,
|
||||
Index offset = 0) const {
|
||||
pstoret_partial<Scalar, PacketType, AlignmentType>(m_data + i, p, n, offset);
|
||||
}
|
||||
|
||||
protected:
|
||||
Scalar *m_data;
|
||||
protected:
|
||||
Scalar* m_data;
|
||||
};
|
||||
|
||||
// Lightweight helper class to access matrix coefficients.
|
||||
template<typename Scalar, typename Index, int StorageOrder, int AlignmentType = Unaligned, int Incr = 1>
|
||||
template <typename Scalar, typename Index, int StorageOrder, int AlignmentType = Unaligned, int Incr = 1>
|
||||
class blas_data_mapper;
|
||||
|
||||
// TMP to help PacketBlock store implementation.
|
||||
// There's currently no known use case for PacketBlock load.
|
||||
// The default implementation assumes ColMajor order.
|
||||
// It always store each packet sequentially one `stride` apart.
|
||||
template<typename Index, typename Scalar, typename Packet, int n, int idx, int StorageOrder>
|
||||
struct PacketBlockManagement
|
||||
{
|
||||
template <typename Index, typename Scalar, typename Packet, int n, int idx, int StorageOrder>
|
||||
struct PacketBlockManagement {
|
||||
PacketBlockManagement<Index, Scalar, Packet, n, idx - 1, StorageOrder> pbm;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar *to, const Index stride, Index i, Index j, const PacketBlock<Packet, n> &block) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar* to, const Index stride, Index i, Index j,
|
||||
const PacketBlock<Packet, n>& block) const {
|
||||
pbm.store(to, stride, i, j, block);
|
||||
pstoreu<Scalar>(to + i + (j + idx)*stride, block.packet[idx]);
|
||||
pstoreu<Scalar>(to + i + (j + idx) * stride, block.packet[idx]);
|
||||
}
|
||||
};
|
||||
|
||||
// PacketBlockManagement specialization to take care of RowMajor order without ifs.
|
||||
template<typename Index, typename Scalar, typename Packet, int n, int idx>
|
||||
struct PacketBlockManagement<Index, Scalar, Packet, n, idx, RowMajor>
|
||||
{
|
||||
template <typename Index, typename Scalar, typename Packet, int n, int idx>
|
||||
struct PacketBlockManagement<Index, Scalar, Packet, n, idx, RowMajor> {
|
||||
PacketBlockManagement<Index, Scalar, Packet, n, idx - 1, RowMajor> pbm;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar *to, const Index stride, Index i, Index j, const PacketBlock<Packet, n> &block) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar* to, const Index stride, Index i, Index j,
|
||||
const PacketBlock<Packet, n>& block) const {
|
||||
pbm.store(to, stride, i, j, block);
|
||||
pstoreu<Scalar>(to + j + (i + idx)*stride, block.packet[idx]);
|
||||
pstoreu<Scalar>(to + j + (i + idx) * stride, block.packet[idx]);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Index, typename Scalar, typename Packet, int n, int StorageOrder>
|
||||
struct PacketBlockManagement<Index, Scalar, Packet, n, -1, StorageOrder>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar *to, const Index stride, Index i, Index j, const PacketBlock<Packet, n> &block) const {
|
||||
template <typename Index, typename Scalar, typename Packet, int n, int StorageOrder>
|
||||
struct PacketBlockManagement<Index, Scalar, Packet, n, -1, StorageOrder> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar* to, const Index stride, Index i, Index j,
|
||||
const PacketBlock<Packet, n>& block) const {
|
||||
EIGEN_UNUSED_VARIABLE(to);
|
||||
EIGEN_UNUSED_VARIABLE(stride);
|
||||
EIGEN_UNUSED_VARIABLE(i);
|
||||
@@ -166,10 +159,10 @@ struct PacketBlockManagement<Index, Scalar, Packet, n, -1, StorageOrder>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Index, typename Scalar, typename Packet, int n>
|
||||
struct PacketBlockManagement<Index, Scalar, Packet, n, -1, RowMajor>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar *to, const Index stride, Index i, Index j, const PacketBlock<Packet, n> &block) const {
|
||||
template <typename Index, typename Scalar, typename Packet, int n>
|
||||
struct PacketBlockManagement<Index, Scalar, Packet, n, -1, RowMajor> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(Scalar* to, const Index stride, Index i, Index j,
|
||||
const PacketBlock<Packet, n>& block) const {
|
||||
EIGEN_UNUSED_VARIABLE(to);
|
||||
EIGEN_UNUSED_VARIABLE(stride);
|
||||
EIGEN_UNUSED_VARIABLE(i);
|
||||
@@ -178,50 +171,45 @@ struct PacketBlockManagement<Index, Scalar, Packet, n, -1, RowMajor>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, typename Index, int StorageOrder, int AlignmentType>
|
||||
class blas_data_mapper<Scalar,Index,StorageOrder,AlignmentType,1>
|
||||
{
|
||||
public:
|
||||
template <typename Scalar, typename Index, int StorageOrder, int AlignmentType>
|
||||
class blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, 1> {
|
||||
public:
|
||||
typedef BlasLinearMapper<Scalar, Index, AlignmentType> LinearMapper;
|
||||
typedef blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType> SubMapper;
|
||||
typedef BlasVectorMapper<Scalar, Index> VectorMapper;
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr=1)
|
||||
: m_data(data), m_stride(stride)
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr = 1)
|
||||
: m_data(data), m_stride(stride) {
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(incr);
|
||||
eigen_assert(incr==1);
|
||||
eigen_assert(incr == 1);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubMapper
|
||||
getSubMapper(Index i, Index j) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubMapper getSubMapper(Index i, Index j) const {
|
||||
return SubMapper(&operator()(i, j), m_stride);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
|
||||
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 {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE VectorMapper getVectorMapper(Index i, Index j) const {
|
||||
return VectorMapper(&operator()(i, j));
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i, Index j) const {
|
||||
internal::prefetch(&operator()(i, j));
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i, Index j) const { internal::prefetch(&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 Scalar& operator()(Index i, Index j) const {
|
||||
return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride];
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i, Index j) const {
|
||||
return ploadt<PacketType, AlignmentType>(&operator()(i, j));
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index j, Index n, Index offset = 0) const {
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index j, Index n,
|
||||
Index offset = 0) const {
|
||||
return ploadt_partial<PacketType, AlignmentType>(&operator()(i, j), n, offset);
|
||||
}
|
||||
|
||||
@@ -230,22 +218,23 @@ public:
|
||||
return ploadt<PacketT, AlignmentT>(&operator()(i, j));
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, Index j, const PacketType &p) const {
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, Index j, const PacketType& p) const {
|
||||
pstoret<Scalar, PacketType, AlignmentType>(&operator()(i, j), p);
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, Index j, const PacketType &p, Index n, Index offset = 0) const {
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, Index j, const PacketType& p, Index n,
|
||||
Index offset = 0) const {
|
||||
pstoret_partial<Scalar, PacketType, AlignmentType>(&operator()(i, j), p, n, offset);
|
||||
}
|
||||
|
||||
template<typename SubPacket>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const {
|
||||
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>
|
||||
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);
|
||||
}
|
||||
@@ -255,18 +244,20 @@ public:
|
||||
EIGEN_DEVICE_FUNC const Scalar* data() const { return m_data; }
|
||||
|
||||
EIGEN_DEVICE_FUNC Index firstAligned(Index size) const {
|
||||
if (std::uintptr_t(m_data)%sizeof(Scalar)) {
|
||||
if (std::uintptr_t(m_data) % sizeof(Scalar)) {
|
||||
return -1;
|
||||
}
|
||||
return internal::first_default_aligned(m_data, size);
|
||||
}
|
||||
|
||||
template<typename SubPacket, int n>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketBlock(Index i, Index j, const PacketBlock<SubPacket, n> &block) const {
|
||||
PacketBlockManagement<Index, Scalar, SubPacket, n, n-1, StorageOrder> pbm;
|
||||
template <typename SubPacket, int n>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketBlock(Index i, Index j,
|
||||
const PacketBlock<SubPacket, n>& block) const {
|
||||
PacketBlockManagement<Index, Scalar, SubPacket, n, n - 1, StorageOrder> pbm;
|
||||
pbm.store(m_data, m_stride, i, j, block);
|
||||
}
|
||||
protected:
|
||||
|
||||
protected:
|
||||
Scalar* EIGEN_RESTRICT m_data;
|
||||
const Index m_stride;
|
||||
};
|
||||
@@ -274,198 +265,198 @@ protected:
|
||||
// Implementation of non-natural increment (i.e. inner-stride != 1)
|
||||
// The exposed API is not complete yet compared to the Incr==1 case
|
||||
// because some features makes less sense in this case.
|
||||
template<typename Scalar, typename Index, int AlignmentType, int Incr>
|
||||
class BlasLinearMapper
|
||||
{
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data,Index incr) : m_data(data), m_incr(incr) {}
|
||||
template <typename Scalar, typename Index, int AlignmentType, int Incr>
|
||||
class BlasLinearMapper {
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar* data, Index incr) : m_data(data), m_incr(incr) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const {
|
||||
internal::prefetch(&operator()(i));
|
||||
}
|
||||
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*m_incr.value()];
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const { return m_data[i * m_incr.value()]; }
|
||||
|
||||
template<typename PacketType>
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i) const {
|
||||
return pgather<Scalar,PacketType>(m_data + i*m_incr.value(), m_incr.value());
|
||||
return pgather<Scalar, PacketType>(m_data + i * m_incr.value(), m_incr.value());
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index n, Index /*offset*/ = 0) const {
|
||||
return pgather_partial<Scalar,PacketType>(m_data + i*m_incr.value(), m_incr.value(), n);
|
||||
return pgather_partial<Scalar, PacketType>(m_data + i * m_incr.value(), m_incr.value(), n);
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const PacketType &p) const {
|
||||
pscatter<Scalar, PacketType>(m_data + i*m_incr.value(), p, m_incr.value());
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const PacketType& p) const {
|
||||
pscatter<Scalar, PacketType>(m_data + i * m_incr.value(), p, m_incr.value());
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, const PacketType &p, Index n, Index /*offset*/ = 0) const {
|
||||
pscatter_partial<Scalar, PacketType>(m_data + i*m_incr.value(), p, m_incr.value(), n);
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, const PacketType& p, Index n,
|
||||
Index /*offset*/ = 0) const {
|
||||
pscatter_partial<Scalar, PacketType>(m_data + i * m_incr.value(), p, m_incr.value(), n);
|
||||
}
|
||||
|
||||
protected:
|
||||
Scalar *m_data;
|
||||
const internal::variable_if_dynamic<Index,Incr> m_incr;
|
||||
protected:
|
||||
Scalar* m_data;
|
||||
const internal::variable_if_dynamic<Index, Incr> m_incr;
|
||||
};
|
||||
|
||||
template<typename Scalar, typename Index, int StorageOrder, int AlignmentType,int Incr>
|
||||
class blas_data_mapper
|
||||
{
|
||||
public:
|
||||
typedef BlasLinearMapper<Scalar, Index, AlignmentType,Incr> LinearMapper;
|
||||
template <typename Scalar, typename Index, int StorageOrder, int AlignmentType, int Incr>
|
||||
class blas_data_mapper {
|
||||
public:
|
||||
typedef BlasLinearMapper<Scalar, Index, AlignmentType, Incr> LinearMapper;
|
||||
typedef blas_data_mapper SubMapper;
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr) : m_data(data), m_stride(stride), m_incr(incr) {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr)
|
||||
: m_data(data), m_stride(stride), m_incr(incr) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubMapper
|
||||
getSubMapper(Index i, Index j) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubMapper getSubMapper(Index i, Index j) const {
|
||||
return SubMapper(&operator()(i, j), m_stride, m_incr.value());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
|
||||
return LinearMapper(&operator()(i, j), m_incr.value());
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i, Index j) const {
|
||||
internal::prefetch(&operator()(i, j));
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(Index i, Index j) const { internal::prefetch(&operator()(i, j)); }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
|
||||
return m_data[StorageOrder == RowMajor ? j * m_incr.value() + i * m_stride : i * m_incr.value() + j * m_stride];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
|
||||
return m_data[StorageOrder==RowMajor ? j*m_incr.value() + i*m_stride : i*m_incr.value() + j*m_stride];
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacket(Index i, Index j) const {
|
||||
return pgather<Scalar,PacketType>(&operator()(i, j),m_incr.value());
|
||||
return pgather<Scalar, PacketType>(&operator()(i, j), m_incr.value());
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index j, Index n, Index /*offset*/ = 0) const {
|
||||
return pgather_partial<Scalar,PacketType>(&operator()(i, j),m_incr.value(),n);
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index j, Index n,
|
||||
Index /*offset*/ = 0) const {
|
||||
return pgather_partial<Scalar, PacketType>(&operator()(i, j), m_incr.value(), n);
|
||||
}
|
||||
|
||||
template <typename PacketT, int AlignmentT>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT load(Index i, Index j) const {
|
||||
return pgather<Scalar,PacketT>(&operator()(i, j),m_incr.value());
|
||||
return pgather<Scalar, PacketT>(&operator()(i, j), m_incr.value());
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, Index j, const PacketType &p) const {
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, Index j, const PacketType& p) const {
|
||||
pscatter<Scalar, PacketType>(&operator()(i, j), p, m_incr.value());
|
||||
}
|
||||
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, Index j, const PacketType &p, Index n, Index /*offset*/ = 0) const {
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, Index j, const PacketType& p, Index n,
|
||||
Index /*offset*/ = 0) const {
|
||||
pscatter_partial<Scalar, PacketType>(&operator()(i, j), p, m_incr.value(), n);
|
||||
}
|
||||
|
||||
template<typename SubPacket>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const {
|
||||
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>
|
||||
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);
|
||||
}
|
||||
|
||||
// storePacketBlock_helper defines a way to access values inside the PacketBlock, this is essentially required by the Complex types.
|
||||
template<typename SubPacket, typename Scalar_, int n, int idx>
|
||||
struct storePacketBlock_helper
|
||||
{
|
||||
storePacketBlock_helper<SubPacket, Scalar_, n, idx-1> spbh;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>* sup, Index i, Index j, const PacketBlock<SubPacket, n>& block) const {
|
||||
spbh.store(sup, i,j,block);
|
||||
sup->template storePacket<SubPacket>(i, j+idx, block.packet[idx]);
|
||||
// storePacketBlock_helper defines a way to access values inside the PacketBlock, this is essentially required by the
|
||||
// Complex types.
|
||||
template <typename SubPacket, typename Scalar_, int n, int idx>
|
||||
struct storePacketBlock_helper {
|
||||
storePacketBlock_helper<SubPacket, Scalar_, n, idx - 1> spbh;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(
|
||||
const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>* sup, Index i, Index j,
|
||||
const PacketBlock<SubPacket, n>& block) const {
|
||||
spbh.store(sup, i, j, block);
|
||||
sup->template storePacket<SubPacket>(i, j + idx, block.packet[idx]);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename SubPacket, int n, int idx>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<float>, n, idx>
|
||||
{
|
||||
storePacketBlock_helper<SubPacket, std::complex<float>, n, idx-1> spbh;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>* sup, Index i, Index j, const PacketBlock<SubPacket, n>& block) const {
|
||||
spbh.store(sup,i,j,block);
|
||||
sup->template storePacket<SubPacket>(i, j+idx, block.packet[idx]);
|
||||
template <typename SubPacket, int n, int idx>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<float>, n, idx> {
|
||||
storePacketBlock_helper<SubPacket, std::complex<float>, n, idx - 1> spbh;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(
|
||||
const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>* sup, Index i, Index j,
|
||||
const PacketBlock<SubPacket, n>& block) const {
|
||||
spbh.store(sup, i, j, block);
|
||||
sup->template storePacket<SubPacket>(i, j + idx, block.packet[idx]);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename SubPacket, int n, int idx>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<double>, n, idx>
|
||||
{
|
||||
storePacketBlock_helper<SubPacket, std::complex<double>, n, idx-1> spbh;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>* sup, Index i, Index j, const PacketBlock<SubPacket, n>& block) const {
|
||||
spbh.store(sup,i,j,block);
|
||||
for(int l = 0; l < unpacket_traits<SubPacket>::size; l++)
|
||||
{
|
||||
std::complex<double> *v = &sup->operator()(i+l, j+idx);
|
||||
v->real(block.packet[idx].v[2*l+0]);
|
||||
v->imag(block.packet[idx].v[2*l+1]);
|
||||
template <typename SubPacket, int n, int idx>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<double>, n, idx> {
|
||||
storePacketBlock_helper<SubPacket, std::complex<double>, n, idx - 1> spbh;
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(
|
||||
const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>* sup, Index i, Index j,
|
||||
const PacketBlock<SubPacket, n>& block) const {
|
||||
spbh.store(sup, i, j, block);
|
||||
for (int l = 0; l < unpacket_traits<SubPacket>::size; l++) {
|
||||
std::complex<double>* v = &sup->operator()(i + l, j + idx);
|
||||
v->real(block.packet[idx].v[2 * l + 0]);
|
||||
v->imag(block.packet[idx].v[2 * l + 1]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename SubPacket, typename Scalar_, int n>
|
||||
struct storePacketBlock_helper<SubPacket, Scalar_, n, -1>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>*, Index, Index, const PacketBlock<SubPacket, n>& ) const {
|
||||
}
|
||||
template <typename SubPacket, typename Scalar_, int n>
|
||||
struct storePacketBlock_helper<SubPacket, Scalar_, n, -1> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(
|
||||
const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>*, Index, Index,
|
||||
const PacketBlock<SubPacket, n>&) const {}
|
||||
};
|
||||
|
||||
template<typename SubPacket, int n>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<float>, n, -1>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>*, Index, Index, const PacketBlock<SubPacket, n>& ) const {
|
||||
}
|
||||
template <typename SubPacket, int n>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<float>, n, -1> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(
|
||||
const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>*, Index, Index,
|
||||
const PacketBlock<SubPacket, n>&) const {}
|
||||
};
|
||||
|
||||
template<typename SubPacket, int n>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<double>, n, -1>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>*, Index, Index, const PacketBlock<SubPacket, n>& ) const {
|
||||
}
|
||||
template <typename SubPacket, int n>
|
||||
struct storePacketBlock_helper<SubPacket, std::complex<double>, n, -1> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void store(
|
||||
const blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType, Incr>*, Index, Index,
|
||||
const PacketBlock<SubPacket, n>&) const {}
|
||||
};
|
||||
// This function stores a PacketBlock on m_data, this approach is really quite slow compare to Incr=1 and should be avoided when possible.
|
||||
template<typename SubPacket, int n>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketBlock(Index i, Index j, const PacketBlock<SubPacket, n>&block) const {
|
||||
storePacketBlock_helper<SubPacket, Scalar, n, n-1> spb;
|
||||
spb.store(this, i,j,block);
|
||||
// This function stores a PacketBlock on m_data, this approach is really quite slow compare to Incr=1 and should be
|
||||
// avoided when possible.
|
||||
template <typename SubPacket, int n>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketBlock(Index i, Index j,
|
||||
const PacketBlock<SubPacket, n>& block) const {
|
||||
storePacketBlock_helper<SubPacket, Scalar, n, n - 1> spb;
|
||||
spb.store(this, i, j, block);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC const Index stride() const { return m_stride; }
|
||||
EIGEN_DEVICE_FUNC const Index incr() const { return m_incr.value(); }
|
||||
EIGEN_DEVICE_FUNC Scalar* data() const { return m_data; }
|
||||
protected:
|
||||
|
||||
protected:
|
||||
Scalar* EIGEN_RESTRICT m_data;
|
||||
const Index m_stride;
|
||||
const internal::variable_if_dynamic<Index,Incr> m_incr;
|
||||
const internal::variable_if_dynamic<Index, Incr> m_incr;
|
||||
};
|
||||
|
||||
// lightweight helper class to access matrix coefficients (const version)
|
||||
template<typename Scalar, typename Index, int StorageOrder>
|
||||
template <typename Scalar, typename Index, int StorageOrder>
|
||||
class const_blas_data_mapper : public blas_data_mapper<const Scalar, Index, StorageOrder> {
|
||||
public:
|
||||
public:
|
||||
typedef const_blas_data_mapper<Scalar, Index, StorageOrder> SubMapper;
|
||||
|
||||
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(const Scalar* data, Index stride)
|
||||
: blas_data_mapper<const Scalar, Index, StorageOrder>(data, stride) {}
|
||||
|
||||
EIGEN_ALWAYS_INLINE SubMapper getSubMapper(Index i, Index j) const {
|
||||
return SubMapper(&(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
|
||||
{
|
||||
template <typename XprType>
|
||||
struct blas_traits {
|
||||
typedef typename traits<XprType>::Scalar Scalar;
|
||||
typedef const XprType& ExtractType;
|
||||
typedef XprType ExtractType_;
|
||||
@@ -473,130 +464,121 @@ template<typename XprType> struct blas_traits
|
||||
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,
|
||||
HasUsableDirectAccess =
|
||||
((int(XprType::Flags) & DirectAccessBit) &&
|
||||
(bool(XprType::IsVectorAtCompileTime) || int(inner_stride_at_compile_time<XprType>::ret) == 1))
|
||||
? 1
|
||||
: 0,
|
||||
HasScalarFactor = false
|
||||
};
|
||||
typedef std::conditional_t<bool(HasUsableDirectAccess),
|
||||
ExtractType,
|
||||
typename ExtractType_::PlainObject
|
||||
> DirectLinearAccessType;
|
||||
typedef std::conditional_t<bool(HasUsableDirectAccess), ExtractType, typename ExtractType_::PlainObject>
|
||||
DirectLinearAccessType;
|
||||
EIGEN_DEVICE_FUNC static inline EIGEN_DEVICE_FUNC ExtractType extract(const XprType& x) { return x; }
|
||||
EIGEN_DEVICE_FUNC static inline EIGEN_DEVICE_FUNC const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
|
||||
EIGEN_DEVICE_FUNC static inline EIGEN_DEVICE_FUNC 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>
|
||||
{
|
||||
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
|
||||
};
|
||||
enum { IsComplex = NumTraits<Scalar>::IsComplex, NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex };
|
||||
EIGEN_DEVICE_FUNC static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
|
||||
EIGEN_DEVICE_FUNC static inline Scalar extractScalarFactor(const XprType& x) { return conj(Base::extractScalarFactor(x.nestedExpression())); }
|
||||
EIGEN_DEVICE_FUNC 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>
|
||||
{
|
||||
enum {
|
||||
HasScalarFactor = true
|
||||
};
|
||||
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> {
|
||||
enum { HasScalarFactor = true };
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain>, NestedXpr> XprType;
|
||||
typedef CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>, Plain>, NestedXpr>
|
||||
XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
EIGEN_DEVICE_FUNC static inline EIGEN_DEVICE_FUNC ExtractType extract(const XprType& x) { return Base::extract(x.rhs()); }
|
||||
EIGEN_DEVICE_FUNC static inline EIGEN_DEVICE_FUNC Scalar extractScalarFactor(const XprType& x)
|
||||
{ return x.lhs().functor().m_other * Base::extractScalarFactor(x.rhs()); }
|
||||
EIGEN_DEVICE_FUNC static inline EIGEN_DEVICE_FUNC ExtractType extract(const XprType& x) {
|
||||
return Base::extract(x.rhs());
|
||||
}
|
||||
EIGEN_DEVICE_FUNC static inline EIGEN_DEVICE_FUNC 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>
|
||||
{
|
||||
enum {
|
||||
HasScalarFactor = true
|
||||
};
|
||||
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> {
|
||||
enum { HasScalarFactor = true };
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseBinaryOp<scalar_product_op<Scalar>, NestedXpr, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain> > XprType;
|
||||
typedef CwiseBinaryOp<scalar_product_op<Scalar>, NestedXpr, const CwiseNullaryOp<scalar_constant_op<Scalar>, Plain> >
|
||||
XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
EIGEN_DEVICE_FUNC static inline ExtractType extract(const XprType& x) { return Base::extract(x.lhs()); }
|
||||
EIGEN_DEVICE_FUNC static inline Scalar extractScalarFactor(const XprType& x)
|
||||
{ return Base::extractScalarFactor(x.lhs()) * x.rhs().functor().m_other; }
|
||||
EIGEN_DEVICE_FUNC 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> >
|
||||
{};
|
||||
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>
|
||||
{
|
||||
enum {
|
||||
HasScalarFactor = true
|
||||
};
|
||||
template <typename Scalar, typename NestedXpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> > : blas_traits<NestedXpr> {
|
||||
enum { HasScalarFactor = true };
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
EIGEN_DEVICE_FUNC static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
|
||||
EIGEN_DEVICE_FUNC static inline Scalar extractScalarFactor(const XprType& x)
|
||||
{ return - Base::extractScalarFactor(x.nestedExpression()); }
|
||||
EIGEN_DEVICE_FUNC 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>
|
||||
{
|
||||
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; // 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 std::conditional_t<bool(Base::HasUsableDirectAccess),
|
||||
ExtractType,
|
||||
typename ExtractType::PlainObject
|
||||
> DirectLinearAccessType;
|
||||
enum {
|
||||
IsTransposed = Base::IsTransposed ? 0 : 1
|
||||
};
|
||||
EIGEN_DEVICE_FUNC static inline ExtractType extract(const XprType& x) { return ExtractType(Base::extract(x.nestedExpression())); }
|
||||
EIGEN_DEVICE_FUNC static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); }
|
||||
typedef std::conditional_t<bool(Base::HasUsableDirectAccess), ExtractType, typename ExtractType::PlainObject>
|
||||
DirectLinearAccessType;
|
||||
enum { IsTransposed = Base::IsTransposed ? 0 : 1 };
|
||||
EIGEN_DEVICE_FUNC static inline ExtractType extract(const XprType& x) {
|
||||
return ExtractType(Base::extract(x.nestedExpression()));
|
||||
}
|
||||
EIGEN_DEVICE_FUNC 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>
|
||||
struct blas_traits<const T> : blas_traits<T> {};
|
||||
|
||||
template<typename T, bool HasUsableDirectAccess=blas_traits<T>::HasUsableDirectAccess>
|
||||
template <typename T, bool HasUsableDirectAccess = blas_traits<T>::HasUsableDirectAccess>
|
||||
struct extract_data_selector {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static const typename T::Scalar* run(const T& m)
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE 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> {
|
||||
template <typename T>
|
||||
struct extract_data_selector<T, false> {
|
||||
EIGEN_DEVICE_FUNC static typename T::Scalar* run(const T&) { return 0; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const typename T::Scalar* extract_data(const T& m)
|
||||
{
|
||||
template <typename T>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const typename T::Scalar* extract_data(const T& m) {
|
||||
return extract_data_selector<T>::run(m);
|
||||
}
|
||||
|
||||
@@ -604,45 +586,37 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const typename T::Scalar* extract_data(con
|
||||
* \c combine_scalar_factors extracts and multiplies factors from GEMM and GEMV products.
|
||||
* There is a specialization for booleans
|
||||
*/
|
||||
template<typename ResScalar, typename Lhs, typename Rhs>
|
||||
struct combine_scalar_factors_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static ResScalar run(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
template <typename ResScalar, typename Lhs, typename Rhs>
|
||||
struct combine_scalar_factors_impl {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static ResScalar run(const Lhs& lhs, const Rhs& rhs) {
|
||||
return blas_traits<Lhs>::extractScalarFactor(lhs) * blas_traits<Rhs>::extractScalarFactor(rhs);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static ResScalar run(const ResScalar& alpha, const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static ResScalar run(const ResScalar& alpha, const Lhs& lhs, const Rhs& rhs) {
|
||||
return alpha * blas_traits<Lhs>::extractScalarFactor(lhs) * blas_traits<Rhs>::extractScalarFactor(rhs);
|
||||
}
|
||||
};
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct combine_scalar_factors_impl<bool, Lhs, Rhs>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static bool run(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
template <typename Lhs, typename Rhs>
|
||||
struct combine_scalar_factors_impl<bool, Lhs, Rhs> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static bool run(const Lhs& lhs, const Rhs& rhs) {
|
||||
return blas_traits<Lhs>::extractScalarFactor(lhs) && blas_traits<Rhs>::extractScalarFactor(rhs);
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static bool run(const bool& alpha, const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static bool run(const bool& alpha, const Lhs& lhs, const Rhs& rhs) {
|
||||
return alpha && blas_traits<Lhs>::extractScalarFactor(lhs) && blas_traits<Rhs>::extractScalarFactor(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ResScalar, typename Lhs, typename Rhs>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const ResScalar& alpha, const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
return combine_scalar_factors_impl<ResScalar,Lhs,Rhs>::run(alpha, lhs, rhs);
|
||||
template <typename ResScalar, typename Lhs, typename Rhs>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const ResScalar& alpha, const Lhs& lhs,
|
||||
const Rhs& rhs) {
|
||||
return combine_scalar_factors_impl<ResScalar, Lhs, Rhs>::run(alpha, lhs, rhs);
|
||||
}
|
||||
template<typename ResScalar, typename Lhs, typename Rhs>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
return combine_scalar_factors_impl<ResScalar,Lhs,Rhs>::run(lhs, rhs);
|
||||
template <typename ResScalar, typename Lhs, typename Rhs>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE ResScalar combine_scalar_factors(const Lhs& lhs, const Rhs& rhs) {
|
||||
return combine_scalar_factors_impl<ResScalar, Lhs, Rhs>::run(lhs, rhs);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace Eigen
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_BLASUTIL_H
|
||||
#endif // EIGEN_BLASUTIL_H
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
// to be used to declare statically aligned buffers.
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
|
||||
* However, we do that EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
|
||||
* so that vectorization doesn't affect binary compatibility.
|
||||
@@ -32,34 +31,33 @@
|
||||
* vectorized and non-vectorized code.
|
||||
*/
|
||||
#if (defined EIGEN_CUDACC)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __align__(n)
|
||||
#define EIGEN_ALIGNOF(x) __alignof(x)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) __align__(n)
|
||||
#define EIGEN_ALIGNOF(x) __alignof(x)
|
||||
#else
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) alignas(n)
|
||||
#define EIGEN_ALIGNOF(x) alignof(x)
|
||||
#define EIGEN_ALIGN_TO_BOUNDARY(n) alignas(n)
|
||||
#define EIGEN_ALIGNOF(x) alignof(x)
|
||||
#endif
|
||||
|
||||
// If the user explicitly disable vectorization, then we also disable alignment
|
||||
#if defined(EIGEN_DONT_VECTORIZE)
|
||||
#if defined(EIGEN_GPUCC)
|
||||
// GPU code is always vectorized and requires memory alignment for
|
||||
// statically allocated buffers.
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 16
|
||||
#else
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 0
|
||||
#endif
|
||||
#elif defined(__AVX512F__)
|
||||
// 64 bytes static alignment is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 64
|
||||
#elif defined(__AVX__)
|
||||
// 32 bytes static alignment is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 32
|
||||
#elif defined __HVX__ && (__HVX_LENGTH__ == 128)
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 128
|
||||
#if defined(EIGEN_GPUCC)
|
||||
// GPU code is always vectorized and requires memory alignment for
|
||||
// statically allocated buffers.
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 16
|
||||
#else
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 16
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 0
|
||||
#endif
|
||||
#elif defined(__AVX512F__)
|
||||
// 64 bytes static alignment is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 64
|
||||
#elif defined(__AVX__)
|
||||
// 32 bytes static alignment is preferred only if really required
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 32
|
||||
#elif defined __HVX__ && (__HVX_LENGTH__ == 128)
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 128
|
||||
#else
|
||||
#define EIGEN_IDEAL_MAX_ALIGN_BYTES 16
|
||||
#endif
|
||||
|
||||
|
||||
// EIGEN_MIN_ALIGN_BYTES defines the minimal value for which the notion of explicit alignment makes sense
|
||||
#define EIGEN_MIN_ALIGN_BYTES 16
|
||||
@@ -68,93 +66,91 @@
|
||||
// that unless EIGEN_ALIGN is defined and not equal to 0, the data may not be
|
||||
// aligned at all regardless of the value of this #define.
|
||||
|
||||
#if (defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)) && defined(EIGEN_MAX_STATIC_ALIGN_BYTES) && EIGEN_MAX_STATIC_ALIGN_BYTES>0
|
||||
#if (defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)) && defined(EIGEN_MAX_STATIC_ALIGN_BYTES) && \
|
||||
EIGEN_MAX_STATIC_ALIGN_BYTES > 0
|
||||
#error EIGEN_MAX_STATIC_ALIGN_BYTES and EIGEN_DONT_ALIGN[_STATICALLY] are both defined with EIGEN_MAX_STATIC_ALIGN_BYTES!=0. Use EIGEN_MAX_STATIC_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN_STATICALLY.
|
||||
#endif
|
||||
|
||||
// EIGEN_DONT_ALIGN_STATICALLY and EIGEN_DONT_ALIGN are deprecated
|
||||
// They imply EIGEN_MAX_STATIC_ALIGN_BYTES=0
|
||||
#if defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)
|
||||
#ifdef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#ifdef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
|
||||
// Try to automatically guess what is the best default value for EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
// Try to automatically guess what is the best default value for EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
|
||||
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
|
||||
// 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
|
||||
// enable alignment, but it can be a cause of problems on some platforms, so we just disable it in
|
||||
// certain common platform (compiler+architecture combinations) to avoid these problems.
|
||||
// Only static alignment is really problematic (relies on nonstandard compiler extensions),
|
||||
// try to keep heap alignment even when we have to disable static alignment.
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM_OR_ARM64 || EIGEN_ARCH_PPC || EIGEN_ARCH_IA64 || EIGEN_ARCH_MIPS)
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
|
||||
// 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
|
||||
// enable alignment, but it can be a cause of problems on some platforms, so we just disable it in
|
||||
// certain common platform (compiler+architecture combinations) to avoid these problems.
|
||||
// Only static alignment is really problematic (relies on nonstandard compiler extensions),
|
||||
// try to keep heap alignment even when we have to disable static alignment.
|
||||
#if EIGEN_COMP_GNUC && \
|
||||
!(EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM_OR_ARM64 || EIGEN_ARCH_PPC || EIGEN_ARCH_IA64 || EIGEN_ARCH_MIPS)
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
// static alignment is completely disabled with GCC 3, Sun Studio, and QCC/QNX
|
||||
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT \
|
||||
&& !EIGEN_COMP_SUNCC \
|
||||
&& !EIGEN_OS_QNX
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
// static alignment is completely disabled with GCC 3, Sun Studio, and QCC/QNX
|
||||
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT && !EIGEN_COMP_SUNCC && !EIGEN_OS_QNX
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
|
||||
#else
|
||||
#define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#else
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#endif
|
||||
#if EIGEN_ARCH_WANTS_STACK_ALIGNMENT
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#else
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// If EIGEN_MAX_ALIGN_BYTES is defined, then it is considered as an upper bound for EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#if defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES<EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#if defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES < EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_STATIC_ALIGN_BYTES
|
||||
#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES==0 && !defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
||||
#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES == 0 && !defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
|
||||
#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
|
||||
#endif
|
||||
|
||||
// At this stage, EIGEN_MAX_STATIC_ALIGN_BYTES>0 is the true test whether we want to align arrays on the stack or not.
|
||||
// It takes into account both the user choice to explicitly enable/disable alignment (by setting EIGEN_MAX_STATIC_ALIGN_BYTES)
|
||||
// and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT).
|
||||
// Henceforth, only EIGEN_MAX_STATIC_ALIGN_BYTES should be used.
|
||||
|
||||
// It takes into account both the user choice to explicitly enable/disable alignment (by setting
|
||||
// EIGEN_MAX_STATIC_ALIGN_BYTES) and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT). Henceforth, only
|
||||
// EIGEN_MAX_STATIC_ALIGN_BYTES should be used.
|
||||
|
||||
// Shortcuts to EIGEN_ALIGN_TO_BOUNDARY
|
||||
#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8)
|
||||
#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8)
|
||||
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
|
||||
#define EIGEN_ALIGN32 EIGEN_ALIGN_TO_BOUNDARY(32)
|
||||
#define EIGEN_ALIGN64 EIGEN_ALIGN_TO_BOUNDARY(64)
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
|
||||
#if EIGEN_MAX_STATIC_ALIGN_BYTES > 0
|
||||
#define EIGEN_ALIGN_MAX EIGEN_ALIGN_TO_BOUNDARY(EIGEN_MAX_STATIC_ALIGN_BYTES)
|
||||
#else
|
||||
#define EIGEN_ALIGN_MAX
|
||||
#endif
|
||||
|
||||
|
||||
// Dynamic alignment control
|
||||
|
||||
#if defined(EIGEN_DONT_ALIGN) && defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES>0
|
||||
#if defined(EIGEN_DONT_ALIGN) && defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES > 0
|
||||
#error EIGEN_MAX_ALIGN_BYTES and EIGEN_DONT_ALIGN are both defined with EIGEN_MAX_ALIGN_BYTES!=0. Use EIGEN_MAX_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN.
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_DONT_ALIGN
|
||||
#ifdef EIGEN_MAX_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_ALIGN_BYTES 0
|
||||
#ifdef EIGEN_MAX_ALIGN_BYTES
|
||||
#undef EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
#define EIGEN_MAX_ALIGN_BYTES 0
|
||||
#elif !defined(EIGEN_MAX_ALIGN_BYTES)
|
||||
#define EIGEN_MAX_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#define EIGEN_MAX_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
#if EIGEN_IDEAL_MAX_ALIGN_BYTES > EIGEN_MAX_ALIGN_BYTES
|
||||
@@ -163,7 +159,6 @@
|
||||
#define EIGEN_DEFAULT_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef EIGEN_UNALIGNED_VECTORIZE
|
||||
#define EIGEN_UNALIGNED_VECTORIZE 1
|
||||
#endif
|
||||
@@ -172,229 +167,230 @@
|
||||
|
||||
// if alignment is disabled, then disable vectorization. Note: EIGEN_MAX_ALIGN_BYTES is the proper check, it takes into
|
||||
// account both the user's will (EIGEN_MAX_ALIGN_BYTES,EIGEN_DONT_ALIGN) and our own platform checks
|
||||
#if EIGEN_MAX_ALIGN_BYTES==0
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
#if EIGEN_MAX_ALIGN_BYTES == 0
|
||||
#ifndef EIGEN_DONT_VECTORIZE
|
||||
#define EIGEN_DONT_VECTORIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// The following (except #include <malloc.h> and _M_IX86_FP ??) can likely be
|
||||
// removed as gcc 4.1 and msvc 2008 are not supported anyways.
|
||||
#if EIGEN_COMP_MSVC
|
||||
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
||||
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
|
||||
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || EIGEN_ARCH_x86_64
|
||||
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
||||
#endif
|
||||
#include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
|
||||
// a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
|
||||
#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || EIGEN_ARCH_x86_64
|
||||
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
|
||||
#endif
|
||||
#else
|
||||
#if defined(__SSE2__)
|
||||
#define EIGEN_SSE2_ON_NON_MSVC
|
||||
#endif
|
||||
#if defined(__SSE2__)
|
||||
#define EIGEN_SSE2_ON_NON_MSVC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !(defined(EIGEN_DONT_VECTORIZE) || defined(EIGEN_GPUCC))
|
||||
|
||||
#if defined (EIGEN_SSE2_ON_NON_MSVC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||
#if defined(EIGEN_SSE2_ON_NON_MSVC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
|
||||
|
||||
// Defines symbols for compile-time detection of which instructions are
|
||||
// used.
|
||||
// EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_SSE
|
||||
#define EIGEN_VECTORIZE_SSE2
|
||||
// Defines symbols for compile-time detection of which instructions are
|
||||
// used.
|
||||
// EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_SSE
|
||||
#define EIGEN_VECTORIZE_SSE2
|
||||
|
||||
// Detect sse3/ssse3/sse4:
|
||||
// gcc and icc defines __SSE3__, ...
|
||||
// there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
|
||||
// want to force the use of those instructions with msvc.
|
||||
#ifdef __SSE3__
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#endif
|
||||
#ifdef __SSSE3__
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#endif
|
||||
#ifdef __SSE4_1__
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#endif
|
||||
#ifdef __SSE4_2__
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX__
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX2__
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#define EIGEN_VECTORIZE_AVX2
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#if defined(__FMA__) || (EIGEN_COMP_MSVC && defined(__AVX2__))
|
||||
// MSVC does not expose a switch dedicated for FMA
|
||||
// For MSVC, AVX2 => FMA
|
||||
#define EIGEN_VECTORIZE_FMA
|
||||
#endif
|
||||
#if defined(__AVX512F__)
|
||||
#ifndef EIGEN_VECTORIZE_FMA
|
||||
#if EIGEN_COMP_GNUC
|
||||
#error Please add -mfma to your compiler flags: compiling with -mavx512f alone without SSE/AVX FMA is not supported (bug 1638).
|
||||
#else
|
||||
#error Please enable FMA in your compiler flags (e.g. -mfma): compiling with AVX512 alone without SSE/AVX FMA is not supported (bug 1638).
|
||||
#endif
|
||||
#endif
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#define EIGEN_VECTORIZE_AVX512
|
||||
#define EIGEN_VECTORIZE_AVX2
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE_FMA
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#ifdef __AVX512DQ__
|
||||
#define EIGEN_VECTORIZE_AVX512DQ
|
||||
#endif
|
||||
#ifdef __AVX512ER__
|
||||
#define EIGEN_VECTORIZE_AVX512ER
|
||||
#endif
|
||||
#ifdef __AVX512BF16__
|
||||
#define EIGEN_VECTORIZE_AVX512BF16
|
||||
#endif
|
||||
#ifdef __AVX512FP16__
|
||||
#ifdef __AVX512VL__
|
||||
#define EIGEN_VECTORIZE_AVX512FP16
|
||||
#else
|
||||
#if EIGEN_COMP_GNUC
|
||||
#error Please add -mavx512vl to your compiler flags: compiling with -mavx512fp16 alone without AVX512-VL is not supported.
|
||||
#else
|
||||
#error Please enable AVX512-VL in your compiler flags (e.g. -mavx512vl): compiling with AVX512-FP16 alone without AVX512-VL is not supported.
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
// Detect sse3/ssse3/sse4:
|
||||
// gcc and icc defines __SSE3__, ...
|
||||
// there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
|
||||
// want to force the use of those instructions with msvc.
|
||||
#ifdef __SSE3__
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#endif
|
||||
#ifdef __SSSE3__
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#endif
|
||||
#ifdef __SSE4_1__
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#endif
|
||||
#ifdef __SSE4_2__
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX__
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#ifdef __AVX2__
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#define EIGEN_VECTORIZE_AVX2
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#endif
|
||||
#if defined(__FMA__) || (EIGEN_COMP_MSVC && defined(__AVX2__))
|
||||
// MSVC does not expose a switch dedicated for FMA
|
||||
// For MSVC, AVX2 => FMA
|
||||
#define EIGEN_VECTORIZE_FMA
|
||||
#endif
|
||||
#if defined(__AVX512F__)
|
||||
#ifndef EIGEN_VECTORIZE_FMA
|
||||
#if EIGEN_COMP_GNUC
|
||||
#error Please add -mfma to your compiler flags: compiling with -mavx512f alone without SSE/AVX FMA is not supported (bug 1638).
|
||||
#else
|
||||
#error Please enable FMA in your compiler flags (e.g. -mfma): compiling with AVX512 alone without SSE/AVX FMA is not supported (bug 1638).
|
||||
#endif
|
||||
#endif
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#define EIGEN_VECTORIZE_AVX512
|
||||
#define EIGEN_VECTORIZE_AVX2
|
||||
#define EIGEN_VECTORIZE_AVX
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE_FMA
|
||||
#define EIGEN_VECTORIZE_SSE3
|
||||
#define EIGEN_VECTORIZE_SSSE3
|
||||
#define EIGEN_VECTORIZE_SSE4_1
|
||||
#define EIGEN_VECTORIZE_SSE4_2
|
||||
#ifndef EIGEN_USE_SYCL
|
||||
#ifdef __AVX512DQ__
|
||||
#define EIGEN_VECTORIZE_AVX512DQ
|
||||
#endif
|
||||
#ifdef __AVX512ER__
|
||||
#define EIGEN_VECTORIZE_AVX512ER
|
||||
#endif
|
||||
#ifdef __AVX512BF16__
|
||||
#define EIGEN_VECTORIZE_AVX512BF16
|
||||
#endif
|
||||
#ifdef __AVX512FP16__
|
||||
#ifdef __AVX512VL__
|
||||
#define EIGEN_VECTORIZE_AVX512FP16
|
||||
#else
|
||||
#if EIGEN_COMP_GNUC
|
||||
#error Please add -mavx512vl to your compiler flags: compiling with -mavx512fp16 alone without AVX512-VL is not supported.
|
||||
#else
|
||||
#error Please enable AVX512-VL in your compiler flags (e.g. -mavx512vl): compiling with AVX512-FP16 alone without AVX512-VL is not supported.
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Disable AVX support on broken xcode versions
|
||||
#if ( EIGEN_COMP_CLANGAPPLE == 11000033 ) && ( __MAC_OS_X_VERSION_MIN_REQUIRED == 101500 )
|
||||
// A nasty bug in the clang compiler shipped with xcode in a common compilation situation
|
||||
// when XCode 11.0 and Mac deployment target macOS 10.15 is https://trac.macports.org/ticket/58776#no1
|
||||
#ifdef EIGEN_VECTORIZE_AVX
|
||||
#undef EIGEN_VECTORIZE_AVX
|
||||
#warning "Disabling AVX support: clang compiler shipped with XCode 11.[012] generates broken assembly with -macosx-version-min=10.15 and AVX enabled. "
|
||||
#ifdef EIGEN_VECTORIZE_AVX2
|
||||
#undef EIGEN_VECTORIZE_AVX2
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_FMA
|
||||
#undef EIGEN_VECTORIZE_FMA
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_AVX512
|
||||
#undef EIGEN_VECTORIZE_AVX512
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_AVX512DQ
|
||||
#undef EIGEN_VECTORIZE_AVX512DQ
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_AVX512ER
|
||||
#undef EIGEN_VECTORIZE_AVX512ER
|
||||
#endif
|
||||
#endif
|
||||
// NOTE: Confirmed test failures in XCode 11.0, and XCode 11.2 with -macosx-version-min=10.15 and AVX
|
||||
// NOTE using -macosx-version-min=10.15 with Xcode 11.0 results in runtime segmentation faults in many tests, 11.2 produce core dumps in 3 tests
|
||||
// NOTE using -macosx-version-min=10.14 produces functioning and passing tests in all cases
|
||||
// NOTE __clang_version__ "11.0.0 (clang-1100.0.33.8)" XCode 11.0 <- Produces many segfault and core dumping tests
|
||||
// with -macosx-version-min=10.15 and AVX
|
||||
// NOTE __clang_version__ "11.0.0 (clang-1100.0.33.12)" XCode 11.2 <- Produces 3 core dumping tests with
|
||||
// -macosx-version-min=10.15 and AVX
|
||||
#endif
|
||||
// Disable AVX support on broken xcode versions
|
||||
#if (EIGEN_COMP_CLANGAPPLE == 11000033) && (__MAC_OS_X_VERSION_MIN_REQUIRED == 101500)
|
||||
// A nasty bug in the clang compiler shipped with xcode in a common compilation situation
|
||||
// when XCode 11.0 and Mac deployment target macOS 10.15 is https://trac.macports.org/ticket/58776#no1
|
||||
#ifdef EIGEN_VECTORIZE_AVX
|
||||
#undef EIGEN_VECTORIZE_AVX
|
||||
#warning \
|
||||
"Disabling AVX support: clang compiler shipped with XCode 11.[012] generates broken assembly with -macosx-version-min=10.15 and AVX enabled. "
|
||||
#ifdef EIGEN_VECTORIZE_AVX2
|
||||
#undef EIGEN_VECTORIZE_AVX2
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_FMA
|
||||
#undef EIGEN_VECTORIZE_FMA
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_AVX512
|
||||
#undef EIGEN_VECTORIZE_AVX512
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_AVX512DQ
|
||||
#undef EIGEN_VECTORIZE_AVX512DQ
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_AVX512ER
|
||||
#undef EIGEN_VECTORIZE_AVX512ER
|
||||
#endif
|
||||
#endif
|
||||
// NOTE: Confirmed test failures in XCode 11.0, and XCode 11.2 with -macosx-version-min=10.15 and AVX
|
||||
// NOTE using -macosx-version-min=10.15 with Xcode 11.0 results in runtime segmentation faults in many tests, 11.2
|
||||
// produce core dumps in 3 tests NOTE using -macosx-version-min=10.14 produces functioning and passing tests in all
|
||||
// cases NOTE __clang_version__ "11.0.0 (clang-1100.0.33.8)" XCode 11.0 <- Produces many segfault and core dumping
|
||||
// tests
|
||||
// with -macosx-version-min=10.15 and AVX
|
||||
// NOTE __clang_version__ "11.0.0 (clang-1100.0.33.12)" XCode 11.2 <- Produces 3 core dumping tests with
|
||||
// -macosx-version-min=10.15 and AVX
|
||||
#endif
|
||||
|
||||
// include files
|
||||
// include files
|
||||
|
||||
// This extern "C" works around a MINGW-w64 compilation issue
|
||||
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
|
||||
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
|
||||
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
|
||||
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
|
||||
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
|
||||
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
|
||||
extern "C" {
|
||||
// In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
|
||||
// Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
|
||||
#if EIGEN_COMP_ICC >= 1110 || EIGEN_COMP_EMSCRIPTEN
|
||||
#include <immintrin.h>
|
||||
#else
|
||||
#include <mmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#ifdef EIGEN_VECTORIZE_SSE3
|
||||
#include <pmmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_2
|
||||
#include <nmmintrin.h>
|
||||
#endif
|
||||
#if defined(EIGEN_VECTORIZE_AVX) || defined(EIGEN_VECTORIZE_AVX512)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
} // end extern "C"
|
||||
// This extern "C" works around a MINGW-w64 compilation issue
|
||||
// https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
|
||||
// In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
|
||||
// However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
|
||||
// with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
|
||||
// so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
|
||||
// notice that since these are C headers, the extern "C" is theoretically needed anyways.
|
||||
extern "C" {
|
||||
// In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
|
||||
// Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
|
||||
#if EIGEN_COMP_ICC >= 1110 || EIGEN_COMP_EMSCRIPTEN
|
||||
#include <immintrin.h>
|
||||
#else
|
||||
#include <mmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#ifdef EIGEN_VECTORIZE_SSE3
|
||||
#include <pmmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSSE3
|
||||
#include <tmmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
#include <smmintrin.h>
|
||||
#endif
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_2
|
||||
#include <nmmintrin.h>
|
||||
#endif
|
||||
#if defined(EIGEN_VECTORIZE_AVX) || defined(EIGEN_VECTORIZE_AVX512)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
} // end extern "C"
|
||||
|
||||
#elif defined(__VSX__) && !defined(__APPLE__)
|
||||
#elif defined(__VSX__) && !defined(__APPLE__)
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_VSX 1
|
||||
#include <altivec.h>
|
||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||
// => use __vector instead of vector
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_VSX 1
|
||||
#include <altivec.h>
|
||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||
// => use __vector instead of vector
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
|
||||
#elif defined __ALTIVEC__
|
||||
#elif defined __ALTIVEC__
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_ALTIVEC
|
||||
#include <altivec.h>
|
||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||
// => use __vector instead of vector
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_ALTIVEC
|
||||
#include <altivec.h>
|
||||
// We need to #undef all these ugly tokens defined in <altivec.h>
|
||||
// => use __vector instead of vector
|
||||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
|
||||
#elif ((defined __ARM_NEON) || (defined __ARM_NEON__)) && !(defined EIGEN_ARM64_USE_SVE)
|
||||
#elif ((defined __ARM_NEON) || (defined __ARM_NEON__)) && !(defined EIGEN_ARM64_USE_SVE)
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_NEON
|
||||
#include <arm_neon.h>
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_NEON
|
||||
#include <arm_neon.h>
|
||||
|
||||
// We currently require SVE to be enabled explicitly via EIGEN_ARM64_USE_SVE and
|
||||
// will not select the backend automatically
|
||||
#elif (defined __ARM_FEATURE_SVE) && (defined EIGEN_ARM64_USE_SVE)
|
||||
// We currently require SVE to be enabled explicitly via EIGEN_ARM64_USE_SVE and
|
||||
// will not select the backend automatically
|
||||
#elif (defined __ARM_FEATURE_SVE) && (defined EIGEN_ARM64_USE_SVE)
|
||||
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_SVE
|
||||
#include <arm_sve.h>
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_SVE
|
||||
#include <arm_sve.h>
|
||||
|
||||
// Since we depend on knowing SVE vector lengths at compile-time, we need
|
||||
// to ensure a fixed lengths is set
|
||||
#if defined __ARM_FEATURE_SVE_BITS
|
||||
#define EIGEN_ARM64_SVE_VL __ARM_FEATURE_SVE_BITS
|
||||
#else
|
||||
// Since we depend on knowing SVE vector lengths at compile-time, we need
|
||||
// to ensure a fixed lengths is set
|
||||
#if defined __ARM_FEATURE_SVE_BITS
|
||||
#define EIGEN_ARM64_SVE_VL __ARM_FEATURE_SVE_BITS
|
||||
#else
|
||||
#error "Eigen requires a fixed SVE lector length but EIGEN_ARM64_SVE_VL is not set."
|
||||
#endif
|
||||
|
||||
@@ -432,46 +428,45 @@
|
||||
// compilers seem to follow this. We therefore include it explicitly.
|
||||
// See also: https://bugs.llvm.org/show_bug.cgi?id=47955
|
||||
#if defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
|
||||
#include <arm_fp16.h>
|
||||
#include <arm_fp16.h>
|
||||
#endif
|
||||
|
||||
#if defined(__F16C__) && !defined(EIGEN_GPUCC) && (!EIGEN_COMP_CLANG_STRICT || EIGEN_CLANG_STRICT_AT_LEAST(3,8,0))
|
||||
// We can use the optimized fp16 to float and float to fp16 conversion routines
|
||||
#define EIGEN_HAS_FP16_C
|
||||
#if defined(__F16C__) && !defined(EIGEN_GPUCC) && (!EIGEN_COMP_CLANG_STRICT || EIGEN_CLANG_STRICT_AT_LEAST(3, 8, 0))
|
||||
// We can use the optimized fp16 to float and float to fp16 conversion routines
|
||||
#define EIGEN_HAS_FP16_C
|
||||
|
||||
#if EIGEN_COMP_GNUC
|
||||
// Make sure immintrin.h is included, even if e.g. vectorization is
|
||||
// explicitly disabled (see also issue #2395).
|
||||
// Note that FP16C intrinsics for gcc and clang are included by immintrin.h,
|
||||
// as opposed to emmintrin.h as suggested by Intel:
|
||||
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#othertechs=FP16C&expand=1711
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#if EIGEN_COMP_GNUC
|
||||
// Make sure immintrin.h is included, even if e.g. vectorization is
|
||||
// explicitly disabled (see also issue #2395).
|
||||
// Note that FP16C intrinsics for gcc and clang are included by immintrin.h,
|
||||
// as opposed to emmintrin.h as suggested by Intel:
|
||||
// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#othertechs=FP16C&expand=1711
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined EIGEN_CUDACC
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <vector_types.h>
|
||||
#if EIGEN_CUDA_SDK_VER >= 70500
|
||||
#define EIGEN_HAS_CUDA_FP16
|
||||
#endif
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <vector_types.h>
|
||||
#if EIGEN_CUDA_SDK_VER >= 70500
|
||||
#define EIGEN_HAS_CUDA_FP16
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HAS_CUDA_FP16)
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_fp16.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_fp16.h>
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HIPCC)
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <hip/hip_vector_types.h>
|
||||
#define EIGEN_HAS_HIP_FP16
|
||||
#include <hip/hip_fp16.h>
|
||||
#define EIGEN_HAS_HIP_BF16
|
||||
#include <hip/hip_bfloat16.h>
|
||||
#define EIGEN_VECTORIZE_GPU
|
||||
#include <hip/hip_vector_types.h>
|
||||
#define EIGEN_HAS_HIP_FP16
|
||||
#include <hip/hip_fp16.h>
|
||||
#define EIGEN_HAS_HIP_BF16
|
||||
#include <hip/hip_bfloat16.h>
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Namespace containing all symbols from the %Eigen library. */
|
||||
// IWYU pragma: private
|
||||
#include "../InternalHeaderCheck.h"
|
||||
@@ -510,7 +505,6 @@ inline static const char *SimdInstructionSetsInUse(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
#endif // EIGEN_CONFIGURE_VECTORIZATION_H
|
||||
#endif // EIGEN_CONFIGURE_VECTORIZATION_H
|
||||
|
||||
@@ -18,166 +18,167 @@
|
||||
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.
|
||||
*/
|
||||
* 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.
|
||||
*/
|
||||
/** 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.
|
||||
*/
|
||||
* 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.
|
||||
*/
|
||||
* 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 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 */
|
||||
*
|
||||
* 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 */
|
||||
* 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
|
||||
* \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.
|
||||
*/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
*
|
||||
* 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 not
|
||||
* 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.
|
||||
*/
|
||||
*
|
||||
* 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
|
||||
* not 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.
|
||||
*/
|
||||
*
|
||||
* 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 have 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
|
||||
*/
|
||||
*
|
||||
* means the first coefficient packet is guaranteed to be aligned.
|
||||
* An expression cannot have 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 */
|
||||
*
|
||||
* 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
|
||||
@@ -193,65 +194,63 @@ const unsigned int NoPreferredStorageOrderBit = 0x200;
|
||||
*/
|
||||
const unsigned int CompressedAccessBit = 0x400;
|
||||
|
||||
|
||||
// list of flags that are inherited by default
|
||||
const unsigned int HereditaryBits = RowMajorBit
|
||||
| EvalBeforeNestingBit;
|
||||
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 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 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,
|
||||
Lower = 0x1,
|
||||
/** View matrix as an upper triangular matrix. */
|
||||
Upper=0x2,
|
||||
Upper = 0x2,
|
||||
/** %Matrix has ones on the diagonal; to be used in combination with #Lower or #Upper. */
|
||||
UnitDiag=0x4,
|
||||
UnitDiag = 0x4,
|
||||
/** %Matrix has zeros on the diagonal; to be used in combination with #Lower or #Upper. */
|
||||
ZeroDiag=0x8,
|
||||
ZeroDiag = 0x8,
|
||||
/** View matrix as a lower triangular matrix with ones on the diagonal. */
|
||||
UnitLower=UnitDiag|Lower,
|
||||
UnitLower = UnitDiag | Lower,
|
||||
/** View matrix as an upper triangular matrix with ones on the diagonal. */
|
||||
UnitUpper=UnitDiag|Upper,
|
||||
UnitUpper = UnitDiag | Upper,
|
||||
/** View matrix as a lower triangular matrix with zeros on the diagonal. */
|
||||
StrictlyLower=ZeroDiag|Lower,
|
||||
StrictlyLower = ZeroDiag | Lower,
|
||||
/** View matrix as an upper triangular matrix with zeros on the diagonal. */
|
||||
StrictlyUpper=ZeroDiag|Upper,
|
||||
StrictlyUpper = ZeroDiag | Upper,
|
||||
/** Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint. */
|
||||
SelfAdjoint=0x10,
|
||||
SelfAdjoint = 0x10,
|
||||
/** Used to support symmetric, non-selfadjoint, complex matrices. */
|
||||
Symmetric=0x20
|
||||
Symmetric = 0x20
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for indicating whether a buffer is aligned or not. */
|
||||
* 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
|
||||
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
|
||||
#elif EIGEN_MAX_ALIGN_BYTES == 64
|
||||
AlignedMax = Aligned64
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==32
|
||||
#elif EIGEN_MAX_ALIGN_BYTES == 32
|
||||
AlignedMax = Aligned32
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==16
|
||||
#elif EIGEN_MAX_ALIGN_BYTES == 16
|
||||
AlignedMax = Aligned16
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==8
|
||||
#elif EIGEN_MAX_ALIGN_BYTES == 8
|
||||
AlignedMax = Aligned8
|
||||
#elif EIGEN_MAX_ALIGN_BYTES==0
|
||||
#elif EIGEN_MAX_ALIGN_BYTES == 0
|
||||
AlignedMax = Unaligned
|
||||
#else
|
||||
#error Invalid value for EIGEN_MAX_ALIGN_BYTES
|
||||
@@ -259,35 +258,35 @@ enum AlignmentType {
|
||||
};
|
||||
|
||||
/** \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
|
||||
* 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 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 */
|
||||
* and good size */
|
||||
InnerVectorizedTraversal,
|
||||
/** \internal Vectorization path using a single loop plus scalar loops for the
|
||||
* unaligned boundaries */
|
||||
* unaligned boundaries */
|
||||
LinearVectorizedTraversal,
|
||||
/** \internal Generic vectorization path using one vectorized loop per row/column with some
|
||||
* scalar loops to handle the unaligned boundaries */
|
||||
* scalar loops to handle the unaligned boundaries */
|
||||
SliceVectorizedTraversal,
|
||||
/** \internal Special case to properly handle incompatible scalar types or other defecting cases*/
|
||||
InvalidTraversal,
|
||||
@@ -296,27 +295,24 @@ enum TraversalType {
|
||||
};
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum to specify whether to unroll loops when traversing over the entries of a matrix. */
|
||||
* 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. */
|
||||
/** \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
|
||||
};
|
||||
* 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 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,
|
||||
@@ -329,7 +325,7 @@ enum StorageOptions {
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for specifying whether to apply or solve on the left or right. */
|
||||
* Enum for specifying whether to apply or solve on the left or right. */
|
||||
enum SideType {
|
||||
/** Apply transformation on the left. */
|
||||
OnTheLeft = 1,
|
||||
@@ -355,74 +351,71 @@ enum NaNPropagationOptions {
|
||||
* EIGEN_UNUSED NoChange_t NoChange;
|
||||
* }
|
||||
*
|
||||
* on the ground that it feels dangerous to disambiguate overloaded functions on enum/integer types.
|
||||
* 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 NoChange_t { NoChange };
|
||||
enum Sequential_t { Sequential };
|
||||
enum Default_t { Default };
|
||||
enum Default_t { Default };
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Used in AmbiVector. */
|
||||
enum AmbiVectorMode {
|
||||
IsDense = 0,
|
||||
IsSparse
|
||||
};
|
||||
* 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. */
|
||||
* 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,
|
||||
ReadOnlyAccessors,
|
||||
/** Read/write access via member functions. */
|
||||
WriteAccessors,
|
||||
WriteAccessors,
|
||||
/** Direct read-only access to the coefficients. */
|
||||
DirectAccessors,
|
||||
DirectAccessors,
|
||||
/** Direct read/write access to the coefficients. */
|
||||
DirectWriteAccessors
|
||||
};
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum with options to give to various decompositions. */
|
||||
* Enum with options to give to various decompositions. */
|
||||
enum DecompositionOptions {
|
||||
/** \internal Not used (meant for LDLT?). */
|
||||
Pivoting = 0x01,
|
||||
Pivoting = 0x01,
|
||||
/** \internal Not used (meant for LDLT?). */
|
||||
NoPivoting = 0x02,
|
||||
NoPivoting = 0x02,
|
||||
/** Used in JacobiSVD to indicate that the square matrix U is to be computed. */
|
||||
ComputeFullU = 0x04,
|
||||
ComputeFullU = 0x04,
|
||||
/** Used in JacobiSVD to indicate that the thin matrix U is to be computed. */
|
||||
ComputeThinU = 0x08,
|
||||
ComputeThinU = 0x08,
|
||||
/** Used in JacobiSVD to indicate that the square matrix V is to be computed. */
|
||||
ComputeFullV = 0x10,
|
||||
ComputeFullV = 0x10,
|
||||
/** Used in JacobiSVD to indicate that the thin matrix V is to be computed. */
|
||||
ComputeThinV = 0x20,
|
||||
ComputeThinV = 0x20,
|
||||
/** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify
|
||||
* that only the eigenvalues are to be computed and not the eigenvectors. */
|
||||
EigenvaluesOnly = 0x40,
|
||||
* 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. */
|
||||
* 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,
|
||||
* 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,
|
||||
* 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,
|
||||
* 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. */
|
||||
* Possible values for the \p QRPreconditioner template parameter of JacobiSVD. */
|
||||
enum QRPreconditioners {
|
||||
/** Use a QR decomposition with column pivoting as the first step. */
|
||||
ColPivHouseholderQRPreconditioner = 0x0,
|
||||
@@ -441,75 +434,83 @@ enum QRPreconditioners {
|
||||
#endif
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for reporting the status of a computation. */
|
||||
* Enum for reporting the status of a computation. */
|
||||
enum ComputationInfo {
|
||||
/** Computation was successful. */
|
||||
Success = 0,
|
||||
Success = 0,
|
||||
/** The provided data did not satisfy the prerequisites. */
|
||||
NumericalIssue = 1,
|
||||
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. */
|
||||
* 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 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,
|
||||
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
|
||||
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,
|
||||
MSA = 0x5,
|
||||
SVE = 0x6,
|
||||
HVX = 0x7,
|
||||
* 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,
|
||||
MSA = 0x5,
|
||||
SVE = 0x6,
|
||||
HVX = 0x7,
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
Target = SSE
|
||||
Target = SSE
|
||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||
Target = AltiVec
|
||||
Target = AltiVec
|
||||
#elif defined EIGEN_VECTORIZE_VSX
|
||||
Target = VSX
|
||||
Target = VSX
|
||||
#elif defined EIGEN_VECTORIZE_NEON
|
||||
Target = NEON
|
||||
Target = NEON
|
||||
#elif defined EIGEN_VECTORIZE_SVE
|
||||
Target = SVE
|
||||
Target = SVE
|
||||
#elif defined EIGEN_VECTORIZE_MSA
|
||||
Target = MSA
|
||||
Target = MSA
|
||||
#elif defined EIGEN_VECTORIZE_HVX
|
||||
Target = HVX
|
||||
Target = HVX
|
||||
#else
|
||||
Target = Generic
|
||||
Target = Generic
|
||||
#endif
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace Architecture
|
||||
|
||||
/** \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 };
|
||||
* 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};
|
||||
* Enum used in experimental parallel implementation. */
|
||||
enum Action { GetAction, SetAction };
|
||||
|
||||
/** The type used to identify a dense storage. */
|
||||
struct Dense {};
|
||||
@@ -533,24 +534,46 @@ struct MatrixXpr {};
|
||||
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 SkewSymmetricShape { static std::string debugName() { return "SkewSymmetricShape"; } };
|
||||
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"; } };
|
||||
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 SkewSymmetricShape {
|
||||
static std::string debugName() { return "SkewSymmetricShape"; }
|
||||
};
|
||||
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.
|
||||
// random access iterators based on coeff*() accessors.
|
||||
struct IndexBased {};
|
||||
|
||||
// evaluator based on iterators to access coefficients.
|
||||
// evaluator based on iterators to access coefficients.
|
||||
struct IteratorBased {};
|
||||
|
||||
/** \internal
|
||||
@@ -565,8 +588,8 @@ enum ComparisonName : unsigned int {
|
||||
cmp_GT = 5,
|
||||
cmp_GE = 6
|
||||
};
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_CONSTANTS_H
|
||||
#endif // EIGEN_CONSTANTS_H
|
||||
|
||||
@@ -2,143 +2,145 @@
|
||||
#define EIGEN_WARNINGS_DISABLED
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
|
||||
// 4101 - unreferenced local variable
|
||||
// 4127 - conditional expression is constant
|
||||
// 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 4127 4181 4211 4244 4273 4324 4503 4512 4522 4700 4714 4717 4800)
|
||||
// We currently rely on has_denorm in tests, and need it defined correctly for half/bfloat16.
|
||||
#ifndef _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#define EIGEN_REENABLE_CXX23_DENORM_DEPRECATION_WARNING 1
|
||||
#define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#endif
|
||||
// 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
|
||||
// 4101 - unreferenced local variable
|
||||
// 4127 - conditional expression is constant
|
||||
// 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 4127 4181 4211 4244 4273 4324 4503 4512 4522 4700 4714 4717 4800)
|
||||
// We currently rely on has_denorm in tests, and need it defined correctly for half/bfloat16.
|
||||
#ifndef _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#define EIGEN_REENABLE_CXX23_DENORM_DEPRECATION_WARNING 1
|
||||
#define _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#endif
|
||||
|
||||
#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
|
||||
// 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__
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma clang diagnostic push
|
||||
#endif
|
||||
#if defined(__has_warning)
|
||||
// -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
|
||||
#if __has_warning("-Wconstant-logical-operand")
|
||||
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
||||
#endif
|
||||
#if __has_warning("-Wimplicit-int-float-conversion")
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
||||
#endif
|
||||
#if ( defined(__ALTIVEC__) || defined(__VSX__) ) && ( !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L) )
|
||||
// warning: generic selections are a C11-specific feature
|
||||
// ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h
|
||||
#if __has_warning("-Wc11-extensions")
|
||||
#pragma clang diagnostic ignored "-Wc11-extensions"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma clang diagnostic push
|
||||
#endif
|
||||
#if defined(__has_warning)
|
||||
// -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
|
||||
#if __has_warning("-Wconstant-logical-operand")
|
||||
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
||||
#endif
|
||||
#if __has_warning("-Wimplicit-int-float-conversion")
|
||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
|
||||
#endif
|
||||
#if (defined(__ALTIVEC__) || defined(__VSX__)) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L))
|
||||
// warning: generic selections are a C11-specific feature
|
||||
// ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h
|
||||
#if __has_warning("-Wc11-extensions")
|
||||
#pragma clang diagnostic ignored "-Wc11-extensions"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined __GNUC__ && !defined(__FUJITSU)
|
||||
|
||||
#if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
// g++ warns about local variables shadowing member functions, which is too strict
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ < 8
|
||||
// Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions:
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#if __GNUC__>=6
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
#endif
|
||||
#if __GNUC__==7
|
||||
// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
#endif
|
||||
#if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
// g++ warns about local variables shadowing member functions, which is too strict
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ < 8
|
||||
// Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions:
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#if __GNUC__ >= 6
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
#endif
|
||||
#if __GNUC__ == 7
|
||||
// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325
|
||||
#pragma GCC diagnostic ignored "-Wattributes"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__
|
||||
// MSVC 14.16 (required by CUDA 9.*) does not support the _Pragma keyword, so
|
||||
// we instead use Microsoft's __pragma extension.
|
||||
#if defined _MSC_VER
|
||||
#define EIGEN_MAKE_PRAGMA(X) __pragma(#X)
|
||||
#else
|
||||
#define EIGEN_MAKE_PRAGMA(X) _Pragma(#X)
|
||||
#endif
|
||||
#if defined __NVCC_DIAG_PRAGMA_SUPPORT__
|
||||
#define EIGEN_NV_DIAG_SUPPRESS(X) EIGEN_MAKE_PRAGMA(nv_diag_suppress X)
|
||||
#else
|
||||
#define EIGEN_NV_DIAG_SUPPRESS(X) EIGEN_MAKE_PRAGMA(diag_suppress X)
|
||||
#endif
|
||||
// MSVC 14.16 (required by CUDA 9.*) does not support the _Pragma keyword, so
|
||||
// we instead use Microsoft's __pragma extension.
|
||||
#if defined _MSC_VER
|
||||
#define EIGEN_MAKE_PRAGMA(X) __pragma(#X)
|
||||
#else
|
||||
#define EIGEN_MAKE_PRAGMA(X) _Pragma(#X)
|
||||
#endif
|
||||
#if defined __NVCC_DIAG_PRAGMA_SUPPORT__
|
||||
#define EIGEN_NV_DIAG_SUPPRESS(X) EIGEN_MAKE_PRAGMA(nv_diag_suppress X)
|
||||
#else
|
||||
#define EIGEN_NV_DIAG_SUPPRESS(X) EIGEN_MAKE_PRAGMA(diag_suppress X)
|
||||
#endif
|
||||
|
||||
EIGEN_NV_DIAG_SUPPRESS(boolean_controlling_expr_is_constant)
|
||||
// Disable the "statement is unreachable" message
|
||||
EIGEN_NV_DIAG_SUPPRESS(code_is_unreachable)
|
||||
// Disable the "dynamic initialization in unreachable code" message
|
||||
EIGEN_NV_DIAG_SUPPRESS(initialization_not_reachable)
|
||||
// Disable the "invalid error number" message that we get with older versions of nvcc
|
||||
EIGEN_NV_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)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2527)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2529)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2651)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2653)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2668)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2669)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2670)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2671)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2735)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2737)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2739)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2885)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2888)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2976)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2979)
|
||||
EIGEN_NV_DIAG_SUPPRESS(20011)
|
||||
EIGEN_NV_DIAG_SUPPRESS(20014)
|
||||
// Disable the "// __device__ annotation is ignored on a function(...) that is
|
||||
// explicitly defaulted on its first declaration" message.
|
||||
// The __device__ annotation seems to actually be needed in some cases,
|
||||
// otherwise resulting in kernel runtime errors.
|
||||
EIGEN_NV_DIAG_SUPPRESS(2886)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2929)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2977)
|
||||
EIGEN_NV_DIAG_SUPPRESS(20012)
|
||||
#undef EIGEN_NV_DIAG_SUPPRESS
|
||||
#undef EIGEN_MAKE_PRAGMA
|
||||
EIGEN_NV_DIAG_SUPPRESS(boolean_controlling_expr_is_constant)
|
||||
// Disable the "statement is unreachable" message
|
||||
EIGEN_NV_DIAG_SUPPRESS(code_is_unreachable)
|
||||
// Disable the "dynamic initialization in unreachable code" message
|
||||
EIGEN_NV_DIAG_SUPPRESS(initialization_not_reachable)
|
||||
// Disable the "invalid error number" message that we get with older versions of nvcc
|
||||
EIGEN_NV_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)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2527)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2529)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2651)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2653)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2668)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2669)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2670)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2671)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2735)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2737)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2739)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2885)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2888)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2976)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2979)
|
||||
EIGEN_NV_DIAG_SUPPRESS(20011)
|
||||
EIGEN_NV_DIAG_SUPPRESS(20014)
|
||||
// Disable the "// __device__ annotation is ignored on a function(...) that is
|
||||
// explicitly defaulted on its first declaration" message.
|
||||
// The __device__ annotation seems to actually be needed in some cases,
|
||||
// otherwise resulting in kernel runtime errors.
|
||||
EIGEN_NV_DIAG_SUPPRESS(2886)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2929)
|
||||
EIGEN_NV_DIAG_SUPPRESS(2977)
|
||||
EIGEN_NV_DIAG_SUPPRESS(20012)
|
||||
#undef EIGEN_NV_DIAG_SUPPRESS
|
||||
#undef EIGEN_MAKE_PRAGMA
|
||||
#endif
|
||||
|
||||
#else
|
||||
// warnings already disabled:
|
||||
# ifndef EIGEN_WARNINGS_DISABLED_2
|
||||
# define EIGEN_WARNINGS_DISABLED_2
|
||||
# elif defined(EIGEN_INTERNAL_DEBUGGING)
|
||||
# error "Do not include \"DisableStupidWarnings.h\" recursively more than twice!"
|
||||
# endif
|
||||
#ifndef EIGEN_WARNINGS_DISABLED_2
|
||||
#define EIGEN_WARNINGS_DISABLED_2
|
||||
#elif defined(EIGEN_INTERNAL_DEBUGGING)
|
||||
#error "Do not include \"DisableStupidWarnings.h\" recursively more than twice!"
|
||||
#endif
|
||||
|
||||
#endif // not EIGEN_WARNINGS_DISABLED
|
||||
#endif // not EIGEN_WARNINGS_DISABLED
|
||||
|
||||
@@ -14,108 +14,92 @@
|
||||
#if defined(EIGEN_GPUCC) || defined(EIGEN_AVOID_STL_ARRAY)
|
||||
|
||||
namespace Eigen {
|
||||
template <typename T, size_t n> class array {
|
||||
|
||||
template <typename T, size_t n>
|
||||
class array {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE iterator begin() { return values; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const_iterator begin() const { return values; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE iterator end() { return values + n; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const_iterator end() const { return values + n; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE iterator begin() { return values; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_iterator begin() const { return values; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE iterator end() { return values + n; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_iterator end() const { return values + n; }
|
||||
|
||||
#if !defined(EIGEN_GPUCC)
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE reverse_iterator rbegin() { return reverse_iterator(end());}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE T& operator[] (size_t index) { eigen_internal_assert(index < size()); return values[index]; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { eigen_internal_assert(index < size()); return values[index]; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[](size_t index) {
|
||||
eigen_internal_assert(index < size());
|
||||
return values[index];
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[](size_t index) const {
|
||||
eigen_internal_assert(index < size());
|
||||
return values[index];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE T& at(size_t index) { eigen_assert(index < size()); return values[index]; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const T& at(size_t index) const { eigen_assert(index < size()); return values[index]; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& at(size_t index) {
|
||||
eigen_assert(index < size());
|
||||
return values[index];
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& at(size_t index) const {
|
||||
eigen_assert(index < size());
|
||||
return values[index];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE T& front() { return values[0]; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const T& front() const { return values[0]; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& front() { return values[0]; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& front() const { return values[0]; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE T& back() { return values[n-1]; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const T& back() const { return values[n-1]; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& back() { return values[n - 1]; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const { return values[n - 1]; }
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
|
||||
static std::size_t size() { return n; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE static std::size_t size() { return n; }
|
||||
|
||||
T values[n];
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array() { }
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(const T& v) {
|
||||
EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array() {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v) {
|
||||
EIGEN_STATIC_ASSERT(n == 1, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
|
||||
EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
|
||||
EIGEN_STATIC_ASSERT(n == 2, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v1;
|
||||
values[1] = v2;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
|
||||
EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
|
||||
EIGEN_STATIC_ASSERT(n == 3, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v1;
|
||||
values[1] = v2;
|
||||
values[2] = v3;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3,
|
||||
const T& v4) {
|
||||
EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4) {
|
||||
EIGEN_STATIC_ASSERT(n == 4, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v1;
|
||||
values[1] = v2;
|
||||
values[2] = v3;
|
||||
values[3] = v4;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
|
||||
const T& v5) {
|
||||
EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) {
|
||||
EIGEN_STATIC_ASSERT(n == 5, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v1;
|
||||
values[1] = v2;
|
||||
values[2] = v3;
|
||||
values[3] = v4;
|
||||
values[4] = v5;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
|
||||
const T& v5, const T& v6) {
|
||||
EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
|
||||
const T& v6) {
|
||||
EIGEN_STATIC_ASSERT(n == 6, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v1;
|
||||
values[1] = v2;
|
||||
values[2] = v3;
|
||||
@@ -123,10 +107,9 @@ template <typename T, size_t n> class array {
|
||||
values[4] = v5;
|
||||
values[5] = v6;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
|
||||
const T& v5, const T& v6, const T& v7) {
|
||||
EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
|
||||
const T& v6, const T& v7) {
|
||||
EIGEN_STATIC_ASSERT(n == 7, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v1;
|
||||
values[1] = v2;
|
||||
values[2] = v3;
|
||||
@@ -135,11 +118,9 @@ template <typename T, size_t n> class array {
|
||||
values[5] = v6;
|
||||
values[6] = v7;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(
|
||||
const T& v1, const T& v2, const T& v3, const T& v4,
|
||||
const T& v5, const T& v6, const T& v7, const T& v8) {
|
||||
EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5,
|
||||
const T& v6, const T& v7, const T& v8) {
|
||||
EIGEN_STATIC_ASSERT(n == 8, YOU_MADE_A_PROGRAMMING_MISTAKE)
|
||||
values[0] = v1;
|
||||
values[1] = v2;
|
||||
values[2] = v3;
|
||||
@@ -150,53 +131,45 @@ template <typename T, size_t n> class array {
|
||||
values[7] = v8;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
|
||||
eigen_assert(l.size() == n);
|
||||
internal::smart_copy(l.begin(), l.end(), values);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Specialize array for zero size
|
||||
template <typename T> class array<T, 0> {
|
||||
template <typename T>
|
||||
class array<T, 0> {
|
||||
public:
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE T& operator[] (size_t) {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[](size_t) {
|
||||
eigen_assert(false && "Can't index a zero size array");
|
||||
return dummy;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const T& operator[] (size_t) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[](size_t) const {
|
||||
eigen_assert(false && "Can't index a zero size array");
|
||||
return dummy;
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE T& front() {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& front() {
|
||||
eigen_assert(false && "Can't index a zero size array");
|
||||
return dummy;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const T& front() const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& front() const {
|
||||
eigen_assert(false && "Can't index a zero size array");
|
||||
return dummy;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE T& back() {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& back() {
|
||||
eigen_assert(false && "Can't index a zero size array");
|
||||
return dummy;
|
||||
}
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const T& back() const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const {
|
||||
eigen_assert(false && "Can't index a zero size array");
|
||||
return dummy;
|
||||
}
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; }
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE array() : dummy() { }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array() : dummy() {}
|
||||
|
||||
EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() {
|
||||
EIGEN_UNUSED_VARIABLE(l);
|
||||
@@ -209,8 +182,8 @@ template <typename T> class array<T, 0> {
|
||||
|
||||
// Comparison operator
|
||||
// Todo: implement !=, <, <=, >, and >=
|
||||
template<class T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC bool operator==(const array<T,N>& lhs, const array<T,N>& rhs) {
|
||||
template <class T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC bool operator==(const array<T, N>& lhs, const array<T, N>& rhs) {
|
||||
for (std::size_t i = 0; i < N; ++i) {
|
||||
if (lhs[i] != rhs[i]) {
|
||||
return false;
|
||||
@@ -219,27 +192,30 @@ EIGEN_DEVICE_FUNC bool operator==(const array<T,N>& lhs, const array<T,N>& rhs)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
namespace internal {
|
||||
template<std::size_t I_, class T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T,N>& a) {
|
||||
template <std::size_t I_, class T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T, N>& a) {
|
||||
return a[I_];
|
||||
}
|
||||
template<std::size_t I_, class T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) {
|
||||
template <std::size_t I_, class T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T, N>& a) {
|
||||
return a[I_];
|
||||
}
|
||||
|
||||
template<class T, std::size_t N> struct array_size<array<T,N> > {
|
||||
template <class T, std::size_t N>
|
||||
struct array_size<array<T, N> > {
|
||||
enum { value = N };
|
||||
};
|
||||
template<class T, std::size_t N> struct array_size<array<T,N>& > {
|
||||
template <class T, std::size_t N>
|
||||
struct array_size<array<T, N>&> {
|
||||
enum { value = N };
|
||||
};
|
||||
template<class T, std::size_t N> struct array_size<const array<T,N> > {
|
||||
template <class T, std::size_t N>
|
||||
struct array_size<const array<T, N> > {
|
||||
enum { value = N };
|
||||
};
|
||||
template<class T, std::size_t N> struct array_size<const array<T,N>& > {
|
||||
template <class T, std::size_t N>
|
||||
struct array_size<const array<T, N>&> {
|
||||
enum { value = N };
|
||||
};
|
||||
|
||||
@@ -253,7 +229,8 @@ template<class T, std::size_t N> struct array_size<const array<T,N>& > {
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template <typename T, std::size_t N> using array = std::array<T, N>;
|
||||
template <typename T, std::size_t N>
|
||||
using array = std::array<T, N>;
|
||||
|
||||
namespace internal {
|
||||
/* std::get is only constexpr in C++14, not yet in C++11
|
||||
@@ -265,16 +242,25 @@ namespace internal {
|
||||
* this may not be constexpr
|
||||
*/
|
||||
#if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
|
||||
#define STD_GET_ARR_HACK a._M_instance[I_]
|
||||
#define STD_GET_ARR_HACK a._M_instance[I_]
|
||||
#elif defined(_LIBCPP_VERSION)
|
||||
#define STD_GET_ARR_HACK a.__elems_[I_]
|
||||
#define STD_GET_ARR_HACK a.__elems_[I_]
|
||||
#else
|
||||
#define STD_GET_ARR_HACK std::template get<I_, T, N>(a)
|
||||
#define STD_GET_ARR_HACK std::template get<I_, T, N>(a)
|
||||
#endif
|
||||
|
||||
template<std::size_t I_, class T, std::size_t N> constexpr inline T& array_get(std::array<T,N>& a) { return (T&) STD_GET_ARR_HACK; }
|
||||
template<std::size_t I_, class T, std::size_t N> constexpr inline T&& array_get(std::array<T,N>&& a) { return (T&&) STD_GET_ARR_HACK; }
|
||||
template<std::size_t I_, class T, std::size_t N> constexpr inline T const& array_get(std::array<T,N> const& a) { return (T const&) STD_GET_ARR_HACK; }
|
||||
template <std::size_t I_, class T, std::size_t N>
|
||||
constexpr inline T& array_get(std::array<T, N>& a) {
|
||||
return (T&)STD_GET_ARR_HACK;
|
||||
}
|
||||
template <std::size_t I_, class T, std::size_t N>
|
||||
constexpr inline T&& array_get(std::array<T, N>&& a) {
|
||||
return (T&&)STD_GET_ARR_HACK;
|
||||
}
|
||||
template <std::size_t I_, class T, std::size_t N>
|
||||
constexpr inline T const& array_get(std::array<T, N> const& a) {
|
||||
return (T const&)STD_GET_ARR_HACK;
|
||||
}
|
||||
|
||||
#undef STD_GET_ARR_HACK
|
||||
|
||||
|
||||
@@ -17,253 +17,394 @@
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
template<typename T> struct traits;
|
||||
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 T>
|
||||
struct traits<const T> : traits<T> {};
|
||||
|
||||
template<typename Derived> struct has_direct_access
|
||||
{
|
||||
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 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_traits;
|
||||
|
||||
template< typename T> struct evaluator;
|
||||
template <typename T>
|
||||
struct evaluator;
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
template<typename T> struct NumTraits;
|
||||
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> class DenseCoeffsBase;
|
||||
template <typename Derived>
|
||||
struct EigenBase;
|
||||
template <typename Derived>
|
||||
class DenseBase;
|
||||
template <typename Derived>
|
||||
class PlainObjectBase;
|
||||
template <typename Derived, int Level>
|
||||
class DenseCoeffsBase;
|
||||
|
||||
template<typename Scalar_, int Rows_, int Cols_,
|
||||
int Options_ = AutoAlign |
|
||||
( (Rows_==1 && Cols_!=1) ? Eigen::RowMajor
|
||||
: (Cols_==1 && Rows_!=1) ? Eigen::ColMajor
|
||||
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
|
||||
int MaxRows_ = Rows_,
|
||||
int MaxCols_ = Cols_
|
||||
> class Matrix;
|
||||
template <typename Scalar_, int Rows_, int Cols_,
|
||||
int Options_ = AutoAlign | ((Rows_ == 1 && Cols_ != 1) ? Eigen::RowMajor
|
||||
: (Cols_ == 1 && Rows_ != 1) ? Eigen::ColMajor
|
||||
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION),
|
||||
int MaxRows_ = Rows_, int MaxCols_ = Cols_>
|
||||
class Matrix;
|
||||
|
||||
template<typename Derived> class MatrixBase;
|
||||
template<typename Derived> class ArrayBase;
|
||||
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 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 XprType, int Rows=Dynamic, int Cols=Dynamic, int Order=0> class Reshaped;
|
||||
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 XprType, int Rows = Dynamic, int Cols = Dynamic, int Order = 0>
|
||||
class Reshaped;
|
||||
|
||||
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 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 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 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 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<typename Derived> class SkewSymmetricBase;
|
||||
template<typename VectorType_> class SkewSymmetricWrapper;
|
||||
template<typename Scalar_> class SkewSymmetricMatrix3;
|
||||
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>
|
||||
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 <typename Derived>
|
||||
class SkewSymmetricBase;
|
||||
template <typename VectorType_>
|
||||
class SkewSymmetricWrapper;
|
||||
template <typename Scalar_>
|
||||
class SkewSymmetricMatrix3;
|
||||
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 OuterStrideAtCompileTime, int InnerStrideAtCompileTime> 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 std::conditional_t<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> > > class Ref;
|
||||
template<typename ViewOp, typename MatrixType, typename StrideType = Stride<0,0>> class CwiseUnaryView;
|
||||
template <typename Derived,
|
||||
int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors>
|
||||
class MapBase;
|
||||
template <int OuterStrideAtCompileTime, int InnerStrideAtCompileTime>
|
||||
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 std::conditional_t<PlainObjectType::IsVectorAtCompileTime, InnerStride<1>, OuterStride<>>>
|
||||
class Ref;
|
||||
template <typename ViewOp, typename MatrixType, typename StrideType = Stride<0, 0>>
|
||||
class CwiseUnaryView;
|
||||
|
||||
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;
|
||||
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 XprType> class generic_randaccess_stl_iterator;
|
||||
template<typename XprType> class pointer_based_stl_iterator;
|
||||
template<typename XprType, DirectionType Direction> class subvector_stl_iterator;
|
||||
template<typename XprType, DirectionType Direction> class subvector_stl_reverse_iterator;
|
||||
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
|
||||
template <typename XprType>
|
||||
class generic_randaccess_stl_iterator;
|
||||
template <typename XprType>
|
||||
class pointer_based_stl_iterator;
|
||||
template <typename XprType, DirectionType Direction>
|
||||
class subvector_stl_iterator;
|
||||
template <typename XprType, DirectionType Direction>
|
||||
class subvector_stl_reverse_iterator;
|
||||
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;
|
||||
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 <typename Lhs, typename Rhs>
|
||||
struct product_type;
|
||||
|
||||
template<bool> struct EnableIf;
|
||||
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,
|
||||
* \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;
|
||||
}
|
||||
typename RhsScalar = typename traits<typename T::Rhs>::Scalar>
|
||||
struct product_evaluator;
|
||||
} // namespace internal
|
||||
|
||||
template<typename Lhs, typename Rhs,
|
||||
int ProductType = internal::product_type<Lhs,Rhs>::value>
|
||||
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;
|
||||
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, 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, int NaNPropagation=PropagateFast> struct scalar_min_op;
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar, int NaNPropagation=PropagateFast> 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 LhsScalar,typename RhsScalar=LhsScalar> struct scalar_absolute_difference_op;
|
||||
template<typename Scalar> struct scalar_sqrt_op;
|
||||
template<typename Scalar> struct scalar_cbrt_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_atan_op;
|
||||
template <typename LhsScalar, typename RhsScalar = LhsScalar> struct scalar_atan2_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> struct scalar_sign_op;
|
||||
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, int NaNPropagation = PropagateFast>
|
||||
struct scalar_min_op;
|
||||
template <typename LhsScalar, typename RhsScalar = LhsScalar, int NaNPropagation = PropagateFast>
|
||||
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 LhsScalar, typename RhsScalar = LhsScalar>
|
||||
struct scalar_absolute_difference_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_sqrt_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_cbrt_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_atan_op;
|
||||
template <typename LhsScalar, typename RhsScalar = LhsScalar>
|
||||
struct scalar_atan2_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>
|
||||
struct scalar_sign_op;
|
||||
template <typename Scalar, typename ScalarExponent>
|
||||
struct scalar_pow_op;
|
||||
template <typename Scalar, typename ScalarExponent, bool BaseIsInteger, bool ExponentIsInteger, bool BaseIsComplex,
|
||||
bool ExponentIsComplex>
|
||||
struct scalar_unary_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;
|
||||
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;
|
||||
// logical and bitwise operations
|
||||
template <typename Scalar> struct scalar_boolean_and_op;
|
||||
template <typename Scalar> struct scalar_boolean_or_op;
|
||||
template <typename Scalar> struct scalar_boolean_xor_op;
|
||||
template <typename Scalar> struct scalar_boolean_not_op;
|
||||
template <typename Scalar> struct scalar_bitwise_and_op;
|
||||
template <typename Scalar> struct scalar_bitwise_or_op;
|
||||
template <typename Scalar> struct scalar_bitwise_xor_op;
|
||||
template <typename Scalar> struct scalar_bitwise_not_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_boolean_and_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_boolean_or_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_boolean_xor_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_boolean_not_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_and_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_or_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_xor_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_not_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_ndtri_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;
|
||||
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_ndtri_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;
|
||||
|
||||
// Bessel functions in SpecialFunctions module
|
||||
template<typename Scalar> struct scalar_bessel_i0_op;
|
||||
template<typename Scalar> struct scalar_bessel_i0e_op;
|
||||
template<typename Scalar> struct scalar_bessel_i1_op;
|
||||
template<typename Scalar> struct scalar_bessel_i1e_op;
|
||||
template<typename Scalar> struct scalar_bessel_j0_op;
|
||||
template<typename Scalar> struct scalar_bessel_y0_op;
|
||||
template<typename Scalar> struct scalar_bessel_j1_op;
|
||||
template<typename Scalar> struct scalar_bessel_y1_op;
|
||||
template<typename Scalar> struct scalar_bessel_k0_op;
|
||||
template<typename Scalar> struct scalar_bessel_k0e_op;
|
||||
template<typename Scalar> struct scalar_bessel_k1_op;
|
||||
template<typename Scalar> struct scalar_bessel_k1e_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_i0_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_i0e_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_i1_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_i1e_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_j0_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_y0_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_j1_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_y1_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_k0_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_k0e_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_k1_op;
|
||||
template <typename Scalar>
|
||||
struct scalar_bessel_k1e_op;
|
||||
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
struct IOFormat;
|
||||
|
||||
// Array module
|
||||
template<typename Scalar_, int Rows_, int Cols_,
|
||||
int Options_ = AutoAlign |
|
||||
( (Rows_==1 && Cols_!=1) ? Eigen::RowMajor
|
||||
: (Cols_==1 && Rows_!=1) ? Eigen::ColMajor
|
||||
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
|
||||
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 Scalar_, int Rows_, int Cols_,
|
||||
int Options_ = AutoAlign | ((Rows_ == 1 && Cols_ != 1) ? Eigen::RowMajor
|
||||
: (Cols_ == 1 && Rows_ != 1) ? Eigen::ColMajor
|
||||
: EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION),
|
||||
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;
|
||||
|
||||
#if defined(EIGEN_USE_LAPACKE) && defined(lapack_int)
|
||||
// Lapacke interface requires StorageIndex to be lapack_int
|
||||
@@ -272,60 +413,93 @@ typedef lapack_int DefaultPermutationIndex;
|
||||
typedef int DefaultPermutationIndex;
|
||||
#endif
|
||||
|
||||
template<typename MatrixType, typename PermutationIndex = DefaultPermutationIndex> class FullPivLU;
|
||||
template<typename MatrixType, typename PermutationIndex = DefaultPermutationIndex> class PartialPivLU;
|
||||
template <typename MatrixType, typename PermutationIndex = DefaultPermutationIndex>
|
||||
class FullPivLU;
|
||||
template <typename MatrixType, typename PermutationIndex = DefaultPermutationIndex>
|
||||
class PartialPivLU;
|
||||
namespace internal {
|
||||
template<typename MatrixType> struct inverse_impl;
|
||||
template <typename MatrixType>
|
||||
struct inverse_impl;
|
||||
}
|
||||
template<typename MatrixType> class HouseholderQR;
|
||||
template<typename MatrixType, typename PermutationIndex = DefaultPermutationIndex> class ColPivHouseholderQR;
|
||||
template<typename MatrixType, typename PermutationIndex = DefaultPermutationIndex> class FullPivHouseholderQR;
|
||||
template<typename MatrixType, typename PermutationIndex = DefaultPermutationIndex> class CompleteOrthogonalDecomposition;
|
||||
template<typename MatrixType> class SVDBase;
|
||||
template<typename MatrixType, int Options = 0> class JacobiSVD;
|
||||
template<typename MatrixType, int Options = 0> 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;
|
||||
template <typename MatrixType>
|
||||
class HouseholderQR;
|
||||
template <typename MatrixType, typename PermutationIndex = DefaultPermutationIndex>
|
||||
class ColPivHouseholderQR;
|
||||
template <typename MatrixType, typename PermutationIndex = DefaultPermutationIndex>
|
||||
class FullPivHouseholderQR;
|
||||
template <typename MatrixType, typename PermutationIndex = DefaultPermutationIndex>
|
||||
class CompleteOrthogonalDecomposition;
|
||||
template <typename MatrixType>
|
||||
class SVDBase;
|
||||
template <typename MatrixType, int Options = 0>
|
||||
class JacobiSVD;
|
||||
template <typename MatrixType, int Options = 0>
|
||||
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:
|
||||
namespace internal {
|
||||
template<typename Derived, typename OtherDerived, int Size = MatrixBase<Derived>::SizeAtCompileTime> struct cross_impl;
|
||||
template <typename Derived, typename OtherDerived, int Size = MatrixBase<Derived>::SizeAtCompileTime>
|
||||
struct cross_impl;
|
||||
}
|
||||
template<typename Derived, int Dim_> class RotationBase;
|
||||
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;
|
||||
template <typename Derived, int Dim_>
|
||||
class RotationBase;
|
||||
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;
|
||||
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;
|
||||
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
|
||||
{
|
||||
struct stem_function {
|
||||
typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
|
||||
typedef ComplexScalar type(ComplexScalar, int);
|
||||
};
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_FORWARDDECLARATIONS_H
|
||||
#endif // EIGEN_FORWARDDECLARATIONS_H
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
// 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
|
||||
|
||||
@@ -25,23 +24,24 @@ namespace placeholders {
|
||||
typedef symbolic::SymbolExpr<internal::symbolic_last_tag> last_t;
|
||||
|
||||
/** \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 supports standard arithmetic operations.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
* \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 supports standard arithmetic operations.
|
||||
*
|
||||
* 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 last_t last;
|
||||
|
||||
} // namespace placeholders
|
||||
@@ -49,44 +49,48 @@ static const last_t last;
|
||||
namespace internal {
|
||||
|
||||
// Replace symbolic last/end "keywords" by their true runtime value
|
||||
inline Index eval_expr_given_size(Index x, Index /* size */) { return x; }
|
||||
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 <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(Eigen::placeholders::last=size-1);
|
||||
template <typename Derived>
|
||||
Index eval_expr_given_size(const symbolic::BaseExpr<Derived>& x, Index size) {
|
||||
return x.derived().eval(Eigen::placeholders::last = size - 1);
|
||||
}
|
||||
|
||||
// Extract increment/step at compile time
|
||||
template<typename T, typename EnableIf = void> struct get_compile_time_incr {
|
||||
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>
|
||||
EIGEN_CONSTEXPR Index first(const T& x) EIGEN_NOEXCEPT { return x.first(); }
|
||||
template <typename T>
|
||||
EIGEN_CONSTEXPR Index first(const T& x) EIGEN_NOEXCEPT {
|
||||
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>
|
||||
// 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; }
|
||||
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
|
||||
};
|
||||
enum { SizeAtCompileTime = 1 };
|
||||
SingleRange(Index val) : m_value(val) {}
|
||||
Index operator[](Index) const { return m_value; }
|
||||
static EIGEN_CONSTEXPR Index size() EIGEN_NOEXCEPT { return 1; }
|
||||
@@ -94,103 +98,111 @@ struct SingleRange {
|
||||
Index m_value;
|
||||
};
|
||||
|
||||
template<> struct get_compile_time_incr<SingleRange> {
|
||||
enum { value = 1 }; // 1 or 0 ??
|
||||
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 operator[](int) methods)
|
||||
template<typename T, int XprSize>
|
||||
struct IndexedViewCompatibleType<T,XprSize,std::enable_if_t<internal::is_integral<T>::value>> {
|
||||
// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operator[](int)
|
||||
// methods)
|
||||
template <typename T, int XprSize>
|
||||
struct IndexedViewCompatibleType<T, XprSize, std::enable_if_t<internal::is_integral<T>::value>> {
|
||||
// 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 Eigen::Array<Index,1,1> type;
|
||||
typedef SingleRange type;
|
||||
};
|
||||
|
||||
template<typename T, int XprSize>
|
||||
template <typename T, int XprSize>
|
||||
struct IndexedViewCompatibleType<T, XprSize, std::enable_if_t<symbolic::is_symbolic<T>::value>> {
|
||||
typedef SingleRange type;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<symbolic::is_symbolic<T>::value,SingleRange>
|
||||
makeIndexedViewCompatible(const T& id, Index size, SpecializedType) {
|
||||
return eval_expr_given_size(id,size);
|
||||
template <typename T>
|
||||
std::enable_if_t<symbolic::is_symbolic<T>::value, SingleRange> makeIndexedViewCompatible(const T& id, Index size,
|
||||
SpecializedType) {
|
||||
return eval_expr_given_size(id, size);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Handling of all
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
struct all_t { all_t() {} };
|
||||
struct all_t {
|
||||
all_t() {}
|
||||
};
|
||||
|
||||
// Convert a symbolic 'all' into a usable range type
|
||||
template<int XprSize>
|
||||
template <int XprSize>
|
||||
struct AllRange {
|
||||
enum { SizeAtCompileTime = XprSize };
|
||||
AllRange(Index size = XprSize) : m_size(size) {}
|
||||
EIGEN_CONSTEXPR Index operator[](Index i) const EIGEN_NOEXCEPT { return i; }
|
||||
EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_size.value(); }
|
||||
EIGEN_CONSTEXPR Index first() const EIGEN_NOEXCEPT { return 0; }
|
||||
variable_if_dynamic<Index,XprSize> m_size;
|
||||
variable_if_dynamic<Index, XprSize> m_size;
|
||||
};
|
||||
|
||||
template<int XprSize>
|
||||
struct IndexedViewCompatibleType<all_t,XprSize> {
|
||||
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) {
|
||||
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> > {
|
||||
template <int Size>
|
||||
struct get_compile_time_incr<AllRange<Size>> {
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
namespace placeholders {
|
||||
|
||||
typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,symbolic::ValueExpr<Eigen::internal::FixedInt<1> > > lastp1_t;
|
||||
typedef symbolic::AddExpr<symbolic::SymbolExpr<internal::symbolic_last_tag>,
|
||||
symbolic::ValueExpr<Eigen::internal::FixedInt<1>>>
|
||||
lastp1_t;
|
||||
typedef Eigen::internal::all_t all_t;
|
||||
|
||||
/** \var lastp1
|
||||
* \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 supports standard arithmetic operations.
|
||||
* It is essentially an alias to last+fix<1>.
|
||||
*
|
||||
* \sa last
|
||||
*/
|
||||
* \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 supports standard arithmetic operations.
|
||||
* It is essentially an alias to last+fix<1>.
|
||||
*
|
||||
* \sa last
|
||||
*/
|
||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||
static const auto lastp1 = last+fix<1>;
|
||||
static const auto lastp1 = last + fix<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 lastp1_t lastp1(last+fix<1>());
|
||||
static const lastp1_t lastp1(last + fix<1>());
|
||||
#endif
|
||||
|
||||
/** \var end
|
||||
* \ingroup Core_Module
|
||||
* \sa lastp1
|
||||
*/
|
||||
* \ingroup Core_Module
|
||||
* \sa lastp1
|
||||
*/
|
||||
static const lastp1_t end = lastp1;
|
||||
|
||||
/** \var all
|
||||
* \ingroup Core_Module
|
||||
* Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns
|
||||
*/
|
||||
* \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;
|
||||
|
||||
} // namespace placeholders
|
||||
} // namespace placeholders
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_INDEXED_VIEW_HELPER_H
|
||||
#endif // EIGEN_INDEXED_VIEW_HELPER_H
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
// 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
|
||||
|
||||
@@ -18,236 +17,268 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<int N> class FixedInt;
|
||||
template<int N> class VariableAndFixedInt;
|
||||
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 expected to
|
||||
* be created by the user using Eigen::fix<N> or Eigen::fix<N>().
|
||||
* \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:
|
||||
* \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 expected to
|
||||
* be created by the user using Eigen::fix<N> or Eigen::fix<N>().
|
||||
* \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;
|
||||
EIGEN_CONSTEXPR operator int() const { return value; }
|
||||
|
||||
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt() = default;
|
||||
|
||||
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt(std::integral_constant<int,N>) {}
|
||||
|
||||
FixedInt(std::integral_constant<int, N>) {}
|
||||
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt( VariableAndFixedInt<N> other) {
|
||||
#ifndef EIGEN_INTERNAL_DEBUGGING
|
||||
FixedInt(VariableAndFixedInt<N> other) {
|
||||
#ifndef EIGEN_INTERNAL_DEBUGGING
|
||||
EIGEN_UNUSED_VARIABLE(other);
|
||||
#endif
|
||||
eigen_internal_assert(int(other)==N);
|
||||
#endif
|
||||
eigen_internal_assert(int(other) == N);
|
||||
}
|
||||
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<-N> operator-() const { return FixedInt<-N>(); }
|
||||
|
||||
template<int M>
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<N+M> operator+( FixedInt<M>) const { return FixedInt<N+M>(); }
|
||||
|
||||
template<int M>
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<N-M> operator-( FixedInt<M>) const { return FixedInt<N-M>(); }
|
||||
|
||||
template<int M>
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<N*M> operator*( FixedInt<M>) const { return FixedInt<N*M>(); }
|
||||
|
||||
template<int M>
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<N/M> operator/( FixedInt<M>) const { return FixedInt<N/M>(); }
|
||||
|
||||
template<int M>
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<N%M> operator%( FixedInt<M>) const { return FixedInt<N%M>(); }
|
||||
|
||||
template<int M>
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<N|M> operator|( FixedInt<M>) const { return FixedInt<N|M>(); }
|
||||
|
||||
template<int M>
|
||||
EIGEN_CONSTEXPR
|
||||
FixedInt<N&M> operator&( FixedInt<M>) const { return FixedInt<N&M>(); }
|
||||
|
||||
template <int M>
|
||||
EIGEN_CONSTEXPR FixedInt<N + M> operator+(FixedInt<M>) const {
|
||||
return FixedInt<N + M>();
|
||||
}
|
||||
|
||||
template <int M>
|
||||
EIGEN_CONSTEXPR FixedInt<N - M> operator-(FixedInt<M>) const {
|
||||
return FixedInt<N - M>();
|
||||
}
|
||||
|
||||
template <int M>
|
||||
EIGEN_CONSTEXPR FixedInt<N * M> operator*(FixedInt<M>) const {
|
||||
return FixedInt<N * M>();
|
||||
}
|
||||
|
||||
template <int M>
|
||||
EIGEN_CONSTEXPR FixedInt<N / M> operator/(FixedInt<M>) const {
|
||||
return FixedInt<N / M>();
|
||||
}
|
||||
|
||||
template <int M>
|
||||
EIGEN_CONSTEXPR FixedInt<N % M> operator%(FixedInt<M>) const {
|
||||
return FixedInt<N % M>();
|
||||
}
|
||||
|
||||
template <int M>
|
||||
EIGEN_CONSTEXPR FixedInt<N | M> operator|(FixedInt<M>) const {
|
||||
return FixedInt<N | M>();
|
||||
}
|
||||
|
||||
template <int M>
|
||||
EIGEN_CONSTEXPR FixedInt<N & M> operator&(FixedInt<M>) const {
|
||||
return FixedInt<N & M>();
|
||||
}
|
||||
|
||||
// Needed in C++14 to allow fix<N>():
|
||||
EIGEN_CONSTEXPR FixedInt operator() () const { return *this; }
|
||||
EIGEN_CONSTEXPR FixedInt operator()() const { return *this; }
|
||||
|
||||
VariableAndFixedInt<N> operator() (int val) const { return VariableAndFixedInt<N>(val); }
|
||||
VariableAndFixedInt<N> operator()(int val) const { return VariableAndFixedInt<N>(val); }
|
||||
};
|
||||
|
||||
/** \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:
|
||||
* \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:
|
||||
|
||||
protected:
|
||||
int m_value;
|
||||
};
|
||||
|
||||
template<typename T, int Default=Dynamic> struct get_fixed_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> {
|
||||
template <int N, int Default>
|
||||
struct get_fixed_value<FixedInt<N>, Default> {
|
||||
static const int value = N;
|
||||
};
|
||||
|
||||
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> {
|
||||
template <int N, int Default>
|
||||
struct get_fixed_value<VariableAndFixedInt<N>, Default> {
|
||||
static const int value = N;
|
||||
};
|
||||
|
||||
template<typename T> EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) { return x; }
|
||||
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;
|
||||
}
|
||||
|
||||
// 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; };
|
||||
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,std::enable_if_t<internal::is_integral<T>::value>> { typedef Index type; };
|
||||
template <typename T, int DynamicKey>
|
||||
struct cleanup_index_type<T, DynamicKey, std::enable_if_t<internal::is_integral<T>::value>> {
|
||||
typedef Index type;
|
||||
};
|
||||
|
||||
// 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; };
|
||||
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; };
|
||||
template <int DynamicKey>
|
||||
struct cleanup_index_type<VariableAndFixedInt<DynamicKey>, DynamicKey> {
|
||||
typedef Index type;
|
||||
};
|
||||
|
||||
template<int N, int DynamicKey> struct cleanup_index_type<std::integral_constant<int,N>, DynamicKey> { typedef FixedInt<N> type; };
|
||||
template <int N, int DynamicKey>
|
||||
struct cleanup_index_type<std::integral_constant<int, N>, DynamicKey> {
|
||||
typedef FixedInt<N> type;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
template<int N>
|
||||
template <int N>
|
||||
constexpr internal::FixedInt<N> fix{};
|
||||
|
||||
#else // EIGEN_PARSED_BY_DOXYGEN
|
||||
#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>.
|
||||
*
|
||||
* \sa fix<N>(int), seq, seqN
|
||||
*/
|
||||
template<int 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>.
|
||||
*
|
||||
* \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>
|
||||
* \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
|
||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_INTEGRAL_CONSTANT_H
|
||||
#endif // EIGEN_INTEGRAL_CONSTANT_H
|
||||
|
||||
@@ -34,49 +34,49 @@
|
||||
#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
|
||||
#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
|
||||
#define EIGEN_USE_LAPACKE
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_USE_MKL_VML) && !defined(EIGEN_USE_MKL)
|
||||
#define EIGEN_USE_MKL
|
||||
#define EIGEN_USE_MKL
|
||||
#endif
|
||||
|
||||
|
||||
#if defined EIGEN_USE_MKL
|
||||
# if (!defined MKL_DIRECT_CALL) && (!defined EIGEN_MKL_NO_DIRECT_CALL)
|
||||
# define MKL_DIRECT_CALL
|
||||
# define MKL_DIRECT_CALL_JUST_SET
|
||||
# endif
|
||||
# include <mkl.h>
|
||||
#if (!defined MKL_DIRECT_CALL) && (!defined EIGEN_MKL_NO_DIRECT_CALL)
|
||||
#define MKL_DIRECT_CALL
|
||||
#define MKL_DIRECT_CALL_JUST_SET
|
||||
#endif
|
||||
#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
|
||||
# ifdef MKL_DIRECT_CALL_JUST_SET
|
||||
# undef MKL_DIRECT_CALL
|
||||
# endif
|
||||
# endif
|
||||
#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
|
||||
#ifdef MKL_DIRECT_CALL_JUST_SET
|
||||
#undef MKL_DIRECT_CALL
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined EIGEN_USE_MKL
|
||||
@@ -126,7 +126,7 @@
|
||||
namespace Eigen {
|
||||
|
||||
typedef std::complex<double> dcomplex;
|
||||
typedef std::complex<float> scomplex;
|
||||
typedef std::complex<float> scomplex;
|
||||
|
||||
#if defined(EIGEN_USE_MKL)
|
||||
typedef MKL_INT BlasIndex;
|
||||
@@ -134,7 +134,6 @@ typedef MKL_INT BlasIndex;
|
||||
typedef int BlasIndex;
|
||||
#endif
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
|
||||
#endif // EIGEN_MKL_SUPPORT_H
|
||||
#endif // EIGEN_MKL_SUPPORT_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,55 +13,52 @@
|
||||
namespace Eigen {
|
||||
|
||||
/** \class MaxSizeVector
|
||||
* \ingroup Core
|
||||
*
|
||||
* \brief The MaxSizeVector class.
|
||||
*
|
||||
* The %MaxSizeVector provides a subset of std::vector functionality.
|
||||
*
|
||||
* The goal is to provide basic std::vector operations when using
|
||||
* std::vector is not an option (e.g. on GPU or when compiling using
|
||||
* FMA/AVX, as this can cause either compilation failures or illegal
|
||||
* instruction failures).
|
||||
*
|
||||
* Beware: The constructors are not API compatible with these of
|
||||
* std::vector.
|
||||
*/
|
||||
* \ingroup Core
|
||||
*
|
||||
* \brief The MaxSizeVector class.
|
||||
*
|
||||
* The %MaxSizeVector provides a subset of std::vector functionality.
|
||||
*
|
||||
* The goal is to provide basic std::vector operations when using
|
||||
* std::vector is not an option (e.g. on GPU or when compiling using
|
||||
* FMA/AVX, as this can cause either compilation failures or illegal
|
||||
* instruction failures).
|
||||
*
|
||||
* Beware: The constructors are not API compatible with these of
|
||||
* std::vector.
|
||||
*/
|
||||
template <typename T>
|
||||
class MaxSizeVector {
|
||||
static const size_t alignment = internal::plain_enum_max(EIGEN_ALIGNOF(T), sizeof(void*));
|
||||
|
||||
public:
|
||||
// Construct a new MaxSizeVector, reserve n elements.
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
explicit MaxSizeVector(size_t n)
|
||||
: reserve_(n), size_(0),
|
||||
data_(static_cast<T*>(internal::handmade_aligned_malloc(n * sizeof(T), alignment))) {
|
||||
}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit MaxSizeVector(size_t n)
|
||||
: reserve_(n), size_(0), data_(static_cast<T*>(internal::handmade_aligned_malloc(n * sizeof(T), alignment))) {}
|
||||
|
||||
// Construct a new MaxSizeVector, reserve and resize to n.
|
||||
// Copy the init value to all elements.
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
MaxSizeVector(size_t n, const T& init)
|
||||
: reserve_(n), size_(n),
|
||||
data_(static_cast<T*>(internal::handmade_aligned_malloc(n * sizeof(T), alignment))) {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE MaxSizeVector(size_t n, const T& init)
|
||||
: reserve_(n), size_(n), data_(static_cast<T*>(internal::handmade_aligned_malloc(n * sizeof(T), alignment))) {
|
||||
size_t i = 0;
|
||||
EIGEN_TRY
|
||||
{
|
||||
for(; i < size_; ++i) { new (&data_[i]) T(init); }
|
||||
EIGEN_TRY {
|
||||
for (; i < size_; ++i) {
|
||||
new (&data_[i]) T(init);
|
||||
}
|
||||
}
|
||||
EIGEN_CATCH(...)
|
||||
{
|
||||
EIGEN_CATCH(...) {
|
||||
// Construction failed, destruct in reverse order:
|
||||
for(; (i+1) > 0; --i) { data_[i-1].~T(); }
|
||||
for (; (i + 1) > 0; --i) {
|
||||
data_[i - 1].~T();
|
||||
}
|
||||
internal::handmade_aligned_free(data_);
|
||||
EIGEN_THROW;
|
||||
}
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
~MaxSizeVector() {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~MaxSizeVector() {
|
||||
for (size_t i = size_; i > 0; --i) {
|
||||
data_[i-1].~T();
|
||||
data_[i - 1].~T();
|
||||
}
|
||||
internal::handmade_aligned_free(data_);
|
||||
}
|
||||
@@ -72,80 +69,64 @@ class MaxSizeVector {
|
||||
new (&data_[size_]) T;
|
||||
}
|
||||
for (; size_ > n; --size_) {
|
||||
data_[size_-1].~T();
|
||||
data_[size_ - 1].~T();
|
||||
}
|
||||
eigen_assert(size_ == n);
|
||||
}
|
||||
|
||||
// Append new elements (up to reserved size).
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
void push_back(const T& t) {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void push_back(const T& t) {
|
||||
eigen_assert(size_ < reserve_);
|
||||
new (&data_[size_++]) T(t);
|
||||
}
|
||||
|
||||
// For C++03 compatibility this only takes one argument
|
||||
template<class X>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
void emplace_back(const X& x) {
|
||||
template <class X>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void emplace_back(const X& x) {
|
||||
eigen_assert(size_ < reserve_);
|
||||
new (&data_[size_++]) T(x);
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const T& operator[] (size_t i) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator[](size_t i) const {
|
||||
eigen_assert(i < size_);
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
T& operator[] (size_t i) {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& operator[](size_t i) {
|
||||
eigen_assert(i < size_);
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
T& back() {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& back() {
|
||||
eigen_assert(size_ > 0);
|
||||
return data_[size_ - 1];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const T& back() const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& back() const {
|
||||
eigen_assert(size_ > 0);
|
||||
return data_[size_ - 1];
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
void pop_back() {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void pop_back() {
|
||||
eigen_assert(size_ > 0);
|
||||
data_[--size_].~T();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
size_t size() const { return size_; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t size() const { return size_; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
bool empty() const { return size_ == 0; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool empty() const { return size_ == 0; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
T* data() { return data_; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* data() { return data_; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const T* data() const { return data_; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* data() const { return data_; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
T* begin() { return data_; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* begin() { return data_; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
T* end() { return data_ + size_; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T* end() { return data_ + size_; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const T* begin() const { return data_; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* begin() const { return data_; }
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const T* end() const { return data_ + size_; }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T* end() const { return data_ + size_; }
|
||||
|
||||
private:
|
||||
size_t reserve_;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,15 +16,15 @@
|
||||
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
|
||||
#include <cfloat>
|
||||
#include <cfloat>
|
||||
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
#include <math_constants.h>
|
||||
#endif
|
||||
#if defined(EIGEN_CUDA_ARCH)
|
||||
#include <math_constants.h>
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#include "Eigen/src/Core/arch/HIP/hcc/math_constants.h"
|
||||
#endif
|
||||
#if defined(EIGEN_HIP_DEVICE_COMPILE)
|
||||
#include "Eigen/src/Core/arch/HIP/hcc/math_constants.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,42 +33,42 @@
|
||||
|
||||
namespace Eigen {
|
||||
namespace numext {
|
||||
typedef std::uint8_t uint8_t;
|
||||
typedef std::int8_t int8_t;
|
||||
typedef std::uint8_t uint8_t;
|
||||
typedef std::int8_t int8_t;
|
||||
typedef std::uint16_t uint16_t;
|
||||
typedef std::int16_t int16_t;
|
||||
typedef std::int16_t int16_t;
|
||||
typedef std::uint32_t uint32_t;
|
||||
typedef std::int32_t int32_t;
|
||||
typedef std::int32_t int32_t;
|
||||
typedef std::uint64_t uint64_t;
|
||||
typedef std::int64_t int64_t;
|
||||
typedef std::int64_t int64_t;
|
||||
|
||||
template <size_t Size>
|
||||
struct get_integer_by_size {
|
||||
typedef void signed_type;
|
||||
typedef void unsigned_type;
|
||||
typedef void signed_type;
|
||||
typedef void unsigned_type;
|
||||
};
|
||||
template <>
|
||||
struct get_integer_by_size<1> {
|
||||
typedef int8_t signed_type;
|
||||
typedef uint8_t unsigned_type;
|
||||
typedef int8_t signed_type;
|
||||
typedef uint8_t unsigned_type;
|
||||
};
|
||||
template <>
|
||||
struct get_integer_by_size<2> {
|
||||
typedef int16_t signed_type;
|
||||
typedef uint16_t unsigned_type;
|
||||
typedef int16_t signed_type;
|
||||
typedef uint16_t unsigned_type;
|
||||
};
|
||||
template <>
|
||||
struct get_integer_by_size<4> {
|
||||
typedef int32_t signed_type;
|
||||
typedef uint32_t unsigned_type;
|
||||
typedef int32_t signed_type;
|
||||
typedef uint32_t unsigned_type;
|
||||
};
|
||||
template <>
|
||||
struct get_integer_by_size<8> {
|
||||
typedef int64_t signed_type;
|
||||
typedef uint64_t unsigned_type;
|
||||
typedef int64_t signed_type;
|
||||
typedef uint64_t unsigned_type;
|
||||
};
|
||||
}
|
||||
}
|
||||
} // namespace numext
|
||||
} // namespace Eigen
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
@@ -85,310 +85,419 @@ 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.
|
||||
*/
|
||||
* \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.
|
||||
*/
|
||||
|
||||
struct true_type { enum { value = 1 }; };
|
||||
struct false_type { enum { value = 0 }; };
|
||||
struct true_type {
|
||||
enum { value = 1 };
|
||||
};
|
||||
struct false_type {
|
||||
enum { value = 0 };
|
||||
};
|
||||
|
||||
template<bool Condition>
|
||||
template <bool Condition>
|
||||
struct bool_constant;
|
||||
|
||||
template<>
|
||||
template <>
|
||||
struct bool_constant<true> : true_type {};
|
||||
|
||||
template<>
|
||||
template <>
|
||||
struct bool_constant<false> : false_type {};
|
||||
|
||||
// Third-party libraries rely on these.
|
||||
using std::conditional;
|
||||
using std::remove_reference;
|
||||
using std::remove_pointer;
|
||||
using std::remove_const;
|
||||
using std::remove_pointer;
|
||||
using std::remove_reference;
|
||||
|
||||
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 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>
|
||||
template <typename T>
|
||||
using remove_all_t = typename remove_all<T>::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 <typename T>
|
||||
struct is_arithmetic {
|
||||
enum { value = false };
|
||||
};
|
||||
template <>
|
||||
struct is_arithmetic<float> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_arithmetic<double> {
|
||||
enum { value = true };
|
||||
};
|
||||
// GPU devices treat `long double` as `double`.
|
||||
#ifndef EIGEN_GPU_COMPILE_PHASE
|
||||
template<> struct is_arithmetic<long double> { enum { value = true }; };
|
||||
template <>
|
||||
struct is_arithmetic<long double> {
|
||||
enum { value = true };
|
||||
};
|
||||
#endif
|
||||
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 }; };
|
||||
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 };
|
||||
};
|
||||
|
||||
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, typename U>
|
||||
struct is_same {
|
||||
enum { value = 0 };
|
||||
};
|
||||
template <typename T>
|
||||
struct is_same<T, T> {
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
template< class T >
|
||||
template <class T>
|
||||
struct is_void : is_same<void, std::remove_const_t<T>> {};
|
||||
|
||||
/** \internal
|
||||
* Implementation of std::void_t for SFINAE.
|
||||
*
|
||||
* Pre C++17:
|
||||
* Custom implementation.
|
||||
*
|
||||
* Post C++17: Uses std::void_t
|
||||
*/
|
||||
* Implementation of std::void_t for SFINAE.
|
||||
*
|
||||
* Pre C++17:
|
||||
* Custom implementation.
|
||||
*
|
||||
* Post C++17: Uses std::void_t
|
||||
*/
|
||||
#if EIGEN_COMP_CXXVER >= 17
|
||||
using std::void_t;
|
||||
#else
|
||||
template<typename...>
|
||||
template <typename...>
|
||||
using void_t = void;
|
||||
#endif
|
||||
|
||||
template<> struct is_arithmetic<signed long long> { enum { value = true }; };
|
||||
template<> struct is_arithmetic<unsigned long long> { enum { value = true }; };
|
||||
template <>
|
||||
struct is_arithmetic<signed long long> {
|
||||
enum { value = true };
|
||||
};
|
||||
template <>
|
||||
struct is_arithmetic<unsigned long long> {
|
||||
enum { value = true };
|
||||
};
|
||||
using std::is_integral;
|
||||
|
||||
using std::make_unsigned;
|
||||
|
||||
template <typename T> struct is_const { enum { value = 0 }; };
|
||||
template <typename T> struct is_const<T const> { enum { value = 1 }; };
|
||||
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 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 T>
|
||||
template <typename T>
|
||||
using add_const_on_value_type_t = typename add_const_on_value_type<T>::type;
|
||||
|
||||
using std::is_convertible;
|
||||
|
||||
/** \internal
|
||||
* A base class do disable default copy ctor and copy assignment operator.
|
||||
*/
|
||||
class noncopyable
|
||||
{
|
||||
* A base class do disable default copy ctor and copy assignment operator.
|
||||
*/
|
||||
class noncopyable {
|
||||
EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
|
||||
EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
|
||||
protected:
|
||||
|
||||
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 {
|
||||
* 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, std::enable_if_t<((T::SizeAtCompileTime&0)==0)>> {
|
||||
template <typename T>
|
||||
struct array_size<T, std::enable_if_t<((T::SizeAtCompileTime & 0) == 0)>> {
|
||||
enum { value = T::SizeAtCompileTime };
|
||||
};
|
||||
|
||||
template<typename T, int N> struct array_size<const T (&)[N]> {
|
||||
template <typename T, int N>
|
||||
struct array_size<const T (&)[N]> {
|
||||
enum { value = N };
|
||||
};
|
||||
template<typename T, int N> struct array_size<T (&)[N]> {
|
||||
template <typename T, int N>
|
||||
struct array_size<T (&)[N]> {
|
||||
enum { value = N };
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N> struct array_size<const std::array<T,N> > {
|
||||
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> > {
|
||||
template <typename T, std::size_t N>
|
||||
struct array_size<std::array<T, N>> {
|
||||
enum { value = N };
|
||||
};
|
||||
|
||||
|
||||
/** \internal
|
||||
* Analogue of the std::ssize free function.
|
||||
* It returns the signed 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]
|
||||
*
|
||||
* For C++20, this function just forwards to `std::ssize`, or any ADL discoverable `ssize` function.
|
||||
*/
|
||||
#if EIGEN_COMP_CXXVER < 20 || EIGEN_GNUC_STRICT_LESS_THAN(10,0,0)
|
||||
* Analogue of the std::ssize free function.
|
||||
* It returns the signed 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]
|
||||
*
|
||||
* For C++20, this function just forwards to `std::ssize`, or any ADL discoverable `ssize` function.
|
||||
*/
|
||||
#if EIGEN_COMP_CXXVER < 20 || EIGEN_GNUC_STRICT_LESS_THAN(10, 0, 0)
|
||||
template <typename T>
|
||||
EIGEN_CONSTEXPR auto index_list_size(const T& x) {
|
||||
using R = std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(x.size())>>;
|
||||
return static_cast<R>(x.size());
|
||||
}
|
||||
|
||||
template<typename T, std::ptrdiff_t N>
|
||||
EIGEN_CONSTEXPR std::ptrdiff_t index_list_size(const T (&)[N]) { return N; }
|
||||
template <typename T, std::ptrdiff_t N>
|
||||
EIGEN_CONSTEXPR std::ptrdiff_t index_list_size(const T (&)[N]) {
|
||||
return N;
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
EIGEN_CONSTEXPR auto index_list_size(T&& x) {
|
||||
using std::ssize;
|
||||
return ssize(std::forward<T>(x));
|
||||
}
|
||||
#endif // EIGEN_COMP_CXXVER
|
||||
#endif // EIGEN_COMP_CXXVER
|
||||
|
||||
/** \internal
|
||||
* Convenient struct to get the result type of a nullary, unary, binary, or
|
||||
* ternary functor.
|
||||
*
|
||||
* Pre C++17:
|
||||
* This uses std::result_of. However, note the `type` member removes
|
||||
* const and converts references/pointers to their corresponding value type.
|
||||
*
|
||||
* Post C++17: Uses std::invoke_result
|
||||
*/
|
||||
* Convenient struct to get the result type of a nullary, unary, binary, or
|
||||
* ternary functor.
|
||||
*
|
||||
* Pre C++17:
|
||||
* This uses std::result_of. However, note the `type` member removes
|
||||
* const and converts references/pointers to their corresponding value type.
|
||||
*
|
||||
* Post C++17: Uses std::invoke_result
|
||||
*/
|
||||
#if EIGEN_HAS_STD_INVOKE_RESULT
|
||||
template<typename T> struct result_of;
|
||||
template <typename T>
|
||||
struct result_of;
|
||||
|
||||
template<typename F, typename... ArgTypes>
|
||||
template <typename F, typename... ArgTypes>
|
||||
struct result_of<F(ArgTypes...)> {
|
||||
typedef typename std::invoke_result<F, ArgTypes...>::type type1;
|
||||
typedef remove_all_t<type1> type;
|
||||
};
|
||||
|
||||
template<typename F, typename... ArgTypes>
|
||||
template <typename F, typename... ArgTypes>
|
||||
struct invoke_result {
|
||||
typedef typename std::invoke_result<F, ArgTypes...>::type type1;
|
||||
typedef remove_all_t<type1> type;
|
||||
};
|
||||
#else
|
||||
template<typename T> struct result_of {
|
||||
template <typename T>
|
||||
struct result_of {
|
||||
typedef typename std::result_of<T>::type type1;
|
||||
typedef remove_all_t<type1> type;
|
||||
};
|
||||
|
||||
template<typename F, typename... ArgTypes>
|
||||
template <typename F, typename... ArgTypes>
|
||||
struct invoke_result {
|
||||
typedef typename result_of<F(ArgTypes...)>::type type1;
|
||||
typedef remove_all_t<type1> type;
|
||||
typedef typename result_of<F(ArgTypes...)>::type type1;
|
||||
typedef remove_all_t<type1> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
// Reduces a sequence of bools to true if all are true, false otherwise.
|
||||
template<bool... values>
|
||||
using reduce_all = std::is_same<std::integer_sequence<bool, values..., true>,
|
||||
std::integer_sequence<bool, true, values...> >;
|
||||
template <bool... values>
|
||||
using reduce_all =
|
||||
std::is_same<std::integer_sequence<bool, values..., true>, std::integer_sequence<bool, true, values...>>;
|
||||
|
||||
// Reduces a sequence of bools to true if any are true, false if all false.
|
||||
template<bool... values>
|
||||
using reduce_any = std::integral_constant<bool,
|
||||
!std::is_same<std::integer_sequence<bool, values..., false>, std::integer_sequence<bool, false, values...> >::value>;
|
||||
template <bool... values>
|
||||
using reduce_any = std::integral_constant<bool, !std::is_same<std::integer_sequence<bool, values..., false>,
|
||||
std::integer_sequence<bool, false, values...>>::value>;
|
||||
|
||||
struct meta_yes { char a[1]; };
|
||||
struct meta_no { char a[2]; };
|
||||
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(...);
|
||||
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>
|
||||
const T* return_ptr();
|
||||
|
||||
template <typename T, typename IndexType=Index>
|
||||
struct has_nullary_operator
|
||||
{
|
||||
template <typename C> static meta_yes testFunctor(C const *,std::enable_if_t<(sizeof(return_ptr<C>()->operator()())>0)> * = 0);
|
||||
template <typename T, typename IndexType = Index>
|
||||
struct has_nullary_operator {
|
||||
template <typename C>
|
||||
static meta_yes testFunctor(C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()()) > 0)>* = 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 *,std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)> * = 0);
|
||||
template <typename T, typename IndexType = Index>
|
||||
struct has_unary_operator {
|
||||
template <typename C>
|
||||
static meta_yes testFunctor(C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0))) > 0)>* = 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 *,std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)> * = 0);
|
||||
template <typename T, typename IndexType = Index>
|
||||
struct has_binary_operator {
|
||||
template <typename C>
|
||||
static meta_yes testFunctor(
|
||||
C const*, std::enable_if_t<(sizeof(return_ptr<C>()->operator()(IndexType(0), IndexType(0))) > 0)>* = 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 || ((SupX * SupX <= Y) && ((SupX + 1) * (SupX + 1) > Y)))>
|
||||
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 };
|
||||
* 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 || ((SupX * SupX <= Y) && ((SupX + 1) * (SupX + 1) > Y)))>
|
||||
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 }; };
|
||||
|
||||
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.
|
||||
*/
|
||||
template<int A, int B, int K=1, bool Done = ((A*K)%B)==0, bool Big=(A>=B)>
|
||||
struct meta_least_common_multiple
|
||||
{
|
||||
enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
|
||||
* at compile-time.
|
||||
*/
|
||||
template <int A, int B, int K = 1, bool Done = ((A * K) % B) == 0, bool Big = (A >= B)>
|
||||
struct meta_least_common_multiple {
|
||||
enum { ret = meta_least_common_multiple<A, B, K + 1>::ret };
|
||||
};
|
||||
template<int A, int B, int K, bool Done>
|
||||
struct meta_least_common_multiple<A,B,K,Done,false>
|
||||
{
|
||||
enum { ret = meta_least_common_multiple<B,A,K>::ret };
|
||||
template <int A, int B, int K, bool Done>
|
||||
struct meta_least_common_multiple<A, B, K, Done, false> {
|
||||
enum { ret = meta_least_common_multiple<B, A, K>::ret };
|
||||
};
|
||||
template<int A, int B, int K>
|
||||
struct meta_least_common_multiple<A,B,K,true,true>
|
||||
{
|
||||
enum { ret = A*K };
|
||||
template <int A, int B, int K>
|
||||
struct meta_least_common_multiple<A, B, K, true, 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
|
||||
{
|
||||
template <typename T, typename U>
|
||||
struct scalar_product_traits {
|
||||
enum { Defined = 0 };
|
||||
};
|
||||
|
||||
@@ -399,25 +508,34 @@ template<typename T, typename U> struct scalar_product_traits
|
||||
// };
|
||||
|
||||
/** \internal Obtains a POD type suitable to use as storage for an object of a size
|
||||
* of at most Len bytes, aligned as specified by \c Align.
|
||||
*/
|
||||
template<unsigned Len, unsigned Align>
|
||||
* of at most Len bytes, aligned as specified by \c Align.
|
||||
*/
|
||||
template <unsigned Len, unsigned Align>
|
||||
struct aligned_storage {
|
||||
struct type {
|
||||
EIGEN_ALIGN_TO_BOUNDARY(Align) unsigned char data[Len];
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
template<typename T> struct NumTraits;
|
||||
template <typename T>
|
||||
struct NumTraits;
|
||||
|
||||
namespace numext {
|
||||
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
|
||||
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); }
|
||||
template <typename T>
|
||||
EIGEN_STRONG_INLINE void swap(T& a, T& b) {
|
||||
std::swap(a, b);
|
||||
}
|
||||
#endif
|
||||
|
||||
using std::numeric_limits;
|
||||
@@ -449,74 +567,91 @@ struct equal_strict_impl<X, Y, true, true, true, false> {
|
||||
|
||||
// The aim of the following functions is to bypass -Wfloat-equal warnings
|
||||
// when we really want a strict equality comparison on floating points.
|
||||
template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X& x, const Y& y) { return equal_strict_impl<X, Y>::run(x, y); }
|
||||
template <typename X, typename Y>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X& x, const Y& y) {
|
||||
return equal_strict_impl<X, Y>::run(x, y);
|
||||
}
|
||||
|
||||
#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); }
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const float& x, const float& y) {
|
||||
return std::equal_to<float>()(x, y);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); }
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const double& x, const double& y) {
|
||||
return std::equal_to<double>()(x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \internal Performs an exact comparison of x to zero, e.g. to decide whether a term can be ignored.
|
||||
* Use this to to bypass -Wfloat-equal warnings when exact zero is what needs to be tested.
|
||||
*/
|
||||
template<typename X> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool is_exactly_zero(const X& x) { return equal_strict(x, typename NumTraits<X>::Literal{0}); }
|
||||
*/
|
||||
template <typename X>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X& x) {
|
||||
return equal_strict(x, typename NumTraits<X>::Literal{0});
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal Performs an exact comparison of x to one, e.g. to decide whether a factor needs to be multiplied.
|
||||
* Use this to to bypass -Wfloat-equal warnings when exact one is what needs to be tested.
|
||||
*/
|
||||
template<typename X> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool is_exactly_one(const X& x) { return equal_strict(x, typename NumTraits<X>::Literal{1}); }
|
||||
*/
|
||||
template <typename X>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_one(const X& x) {
|
||||
return equal_strict(x, typename NumTraits<X>::Literal{1});
|
||||
}
|
||||
|
||||
template<typename X, typename Y> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool not_equal_strict(const X& x,const Y& y) { return !equal_strict_impl<X, Y>::run(x, y); }
|
||||
template <typename X, typename Y>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const X& x, const Y& y) {
|
||||
return !equal_strict_impl<X, Y>::run(x, y);
|
||||
}
|
||||
|
||||
#if !defined(EIGEN_GPU_COMPILE_PHASE) || (!defined(EIGEN_CUDA_ARCH) && defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); }
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const float& x, const float& y) {
|
||||
return std::not_equal_to<float>()(x, y);
|
||||
}
|
||||
|
||||
template<> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
|
||||
bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); }
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool not_equal_strict(const double& x, const double& y) {
|
||||
return std::not_equal_to<double>()(x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // end namespace numext
|
||||
} // end namespace numext
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Scalar>
|
||||
template <typename Scalar>
|
||||
struct is_identically_zero_impl {
|
||||
static inline bool run(const Scalar& s) {
|
||||
return numext::is_exactly_zero(s);
|
||||
}
|
||||
static inline bool run(const Scalar& s) { return numext::is_exactly_zero(s); }
|
||||
};
|
||||
|
||||
template<typename Scalar> EIGEN_STRONG_INLINE
|
||||
bool is_identically_zero(const Scalar& s) { return is_identically_zero_impl<Scalar>::run(s); }
|
||||
template <typename Scalar>
|
||||
EIGEN_STRONG_INLINE bool is_identically_zero(const Scalar& s) {
|
||||
return is_identically_zero_impl<Scalar>::run(s);
|
||||
}
|
||||
|
||||
/// \internal Returns true if its argument is of integer or enum type.
|
||||
/// FIXME this has the same purpose as `is_valid_index_type` in XprHelper.h
|
||||
template<typename A>
|
||||
template <typename A>
|
||||
constexpr bool is_int_or_enum_v = std::is_enum<A>::value || std::is_integral<A>::value;
|
||||
|
||||
/// \internal Gets the minimum of two values which may be integers or enums
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
inline constexpr int plain_enum_min(A a, B b) {
|
||||
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
|
||||
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
|
||||
return ((int) a <= (int) b) ? (int) a : (int) b;
|
||||
return ((int)a <= (int)b) ? (int)a : (int)b;
|
||||
}
|
||||
|
||||
/// \internal Gets the maximum of two values which may be integers or enums
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
inline constexpr int plain_enum_max(A a, B b) {
|
||||
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
|
||||
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
|
||||
return ((int) a >= (int) b) ? (int) a : (int) b;
|
||||
return ((int)a >= (int)b) ? (int)a : (int)b;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -525,52 +660,48 @@ inline constexpr int plain_enum_max(A a, B b) {
|
||||
* followed by Dynamic, followed by other finite values. The reason for giving Dynamic the priority over
|
||||
* finite values is that min(3, Dynamic) should be Dynamic, since that could be anything between 0 and 3.
|
||||
*/
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
inline constexpr int min_size_prefer_dynamic(A a, B b) {
|
||||
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
|
||||
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
|
||||
if ((int) a == 0 || (int) b == 0) return 0;
|
||||
if ((int) a == 1 || (int) b == 1) return 1;
|
||||
if ((int) a == Dynamic || (int) b == Dynamic) return Dynamic;
|
||||
if ((int)a == 0 || (int)b == 0) return 0;
|
||||
if ((int)a == 1 || (int)b == 1) return 1;
|
||||
if ((int)a == Dynamic || (int)b == Dynamic) return Dynamic;
|
||||
return plain_enum_min(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* min_size_prefer_fixed is a variant of `min_size_prefer_dynamic` comparing MaxSizes. The difference is that finite values
|
||||
* now have priority over Dynamic, so that min(3, Dynamic) gives 3. Indeed, whatever the actual value is
|
||||
* (between 0 and 3), it is not more than 3.
|
||||
* min_size_prefer_fixed is a variant of `min_size_prefer_dynamic` comparing MaxSizes. The difference is that finite
|
||||
* values now have priority over Dynamic, so that min(3, Dynamic) gives 3. Indeed, whatever the actual value is (between
|
||||
* 0 and 3), it is not more than 3.
|
||||
*/
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
inline constexpr int min_size_prefer_fixed(A a, B b) {
|
||||
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
|
||||
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
|
||||
if ((int) a == 0 || (int) b == 0) return 0;
|
||||
if ((int) a == 1 || (int) b == 1) return 1;
|
||||
if ((int) a == Dynamic && (int) b == Dynamic) return Dynamic;
|
||||
if ((int) a == Dynamic) return (int) b;
|
||||
if ((int) b == Dynamic) return (int) a;
|
||||
if ((int)a == 0 || (int)b == 0) return 0;
|
||||
if ((int)a == 1 || (int)b == 1) return 1;
|
||||
if ((int)a == Dynamic && (int)b == Dynamic) return Dynamic;
|
||||
if ((int)a == Dynamic) return (int)b;
|
||||
if ((int)b == Dynamic) return (int)a;
|
||||
return plain_enum_min(a, b);
|
||||
}
|
||||
|
||||
/// \internal see `min_size_prefer_fixed`. No need for a separate variant for MaxSizes here.
|
||||
template<typename A, typename B>
|
||||
template <typename A, typename B>
|
||||
inline constexpr int max_size_prefer_dynamic(A a, B b) {
|
||||
static_assert(is_int_or_enum_v<A>, "Argument a must be an integer or enum");
|
||||
static_assert(is_int_or_enum_v<B>, "Argument b must be an integer or enum");
|
||||
if ((int) a == Dynamic || (int) b == Dynamic) return Dynamic;
|
||||
if ((int)a == Dynamic || (int)b == Dynamic) return Dynamic;
|
||||
return plain_enum_max(a, b);
|
||||
}
|
||||
|
||||
/// \internal Calculate logical XOR at compile time
|
||||
inline constexpr bool logical_xor(bool a, bool b) {
|
||||
return a != b;
|
||||
}
|
||||
inline constexpr bool logical_xor(bool a, bool b) { return a != b; }
|
||||
|
||||
/// \internal Calculate logical IMPLIES at compile time
|
||||
inline constexpr bool check_implication(bool a, bool b) {
|
||||
return !a || b;
|
||||
}
|
||||
inline constexpr bool check_implication(bool a, bool b) { return !a || b; }
|
||||
|
||||
/// \internal Provide fallback for std::is_constant_evaluated for pre-C++20.
|
||||
#if EIGEN_COMP_CXXVER >= 20
|
||||
@@ -579,8 +710,8 @@ using std::is_constant_evaluated;
|
||||
constexpr bool is_constant_evaluated() { return false; }
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_META_H
|
||||
#endif // EIGEN_META_H
|
||||
|
||||
@@ -18,18 +18,27 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename... tt>
|
||||
struct type_list { constexpr static int count = sizeof...(tt); };
|
||||
template <typename... tt>
|
||||
struct type_list {
|
||||
constexpr static int count = sizeof...(tt);
|
||||
};
|
||||
|
||||
template<typename t, typename... tt>
|
||||
struct type_list<t, tt...> { constexpr static int count = sizeof...(tt) + 1; typedef t first_type; };
|
||||
template <typename t, typename... tt>
|
||||
struct type_list<t, tt...> {
|
||||
constexpr static int count = sizeof...(tt) + 1;
|
||||
typedef t first_type;
|
||||
};
|
||||
|
||||
template<typename T, T... nn>
|
||||
struct numeric_list { constexpr static std::size_t count = sizeof...(nn); };
|
||||
template <typename T, T... nn>
|
||||
struct numeric_list {
|
||||
constexpr static std::size_t count = sizeof...(nn);
|
||||
};
|
||||
|
||||
template<typename T, T n, T... nn>
|
||||
struct numeric_list<T, n, nn...> { static constexpr std::size_t count = sizeof...(nn) + 1;
|
||||
static constexpr T first_value = n; };
|
||||
template <typename T, T n, T... nn>
|
||||
struct numeric_list<T, n, nn...> {
|
||||
static constexpr std::size_t count = sizeof...(nn) + 1;
|
||||
static constexpr T first_value = n;
|
||||
};
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/* numeric list constructors
|
||||
@@ -42,306 +51,409 @@ struct numeric_list<T, n, nn...> { static constexpr std::size_t count = sizeof..
|
||||
* typename gen_numeric_list_repeated<int, 0, 5>::type numeric_list<int, 0,0,0,0,0>
|
||||
*/
|
||||
|
||||
template<typename T, std::size_t n, T start = 0, T... ii> struct gen_numeric_list : gen_numeric_list<T, n-1, start, start + n-1, ii...> {};
|
||||
template<typename T, T start, T... ii> struct gen_numeric_list<T, 0, start, ii...> { typedef numeric_list<T, ii...> type; };
|
||||
template <typename T, std::size_t n, T start = 0, T... ii>
|
||||
struct gen_numeric_list : gen_numeric_list<T, n - 1, start, start + n - 1, ii...> {};
|
||||
template <typename T, T start, T... ii>
|
||||
struct gen_numeric_list<T, 0, start, ii...> {
|
||||
typedef numeric_list<T, ii...> type;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t n, T start = 0, T... ii> struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n-1, start, ii..., start + n-1> {};
|
||||
template<typename T, T start, T... ii> struct gen_numeric_list_reversed<T, 0, start, ii...> { typedef numeric_list<T, ii...> type; };
|
||||
template <typename T, std::size_t n, T start = 0, T... ii>
|
||||
struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n - 1, start, ii..., start + n - 1> {};
|
||||
template <typename T, T start, T... ii>
|
||||
struct gen_numeric_list_reversed<T, 0, start, ii...> {
|
||||
typedef numeric_list<T, ii...> type;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t n, T a, T b, T start = 0, T... ii> struct gen_numeric_list_swapped_pair : gen_numeric_list_swapped_pair<T, n-1, a, b, start, (start + n-1) == a ? b : ((start + n-1) == b ? a : (start + n-1)), ii...> {};
|
||||
template<typename T, T a, T b, T start, T... ii> struct gen_numeric_list_swapped_pair<T, 0, a, b, start, ii...> { typedef numeric_list<T, ii...> type; };
|
||||
template <typename T, std::size_t n, T a, T b, T start = 0, T... ii>
|
||||
struct gen_numeric_list_swapped_pair
|
||||
: gen_numeric_list_swapped_pair<T, n - 1, a, b, start,
|
||||
(start + n - 1) == a ? b : ((start + n - 1) == b ? a : (start + n - 1)), ii...> {};
|
||||
template <typename T, T a, T b, T start, T... ii>
|
||||
struct gen_numeric_list_swapped_pair<T, 0, a, b, start, ii...> {
|
||||
typedef numeric_list<T, ii...> type;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t n, T V, T... nn> struct gen_numeric_list_repeated : gen_numeric_list_repeated<T, n-1, V, V, nn...> {};
|
||||
template<typename T, T V, T... nn> struct gen_numeric_list_repeated<T, 0, V, nn...> { typedef numeric_list<T, nn...> type; };
|
||||
template <typename T, std::size_t n, T V, T... nn>
|
||||
struct gen_numeric_list_repeated : gen_numeric_list_repeated<T, n - 1, V, V, nn...> {};
|
||||
template <typename T, T V, T... nn>
|
||||
struct gen_numeric_list_repeated<T, 0, V, nn...> {
|
||||
typedef numeric_list<T, nn...> type;
|
||||
};
|
||||
|
||||
/* list manipulation: concatenate */
|
||||
|
||||
template<class a, class b> struct concat;
|
||||
template <class a, class b>
|
||||
struct concat;
|
||||
|
||||
template<typename... as, typename... bs> struct concat<type_list<as...>, type_list<bs...>> { typedef type_list<as..., bs...> type; };
|
||||
template<typename T, T... as, T... bs> struct concat<numeric_list<T, as...>, numeric_list<T, bs...> > { typedef numeric_list<T, as..., bs...> type; };
|
||||
template <typename... as, typename... bs>
|
||||
struct concat<type_list<as...>, type_list<bs...>> {
|
||||
typedef type_list<as..., bs...> type;
|
||||
};
|
||||
template <typename T, T... as, T... bs>
|
||||
struct concat<numeric_list<T, as...>, numeric_list<T, bs...>> {
|
||||
typedef numeric_list<T, as..., bs...> type;
|
||||
};
|
||||
|
||||
template<typename... p> struct mconcat;
|
||||
template<typename a> struct mconcat<a> { typedef a type; };
|
||||
template<typename a, typename b> struct mconcat<a, b> : concat<a, b> {};
|
||||
template<typename a, typename b, typename... cs> struct mconcat<a, b, cs...> : concat<a, typename mconcat<b, cs...>::type> {};
|
||||
template <typename... p>
|
||||
struct mconcat;
|
||||
template <typename a>
|
||||
struct mconcat<a> {
|
||||
typedef a type;
|
||||
};
|
||||
template <typename a, typename b>
|
||||
struct mconcat<a, b> : concat<a, b> {};
|
||||
template <typename a, typename b, typename... cs>
|
||||
struct mconcat<a, b, cs...> : concat<a, typename mconcat<b, cs...>::type> {};
|
||||
|
||||
/* list manipulation: extract slices */
|
||||
|
||||
template<int n, typename x> struct take;
|
||||
template<int n, typename a, typename... as> struct take<n, type_list<a, as...>> : concat<type_list<a>, typename take<n-1, type_list<as...>>::type> {};
|
||||
template<int n> struct take<n, type_list<>> { typedef type_list<> type; };
|
||||
template<typename a, typename... as> struct take<0, type_list<a, as...>> { typedef type_list<> type; };
|
||||
template<> struct take<0, type_list<>> { typedef type_list<> type; };
|
||||
|
||||
template<typename T, int n, T a, T... as> struct take<n, numeric_list<T, a, as...>> : concat<numeric_list<T, a>, typename take<n-1, numeric_list<T, as...>>::type> {};
|
||||
// XXX The following breaks in gcc-11, and is invalid anyways.
|
||||
// template<typename T, int n> struct take<n, numeric_list<T>> { typedef numeric_list<T> type; };
|
||||
template<typename T, T a, T... as> struct take<0, numeric_list<T, a, as...>> { typedef numeric_list<T> type; };
|
||||
template<typename T> struct take<0, numeric_list<T>> { typedef numeric_list<T> type; };
|
||||
|
||||
template<typename T, int n, T... ii> struct h_skip_helper_numeric;
|
||||
template<typename T, int n, T i, T... ii> struct h_skip_helper_numeric<T, n, i, ii...> : h_skip_helper_numeric<T, n-1, ii...> {};
|
||||
template<typename T, T i, T... ii> struct h_skip_helper_numeric<T, 0, i, ii...> { typedef numeric_list<T, i, ii...> type; };
|
||||
template<typename T, int n> struct h_skip_helper_numeric<T, n> { typedef numeric_list<T> type; };
|
||||
template<typename T> struct h_skip_helper_numeric<T, 0> { typedef numeric_list<T> type; };
|
||||
|
||||
template<int n, typename... tt> struct h_skip_helper_type;
|
||||
template<int n, typename t, typename... tt> struct h_skip_helper_type<n, t, tt...> : h_skip_helper_type<n-1, tt...> {};
|
||||
template<typename t, typename... tt> struct h_skip_helper_type<0, t, tt...> { typedef type_list<t, tt...> type; };
|
||||
template<int n> struct h_skip_helper_type<n> { typedef type_list<> type; };
|
||||
template<> struct h_skip_helper_type<0> { typedef type_list<> type; };
|
||||
#endif //not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
template<int n>
|
||||
struct h_skip {
|
||||
template<typename T, T... ii>
|
||||
constexpr static EIGEN_STRONG_INLINE typename h_skip_helper_numeric<T, n, ii...>::type helper(numeric_list<T, ii...>) { return typename h_skip_helper_numeric<T, n, ii...>::type(); }
|
||||
template<typename... tt>
|
||||
constexpr static EIGEN_STRONG_INLINE typename h_skip_helper_type<n, tt...>::type helper(type_list<tt...>) { return typename h_skip_helper_type<n, tt...>::type(); }
|
||||
template <int n, typename x>
|
||||
struct take;
|
||||
template <int n, typename a, typename... as>
|
||||
struct take<n, type_list<a, as...>> : concat<type_list<a>, typename take<n - 1, type_list<as...>>::type> {};
|
||||
template <int n>
|
||||
struct take<n, type_list<>> {
|
||||
typedef type_list<> type;
|
||||
};
|
||||
template <typename a, typename... as>
|
||||
struct take<0, type_list<a, as...>> {
|
||||
typedef type_list<> type;
|
||||
};
|
||||
template <>
|
||||
struct take<0, type_list<>> {
|
||||
typedef type_list<> type;
|
||||
};
|
||||
|
||||
template<int n, typename a> struct skip { typedef decltype(h_skip<n>::helper(a())) type; };
|
||||
template <typename T, int n, T a, T... as>
|
||||
struct take<n, numeric_list<T, a, as...>>
|
||||
: concat<numeric_list<T, a>, typename take<n - 1, numeric_list<T, as...>>::type> {};
|
||||
// XXX The following breaks in gcc-11, and is invalid anyways.
|
||||
// template<typename T, int n> struct take<n, numeric_list<T>> { typedef numeric_list<T> type;
|
||||
// };
|
||||
template <typename T, T a, T... as>
|
||||
struct take<0, numeric_list<T, a, as...>> {
|
||||
typedef numeric_list<T> type;
|
||||
};
|
||||
template <typename T>
|
||||
struct take<0, numeric_list<T>> {
|
||||
typedef numeric_list<T> type;
|
||||
};
|
||||
|
||||
template<int start, int count, typename a> struct slice : take<count, typename skip<start, a>::type> {};
|
||||
template <typename T, int n, T... ii>
|
||||
struct h_skip_helper_numeric;
|
||||
template <typename T, int n, T i, T... ii>
|
||||
struct h_skip_helper_numeric<T, n, i, ii...> : h_skip_helper_numeric<T, n - 1, ii...> {};
|
||||
template <typename T, T i, T... ii>
|
||||
struct h_skip_helper_numeric<T, 0, i, ii...> {
|
||||
typedef numeric_list<T, i, ii...> type;
|
||||
};
|
||||
template <typename T, int n>
|
||||
struct h_skip_helper_numeric<T, n> {
|
||||
typedef numeric_list<T> type;
|
||||
};
|
||||
template <typename T>
|
||||
struct h_skip_helper_numeric<T, 0> {
|
||||
typedef numeric_list<T> type;
|
||||
};
|
||||
|
||||
template <int n, typename... tt>
|
||||
struct h_skip_helper_type;
|
||||
template <int n, typename t, typename... tt>
|
||||
struct h_skip_helper_type<n, t, tt...> : h_skip_helper_type<n - 1, tt...> {};
|
||||
template <typename t, typename... tt>
|
||||
struct h_skip_helper_type<0, t, tt...> {
|
||||
typedef type_list<t, tt...> type;
|
||||
};
|
||||
template <int n>
|
||||
struct h_skip_helper_type<n> {
|
||||
typedef type_list<> type;
|
||||
};
|
||||
template <>
|
||||
struct h_skip_helper_type<0> {
|
||||
typedef type_list<> type;
|
||||
};
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
template <int n>
|
||||
struct h_skip {
|
||||
template <typename T, T... ii>
|
||||
constexpr static EIGEN_STRONG_INLINE typename h_skip_helper_numeric<T, n, ii...>::type helper(
|
||||
numeric_list<T, ii...>) {
|
||||
return typename h_skip_helper_numeric<T, n, ii...>::type();
|
||||
}
|
||||
template <typename... tt>
|
||||
constexpr static EIGEN_STRONG_INLINE typename h_skip_helper_type<n, tt...>::type helper(type_list<tt...>) {
|
||||
return typename h_skip_helper_type<n, tt...>::type();
|
||||
}
|
||||
};
|
||||
|
||||
template <int n, typename a>
|
||||
struct skip {
|
||||
typedef decltype(h_skip<n>::helper(a())) type;
|
||||
};
|
||||
|
||||
template <int start, int count, typename a>
|
||||
struct slice : take<count, typename skip<start, a>::type> {};
|
||||
|
||||
/* list manipulation: retrieve single element from list */
|
||||
|
||||
template<int n, typename x> struct get;
|
||||
template <int n, typename x>
|
||||
struct get;
|
||||
|
||||
template<int n, typename a, typename... as> struct get<n, type_list<a, as...>> : get<n-1, type_list<as...>> {};
|
||||
template<typename a, typename... as> struct get<0, type_list<a, as...>> { typedef a type; };
|
||||
template <int n, typename a, typename... as>
|
||||
struct get<n, type_list<a, as...>> : get<n - 1, type_list<as...>> {};
|
||||
template <typename a, typename... as>
|
||||
struct get<0, type_list<a, as...>> {
|
||||
typedef a type;
|
||||
};
|
||||
|
||||
template<typename T, int n, T a, T... as> struct get<n, numeric_list<T, a, as...>> : get<n-1, numeric_list<T, as...>> {};
|
||||
template<typename T, T a, T... as> struct get<0, numeric_list<T, a, as...>> { constexpr static T value = a; };
|
||||
template <typename T, int n, T a, T... as>
|
||||
struct get<n, numeric_list<T, a, as...>> : get<n - 1, numeric_list<T, as...>> {};
|
||||
template <typename T, T a, T... as>
|
||||
struct get<0, numeric_list<T, a, as...>> {
|
||||
constexpr static T value = a;
|
||||
};
|
||||
|
||||
template<std::size_t n, typename T, T a, T... as> constexpr T array_get(const numeric_list<T, a, as...>&) {
|
||||
return get<(int)n, numeric_list<T, a, as...>>::value;
|
||||
template <std::size_t n, typename T, T a, T... as>
|
||||
constexpr T array_get(const numeric_list<T, a, as...>&) {
|
||||
return get<(int)n, numeric_list<T, a, as...>>::value;
|
||||
}
|
||||
|
||||
/* always get type, regardless of dummy; good for parameter pack expansion */
|
||||
|
||||
template<typename T, T dummy, typename t> struct id_numeric { typedef t type; };
|
||||
template<typename dummy, typename t> struct id_type { typedef t type; };
|
||||
template <typename T, T dummy, typename t>
|
||||
struct id_numeric {
|
||||
typedef t type;
|
||||
};
|
||||
template <typename dummy, typename t>
|
||||
struct id_type {
|
||||
typedef t type;
|
||||
};
|
||||
|
||||
/* equality checking, flagged version */
|
||||
|
||||
template<typename a, typename b> struct is_same_gf : is_same<a, b> { constexpr static int global_flags = 0; };
|
||||
template <typename a, typename b>
|
||||
struct is_same_gf : is_same<a, b> {
|
||||
constexpr static int global_flags = 0;
|
||||
};
|
||||
|
||||
/* apply_op to list */
|
||||
|
||||
template<
|
||||
bool from_left, // false
|
||||
template<typename, typename> class op,
|
||||
typename additional_param,
|
||||
typename... values
|
||||
>
|
||||
struct h_apply_op_helper { typedef type_list<typename op<values, additional_param>::type...> type; };
|
||||
template<
|
||||
template<typename, typename> class op,
|
||||
typename additional_param,
|
||||
typename... values
|
||||
>
|
||||
struct h_apply_op_helper<true, op, additional_param, values...> { typedef type_list<typename op<additional_param, values>::type...> type; };
|
||||
|
||||
template<
|
||||
bool from_left,
|
||||
template<typename, typename> class op,
|
||||
typename additional_param
|
||||
>
|
||||
struct h_apply_op
|
||||
{
|
||||
template<typename... values>
|
||||
constexpr static typename h_apply_op_helper<from_left, op, additional_param, values...>::type helper(type_list<values...>)
|
||||
{ return typename h_apply_op_helper<from_left, op, additional_param, values...>::type(); }
|
||||
template <bool from_left, // false
|
||||
template <typename, typename> class op, typename additional_param, typename... values>
|
||||
struct h_apply_op_helper {
|
||||
typedef type_list<typename op<values, additional_param>::type...> type;
|
||||
};
|
||||
template <template <typename, typename> class op, typename additional_param, typename... values>
|
||||
struct h_apply_op_helper<true, op, additional_param, values...> {
|
||||
typedef type_list<typename op<additional_param, values>::type...> type;
|
||||
};
|
||||
|
||||
template<
|
||||
template<typename, typename> class op,
|
||||
typename additional_param,
|
||||
typename a
|
||||
>
|
||||
struct apply_op_from_left { typedef decltype(h_apply_op<true, op, additional_param>::helper(a())) type; };
|
||||
template <bool from_left, template <typename, typename> class op, typename additional_param>
|
||||
struct h_apply_op {
|
||||
template <typename... values>
|
||||
constexpr static typename h_apply_op_helper<from_left, op, additional_param, values...>::type helper(
|
||||
type_list<values...>) {
|
||||
return typename h_apply_op_helper<from_left, op, additional_param, values...>::type();
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
template<typename, typename> class op,
|
||||
typename additional_param,
|
||||
typename a
|
||||
>
|
||||
struct apply_op_from_right { typedef decltype(h_apply_op<false, op, additional_param>::helper(a())) type; };
|
||||
template <template <typename, typename> class op, typename additional_param, typename a>
|
||||
struct apply_op_from_left {
|
||||
typedef decltype(h_apply_op<true, op, additional_param>::helper(a())) type;
|
||||
};
|
||||
|
||||
template <template <typename, typename> class op, typename additional_param, typename a>
|
||||
struct apply_op_from_right {
|
||||
typedef decltype(h_apply_op<false, op, additional_param>::helper(a())) type;
|
||||
};
|
||||
|
||||
/* see if an element is in a list */
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename h_list,
|
||||
bool last_check_positive = false
|
||||
>
|
||||
template <template <typename, typename> class test, typename check_against, typename h_list,
|
||||
bool last_check_positive = false>
|
||||
struct contained_in_list;
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename h_list
|
||||
>
|
||||
struct contained_in_list<test, check_against, h_list, true>
|
||||
{
|
||||
template <template <typename, typename> class test, typename check_against, typename h_list>
|
||||
struct contained_in_list<test, check_against, h_list, true> {
|
||||
constexpr static bool value = true;
|
||||
};
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename a,
|
||||
typename... as
|
||||
>
|
||||
struct contained_in_list<test, check_against, type_list<a, as...>, false> : contained_in_list<test, check_against, type_list<as...>, test<check_against, a>::value> {};
|
||||
template <template <typename, typename> class test, typename check_against, typename a, typename... as>
|
||||
struct contained_in_list<test, check_against, type_list<a, as...>, false>
|
||||
: contained_in_list<test, check_against, type_list<as...>, test<check_against, a>::value> {};
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename... empty
|
||||
>
|
||||
struct contained_in_list<test, check_against, type_list<empty...>, false> { constexpr static bool value = false; };
|
||||
template <template <typename, typename> class test, typename check_against, typename... empty>
|
||||
struct contained_in_list<test, check_against, type_list<empty...>, false> {
|
||||
constexpr static bool value = false;
|
||||
};
|
||||
|
||||
/* see if an element is in a list and check for global flags */
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename h_list,
|
||||
int default_flags = 0,
|
||||
bool last_check_positive = false,
|
||||
int last_check_flags = default_flags
|
||||
>
|
||||
template <template <typename, typename> class test, typename check_against, typename h_list, int default_flags = 0,
|
||||
bool last_check_positive = false, int last_check_flags = default_flags>
|
||||
struct contained_in_list_gf;
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename h_list,
|
||||
int default_flags,
|
||||
int last_check_flags
|
||||
>
|
||||
struct contained_in_list_gf<test, check_against, h_list, default_flags, true, last_check_flags>
|
||||
{
|
||||
template <template <typename, typename> class test, typename check_against, typename h_list, int default_flags,
|
||||
int last_check_flags>
|
||||
struct contained_in_list_gf<test, check_against, h_list, default_flags, true, last_check_flags> {
|
||||
constexpr static bool value = true;
|
||||
constexpr static int global_flags = last_check_flags;
|
||||
};
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename a,
|
||||
typename... as,
|
||||
int default_flags,
|
||||
int last_check_flags
|
||||
>
|
||||
struct contained_in_list_gf<test, check_against, type_list<a, as...>, default_flags, false, last_check_flags> : contained_in_list_gf<test, check_against, type_list<as...>, default_flags, test<check_against, a>::value, test<check_against, a>::global_flags> {};
|
||||
template <template <typename, typename> class test, typename check_against, typename a, typename... as,
|
||||
int default_flags, int last_check_flags>
|
||||
struct contained_in_list_gf<test, check_against, type_list<a, as...>, default_flags, false, last_check_flags>
|
||||
: contained_in_list_gf<test, check_against, type_list<as...>, default_flags, test<check_against, a>::value,
|
||||
test<check_against, a>::global_flags> {};
|
||||
|
||||
template<
|
||||
template<typename, typename> class test,
|
||||
typename check_against,
|
||||
typename... empty,
|
||||
int default_flags,
|
||||
int last_check_flags
|
||||
>
|
||||
struct contained_in_list_gf<test, check_against, type_list<empty...>, default_flags, false, last_check_flags> { constexpr static bool value = false; constexpr static int global_flags = default_flags; };
|
||||
template <template <typename, typename> class test, typename check_against, typename... empty, int default_flags,
|
||||
int last_check_flags>
|
||||
struct contained_in_list_gf<test, check_against, type_list<empty...>, default_flags, false, last_check_flags> {
|
||||
constexpr static bool value = false;
|
||||
constexpr static int global_flags = default_flags;
|
||||
};
|
||||
|
||||
/* generic reductions */
|
||||
|
||||
template<
|
||||
typename Reducer,
|
||||
typename... Ts
|
||||
> struct reduce;
|
||||
template <typename Reducer, typename... Ts>
|
||||
struct reduce;
|
||||
|
||||
template<
|
||||
typename Reducer
|
||||
> struct reduce<Reducer>
|
||||
{
|
||||
template <typename Reducer>
|
||||
struct reduce<Reducer> {
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE int run() { return Reducer::Identity; }
|
||||
};
|
||||
|
||||
template<
|
||||
typename Reducer,
|
||||
typename A
|
||||
> struct reduce<Reducer, A>
|
||||
{
|
||||
template <typename Reducer, typename A>
|
||||
struct reduce<Reducer, A> {
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE A run(A a) { return a; }
|
||||
};
|
||||
|
||||
template<
|
||||
typename Reducer,
|
||||
typename A,
|
||||
typename... Ts
|
||||
> struct reduce<Reducer, A, Ts...>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, Ts... ts) -> decltype(Reducer::run(a, reduce<Reducer, Ts...>::run(ts...))) {
|
||||
template <typename Reducer, typename A, typename... Ts>
|
||||
struct reduce<Reducer, A, Ts...> {
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, Ts... ts)
|
||||
-> decltype(Reducer::run(a, reduce<Reducer, Ts...>::run(ts...))) {
|
||||
return Reducer::run(a, reduce<Reducer, Ts...>::run(ts...));
|
||||
}
|
||||
};
|
||||
|
||||
/* generic binary operations */
|
||||
|
||||
struct sum_op {
|
||||
template<typename A, typename B> EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a + b) { return a + b; }
|
||||
struct sum_op {
|
||||
template <typename A, typename B>
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a + b) {
|
||||
return a + b;
|
||||
}
|
||||
static constexpr int Identity = 0;
|
||||
};
|
||||
struct product_op {
|
||||
template<typename A, typename B> EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a * b) { return a * b; }
|
||||
struct product_op {
|
||||
template <typename A, typename B>
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a * b) {
|
||||
return a * b;
|
||||
}
|
||||
static constexpr int Identity = 1;
|
||||
};
|
||||
|
||||
struct logical_and_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a && b) { return a && b; } };
|
||||
struct logical_or_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a || b) { return a || b; } };
|
||||
struct logical_and_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a && b) {
|
||||
return a && b;
|
||||
}
|
||||
};
|
||||
struct logical_or_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a || b) {
|
||||
return a || b;
|
||||
}
|
||||
};
|
||||
|
||||
struct equal_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a == b) { return a == b; } };
|
||||
struct not_equal_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a != b) { return a != b; } };
|
||||
struct lesser_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a < b) { return a < b; } };
|
||||
struct lesser_equal_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a <= b) { return a <= b; } };
|
||||
struct greater_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a > b) { return a > b; } };
|
||||
struct greater_equal_op { template<typename A, typename B> constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a >= b) { return a >= b; } };
|
||||
struct equal_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a == b) {
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
struct not_equal_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a != b) {
|
||||
return a != b;
|
||||
}
|
||||
};
|
||||
struct lesser_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a < b) {
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
struct lesser_equal_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a <= b) {
|
||||
return a <= b;
|
||||
}
|
||||
};
|
||||
struct greater_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a > b) {
|
||||
return a > b;
|
||||
}
|
||||
};
|
||||
struct greater_equal_op {
|
||||
template <typename A, typename B>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a, B b) -> decltype(a >= b) {
|
||||
return a >= b;
|
||||
}
|
||||
};
|
||||
|
||||
/* generic unary operations */
|
||||
|
||||
struct not_op { template<typename A> constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(!a) { return !a; } };
|
||||
struct negation_op { template<typename A> constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(-a) { return -a; } };
|
||||
struct greater_equal_zero_op { template<typename A> constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(a >= 0) { return a >= 0; } };
|
||||
|
||||
struct not_op {
|
||||
template <typename A>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(!a) {
|
||||
return !a;
|
||||
}
|
||||
};
|
||||
struct negation_op {
|
||||
template <typename A>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(-a) {
|
||||
return -a;
|
||||
}
|
||||
};
|
||||
struct greater_equal_zero_op {
|
||||
template <typename A>
|
||||
constexpr static EIGEN_STRONG_INLINE auto run(A a) -> decltype(a >= 0) {
|
||||
return a >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
/* reductions for lists */
|
||||
|
||||
// using auto -> return value spec makes ICC 13.0 and 13.1 crash here, so we have to hack it
|
||||
// together in front... (13.0 doesn't work with array_prod/array_reduce/... anyway, but 13.1
|
||||
// does...
|
||||
template<typename... Ts>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE decltype(reduce<product_op, Ts...>::run((*((Ts*)0))...)) arg_prod(Ts... ts)
|
||||
{
|
||||
template <typename... Ts>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE decltype(reduce<product_op, Ts...>::run((*((Ts*)0))...)) arg_prod(
|
||||
Ts... ts) {
|
||||
return reduce<product_op, Ts...>::run(ts...);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
constexpr EIGEN_STRONG_INLINE decltype(reduce<sum_op, Ts...>::run((*((Ts*)0))...)) arg_sum(Ts... ts)
|
||||
{
|
||||
template <typename... Ts>
|
||||
constexpr EIGEN_STRONG_INLINE decltype(reduce<sum_op, Ts...>::run((*((Ts*)0))...)) arg_sum(Ts... ts) {
|
||||
return reduce<sum_op, Ts...>::run(ts...);
|
||||
}
|
||||
|
||||
/* reverse arrays */
|
||||
|
||||
template<typename Array, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE Array h_array_reverse(Array arr, numeric_list<int, n...>)
|
||||
{
|
||||
template <typename Array, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE Array h_array_reverse(Array arr, numeric_list<int, n...>) {
|
||||
return {{array_get<sizeof...(n) - n - 1>(arr)...}};
|
||||
}
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE array<T, N> array_reverse(array<T, N> arr)
|
||||
{
|
||||
template <typename T, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE array<T, N> array_reverse(array<T, N> arr) {
|
||||
return h_array_reverse(arr, typename gen_numeric_list<int, N>::type());
|
||||
}
|
||||
|
||||
|
||||
/* generic array reductions */
|
||||
|
||||
// can't reuse standard reduce() interface above because Intel's Compiler
|
||||
@@ -349,113 +461,108 @@ constexpr EIGEN_STRONG_INLINE array<T, N> array_reverse(array<T, N> arr)
|
||||
// (start from N - 1 and work down to 0 because specialization for
|
||||
// n == N - 1 also doesn't work in Intel's compiler, so it goes into
|
||||
// an infinite loop)
|
||||
template<typename Reducer, typename T, std::size_t N, std::size_t n = N - 1>
|
||||
template <typename Reducer, typename T, std::size_t N, std::size_t n = N - 1>
|
||||
struct h_array_reduce {
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(array<T, N> arr, T identity) -> decltype(Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr)))
|
||||
{
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE auto run(array<T, N> arr, T identity)
|
||||
-> decltype(Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr))) {
|
||||
return Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Reducer, typename T, std::size_t N>
|
||||
struct h_array_reduce<Reducer, T, N, 0>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE T run(const array<T, N>& arr, T)
|
||||
{
|
||||
return array_get<0>(arr);
|
||||
}
|
||||
template <typename Reducer, typename T, std::size_t N>
|
||||
struct h_array_reduce<Reducer, T, N, 0> {
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE T run(const array<T, N>& arr, T) { return array_get<0>(arr); }
|
||||
};
|
||||
|
||||
template<typename Reducer, typename T>
|
||||
struct h_array_reduce<Reducer, T, 0>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE T run(const array<T, 0>&, T identity)
|
||||
{
|
||||
return identity;
|
||||
}
|
||||
template <typename Reducer, typename T>
|
||||
struct h_array_reduce<Reducer, T, 0> {
|
||||
EIGEN_DEVICE_FUNC constexpr static EIGEN_STRONG_INLINE T run(const array<T, 0>&, T identity) { return identity; }
|
||||
};
|
||||
|
||||
template<typename Reducer, typename T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_reduce(const array<T, N>& arr, T identity) -> decltype(h_array_reduce<Reducer, T, N>::run(arr, identity))
|
||||
{
|
||||
template <typename Reducer, typename T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_reduce(const array<T, N>& arr, T identity)
|
||||
-> decltype(h_array_reduce<Reducer, T, N>::run(arr, identity)) {
|
||||
return h_array_reduce<Reducer, T, N>::run(arr, identity);
|
||||
}
|
||||
|
||||
/* standard array reductions */
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_sum(const array<T, N>& arr) -> decltype(array_reduce<sum_op, T, N>(arr, static_cast<T>(0)))
|
||||
{
|
||||
template <typename T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_sum(const array<T, N>& arr)
|
||||
-> decltype(array_reduce<sum_op, T, N>(arr, static_cast<T>(0))) {
|
||||
return array_reduce<sum_op, T, N>(arr, static_cast<T>(0));
|
||||
}
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_prod(const array<T, N>& arr) -> decltype(array_reduce<product_op, T, N>(arr, static_cast<T>(1)))
|
||||
{
|
||||
template <typename T, std::size_t N>
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE auto array_prod(const array<T, N>& arr)
|
||||
-> decltype(array_reduce<product_op, T, N>(arr, static_cast<T>(1))) {
|
||||
return array_reduce<product_op, T, N>(arr, static_cast<T>(1));
|
||||
}
|
||||
|
||||
template<typename t>
|
||||
template <typename t>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector<t>& a) {
|
||||
eigen_assert(a.size() > 0);
|
||||
t prod = 1;
|
||||
for (size_t i = 0; i < a.size(); ++i) { prod *= a[i]; }
|
||||
for (size_t i = 0; i < a.size(); ++i) {
|
||||
prod *= a[i];
|
||||
}
|
||||
return prod;
|
||||
}
|
||||
|
||||
/* zip an array */
|
||||
|
||||
template<typename Op, typename A, typename B, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A(), B())),N> h_array_zip(array<A, N> a, array<B, N> b, numeric_list<int, n...>)
|
||||
{
|
||||
return array<decltype(Op::run(A(), B())),N>{{ Op::run(array_get<n>(a), array_get<n>(b))... }};
|
||||
template <typename Op, typename A, typename B, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A(), B())), N> h_array_zip(array<A, N> a, array<B, N> b,
|
||||
numeric_list<int, n...>) {
|
||||
return array<decltype(Op::run(A(), B())), N>{{Op::run(array_get<n>(a), array_get<n>(b))...}};
|
||||
}
|
||||
|
||||
template<typename Op, typename A, typename B, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A(), B())),N> array_zip(array<A, N> a, array<B, N> b)
|
||||
{
|
||||
template <typename Op, typename A, typename B, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A(), B())), N> array_zip(array<A, N> a, array<B, N> b) {
|
||||
return h_array_zip<Op>(a, b, typename gen_numeric_list<int, N>::type());
|
||||
}
|
||||
|
||||
/* zip an array and reduce the result */
|
||||
|
||||
template<typename Reducer, typename Op, typename A, typename B, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE auto h_array_zip_and_reduce(array<A, N> a, array<B, N> b, numeric_list<int, n...>) -> decltype(reduce<Reducer, typename id_numeric<int,n,decltype(Op::run(A(), B()))>::type...>::run(Op::run(array_get<n>(a), array_get<n>(b))...))
|
||||
{
|
||||
return reduce<Reducer, typename id_numeric<int,n,decltype(Op::run(A(), B()))>::type...>::run(Op::run(array_get<n>(a), array_get<n>(b))...);
|
||||
template <typename Reducer, typename Op, typename A, typename B, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE auto h_array_zip_and_reduce(array<A, N> a, array<B, N> b, numeric_list<int, n...>)
|
||||
-> decltype(reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A(), B()))>::type...>::run(
|
||||
Op::run(array_get<n>(a), array_get<n>(b))...)) {
|
||||
return reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A(), B()))>::type...>::run(
|
||||
Op::run(array_get<n>(a), array_get<n>(b))...);
|
||||
}
|
||||
|
||||
template<typename Reducer, typename Op, typename A, typename B, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE auto array_zip_and_reduce(array<A, N> a, array<B, N> b) -> decltype(h_array_zip_and_reduce<Reducer, Op, A, B, N>(a, b, typename gen_numeric_list<int, N>::type()))
|
||||
{
|
||||
template <typename Reducer, typename Op, typename A, typename B, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE auto array_zip_and_reduce(array<A, N> a, array<B, N> b)
|
||||
-> decltype(h_array_zip_and_reduce<Reducer, Op, A, B, N>(a, b, typename gen_numeric_list<int, N>::type())) {
|
||||
return h_array_zip_and_reduce<Reducer, Op, A, B, N>(a, b, typename gen_numeric_list<int, N>::type());
|
||||
}
|
||||
|
||||
/* apply stuff to an array */
|
||||
|
||||
template<typename Op, typename A, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A())),N> h_array_apply(array<A, N> a, numeric_list<int, n...>)
|
||||
{
|
||||
return array<decltype(Op::run(A())),N>{{ Op::run(array_get<n>(a))... }};
|
||||
template <typename Op, typename A, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A())), N> h_array_apply(array<A, N> a, numeric_list<int, n...>) {
|
||||
return array<decltype(Op::run(A())), N>{{Op::run(array_get<n>(a))...}};
|
||||
}
|
||||
|
||||
template<typename Op, typename A, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A())),N> array_apply(array<A, N> a)
|
||||
{
|
||||
template <typename Op, typename A, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE array<decltype(Op::run(A())), N> array_apply(array<A, N> a) {
|
||||
return h_array_apply<Op>(a, typename gen_numeric_list<int, N>::type());
|
||||
}
|
||||
|
||||
/* apply stuff to an array and reduce */
|
||||
|
||||
template<typename Reducer, typename Op, typename A, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE auto h_array_apply_and_reduce(array<A, N> arr, numeric_list<int, n...>) -> decltype(reduce<Reducer, typename id_numeric<int,n,decltype(Op::run(A()))>::type...>::run(Op::run(array_get<n>(arr))...))
|
||||
{
|
||||
return reduce<Reducer, typename id_numeric<int,n,decltype(Op::run(A()))>::type...>::run(Op::run(array_get<n>(arr))...);
|
||||
template <typename Reducer, typename Op, typename A, std::size_t N, int... n>
|
||||
constexpr EIGEN_STRONG_INLINE auto h_array_apply_and_reduce(array<A, N> arr, numeric_list<int, n...>)
|
||||
-> decltype(reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A()))>::type...>::run(
|
||||
Op::run(array_get<n>(arr))...)) {
|
||||
return reduce<Reducer, typename id_numeric<int, n, decltype(Op::run(A()))>::type...>::run(
|
||||
Op::run(array_get<n>(arr))...);
|
||||
}
|
||||
|
||||
template<typename Reducer, typename Op, typename A, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE auto array_apply_and_reduce(array<A, N> a) -> decltype(h_array_apply_and_reduce<Reducer, Op, A, N>(a, typename gen_numeric_list<int, N>::type()))
|
||||
{
|
||||
template <typename Reducer, typename Op, typename A, std::size_t N>
|
||||
constexpr EIGEN_STRONG_INLINE auto array_apply_and_reduce(array<A, N> a)
|
||||
-> decltype(h_array_apply_and_reduce<Reducer, Op, A, N>(a, typename gen_numeric_list<int, N>::type())) {
|
||||
return h_array_apply_and_reduce<Reducer, Op, A, N>(a, typename gen_numeric_list<int, N>::type());
|
||||
}
|
||||
|
||||
@@ -464,69 +571,60 @@ constexpr EIGEN_STRONG_INLINE auto array_apply_and_reduce(array<A, N> a) -> decl
|
||||
* array<int, 16> = repeat<16>(42);
|
||||
*/
|
||||
|
||||
template<int n>
|
||||
struct h_repeat
|
||||
{
|
||||
template<typename t, int... ii>
|
||||
constexpr static EIGEN_STRONG_INLINE array<t, n> run(t v, numeric_list<int, ii...>)
|
||||
{
|
||||
return {{ typename id_numeric<int, ii, t>::type(v)... }};
|
||||
template <int n>
|
||||
struct h_repeat {
|
||||
template <typename t, int... ii>
|
||||
constexpr static EIGEN_STRONG_INLINE array<t, n> run(t v, numeric_list<int, ii...>) {
|
||||
return {{typename id_numeric<int, ii, t>::type(v)...}};
|
||||
}
|
||||
};
|
||||
|
||||
template<int n, typename t>
|
||||
constexpr array<t, n> repeat(t v) { return h_repeat<n>::run(v, typename gen_numeric_list<int, n>::type()); }
|
||||
template <int n, typename t>
|
||||
constexpr array<t, n> repeat(t v) {
|
||||
return h_repeat<n>::run(v, typename gen_numeric_list<int, n>::type());
|
||||
}
|
||||
|
||||
/* instantiate a class by a C-style array */
|
||||
template<class InstType, typename ArrType, std::size_t N, bool Reverse, typename... Ps>
|
||||
template <class InstType, typename ArrType, std::size_t N, bool Reverse, typename... Ps>
|
||||
struct h_instantiate_by_c_array;
|
||||
|
||||
template<class InstType, typename ArrType, std::size_t N, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, N, false, Ps...>
|
||||
{
|
||||
static InstType run(ArrType* arr, Ps... args)
|
||||
{
|
||||
template <class InstType, typename ArrType, std::size_t N, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, N, false, Ps...> {
|
||||
static InstType run(ArrType* arr, Ps... args) {
|
||||
return h_instantiate_by_c_array<InstType, ArrType, N - 1, false, Ps..., ArrType>::run(arr + 1, args..., arr[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template<class InstType, typename ArrType, std::size_t N, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, N, true, Ps...>
|
||||
{
|
||||
static InstType run(ArrType* arr, Ps... args)
|
||||
{
|
||||
template <class InstType, typename ArrType, std::size_t N, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, N, true, Ps...> {
|
||||
static InstType run(ArrType* arr, Ps... args) {
|
||||
return h_instantiate_by_c_array<InstType, ArrType, N - 1, false, ArrType, Ps...>::run(arr + 1, arr[0], args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<class InstType, typename ArrType, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, 0, false, Ps...>
|
||||
{
|
||||
static InstType run(ArrType* arr, Ps... args)
|
||||
{
|
||||
template <class InstType, typename ArrType, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, 0, false, Ps...> {
|
||||
static InstType run(ArrType* arr, Ps... args) {
|
||||
(void)arr;
|
||||
return InstType(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<class InstType, typename ArrType, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, 0, true, Ps...>
|
||||
{
|
||||
static InstType run(ArrType* arr, Ps... args)
|
||||
{
|
||||
template <class InstType, typename ArrType, typename... Ps>
|
||||
struct h_instantiate_by_c_array<InstType, ArrType, 0, true, Ps...> {
|
||||
static InstType run(ArrType* arr, Ps... args) {
|
||||
(void)arr;
|
||||
return InstType(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<class InstType, typename ArrType, std::size_t N, bool Reverse = false>
|
||||
InstType instantiate_by_c_array(ArrType* arr)
|
||||
{
|
||||
template <class InstType, typename ArrType, std::size_t N, bool Reverse = false>
|
||||
InstType instantiate_by_c_array(ArrType* arr) {
|
||||
return h_instantiate_by_c_array<InstType, ArrType, N, Reverse>::run(arr);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_MOREMETA_H
|
||||
#endif // EIGEN_MOREMETA_H
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
#ifdef EIGEN_WARNINGS_DISABLED_2
|
||||
// "DisableStupidWarnings.h" was included twice recursively: Do not re-enable warnings yet!
|
||||
# undef EIGEN_WARNINGS_DISABLED_2
|
||||
#undef EIGEN_WARNINGS_DISABLED_2
|
||||
|
||||
#elif defined(EIGEN_WARNINGS_DISABLED)
|
||||
#undef EIGEN_WARNINGS_DISABLED
|
||||
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
#ifdef EIGEN_REENABLE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#undef EIGEN_REENABLE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#undef _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#ifdef EIGEN_REENABLE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#undef EIGEN_REENABLE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#undef _SILENCE_CXX23_DENORM_DEPRECATION_WARNING
|
||||
#endif
|
||||
|
||||
#elif defined __INTEL_COMPILER
|
||||
#pragma warning pop
|
||||
#elif defined __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined __GNUC__ && !defined(__FUJITSU) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#elif defined __INTEL_COMPILER
|
||||
#pragma warning pop
|
||||
#elif defined __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined __GNUC__ && !defined(__FUJITSU) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__
|
||||
#if defined __NVCC__
|
||||
// Don't re-enable 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.
|
||||
@@ -37,8 +37,8 @@
|
||||
// EIGEN_NV_DIAG_DEFAULT(2653)
|
||||
// #undef EIGEN_NV_DIAG_DEFAULT
|
||||
// #undef EIGEN_MAKE_PRAGMA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_WARNINGS_DISABLED
|
||||
#endif // EIGEN_WARNINGS_DISABLED
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
// 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_RESHAPED_HELPER_H
|
||||
#define EIGEN_RESHAPED_HELPER_H
|
||||
|
||||
@@ -16,38 +15,37 @@
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
enum AutoSize_t { AutoSize };
|
||||
enum AutoSize_t { AutoSize };
|
||||
const int AutoOrder = 2;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename SizeType,typename OtherSize, int TotalSize>
|
||||
template <typename SizeType, typename OtherSize, int TotalSize>
|
||||
struct get_compiletime_reshape_size {
|
||||
enum { value = get_fixed_value<SizeType>::value };
|
||||
};
|
||||
|
||||
template<typename SizeType>
|
||||
template <typename SizeType>
|
||||
Index get_runtime_reshape_size(SizeType size, Index /*other*/, Index /*total*/) {
|
||||
return internal::get_runtime_value(size);
|
||||
}
|
||||
|
||||
template<typename OtherSize, int TotalSize>
|
||||
struct get_compiletime_reshape_size<AutoSize_t,OtherSize,TotalSize> {
|
||||
template <typename OtherSize, int TotalSize>
|
||||
struct get_compiletime_reshape_size<AutoSize_t, OtherSize, TotalSize> {
|
||||
enum {
|
||||
other_size = get_fixed_value<OtherSize>::value,
|
||||
value = (TotalSize==Dynamic || other_size==Dynamic) ? Dynamic : TotalSize / other_size };
|
||||
value = (TotalSize == Dynamic || other_size == Dynamic) ? Dynamic : TotalSize / other_size
|
||||
};
|
||||
};
|
||||
|
||||
inline Index get_runtime_reshape_size(AutoSize_t /*size*/, Index other, Index total) {
|
||||
return total/other;
|
||||
}
|
||||
inline Index get_runtime_reshape_size(AutoSize_t /*size*/, Index other, Index total) { return total / other; }
|
||||
|
||||
constexpr inline int get_compiletime_reshape_order(int flags, int order) {
|
||||
return order == AutoOrder ? flags & RowMajorBit : order;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_RESHAPED_HELPER_H
|
||||
#endif // EIGEN_RESHAPED_HELPER_H
|
||||
|
||||
@@ -20,29 +20,24 @@ namespace Eigen {
|
||||
|
||||
/**
|
||||
* Serializes an object to a memory buffer.
|
||||
*
|
||||
*
|
||||
* Useful for transferring data (e.g. back-and-forth to a device).
|
||||
*/
|
||||
template<typename T, typename EnableIf = void>
|
||||
template <typename T, typename EnableIf = void>
|
||||
class Serializer;
|
||||
|
||||
// Specialization for POD types.
|
||||
template<typename T>
|
||||
class Serializer<T, typename std::enable_if_t<
|
||||
std::is_trivial<T>::value
|
||||
&& std::is_standard_layout<T>::value>> {
|
||||
template <typename T>
|
||||
class Serializer<T, typename std::enable_if_t<std::is_trivial<T>::value && std::is_standard_layout<T>::value>> {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Determines the required size of the serialization buffer for a value.
|
||||
*
|
||||
*
|
||||
* \param value the value to serialize.
|
||||
* \return the required size.
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC size_t size(const T& value) const {
|
||||
return sizeof(value);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC size_t size(const T& value) const { return sizeof(value); }
|
||||
|
||||
/**
|
||||
* Serializes a value to a byte buffer.
|
||||
* \param dest the destination buffer; if this is nullptr, does nothing.
|
||||
@@ -57,7 +52,7 @@ class Serializer<T, typename std::enable_if_t<
|
||||
memcpy(dest, &value, sizeof(value));
|
||||
return dest + sizeof(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes a value from a byte buffer.
|
||||
* \param src the source buffer; if this is nullptr, does nothing.
|
||||
@@ -76,20 +71,18 @@ class Serializer<T, typename std::enable_if_t<
|
||||
|
||||
// Specialization for DenseBase.
|
||||
// Serializes [rows, cols, data...].
|
||||
template<typename Derived>
|
||||
template <typename Derived>
|
||||
class Serializer<DenseBase<Derived>, void> {
|
||||
public:
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
|
||||
|
||||
struct Header {
|
||||
typename Derived::Index rows;
|
||||
typename Derived::Index cols;
|
||||
};
|
||||
|
||||
EIGEN_DEVICE_FUNC size_t size(const Derived& value) const {
|
||||
return sizeof(Header) + sizeof(Scalar) * value.size();
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC size_t size(const Derived& value) const { return sizeof(Header) + sizeof(Scalar) * value.size(); }
|
||||
|
||||
EIGEN_DEVICE_FUNC uint8_t* serialize(uint8_t* dest, uint8_t* end, const Derived& value) {
|
||||
if (EIGEN_PREDICT_FALSE(dest == nullptr)) return nullptr;
|
||||
if (EIGEN_PREDICT_FALSE(dest + size(value) > end)) return nullptr;
|
||||
@@ -102,7 +95,7 @@ class Serializer<DenseBase<Derived>, void> {
|
||||
memcpy(dest, value.data(), data_bytes);
|
||||
return dest + data_bytes;
|
||||
}
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, Derived& value) const {
|
||||
if (EIGEN_PREDICT_FALSE(src == nullptr)) return nullptr;
|
||||
if (EIGEN_PREDICT_FALSE(src + sizeof(Header) > end)) return nullptr;
|
||||
@@ -119,102 +112,97 @@ class Serializer<DenseBase<Derived>, void> {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
class Serializer<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > : public
|
||||
Serializer<DenseBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > > {};
|
||||
|
||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
class Serializer<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > : public
|
||||
Serializer<DenseBase<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > > {};
|
||||
|
||||
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
class Serializer<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
|
||||
: public Serializer<DenseBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>> {};
|
||||
|
||||
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
class Serializer<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
|
||||
: public Serializer<DenseBase<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>> {};
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
// Recursive serialization implementation helper.
|
||||
template<size_t N, typename... Types>
|
||||
template <size_t N, typename... Types>
|
||||
struct serialize_impl;
|
||||
|
||||
template<size_t N, typename T1, typename... Ts>
|
||||
template <size_t N, typename T1, typename... Ts>
|
||||
struct serialize_impl<N, T1, Ts...> {
|
||||
using Serializer = Eigen::Serializer<typename std::decay<T1>::type>;
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
size_t serialize_size(const T1& value, const Ts&... args) {
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const T1& value, const Ts&... args) {
|
||||
Serializer serializer;
|
||||
size_t size = serializer.size(value);
|
||||
return size + serialize_impl<N-1, Ts...>::serialize_size(args...);
|
||||
return size + serialize_impl<N - 1, Ts...>::serialize_size(args...);
|
||||
}
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
uint8_t* serialize(uint8_t* dest, uint8_t* end, const T1& value, const Ts&... args) {
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* end, const T1& value,
|
||||
const Ts&... args) {
|
||||
Serializer serializer;
|
||||
dest = serializer.serialize(dest, end, value);
|
||||
return serialize_impl<N-1, Ts...>::serialize(dest, end, args...);
|
||||
return serialize_impl<N - 1, Ts...>::serialize(dest, end, args...);
|
||||
}
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, T1& value, Ts&... args) {
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* end,
|
||||
T1& value, Ts&... args) {
|
||||
Serializer serializer;
|
||||
src = serializer.deserialize(src, end, value);
|
||||
return serialize_impl<N-1, Ts...>::deserialize(src, end, args...);
|
||||
return serialize_impl<N - 1, Ts...>::deserialize(src, end, args...);
|
||||
}
|
||||
};
|
||||
|
||||
// Base case.
|
||||
template<>
|
||||
template <>
|
||||
struct serialize_impl<0> {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
size_t serialize_size() { return 0; }
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
uint8_t* serialize(uint8_t* dest, uint8_t* /*end*/) { return dest; }
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const uint8_t* deserialize(const uint8_t* src, const uint8_t* /*end*/) { return src; }
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size() { return 0; }
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* /*end*/) { return dest; }
|
||||
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* /*end*/) {
|
||||
return src;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
/**
|
||||
* Determine the buffer size required to serialize a set of values.
|
||||
*
|
||||
*
|
||||
* \param args ... arguments to serialize in sequence.
|
||||
* \return the total size of the required buffer.
|
||||
*/
|
||||
template<typename... Args>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
size_t serialize_size(const Args&... args) {
|
||||
template <typename... Args>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const Args&... args) {
|
||||
return internal::serialize_impl<sizeof...(args), Args...>::serialize_size(args...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize a set of values to the byte buffer.
|
||||
*
|
||||
*
|
||||
* \param dest output byte buffer; if this is nullptr, does nothing.
|
||||
* \param end the end of the output byte buffer.
|
||||
* \param args ... arguments to serialize in sequence.
|
||||
* \return the next address after all serialized values.
|
||||
*/
|
||||
template<typename... Args>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
uint8_t* serialize(uint8_t* dest, uint8_t* end, const Args&... args) {
|
||||
template <typename... Args>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* end, const Args&... args) {
|
||||
return internal::serialize_impl<sizeof...(args), Args...>::serialize(dest, end, args...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize a set of values from the byte buffer.
|
||||
*
|
||||
*
|
||||
* \param src input byte buffer; if this is nullptr, does nothing.
|
||||
* \param end the end of input byte buffer.
|
||||
* \param args ... arguments to deserialize in sequence.
|
||||
* \return the next address after all parsed values; nullptr if parsing errors are detected.
|
||||
*/
|
||||
template<typename... Args>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, Args&... args) {
|
||||
template <typename... Args>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* end,
|
||||
Args&... args) {
|
||||
return internal::serialize_impl<sizeof...(args), Args...>::deserialize(src, end, args...);
|
||||
}
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
#endif // EIGEN_SERIALIZER_H
|
||||
#endif // EIGEN_SERIALIZER_H
|
||||
|
||||
@@ -23,93 +23,83 @@
|
||||
#ifndef EIGEN_STATIC_ASSERT
|
||||
#ifndef EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
||||
#define EIGEN_STATIC_ASSERT(X, MSG) static_assert(X, #MSG);
|
||||
|
||||
#else // EIGEN_NO_STATIC_ASSERT
|
||||
#else // EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#define EIGEN_STATIC_ASSERT(CONDITION,MSG)
|
||||
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
|
||||
|
||||
#endif // EIGEN_NO_STATIC_ASSERT
|
||||
#endif // EIGEN_STATIC_ASSERT
|
||||
#endif // EIGEN_NO_STATIC_ASSERT
|
||||
#endif // EIGEN_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)
|
||||
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, \
|
||||
#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, \
|
||||
#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, \
|
||||
#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, \
|
||||
#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_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_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(!Eigen::NumTraits<TYPE>::IsInteger, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES)
|
||||
EIGEN_STATIC_ASSERT(!Eigen::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)
|
||||
|
||||
// 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 == Eigen::Dynamic) && \
|
||||
#define EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) \
|
||||
EIGEN_STATIC_ASSERT((TYPE::RowsAtCompileTime == 1 || TYPE::RowsAtCompileTime == Eigen::Dynamic) && \
|
||||
(TYPE::ColsAtCompileTime == 1 || TYPE::ColsAtCompileTime == Eigen::Dynamic), \
|
||||
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS)
|
||||
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)
|
||||
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_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)
|
||||
#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);
|
||||
#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
|
||||
#endif // EIGEN_STATIC_ASSERT_H
|
||||
|
||||
@@ -16,248 +16,286 @@
|
||||
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";
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* It is currently only used internally to define and manipulate the
|
||||
* Eigen::placeholders::last and Eigen::placeholders::lastp1 symbols in
|
||||
* Eigen::seq and Eigen::seqN.
|
||||
*
|
||||
*/
|
||||
* \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";
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* It is currently only used internally to define and manipulate the
|
||||
* Eigen::placeholders::last and Eigen::placeholders::lastp1 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;
|
||||
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>
|
||||
template <typename IndexType = Index>
|
||||
class ValueExpr {
|
||||
public:
|
||||
public:
|
||||
ValueExpr(IndexType val) : m_value(val) {}
|
||||
template<typename T>
|
||||
IndexType eval_impl(const T&) const { return m_value; }
|
||||
protected:
|
||||
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>
|
||||
template <int N>
|
||||
class ValueExpr<internal::FixedInt<N> > {
|
||||
public:
|
||||
public:
|
||||
ValueExpr() {}
|
||||
template<typename T>
|
||||
EIGEN_CONSTEXPR Index eval_impl(const T&) const { return N; }
|
||||
template <typename T>
|
||||
EIGEN_CONSTEXPR 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:
|
||||
* \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); }
|
||||
*
|
||||
* \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);
|
||||
}
|
||||
|
||||
template<typename... Types>
|
||||
Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); }
|
||||
template <typename... Types>
|
||||
Index eval(Types&&... values) const {
|
||||
return derived().eval_impl(std::make_tuple(values...));
|
||||
}
|
||||
|
||||
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); }
|
||||
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()); }
|
||||
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>
|
||||
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()); }
|
||||
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());
|
||||
}
|
||||
|
||||
template <typename OtherDerived>
|
||||
AddExpr<Derived, OtherDerived> operator+(const BaseExpr<OtherDerived>& b) const {
|
||||
return AddExpr<Derived, OtherDerived>(derived(), b.derived());
|
||||
}
|
||||
|
||||
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>
|
||||
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>
|
||||
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 OtherDerived>
|
||||
QuotientExpr<Derived, OtherDerived> operator/(const BaseExpr<OtherDerived>& b) const {
|
||||
return QuotientExpr<Derived, OtherDerived>(derived(), b.derived());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
struct is_symbolic {
|
||||
// BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class BaseExpr<T>.
|
||||
enum { value = internal::is_convertible<T,BaseExpr<T> >::value };
|
||||
// BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class
|
||||
// BaseExpr<T>.
|
||||
enum { value = internal::is_convertible<T, BaseExpr<T> >::value };
|
||||
};
|
||||
|
||||
/** 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:
|
||||
*
|
||||
* 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:
|
||||
|
||||
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:
|
||||
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);
|
||||
}
|
||||
*
|
||||
* 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(); }
|
||||
Index eval_impl(const SymbolValue<Tag>& values) const { return values.value(); }
|
||||
|
||||
// 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(); }
|
||||
template <typename... Types>
|
||||
Index eval_impl(const std::tuple<Types...>& values) const {
|
||||
return std::get<SymbolValue<Tag> >(values).value();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Arg0>
|
||||
class NegateExpr : public BaseExpr<NegateExpr<Arg0> >
|
||||
{
|
||||
public:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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:
|
||||
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 symbolic
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SYMBOLIC_INDEX_H
|
||||
#endif // EIGEN_SYMBOLIC_INDEX_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user