Apply clang-format

This commit is contained in:
Tobias Wood
2023-11-29 11:12:48 +00:00
parent 9ea520fc45
commit f38e16c193
534 changed files with 103368 additions and 116934 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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