mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Pull latest updates from upstream
This commit is contained in:
@@ -123,18 +123,18 @@ template<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::R
|
||||
template<typename Scalar, typename Index>
|
||||
class BlasVectorMapper {
|
||||
public:
|
||||
EIGEN_ALWAYS_INLINE BlasVectorMapper(Scalar *data) : m_data(data) {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasVectorMapper(Scalar *data) : m_data(data) {}
|
||||
|
||||
EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const {
|
||||
return m_data[i];
|
||||
}
|
||||
template <typename Packet, int AlignmentType>
|
||||
EIGEN_ALWAYS_INLINE Packet load(Index i) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet load(Index i) const {
|
||||
return ploadt<Packet, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
template <typename Packet>
|
||||
bool aligned(Index i) const {
|
||||
EIGEN_DEVICE_FUNC bool aligned(Index i) const {
|
||||
return (size_t(m_data+i)%sizeof(Packet))==0;
|
||||
}
|
||||
|
||||
@@ -148,25 +148,25 @@ class BlasLinearMapper {
|
||||
typedef typename packet_traits<Scalar>::type Packet;
|
||||
typedef typename packet_traits<Scalar>::half HalfPacket;
|
||||
|
||||
EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data) : m_data(data) {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data) : m_data(data) {}
|
||||
|
||||
EIGEN_ALWAYS_INLINE void prefetch(int i) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const {
|
||||
internal::prefetch(&operator()(i));
|
||||
}
|
||||
|
||||
EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const {
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const {
|
||||
return ploadt<Packet, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const {
|
||||
return ploadt<HalfPacket, AlignmentType>(m_data + i);
|
||||
}
|
||||
|
||||
EIGEN_ALWAYS_INLINE void storePacket(Index i, const Packet &p) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const Packet &p) const {
|
||||
pstoret<Scalar, Packet, AlignmentType>(m_data + i, p);
|
||||
}
|
||||
|
||||
@@ -184,18 +184,18 @@ class blas_data_mapper {
|
||||
typedef BlasLinearMapper<Scalar, Index, AlignmentType> LinearMapper;
|
||||
typedef BlasVectorMapper<Scalar, Index> VectorMapper;
|
||||
|
||||
EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
|
||||
|
||||
EIGEN_ALWAYS_INLINE blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType>
|
||||
getSubMapper(Index i, Index j) const {
|
||||
return blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType>(&operator()(i, j), m_stride);
|
||||
}
|
||||
|
||||
EIGEN_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_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));
|
||||
}
|
||||
|
||||
@@ -205,28 +205,28 @@ class blas_data_mapper {
|
||||
return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride];
|
||||
}
|
||||
|
||||
EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const {
|
||||
return ploadt<Packet, AlignmentType>(&operator()(i, j));
|
||||
}
|
||||
|
||||
EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i, Index j) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i, Index j) const {
|
||||
return ploadt<HalfPacket, AlignmentType>(&operator()(i, j));
|
||||
}
|
||||
|
||||
template<typename SubPacket>
|
||||
EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const {
|
||||
pscatter<Scalar, SubPacket>(&operator()(i, j), p, m_stride);
|
||||
}
|
||||
|
||||
template<typename SubPacket>
|
||||
EIGEN_ALWAYS_INLINE SubPacket gatherPacket(Index i, Index j) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubPacket gatherPacket(Index i, Index j) const {
|
||||
return pgather<Scalar, SubPacket>(&operator()(i, j), m_stride);
|
||||
}
|
||||
|
||||
const Index stride() const { return m_stride; }
|
||||
const Scalar* data() const { return m_data; }
|
||||
EIGEN_DEVICE_FUNC const Index stride() const { return m_stride; }
|
||||
EIGEN_DEVICE_FUNC const Scalar* data() const { return m_data; }
|
||||
|
||||
Index firstAligned(Index size) const {
|
||||
EIGEN_DEVICE_FUNC Index firstAligned(Index size) const {
|
||||
if (size_t(m_data)%sizeof(Scalar)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,8 @@ const int HugeCost = 10000;
|
||||
* 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 \ref TopicStorageOrders */
|
||||
* the matrix created by evaluation of that expression.
|
||||
* \sa \blank \ref TopicStorageOrders */
|
||||
const unsigned int RowMajorBit = 0x1;
|
||||
|
||||
/** \ingroup flags
|
||||
@@ -67,6 +67,7 @@ const unsigned int EvalBeforeNestingBit = 0x2;
|
||||
/** \ingroup flags
|
||||
* \deprecated
|
||||
* means the expression should be evaluated before any assignment */
|
||||
EIGEN_DEPRECATED
|
||||
const unsigned int EvalBeforeAssigningBit = 0x4; // FIXME deprecated
|
||||
|
||||
/** \ingroup flags
|
||||
@@ -158,7 +159,7 @@ const unsigned int DirectAccessBit = 0x40;
|
||||
* expression.packet<Aligned>(0);
|
||||
* \endcode
|
||||
*/
|
||||
const unsigned int AlignedBit = 0x80;
|
||||
EIGEN_DEPRECATED const unsigned int AlignedBit = 0x80;
|
||||
|
||||
const unsigned int NestByRefBit = 0x100;
|
||||
|
||||
@@ -168,7 +169,7 @@ const unsigned int NestByRefBit = 0x100;
|
||||
* can be either row-major or column-major.
|
||||
* The precise choice will be decided at evaluation time or when
|
||||
* combined with other expressions.
|
||||
* \sa \ref RowMajorBit, \ref TopicStorageOrders */
|
||||
* \sa \blank \ref RowMajorBit, \ref TopicStorageOrders */
|
||||
const unsigned int NoPreferredStorageOrderBit = 0x200;
|
||||
|
||||
/** \ingroup flags
|
||||
@@ -187,8 +188,7 @@ const unsigned int CompressedAccessBit = 0x400;
|
||||
|
||||
// list of flags that are inherited by default
|
||||
const unsigned int HereditaryBits = RowMajorBit
|
||||
| EvalBeforeNestingBit
|
||||
| EvalBeforeAssigningBit;
|
||||
| EvalBeforeNestingBit;
|
||||
|
||||
/** \defgroup enums Enumerations
|
||||
* \ingroup Core_Module
|
||||
@@ -224,7 +224,7 @@ enum {
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for indicating whether a buffer is aligned or not. */
|
||||
enum {
|
||||
enum {
|
||||
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. */
|
||||
|
||||
21
Eigen/src/Core/util/DisableStupidWarnings.h
Normal file → Executable file
21
Eigen/src/Core/util/DisableStupidWarnings.h
Normal file → Executable file
@@ -15,20 +15,25 @@
|
||||
// 4522 - 'class' : multiple assignment operators specified
|
||||
// 4700 - uninitialized local variable 'xyz' used
|
||||
// 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 4717 )
|
||||
#pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4503 4512 4522 4700 4717 4800)
|
||||
|
||||
#elif defined __INTEL_COMPILER
|
||||
// 2196 - routine is both "inline" and "noinline" ("noinline" assumed)
|
||||
// ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body
|
||||
// typedef that may be a reference type.
|
||||
// 279 - controlling expression is constant
|
||||
// ICC 12 generates this warning on assert(constant_expression_depending_on_template_params) and frankly this is a legitimate use case.
|
||||
// 1684 - conversion from pointer to same-sized integral type (potential portability problem)
|
||||
// 2259 - non-pointer conversion from "Eigen::Index={ptrdiff_t={long}}" to "int" may lose significant bits
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma warning push
|
||||
#endif
|
||||
#pragma warning disable 2196 279
|
||||
#pragma warning disable 2196 279 1684 2259
|
||||
|
||||
#elif defined __clang__
|
||||
// -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant
|
||||
// this is really a stupid warning as it warns on compile-time expressions involving enums
|
||||
@@ -38,4 +43,16 @@
|
||||
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__
|
||||
// Disable the "statement is unreachable" message
|
||||
#pragma diag_suppress code_is_unreachable
|
||||
// Disable the "dynamic initialization in unreachable code" message
|
||||
#pragma diag_suppress initialization_not_reachable
|
||||
// Disable the "calling a __host__ function from a __host__ __device__ function is not allowed" messages (yes, there are 4 of them)
|
||||
#pragma diag_suppress 2651
|
||||
#pragma diag_suppress 2653
|
||||
#pragma diag_suppress 2668
|
||||
#pragma diag_suppress 2670
|
||||
#endif
|
||||
|
||||
#endif // not EIGEN_WARNINGS_DISABLED
|
||||
|
||||
@@ -94,12 +94,8 @@ template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp;
|
||||
template<typename Decomposition, typename Rhstype> class Solve;
|
||||
template<typename XprType> class Inverse;
|
||||
|
||||
namespace internal {
|
||||
template<typename Lhs, typename Rhs> struct product_tag;
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs, int Option = DefaultProduct> class Product;
|
||||
|
||||
|
||||
template<typename Derived> class DiagonalBase;
|
||||
template<typename _DiagonalVectorType> class DiagonalWrapper;
|
||||
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime=SizeAtCompileTime> class DiagonalMatrix;
|
||||
@@ -210,6 +206,8 @@ template<typename Scalar> struct scalar_add_op;
|
||||
template<typename Scalar> struct scalar_constant_op;
|
||||
template<typename Scalar> struct scalar_identity_op;
|
||||
template<typename Scalar,bool iscpx> struct scalar_sign_op;
|
||||
template<typename Scalar> struct scalar_igamma_op;
|
||||
template<typename Scalar> struct scalar_igammac_op;
|
||||
|
||||
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_product_op;
|
||||
template<typename LhsScalar,typename RhsScalar> struct scalar_multiple2_op;
|
||||
@@ -252,6 +250,7 @@ template<typename MatrixType> struct inverse_impl;
|
||||
template<typename MatrixType> class HouseholderQR;
|
||||
template<typename MatrixType> class ColPivHouseholderQR;
|
||||
template<typename MatrixType> class FullPivHouseholderQR;
|
||||
template<typename MatrixType> class CompleteOrthogonalDecomposition;
|
||||
template<typename MatrixType, int QRPreconditioner = ColPivHouseholderQRPreconditioner> class JacobiSVD;
|
||||
template<typename MatrixType> class BDCSVD;
|
||||
template<typename MatrixType, int UpLo = Lower> class LLT;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#define EIGEN_USE_LAPACKE
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_USE_BLAS) || defined(EIGEN_USE_LAPACKE) || defined(EIGEN_USE_MKL_VML)
|
||||
#if defined(EIGEN_USE_LAPACKE) || defined(EIGEN_USE_MKL_VML)
|
||||
#define EIGEN_USE_MKL
|
||||
#endif
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
# ifndef EIGEN_USE_MKL
|
||||
/*If the MKL version is too old, undef everything*/
|
||||
# undef EIGEN_USE_MKL_ALL
|
||||
# undef EIGEN_USE_BLAS
|
||||
# undef EIGEN_USE_LAPACKE
|
||||
# undef EIGEN_USE_MKL_VML
|
||||
# undef EIGEN_USE_LAPACKE_STRICT
|
||||
@@ -107,52 +106,23 @@
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_PARDISO MKL_PARDISO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
typedef std::complex<double> dcomplex;
|
||||
typedef std::complex<float> scomplex;
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename MKLType, typename EigenType>
|
||||
static inline void assign_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) {
|
||||
mklScalar=eigenScalar;
|
||||
}
|
||||
|
||||
template<typename MKLType, typename EigenType>
|
||||
static inline void assign_conj_scalar_eig2mkl(MKLType& mklScalar, const EigenType& eigenScalar) {
|
||||
mklScalar=eigenScalar;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void assign_scalar_eig2mkl<MKL_Complex16,dcomplex>(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) {
|
||||
mklScalar.real=eigenScalar.real();
|
||||
mklScalar.imag=eigenScalar.imag();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void assign_scalar_eig2mkl<MKL_Complex8,scomplex>(MKL_Complex8& mklScalar, const scomplex& eigenScalar) {
|
||||
mklScalar.real=eigenScalar.real();
|
||||
mklScalar.imag=eigenScalar.imag();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void assign_conj_scalar_eig2mkl<MKL_Complex16,dcomplex>(MKL_Complex16& mklScalar, const dcomplex& eigenScalar) {
|
||||
mklScalar.real=eigenScalar.real();
|
||||
mklScalar.imag=-eigenScalar.imag();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void assign_conj_scalar_eig2mkl<MKL_Complex8,scomplex>(MKL_Complex8& mklScalar, const scomplex& eigenScalar) {
|
||||
mklScalar.real=eigenScalar.real();
|
||||
mklScalar.imag=-eigenScalar.imag();
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
#if defined(EIGEN_USE_MKL)
|
||||
typedef MKL_INT BlasIndex;
|
||||
#else
|
||||
typedef int BlasIndex;
|
||||
#endif
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#if defined(EIGEN_USE_BLAS)
|
||||
#include "../../misc/blas.h"
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_MKL_SUPPORT_H
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#define EIGEN_WORLD_VERSION 3
|
||||
#define EIGEN_MAJOR_VERSION 2
|
||||
#define EIGEN_MINOR_VERSION 91
|
||||
#define EIGEN_MINOR_VERSION 92
|
||||
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
@@ -99,9 +99,16 @@
|
||||
#define EIGEN_COMP_ARM 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_ARM set to 1 if the compiler is ARM Compiler
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#define EIGEN_COMP_EMSCRIPTEN 1
|
||||
#else
|
||||
#define EIGEN_COMP_EMSCRIPTEN 0
|
||||
#endif
|
||||
|
||||
|
||||
/// \internal EIGEN_GNUC_STRICT set to 1 if the compiler is really GCC and not a compatible compiler (e.g., ICC, clang, mingw, etc.)
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_COMP_CLANG || EIGEN_COMP_ICC || EIGEN_COMP_MINGW || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM )
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_COMP_CLANG || EIGEN_COMP_ICC || EIGEN_COMP_MINGW || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM || EIGEN_COMP_EMSCRIPTEN)
|
||||
#define EIGEN_COMP_GNUC_STRICT 1
|
||||
#else
|
||||
#define EIGEN_COMP_GNUC_STRICT 0
|
||||
@@ -336,25 +343,35 @@
|
||||
// Do we support r-value references?
|
||||
#if (__has_feature(cxx_rvalue_references) || \
|
||||
(defined(__cplusplus) && __cplusplus >= 201103L) || \
|
||||
defined(__GXX_EXPERIMENTAL_CXX0X__) || \
|
||||
(EIGEN_COMP_MSVC >= 1600))
|
||||
#define EIGEN_HAVE_RVALUE_REFERENCES
|
||||
#endif
|
||||
|
||||
// Does the compiler support C99?
|
||||
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) \
|
||||
|| (defined(__GNUC__) && defined(_GLIBCXX_USE_C99)) \
|
||||
|| (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
|
||||
#define EIGEN_HAS_C99_MATH 1
|
||||
#endif
|
||||
|
||||
// Does the compiler support result_of?
|
||||
#if (__has_feature(cxx_lambdas) || (defined(__cplusplus) && __cplusplus >= 201103L))
|
||||
#define EIGEN_HAS_STD_RESULT_OF 1
|
||||
#endif
|
||||
|
||||
// Does the compiler support variadic templates?
|
||||
#if __cplusplus > 199711L
|
||||
#if __cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900
|
||||
// Disable the use of variadic templates when compiling with nvcc on ARM devices:
|
||||
// this prevents nvcc from crashing when compiling Eigen on Tegra X1
|
||||
#if !defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64
|
||||
#define EIGEN_HAS_VARIADIC_TEMPLATES 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Does the compiler support const expressions?
|
||||
#ifdef __CUDACC__
|
||||
// Const expressions are supported provided that c++11 is enabled and we're using nvcc 7.5 or above
|
||||
#if defined(__CUDACC_VER__) && __CUDACC_VER__ >= 70500 && __cplusplus > 199711L
|
||||
// Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above
|
||||
#if __cplusplus > 199711L && defined(__CUDACC_VER__) && (defined(__clang__) || __CUDACC_VER__ >= 70500)
|
||||
#define EIGEN_HAS_CONSTEXPR 1
|
||||
#endif
|
||||
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || \
|
||||
|
||||
@@ -59,28 +59,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_HAS_POSIX_MEMALIGN
|
||||
// See bug 554 (http://eigen.tuxfamily.org/bz/show_bug.cgi?id=554)
|
||||
// It seems to be unsafe to check _POSIX_ADVISORY_INFO without including unistd.h first.
|
||||
// Currently, let's include it only on unix systems:
|
||||
#if EIGEN_OS_UNIX && !(EIGEN_OS_SUN || EIGEN_OS_SOLARIS)
|
||||
#include <unistd.h>
|
||||
#if (EIGEN_OS_QNX || (defined _GNU_SOURCE) || EIGEN_COMP_PGI || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
|
||||
#define EIGEN_HAS_POSIX_MEMALIGN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_HAS_POSIX_MEMALIGN
|
||||
#define EIGEN_HAS_POSIX_MEMALIGN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined EIGEN_VECTORIZE_SSE || defined EIGEN_VECTORIZE_AVX || defined EIGEN_VECTORIZE_AVX512
|
||||
#define EIGEN_HAS_MM_MALLOC 1
|
||||
#else
|
||||
#define EIGEN_HAS_MM_MALLOC 0
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
@@ -122,7 +100,7 @@ inline void handmade_aligned_free(void *ptr)
|
||||
|
||||
/** \internal
|
||||
* \brief Reallocates aligned memory.
|
||||
* Since we know that our handmade version is based on std::realloc
|
||||
* Since we know that our handmade version is based on std::malloc
|
||||
* we can use std::realloc to implement efficient reallocation.
|
||||
*/
|
||||
inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0)
|
||||
@@ -141,47 +119,6 @@ inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t =
|
||||
return aligned;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of generic aligned realloc (when no realloc can be used)***
|
||||
*****************************************************************************/
|
||||
|
||||
EIGEN_DEVICE_FUNC void* aligned_malloc(std::size_t size);
|
||||
EIGEN_DEVICE_FUNC void aligned_free(void *ptr);
|
||||
|
||||
/** \internal
|
||||
* \brief Reallocates aligned memory.
|
||||
* Allows reallocation with aligned ptr types. This implementation will
|
||||
* always create a new memory chunk and copy the old data.
|
||||
*/
|
||||
inline void* generic_aligned_realloc(void* ptr, size_t size, size_t old_size)
|
||||
{
|
||||
if (ptr==0)
|
||||
return aligned_malloc(size);
|
||||
|
||||
if (size==0)
|
||||
{
|
||||
aligned_free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* newptr = aligned_malloc(size);
|
||||
if (newptr == 0)
|
||||
{
|
||||
#ifdef EIGEN_HAS_ERRNO
|
||||
errno = ENOMEM; // according to the standard
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ptr != 0)
|
||||
{
|
||||
std::memcpy(newptr, ptr, (std::min)(size,old_size));
|
||||
aligned_free(ptr);
|
||||
}
|
||||
|
||||
return newptr;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of portable aligned versions of malloc/free/realloc ***
|
||||
*****************************************************************************/
|
||||
@@ -218,16 +155,11 @@ EIGEN_DEVICE_FUNC inline void* aligned_malloc(size_t size)
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
void *result;
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==0
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::malloc(size);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::malloc(size);
|
||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||
if(posix_memalign(&result, EIGEN_DEFAULT_ALIGN_BYTES, size)) result = 0;
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
result = _mm_malloc(size, EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
result = _aligned_malloc(size, EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==16
|
||||
eigen_assert((size<16 || (std::size_t(result)%16)==0) && "System's malloc returned an unaligned pointer. Compile with EIGEN_MALLOC_ALREADY_ALIGNED=0 to fallback to handmade alignd memory allocator.");
|
||||
#endif
|
||||
#else
|
||||
result = handmade_aligned_malloc(size);
|
||||
#endif
|
||||
@@ -241,48 +173,25 @@ EIGEN_DEVICE_FUNC inline void* aligned_malloc(size_t size)
|
||||
/** \internal Frees memory allocated with aligned_malloc. */
|
||||
EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
|
||||
{
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==0
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
std::free(ptr);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
std::free(ptr);
|
||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||
free(ptr);
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
_mm_free(ptr);
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
handmade_aligned_free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \brief Reallocates an aligned block of memory.
|
||||
* \throws std::bad_alloc on allocation failure
|
||||
**/
|
||||
* \internal
|
||||
* \brief Reallocates an aligned block of memory.
|
||||
* \throws std::bad_alloc on allocation failure
|
||||
*/
|
||||
inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(old_size);
|
||||
|
||||
void *result;
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==0
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::realloc(ptr,new_size);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::realloc(ptr,new_size);
|
||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||
result = generic_aligned_realloc(ptr,new_size,old_size);
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
// The defined(_mm_free) is just here to verify that this MSVC version
|
||||
// implements _mm_malloc/_mm_free based on the corresponding _aligned_
|
||||
// functions. This may not always be the case and we just try to be safe.
|
||||
#if EIGEN_OS_WIN_STRICT && defined(_mm_free)
|
||||
result = _aligned_realloc(ptr,new_size,EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#else
|
||||
result = generic_aligned_realloc(ptr,new_size,old_size);
|
||||
#endif
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
result = _aligned_realloc(ptr,new_size,EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#else
|
||||
result = handmade_aligned_realloc(ptr,new_size,old_size);
|
||||
#endif
|
||||
@@ -524,11 +433,11 @@ template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_align
|
||||
* \sa first_default_aligned()
|
||||
*/
|
||||
template<int Alignment, typename Scalar, typename Index>
|
||||
inline Index first_aligned(const Scalar* array, Index size)
|
||||
EIGEN_DEVICE_FUNC inline Index first_aligned(const Scalar* array, Index size)
|
||||
{
|
||||
static const Index ScalarSize = sizeof(Scalar);
|
||||
static const Index AlignmentSize = Alignment / ScalarSize;
|
||||
static const Index AlignmentMask = AlignmentSize-1;
|
||||
const Index ScalarSize = sizeof(Scalar);
|
||||
const Index AlignmentSize = Alignment / ScalarSize;
|
||||
const Index AlignmentMask = AlignmentSize-1;
|
||||
|
||||
if(AlignmentSize<=1)
|
||||
{
|
||||
@@ -544,14 +453,15 @@ inline Index first_aligned(const Scalar* array, Index size)
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::min<Index>( (AlignmentSize - (Index((std::size_t(array)/sizeof(Scalar))) & AlignmentMask)) & AlignmentMask, size);
|
||||
Index first = (AlignmentSize - (Index((std::size_t(array)/sizeof(Scalar))) & AlignmentMask)) & AlignmentMask;
|
||||
return (first < size) ? first : size;
|
||||
}
|
||||
}
|
||||
|
||||
/** \internal Returns the index of the first element of the array that is well aligned with respect the largest packet requirement.
|
||||
* \sa first_aligned(Scalar*,Index) and first_default_aligned(DenseBase<Derived>) */
|
||||
template<typename Scalar, typename Index>
|
||||
inline Index first_default_aligned(const Scalar* array, Index size)
|
||||
EIGEN_DEVICE_FUNC inline Index first_default_aligned(const Scalar* array, Index size)
|
||||
{
|
||||
typedef typename packet_traits<Scalar>::type DefaultPacketType;
|
||||
return first_aligned<unpacket_traits<DefaultPacketType>::alignment>(array, size);
|
||||
@@ -576,7 +486,12 @@ template<typename T> EIGEN_DEVICE_FUNC void smart_copy(const T* start, const T*
|
||||
|
||||
template<typename T> struct smart_copy_helper<T,true> {
|
||||
EIGEN_DEVICE_FUNC static inline void run(const T* start, const T* end, T* target)
|
||||
{ memcpy(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); }
|
||||
{
|
||||
std::ptrdiff_t size = std::ptrdiff_t(end)-std::ptrdiff_t(start);
|
||||
if(size==0) return;
|
||||
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||
memcpy(target, start, size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct smart_copy_helper<T,false> {
|
||||
@@ -594,7 +509,12 @@ template<typename T> void smart_memmove(const T* start, const T* end, T* target)
|
||||
|
||||
template<typename T> struct smart_memmove_helper<T,true> {
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{ std::memmove(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); }
|
||||
{
|
||||
std::ptrdiff_t size = std::ptrdiff_t(end)-std::ptrdiff_t(start);
|
||||
if(size==0) return;
|
||||
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||
std::memmove(target, start, size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct smart_memmove_helper<T,false> {
|
||||
@@ -784,7 +704,7 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
|
||||
* std::map< int, Vector3f > my_map_vec3;
|
||||
* \endcode
|
||||
*
|
||||
* \sa \ref TopicStlContainers.
|
||||
* \sa \blank \ref TopicStlContainers.
|
||||
*/
|
||||
template<class T>
|
||||
class aligned_allocator : public std::allocator<T>
|
||||
|
||||
@@ -147,6 +147,8 @@ template<typename T> struct numeric_limits
|
||||
static T epsilon() { return 0; }
|
||||
static T (max)() { assert(false && "Highest not supported for this type"); }
|
||||
static T (min)() { assert(false && "Lowest not supported for this type"); }
|
||||
static T infinity() { assert(false && "Infinity not supported for this type"); }
|
||||
static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); }
|
||||
};
|
||||
template<> struct numeric_limits<float>
|
||||
{
|
||||
@@ -156,6 +158,10 @@ template<> struct numeric_limits<float>
|
||||
static float (max)() { return CUDART_MAX_NORMAL_F; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float (min)() { return FLT_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float infinity() { return CUDART_INF_F; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static float quiet_NaN() { return CUDART_NAN_F; }
|
||||
};
|
||||
template<> struct numeric_limits<double>
|
||||
{
|
||||
@@ -165,6 +171,10 @@ template<> struct numeric_limits<double>
|
||||
static double (max)() { return DBL_MAX; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double (min)() { return DBL_MIN; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double infinity() { return CUDART_INF; }
|
||||
EIGEN_DEVICE_FUNC
|
||||
static double quiet_NaN() { return CUDART_NAN; }
|
||||
};
|
||||
template<> struct numeric_limits<int>
|
||||
{
|
||||
@@ -257,7 +267,7 @@ struct has_std_result_type {int a[2];};
|
||||
struct has_tr1_result {int a[3];};
|
||||
|
||||
template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
|
||||
struct unary_result_of_select {typedef ArgType type;};
|
||||
struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType>
|
||||
struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
|
||||
@@ -279,7 +289,7 @@ struct result_of<Func(ArgType)> {
|
||||
};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
|
||||
struct binary_result_of_select {typedef ArgType0 type;};
|
||||
struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
|
||||
|
||||
template<typename Func, typename ArgType0, typename ArgType1>
|
||||
struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
|
||||
@@ -326,6 +336,22 @@ class meta_sqrt
|
||||
template<int Y, int InfX, int SupX>
|
||||
class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
|
||||
|
||||
|
||||
/** \internal Computes the least common multiple of two positive integer A and B
|
||||
* at compile-time. It implements a naive algorithm testing all multiples of A.
|
||||
* It thus works better if A>=B.
|
||||
*/
|
||||
template<int A, int B, int K=1, bool Done = ((A*K)%B)==0>
|
||||
struct meta_least_common_multiple
|
||||
{
|
||||
enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
|
||||
};
|
||||
template<int A, int B, int K>
|
||||
struct meta_least_common_multiple<A,B,K,true>
|
||||
{
|
||||
enum { ret = A*K };
|
||||
};
|
||||
|
||||
/** \internal determines whether the product of two numeric types is allowed and what the return type is */
|
||||
template<typename T, typename U> struct scalar_product_traits
|
||||
{
|
||||
@@ -375,6 +401,12 @@ template<typename T> EIGEN_DEVICE_FUNC void swap(T &a, T &b) { T tmp = b; b =
|
||||
template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
|
||||
#endif
|
||||
|
||||
#if defined(__CUDA_ARCH__)
|
||||
using internal::device::numeric_limits;
|
||||
#else
|
||||
using std::numeric_limits;
|
||||
#endif
|
||||
|
||||
// Integer division with rounding up.
|
||||
// T is assumed to be an integer type with a>=0, and b>0
|
||||
template<typename T>
|
||||
|
||||
@@ -9,6 +9,16 @@
|
||||
#elif defined __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined __NVCC__
|
||||
// Don't reenable the diagnostic messages, as it turns out these messages need
|
||||
// to be disabled at the point of the template instantiation (i.e the user code)
|
||||
// otherwise they'll be triggeredby nvcc.
|
||||
// #pragma diag_default code_is_unreachable
|
||||
// #pragma diag_default initialization_not_reachable
|
||||
// #pragma diag_default 2651
|
||||
// #pragma diag_default 2653
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_WARNINGS_DISABLED
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#ifndef EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (EIGEN_COMP_MSVC >= 1600)
|
||||
#if __has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600)
|
||||
|
||||
// if native static_assert is enabled, let's use it
|
||||
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
||||
@@ -50,6 +50,7 @@
|
||||
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
|
||||
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
|
||||
THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE,
|
||||
OUT_OF_RANGE_ACCESS,
|
||||
YOU_MADE_A_PROGRAMMING_MISTAKE,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT,
|
||||
EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE,
|
||||
@@ -96,7 +97,8 @@
|
||||
STORAGE_LAYOUT_DOES_NOT_MATCH,
|
||||
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE,
|
||||
THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS,
|
||||
MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY
|
||||
MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY,
|
||||
THIS_TYPE_IS_NOT_SUPPORTED
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
|
||||
/**
|
||||
* \brief The Index type as used for the API.
|
||||
* \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
|
||||
* \sa \ref TopicPreprocessorDirectives, StorageIndex.
|
||||
* \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
|
||||
*/
|
||||
|
||||
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
|
||||
@@ -390,9 +390,9 @@ struct transfer_constness
|
||||
* a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
|
||||
* many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
|
||||
*
|
||||
* \param T the type of the expression being nested.
|
||||
* \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
|
||||
* \param PlainObject the type of the temporary if needed.
|
||||
* \tparam T the type of the expression being nested.
|
||||
* \tparam n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
|
||||
* \tparam PlainObject the type of the temporary if needed.
|
||||
*/
|
||||
template<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval
|
||||
{
|
||||
@@ -466,17 +466,17 @@ struct special_scalar_op_base : public BaseType
|
||||
template<typename Derived,typename Scalar,typename OtherScalar, typename BaseType>
|
||||
struct special_scalar_op_base<Derived,Scalar,OtherScalar,BaseType,true> : public BaseType
|
||||
{
|
||||
const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
|
||||
const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, const Derived>
|
||||
operator*(const OtherScalar& scalar) const
|
||||
{
|
||||
#ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
|
||||
EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
|
||||
#endif
|
||||
return CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
|
||||
return CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, const Derived>
|
||||
(*static_cast<const Derived*>(this), scalar_multiple2_op<Scalar,OtherScalar>(scalar));
|
||||
}
|
||||
|
||||
inline friend const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
|
||||
inline friend const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, const Derived>
|
||||
operator*(const OtherScalar& scalar, const Derived& matrix)
|
||||
{
|
||||
#ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
|
||||
@@ -485,13 +485,13 @@ struct special_scalar_op_base<Derived,Scalar,OtherScalar,BaseType,true> : publi
|
||||
return static_cast<const special_scalar_op_base&>(matrix).operator*(scalar);
|
||||
}
|
||||
|
||||
const CwiseUnaryOp<scalar_quotient2_op<Scalar,OtherScalar>, Derived>
|
||||
const CwiseUnaryOp<scalar_quotient2_op<Scalar,OtherScalar>, const Derived>
|
||||
operator/(const OtherScalar& scalar) const
|
||||
{
|
||||
#ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
|
||||
EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
|
||||
#endif
|
||||
return CwiseUnaryOp<scalar_quotient2_op<Scalar,OtherScalar>, Derived>
|
||||
return CwiseUnaryOp<scalar_quotient2_op<Scalar,OtherScalar>, const Derived>
|
||||
(*static_cast<const Derived*>(this), scalar_quotient2_op<Scalar,OtherScalar>(scalar));
|
||||
}
|
||||
};
|
||||
@@ -526,22 +526,21 @@ template <typename A> struct promote_storage_type<const A, A>
|
||||
* the functor.
|
||||
* The default rules are as follows:
|
||||
* \code
|
||||
* A op A -> A
|
||||
* A op dense -> dense
|
||||
* dense op B -> dense
|
||||
* A * dense -> A
|
||||
* dense * B -> B
|
||||
* A op A -> A
|
||||
* A op dense -> dense
|
||||
* dense op B -> dense
|
||||
* sparse op dense -> sparse
|
||||
* dense op sparse -> sparse
|
||||
* \endcode
|
||||
*/
|
||||
template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
|
||||
|
||||
template <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; };
|
||||
template <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; };
|
||||
template <typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<Dense,Dense,scalar_product_op<ScalarA,ScalarB> > { typedef Dense ret; };
|
||||
template <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; };
|
||||
template <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; };
|
||||
template <typename A, typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<A,Dense,scalar_product_op<ScalarA,ScalarB> > { typedef A ret; };
|
||||
template <typename B, typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<Dense,B,scalar_product_op<ScalarA,ScalarB> > { typedef B ret; };
|
||||
template <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; };
|
||||
template <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; };
|
||||
template <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; };
|
||||
template <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; };
|
||||
template <typename Functor> struct cwise_promote_storage_type<Sparse,Dense,Functor> { typedef Sparse ret; };
|
||||
template <typename Functor> struct cwise_promote_storage_type<Dense,Sparse,Functor> { typedef Sparse ret; };
|
||||
|
||||
/** \internal Specify the "storage kind" of multiplying an expression of kind A with kind B.
|
||||
* The template parameter ProductTag permits to specialize the resulting storage kind wrt to
|
||||
@@ -575,7 +574,7 @@ template <int ProductTag> struct product_promote_storage_type<Dense,
|
||||
template <int ProductTag> struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { typedef Dense ret; };
|
||||
|
||||
/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type.
|
||||
* \param Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType.
|
||||
* \tparam Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType.
|
||||
*/
|
||||
template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
|
||||
struct plain_row_type
|
||||
|
||||
Reference in New Issue
Block a user