Update Eigen to commit:dceb779ecd822f55b4ae78f760371b0e08a889f2
CHANGELOG
=========
dceb779ec - Fix test for pow with mixed integer types. We do not convert the exponent if it is an integer type.
afc014f1b - Allow mixed types for pow(), as long as the exponent is exactly representable in the base type.
b2c82a934 - Remove bad skew_symmetric_matrix3 test.
e8a2aa24a - Fix a couple of issues with unary pow():
07d075995 - [ROCm] Fix for sparse matrix related breakage on ROCm.
fb212c745 - Fix g++-6 constexpr and c++20 constexpr build errors.
ec9c7163a - Feature/skew symmetric matrix3
311ba66f7 - Fix realloc for non-trivial types.
3c37dd2a1 - Tweak bound for pow to account for floating-point types.
f9dfda28a - Add missing comparison operators for GPU packets.
242325eca - Remove unused variable.
133498c32 - Add constexpr, test for C++14 constexpr.
69f50e3a6 - Adjust overflow threshold bound for pow tests.
3e44f960e - Reduce compiler warnings for tests.
b7e21d4e3 - Call check_that_malloc_is_allowed() in aligned_realloc()
6e83e906c - fix typo in doc/TutorialSparse.dox
525f06667 - fixed msvc compilation error in GeneralizedEigenSolver.h
f241a2c18 - Add asserts for index-out-of-bounds in IndexedView.
f5364331e - Fix some cmake issues.
d816044b6 - Fix mixingtypes tests.
94cc83faa - 2 typos fix in the 3rd table.
30c42222a - Fix some test build errors in new unary pow.
bd393e15c - Vectorize acos, asin, and atan for float.
e5af9f87f - Vectorize pow for integer base / exponent types
8acbf5c11 - re-enable pow for complex types
7064ed134 - Specialize psign<Packet8i> for AVX2, don't vectorize psign<bool>.
98e51c9e2 - Avoid undefined behavior in array_cwise test due to signed integer overflow
a7c1cac18 - Fix GeneralizedEigenSolver::info() and Asserts
714678fc6 - Add missing ptr in realloc call.
b2a13c9dd - Sparse Core: Replace malloc/free with conditional_aligned
6aad0f821 - Fix psign for unsigned integer types, such as bool.
1a09defce - Protect new pblend implementation with EIGEN_VECTORIZE_AVX2
7c67dc67a - Use proper double word division algorithm for pow<double>. Gives 11-15% speedup.
7a3b667c4 - Add support for AVX512-FP16 for vectorizing half precision math
76a669fb4 - add fixed power unary operation
39fcc8979 - Removed unnecessary checks for FP16C
2f7cce2dd - [SYCL] Fix some SYCL tests
27367017b - Disable bad "deprecated warning" edge-case in BDCSVD
b8e93bf58 - Eliminate bool bitwise warnings.
66ea0c09f - Don't double-define Half functions on aarch64
97e0784dc - Vectorize the sign operator in Eigen.
be20207d1 - Fix vectorized Jacobi Rotation
7a87ed1b6 - Fix code and unit test for a few corner cases in vectorized pow()
9e0afe0f0 - Fix non-VSX PowerPC build
84a9d6fac - Fix use of Packet2d type for non-VSX.
ce60a7be8 - Partial Packet support for GEMM real-only (PowerPC). Also fix compilation warnings & errors for some conditions in new API.
5a1c7807e - Fix inner iterator for sparse block.
39d22ef46 - Fix flaky packetmath_1 test.
7896c7dc6 - Use numext::sqrt in ConjugateGradient.
e618c4a5e - Improve pblend AVX implementation
ef4654bae - Add true determinant to QR and it's variants
b7668c037 - Avoid including <sstream> with EIGEN_NO_IO
7dd3dda3d - Updated AccelerateSupport documentation after PR 966.
69714ff61 - Add Sparse Subset of Matrix Inverse
PiperOrigin-RevId: 474559050
Change-Id: Ife8edf526089b3bc65e391c975c8c852489e7225
diff --git a/Eigen/AccelerateSupport b/Eigen/AccelerateSupport
index 0929501..8cee7ac 100644
--- a/Eigen/AccelerateSupport
+++ b/Eigen/AccelerateSupport
@@ -33,17 +33,14 @@
* the include paths, and your binary must be linked to the Accelerate framework.
* The Accelerate library is only available on Apple hardware.
*
- * Note that many of the algorithms require additional information about your
- * matrices. This can be provided by setting the UpLo template argument when
- * defining the factorization class. For example, the following creates an
- * LDLT factorization where your matrix is symmetric and uses the lower
- * triangle:
+ * Note that many of the algorithms can be influenced by the UpLo template
+ * argument. All matrices are assumed to be symmetric. For example, the following
+ * creates an LDLT factorization where your matrix is symmetric (implicit) and
+ * uses the lower triangle:
*
* \code
- * AccelerateLDLT<SparseMatrix<float>, Lower | Symmetric> ldlt;
+ * AccelerateLDLT<SparseMatrix<float>, Lower> ldlt;
* \endcode
- *
- * Failure to do so may result in your application crashing.
*/
#include "src/AccelerateSupport/AccelerateSupport.h"
diff --git a/Eigen/Core b/Eigen/Core
index 63b9850..623d735 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -84,8 +84,8 @@
#include <cmath>
#include <cassert>
#include <functional>
-#include <sstream>
#ifndef EIGEN_NO_IO
+ #include <sstream>
#include <iosfwd>
#endif
#include <cstring>
@@ -178,6 +178,9 @@
#include "src/Core/arch/Default/GenericPacketMathFunctionsFwd.h"
#if defined EIGEN_VECTORIZE_AVX512
+ #if defined EIGEN_VECTORIZE_AVX512FP16
+ #include "src/Core/arch/AVX512/PacketMathFP16.h"
+ #endif
#include "src/Core/arch/SSE/PacketMath.h"
#include "src/Core/arch/SSE/TypeCasting.h"
#include "src/Core/arch/SSE/Complex.h"
@@ -318,6 +321,7 @@
#include "src/Core/DiagonalMatrix.h"
#include "src/Core/Diagonal.h"
#include "src/Core/DiagonalProduct.h"
+#include "src/Core/SkewSymmetricMatrix3.h"
#include "src/Core/Redux.h"
#include "src/Core/Visitor.h"
#include "src/Core/Fuzzy.h"
@@ -350,7 +354,7 @@
#include "src/Core/CoreIterators.h"
#include "src/Core/ConditionEstimator.h"
-#if defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
+#if defined(EIGEN_VECTORIZE_VSX)
#include "src/Core/arch/AltiVec/MatrixProduct.h"
#elif defined EIGEN_VECTORIZE_NEON
#include "src/Core/arch/NEON/GeneralBlockPanelKernel.h"
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h
index 7be8971..ee82214 100644
--- a/Eigen/src/Core/Array.h
+++ b/Eigen/src/Core/Array.h
@@ -130,7 +130,7 @@
*
* \sa resize(Index,Index)
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Array() : Base()
{
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h
index 28397e5..70be252 100644
--- a/Eigen/src/Core/ArrayBase.h
+++ b/Eigen/src/Core/ArrayBase.h
@@ -148,7 +148,7 @@
* \sa MatrixBase::array() */
EIGEN_DEVICE_FUNC
MatrixWrapper<Derived> matrix() { return MatrixWrapper<Derived>(derived()); }
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const MatrixWrapper<const Derived> matrix() const { return MatrixWrapper<const Derived>(derived()); }
// template<typename Dest>
diff --git a/Eigen/src/Core/ArrayWrapper.h b/Eigen/src/Core/ArrayWrapper.h
index e65b8fb..34d4963 100644
--- a/Eigen/src/Core/ArrayWrapper.h
+++ b/Eigen/src/Core/ArrayWrapper.h
@@ -59,7 +59,7 @@
using Base::coeffRef;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
@@ -89,10 +89,10 @@
}
template<typename Dest>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline void evalTo(Dest& dst) const { dst = m_expression; }
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const internal::remove_all_t<NestedExpressionType>&
nestedExpression() const
{
@@ -157,7 +157,7 @@
using Base::coeffRef;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
@@ -186,7 +186,7 @@
return m_expression.coeffRef(index);
}
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const internal::remove_all_t<NestedExpressionType>&
nestedExpression() const
{
diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h
index dc716d3..7f988ec 100644
--- a/Eigen/src/Core/Assign.h
+++ b/Eigen/src/Core/Assign.h
@@ -63,7 +63,7 @@
template<typename Derived>
template <typename OtherDerived>
EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
+EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
{
internal::call_assignment(derived(), other.derived());
return derived();
@@ -71,7 +71,7 @@
template<typename Derived>
template <typename OtherDerived>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
{
internal::call_assignment(derived(), other.derived());
diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h
index f9dc7a1..fe548b5 100644
--- a/Eigen/src/Core/AssignEvaluator.h
+++ b/Eigen/src/Core/AssignEvaluator.h
@@ -208,7 +208,7 @@
inner = Index % DstXprType::InnerSizeAtCompileTime
};
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
kernel.assignCoeffByOuterInner(outer, inner);
copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Index+1, Stop>::run(kernel);
@@ -218,13 +218,13 @@
template<typename Kernel, int Stop>
struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Stop, Stop>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&) { }
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel&) { }
};
template<typename Kernel, int Index_, int Stop>
struct copy_using_evaluator_DefaultTraversal_InnerUnrolling
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel, Index outer)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel, Index outer)
{
kernel.assignCoeffByOuterInner(outer, Index_);
copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, Index_+1, Stop>::run(kernel, outer);
@@ -234,7 +234,7 @@
template<typename Kernel, int Stop>
struct copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, Stop, Stop>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&, Index) { }
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel&, Index) { }
};
/***********************
@@ -276,7 +276,7 @@
DstAlignment = Kernel::AssignmentTraits::DstAlignment
};
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
kernel.template assignPacketByOuterInner<DstAlignment, SrcAlignment, PacketType>(outer, inner);
enum { NextIndex = Index + unpacket_traits<PacketType>::size };
@@ -287,7 +287,7 @@
template<typename Kernel, int Stop>
struct copy_using_evaluator_innervec_CompleteUnrolling<Kernel, Stop, Stop>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&) { }
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel&) { }
};
template<typename Kernel, int Index_, int Stop, int SrcAlignment, int DstAlignment>
@@ -327,7 +327,7 @@
template<typename Kernel, int Unrolling>
struct dense_assignment_loop<Kernel, AllAtOnceTraversal, Unrolling>
{
- EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE run(Kernel& /*kernel*/)
+ EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE EIGEN_CONSTEXPR run(Kernel& /*kernel*/)
{
EIGEN_STATIC_ASSERT(int(Kernel::DstEvaluatorType::XprType::SizeAtCompileTime) == 0,
EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT)
@@ -341,7 +341,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, DefaultTraversal, NoUnrolling>
{
- EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE EIGEN_CONSTEXPR run(Kernel &kernel)
{
for(Index outer = 0; outer < kernel.outerSize(); ++outer) {
for(Index inner = 0; inner < kernel.innerSize(); ++inner) {
@@ -354,7 +354,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, DefaultTraversal, CompleteUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, 0, DstXprType::SizeAtCompileTime>::run(kernel);
@@ -364,7 +364,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, DefaultTraversal, InnerUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
@@ -387,7 +387,7 @@
{
// if IsAligned = true, then do nothing
template <typename Kernel>
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&, Index, Index) {}
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel&, Index, Index) {}
};
template <>
@@ -403,7 +403,7 @@
Index end)
#else
template <typename Kernel>
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel,
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel,
Index start,
Index end)
#endif
@@ -416,7 +416,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, LinearVectorizedTraversal, NoUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
const Index size = kernel.size();
typedef typename Kernel::Scalar Scalar;
@@ -444,7 +444,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, LinearVectorizedTraversal, CompleteUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
typedef typename Kernel::PacketType PacketType;
@@ -470,7 +470,7 @@
SrcAlignment = Kernel::AssignmentTraits::SrcAlignment,
DstAlignment = Kernel::AssignmentTraits::DstAlignment
};
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
const Index innerSize = kernel.innerSize();
const Index outerSize = kernel.outerSize();
@@ -484,7 +484,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, InnerVectorizedTraversal, CompleteUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
copy_using_evaluator_innervec_CompleteUnrolling<Kernel, 0, DstXprType::SizeAtCompileTime>::run(kernel);
@@ -494,7 +494,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, InnerVectorizedTraversal, InnerUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
typedef typename Kernel::AssignmentTraits Traits;
@@ -512,7 +512,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, LinearTraversal, NoUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
const Index size = kernel.size();
for(Index i = 0; i < size; ++i)
@@ -523,7 +523,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, LinearTraversal, CompleteUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
copy_using_evaluator_LinearTraversal_CompleteUnrolling<Kernel, 0, DstXprType::SizeAtCompileTime>::run(kernel);
@@ -537,7 +537,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, NoUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::Scalar Scalar;
typedef typename Kernel::PacketType PacketType;
@@ -585,7 +585,7 @@
template<typename Kernel>
struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, InnerUnrolling>
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void run(Kernel &kernel)
{
typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
typedef typename Kernel::PacketType PacketType;
@@ -630,7 +630,7 @@
typedef typename AssignmentTraits::PacketType PacketType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
generic_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
: m_dst(dst), m_src(src), m_functor(func), m_dstExpr(dstExpr)
{
@@ -650,19 +650,19 @@
EIGEN_DEVICE_FUNC const SrcEvaluatorType& srcEvaluator() const EIGEN_NOEXCEPT { return m_src; }
/// Assign src(row,col) to dst(row,col) through the assignment functor.
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void assignCoeff(Index row, Index col)
{
m_functor.assignCoeff(m_dst.coeffRef(row,col), m_src.coeff(row,col));
}
/// \sa assignCoeff(Index,Index)
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index index)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void assignCoeff(Index index)
{
m_functor.assignCoeff(m_dst.coeffRef(index), m_src.coeff(index));
}
/// \sa assignCoeff(Index,Index)
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeffByOuterInner(Index outer, Index inner)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void assignCoeffByOuterInner(Index outer, Index inner)
{
Index row = rowIndexByOuterInner(outer, inner);
Index col = colIndexByOuterInner(outer, inner);
@@ -671,7 +671,7 @@
template<int StoreMode, int LoadMode, typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacket(Index row, Index col)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void assignPacket(Index row, Index col)
{
m_functor.template assignPacket<StoreMode>(&m_dst.coeffRef(row,col), m_src.template packet<LoadMode,PacketType>(row,col));
}
@@ -683,14 +683,14 @@
}
template<int StoreMode, int LoadMode, typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacketByOuterInner(Index outer, Index inner)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void assignPacketByOuterInner(Index outer, Index inner)
{
Index row = rowIndexByOuterInner(outer, inner);
Index col = colIndexByOuterInner(outer, inner);
assignPacket<StoreMode,LoadMode,PacketType>(row, col);
}
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rowIndexByOuterInner(Index outer, Index inner)
{
typedef typename DstEvaluatorType::ExpressionTraits Traits;
return int(Traits::RowsAtCompileTime) == 1 ? 0
@@ -699,7 +699,7 @@
: inner;
}
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index colIndexByOuterInner(Index outer, Index inner)
{
typedef typename DstEvaluatorType::ExpressionTraits Traits;
return int(Traits::ColsAtCompileTime) == 1 ? 0
@@ -747,7 +747,7 @@
***************************************************************************/
template<typename DstXprType,typename SrcXprType, typename Functor>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const Functor &/*func*/)
{
EIGEN_ONLY_USED_FOR_DEBUG(dst);
@@ -756,7 +756,7 @@
}
template<typename DstXprType,typename SrcXprType, typename T1, typename T2>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const internal::assign_op<T1,T2> &/*func*/)
{
Index dstRows = src.rows();
@@ -767,7 +767,7 @@
}
template<typename DstXprType, typename SrcXprType, typename Functor>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
{
typedef evaluator<DstXprType> DstEvaluatorType;
typedef evaluator<SrcXprType> SrcEvaluatorType;
@@ -831,13 +831,13 @@
// does not has to bother about these annoying details.
template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment(Dst& dst, const Src& src)
{
call_assignment(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
}
template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment(const Dst& dst, const Src& src)
{
call_assignment(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
@@ -845,7 +845,7 @@
// Deal with "assume-aliasing"
template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment(Dst& dst, const Src& src, const Func& func, std::enable_if_t< evaluator_assume_aliasing<Src>::value, void*> = 0)
{
typename plain_matrix_type<Src>::type tmp(src);
@@ -853,7 +853,7 @@
}
template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment(Dst& dst, const Src& src, const Func& func, std::enable_if_t<!evaluator_assume_aliasing<Src>::value, void*> = 0)
{
call_assignment_no_alias(dst, src, func);
@@ -862,7 +862,7 @@
// by-pass "assume-aliasing"
// When there is no aliasing, we require that 'dst' has been properly resized
template<typename Dst, template <typename> class StorageBase, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment(NoAlias<Dst,StorageBase>& dst, const Src& src, const Func& func)
{
call_assignment_no_alias(dst.expression(), src, func);
@@ -870,7 +870,7 @@
template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment_no_alias(Dst& dst, const Src& src, const Func& func)
{
enum {
@@ -912,14 +912,14 @@
}
template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment_no_alias(Dst& dst, const Src& src)
{
call_assignment_no_alias(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
}
template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment_no_alias_no_transpose(Dst& dst, const Src& src, const Func& func)
{
// TODO check whether this is the right place to perform these checks:
@@ -930,14 +930,14 @@
Assignment<Dst,Src,Func>::run(dst, src, func);
}
template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_assignment_no_alias_no_transpose(Dst& dst, const Src& src)
{
call_assignment_no_alias_no_transpose(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
}
// forward declaration
-template<typename Dst, typename Src> void check_for_aliasing(const Dst &dst, const Src &src);
+template<typename Dst, typename Src> EIGEN_CONSTEXPR void check_for_aliasing(const Dst &dst, const Src &src);
// Generic Dense to Dense assignment
// Note that the last template argument "Weak" is needed to make it possible to perform
@@ -945,7 +945,7 @@
template< typename DstXprType, typename SrcXprType, typename Functor, typename Weak>
struct Assignment<DstXprType, SrcXprType, Functor, Dense2Dense, Weak>
{
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
{
#ifndef EIGEN_NO_DEBUG
diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h
index 19c4b68..24b96c7 100644
--- a/Eigen/src/Core/Block.h
+++ b/Eigen/src/Core/Block.h
@@ -116,7 +116,7 @@
/** Column or Row constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Block(XprType& xpr, Index i) : Impl(xpr,i)
{
eigen_assert( (i>=0) && (
@@ -126,7 +126,7 @@
/** Fixed-size constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Block(XprType& xpr, Index startRow, Index startCol)
: Impl(xpr, startRow, startCol)
{
@@ -137,7 +137,7 @@
/** Dynamic-size constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Block(XprType& xpr,
Index startRow, Index startCol,
Index blockRows, Index blockCols)
@@ -161,9 +161,9 @@
public:
typedef Impl Base;
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
: Impl(xpr, startRow, startCol, blockRows, blockCols) {}
};
@@ -186,7 +186,7 @@
/** Column or Row constructor
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline BlockImpl_dense(XprType& xpr, Index i)
: m_xpr(xpr),
// It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
@@ -201,7 +201,7 @@
/** Fixed-size constructor
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
: m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
m_blockRows(BlockRows), m_blockCols(BlockCols)
@@ -209,7 +209,7 @@
/** Dynamic-size constructor
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline BlockImpl_dense(XprType& xpr,
Index startRow, Index startCol,
Index blockRows, Index blockCols)
@@ -217,8 +217,8 @@
m_blockRows(blockRows), m_blockCols(blockCols)
{}
- EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); }
- EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const { return m_blockRows.value(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const { return m_blockCols.value(); }
EIGEN_DEVICE_FUNC
inline Scalar& coeffRef(Index rowId, Index colId)
@@ -296,7 +296,7 @@
EIGEN_DEVICE_FUNC inline Index outerStride() const;
#endif
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const internal::remove_all_t<XprTypeNested>& nestedExpression() const
{
return m_xpr;
@@ -344,7 +344,7 @@
/** Column or Row constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
BlockImpl_dense(XprType& xpr, Index i)
: Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
|| ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
@@ -352,31 +352,37 @@
BlockCols==1 ? 1 : xpr.cols()),
m_xpr(xpr),
m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
- m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)
+ m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
+ m_outerStride(internal::traits<BlockType>::HasSameStorageOrderAsXprType
+ ? m_xpr.outerStride()
+ : m_xpr.innerStride())
{
- init();
}
/** Fixed-size constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
- m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
+ m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
+ m_outerStride(internal::traits<BlockType>::HasSameStorageOrderAsXprType
+ ? m_xpr.outerStride()
+ : m_xpr.innerStride())
{
- init();
}
/** Dynamic-size constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
BlockImpl_dense(XprType& xpr,
Index startRow, Index startCol,
Index blockRows, Index blockCols)
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
- m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
+ m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
+ m_outerStride(internal::traits<BlockType>::HasSameStorageOrderAsXprType
+ ? m_xpr.outerStride()
+ : m_xpr.innerStride())
{
- init();
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
@@ -422,21 +428,15 @@
/** \internal used by allowAligned() */
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
- : Base(data, blockRows, blockCols), m_xpr(xpr)
+ : Base(data, blockRows, blockCols), m_xpr(xpr),
+ m_outerStride(internal::traits<BlockType>::HasSameStorageOrderAsXprType
+ ? m_xpr.outerStride()
+ : m_xpr.innerStride())
{
- init();
}
#endif
protected:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- void init()
- {
- m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
- ? m_xpr.outerStride()
- : m_xpr.innerStride();
- }
-
XprTypeNested m_xpr;
const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
diff --git a/Eigen/src/Core/BooleanRedux.h b/Eigen/src/Core/BooleanRedux.h
index 20e5bd9..80d96ba 100644
--- a/Eigen/src/Core/BooleanRedux.h
+++ b/Eigen/src/Core/BooleanRedux.h
@@ -25,7 +25,7 @@
j = (UnrollCount-1) % InnerSize
};
- EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static inline bool run(const Derived &mat)
{
return all_unroller<Derived, UnrollCount-1, InnerSize>::run(mat) && mat.coeff(IsRowMajor ? i : j, IsRowMajor ? j : i);
}
@@ -34,13 +34,13 @@
template<typename Derived, int InnerSize>
struct all_unroller<Derived, 0, InnerSize>
{
- EIGEN_DEVICE_FUNC static inline bool run(const Derived &/*mat*/) { return true; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static inline bool run(const Derived &/*mat*/) { return true; }
};
template<typename Derived, int InnerSize>
struct all_unroller<Derived, Dynamic, InnerSize>
{
- EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static inline bool run(const Derived &) { return false; }
};
template<typename Derived, int UnrollCount, int InnerSize>
@@ -52,7 +52,7 @@
j = (UnrollCount-1) % InnerSize
};
- EIGEN_DEVICE_FUNC static inline bool run(const Derived &mat)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static inline bool run(const Derived &mat)
{
return any_unroller<Derived, UnrollCount-1, InnerSize>::run(mat) || mat.coeff(IsRowMajor ? i : j, IsRowMajor ? j : i);
}
@@ -61,13 +61,13 @@
template<typename Derived, int InnerSize>
struct any_unroller<Derived, 0, InnerSize>
{
- EIGEN_DEVICE_FUNC static inline bool run(const Derived & /*mat*/) { return false; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static inline bool run(const Derived & /*mat*/) { return false; }
};
template<typename Derived, int InnerSize>
struct any_unroller<Derived, Dynamic, InnerSize>
{
- EIGEN_DEVICE_FUNC static inline bool run(const Derived &) { return false; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static inline bool run(const Derived &) { return false; }
};
} // end namespace internal
@@ -80,7 +80,7 @@
* \sa any(), Cwise::operator<()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::all() const
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline bool DenseBase<Derived>::all() const
{
typedef internal::evaluator<Derived> Evaluator;
enum {
@@ -104,7 +104,7 @@
* \sa all()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline bool DenseBase<Derived>::any() const
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline bool DenseBase<Derived>::any() const
{
typedef internal::evaluator<Derived> Evaluator;
enum {
@@ -128,7 +128,7 @@
* \sa all(), any()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline Eigen::Index DenseBase<Derived>::count() const
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Eigen::Index DenseBase<Derived>::count() const
{
return derived().template cast<bool>().template cast<Index>().sum();
}
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index 1729507..4022d7b 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -92,7 +92,7 @@
struct evaluator : public unary_evaluator<T>
{
typedef unary_evaluator<T> Base;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const T& xpr) : Base(xpr) {}
};
@@ -102,7 +102,7 @@
struct evaluator<const T>
: evaluator<T>
{
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const T& xpr) : evaluator<T>(xpr) {}
};
@@ -120,8 +120,10 @@
// noncopyable:
// Don't make this class inherit noncopyable as this kills EBO (Empty Base Optimization)
// and make complex evaluator much larger than then should do.
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE evaluator_base() {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~evaluator_base() {}
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR evaluator_base() = default;
+#if defined(EIGEN_GPUCC)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ~evaluator_base() = default;
+#endif
private:
EIGEN_DEVICE_FUNC evaluator_base(const evaluator_base&);
EIGEN_DEVICE_FUNC const evaluator_base& operator=(const evaluator_base&);
@@ -137,7 +139,7 @@
// this helper permits to completely eliminate m_outerStride if it is known at compiletime.
template<typename Scalar,int OuterStride> class plainobjectbase_evaluator_data {
public:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr)
{
#ifndef EIGEN_INTERNAL_DEBUGGING
@@ -152,9 +154,10 @@
template<typename Scalar> class plainobjectbase_evaluator_data<Scalar,Dynamic> {
public:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride) : data(ptr), m_outerStride(outerStride) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
+ plainobjectbase_evaluator_data(const Scalar* ptr, Index outerStride)
+ : data(ptr), m_outerStride(outerStride) {}
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index outerStride() const { return m_outerStride; }
const Scalar *data;
protected:
@@ -186,21 +189,21 @@
: RowsAtCompileTime
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
evaluator()
: m_d(0,OuterStrideAtCompileTime)
{
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const PlainObjectType& m)
- : m_d(m.data(),IsVectorAtCompileTime ? 0 : m.outerStride())
+ : m_d(m.data(), IsVectorAtCompileTime ? 0 : m.outerStride())
{
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index col) const
{
if (IsRowMajor)
@@ -209,13 +212,13 @@
return m_d.data[row + col * m_d.outerStride()];
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return m_d.data[index];
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar& coeffRef(Index row, Index col)
{
if (IsRowMajor)
@@ -224,7 +227,7 @@
return const_cast<Scalar*>(m_d.data)[row + col * m_d.outerStride()];
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar& coeffRef(Index index)
{
return const_cast<Scalar*>(m_d.data)[index];
@@ -277,10 +280,10 @@
{
typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
evaluator() {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const XprType& m)
: evaluator<PlainObjectBase<XprType> >(m)
{ }
@@ -292,10 +295,10 @@
{
typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
evaluator() {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const XprType& m)
: evaluator<PlainObjectBase<XprType> >(m)
{ }
@@ -315,31 +318,31 @@
Alignment = evaluator<ArgType>::Alignment
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
typedef typename XprType::Scalar Scalar;
typedef typename XprType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index col) const
{
return m_argImpl.coeff(col, row);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return m_argImpl.coeff(index);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar& coeffRef(Index row, Index col)
{
return m_argImpl.coeffRef(col, row);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename XprType::Scalar& coeffRef(Index index)
{
return m_argImpl.coeffRef(index);
@@ -399,7 +402,7 @@
template<typename Scalar,typename NullaryOp>
struct nullary_wrapper<Scalar,NullaryOp,true,false,false>
{
- template <typename IndexType>
+ template <typename IndexType> EIGEN_CONSTEXPR
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType=0, IndexType=0) const { return op(); }
template <typename T, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType=0, IndexType=0) const { return op.template packetOp<T>(); }
};
@@ -408,7 +411,7 @@
struct nullary_wrapper<Scalar,NullaryOp,false,false,true>
{
template <typename IndexType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i, IndexType j=0) const { return op(i,j); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Scalar operator()(const NullaryOp& op, IndexType i, IndexType j=0) const { return op(i,j); }
template <typename T, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i, IndexType j=0) const { return op.template packetOp<T>(i,j); }
};
@@ -513,7 +516,7 @@
Alignment = AlignedMax
};
- EIGEN_DEVICE_FUNC explicit evaluator(const XprType& n)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR explicit evaluator(const XprType& n)
: m_functor(n.functor()), m_wrapper()
{
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
@@ -522,14 +525,14 @@
typedef typename XprType::CoeffReturnType CoeffReturnType;
template <typename IndexType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(IndexType row, IndexType col) const
{
return m_wrapper(m_functor, row, col);
}
template <typename IndexType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(IndexType index) const
{
return m_wrapper(m_functor,index);
@@ -570,7 +573,7 @@
Alignment = evaluator<ArgType>::Alignment
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit unary_evaluator(const XprType& op) : m_d(op)
{
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
@@ -579,13 +582,13 @@
typedef typename XprType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index col) const
{
return m_d.func()(m_d.argImpl.coeff(row, col));
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return m_d.func()(m_d.argImpl.coeff(index));
@@ -610,9 +613,9 @@
// this helper permits to completely eliminate the functor if it is empty
struct Data
{
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const UnaryOp& func() const { return op; }
UnaryOp op;
evaluator<ArgType> argImpl;
@@ -727,7 +730,7 @@
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const XprType& xpr) : Base(xpr) {}
};
@@ -756,7 +759,7 @@
Alignment = plain_enum_min(evaluator<Lhs>::Alignment, evaluator<Rhs>::Alignment)
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit binary_evaluator(const XprType& xpr) : m_d(xpr)
{
EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
@@ -765,13 +768,13 @@
typedef typename XprType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index col) const
{
return m_d.func()(m_d.lhsImpl.coeff(row, col), m_d.rhsImpl.coeff(row, col));
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return m_d.func()(m_d.lhsImpl.coeff(index), m_d.rhsImpl.coeff(index));
@@ -798,9 +801,9 @@
// this helper permits to completely eliminate the functor if it is empty
struct Data
{
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Data(const XprType& xpr) : op(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const BinaryOp& func() const { return op; }
BinaryOp op;
evaluator<Lhs> lhsImpl;
@@ -853,7 +856,7 @@
return m_d.func()(m_d.argImpl.coeffRef(row, col));
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar& coeffRef(Index index)
{
return m_d.func()(m_d.argImpl.coeffRef(index));
@@ -864,9 +867,9 @@
// this helper permits to completely eliminate the functor if it is empty
struct Data
{
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Data(const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const UnaryOp& func() const { return op; }
UnaryOp op;
evaluator<ArgType> argImpl;
@@ -896,7 +899,7 @@
CoeffReadCost = NumTraits<Scalar>::ReadCost
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit mapbase_evaluator(const XprType& map)
: m_data(const_cast<PointerType>(map.data())),
m_innerStride(map.innerStride()),
@@ -908,32 +911,32 @@
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index col) const
{
return m_data[col * colStride() + row * rowStride()];
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return m_data[index * m_innerStride.value()];
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar& coeffRef(Index row, Index col)
{
return m_data[col * colStride() + row * rowStride()];
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar& coeffRef(Index index)
{
return m_data[index * m_innerStride.value()];
}
template<int LoadMode, typename PacketType>
- EIGEN_STRONG_INLINE
+ EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
PacketType packet(Index row, Index col) const
{
PointerType ptr = m_data + row * rowStride() + col * colStride();
@@ -1004,7 +1007,7 @@
Alignment = int(MapOptions)&int(AlignedMask)
};
- EIGEN_DEVICE_FUNC explicit evaluator(const XprType& map)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR explicit evaluator(const XprType& map)
: mapbase_evaluator<XprType, PlainObjectType>(map)
{ }
};
@@ -1022,7 +1025,7 @@
Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const XprType& ref)
: mapbase_evaluator<XprType, PlainObjectType>(ref)
{ }
@@ -1078,7 +1081,7 @@
Alignment = plain_enum_min(evaluator<ArgType>::Alignment, Alignment0)
};
typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const XprType& block) : block_evaluator_type(block)
{
EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
@@ -1092,7 +1095,7 @@
{
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit block_evaluator(const XprType& block)
: unary_evaluator<XprType>(block)
{}
@@ -1104,7 +1107,7 @@
{
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit unary_evaluator(const XprType& block)
: m_argImpl(block.nestedExpression()),
m_startRow(block.startRow()),
@@ -1120,13 +1123,13 @@
ForwardLinearAccess = (InnerPanel || int(XprType::IsRowMajor)==int(ArgType::IsRowMajor)) && bool(evaluator<ArgType>::Flags&LinearAccessBit)
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index col) const
{
return m_argImpl.coeff(m_startRow.value() + row, m_startCol.value() + col);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return linear_coeff_impl(index, bool_constant<ForwardLinearAccess>());
@@ -1182,12 +1185,12 @@
}
protected:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType linear_coeff_impl(Index index, internal::true_type /* ForwardLinearAccess */) const
{
return m_argImpl.coeff(m_linear_offset.value() + index);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType linear_coeff_impl(Index index, internal::false_type /* not ForwardLinearAccess */) const
{
return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
@@ -1221,7 +1224,7 @@
typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
typedef typename XprType::Scalar Scalar;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit block_evaluator(const XprType& block)
: mapbase_evaluator<XprType, typename XprType::PlainObject>(block)
{
@@ -1389,25 +1392,25 @@
Alignment = evaluator<ArgType>::Alignment
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator_wrapper_base(const ArgType& arg) : m_argImpl(arg) {}
typedef typename ArgType::Scalar Scalar;
typedef typename ArgType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index col) const
{
return m_argImpl.coeff(row, col);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return m_argImpl.coeff(index);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar& coeffRef(Index row, Index col)
{
return m_argImpl.coeffRef(row, col);
@@ -1457,7 +1460,7 @@
{
typedef MatrixWrapper<TArgType> XprType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit unary_evaluator(const XprType& wrapper)
: evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
{ }
@@ -1469,7 +1472,7 @@
{
typedef ArrayWrapper<TArgType> XprType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit unary_evaluator(const XprType& wrapper)
: evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
{ }
@@ -1620,7 +1623,7 @@
Alignment = 0
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit evaluator(const XprType& diagonal)
: m_argImpl(diagonal.nestedExpression()),
m_index(diagonal.index())
@@ -1629,13 +1632,13 @@
typedef typename XprType::Scalar Scalar;
typedef typename XprType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index row, Index) const
{
return m_argImpl.coeff(row + rowOffset(), row + colOffset());
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeff(Index index) const
{
return m_argImpl.coeff(index + rowOffset(), index + colOffset());
diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h
index 21a061a..0710560 100644
--- a/Eigen/src/Core/CwiseBinaryOp.h
+++ b/Eigen/src/Core/CwiseBinaryOp.h
@@ -111,7 +111,7 @@
CwiseBinaryOp(const CwiseBinaryOp<BinaryOp,LhsType,RhsType>&) = default;
#endif
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
: m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
{
@@ -130,13 +130,13 @@
}
/** \returns the left hand side nested expression */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const LhsNested_& lhs() const { return m_lhs; }
/** \returns the right hand side nested expression */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const RhsNested_& rhs() const { return m_rhs; }
/** \returns the functor representing the binary operation */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const BinaryOp& functor() const { return m_functor; }
protected:
@@ -173,7 +173,7 @@
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Derived &
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
{
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
diff --git a/Eigen/src/Core/CwiseNullaryOp.h b/Eigen/src/Core/CwiseNullaryOp.h
index a62f54d..c509726 100644
--- a/Eigen/src/Core/CwiseNullaryOp.h
+++ b/Eigen/src/Core/CwiseNullaryOp.h
@@ -66,7 +66,7 @@
typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
: m_rows(rows), m_cols(cols), m_functor(func)
{
@@ -82,7 +82,7 @@
Index cols() const { return m_cols.value(); }
/** \returns the functor representing the nullary operation */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const NullaryOp& functor() const { return m_functor; }
protected:
@@ -107,7 +107,7 @@
*/
template<typename Derived>
template<typename CustomNullaryOp>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
const CwiseNullaryOp<CustomNullaryOp,typename DenseBase<Derived>::PlainObject>
#else
@@ -138,7 +138,7 @@
*/
template<typename Derived>
template<typename CustomNullaryOp>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
#else
@@ -162,7 +162,7 @@
*/
template<typename Derived>
template<typename CustomNullaryOp>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
#else
@@ -187,7 +187,7 @@
* \sa class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
{
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
@@ -209,7 +209,7 @@
* \sa class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(Index size, const Scalar& value)
{
return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value));
@@ -225,7 +225,7 @@
* \sa class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(const Scalar& value)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
@@ -334,7 +334,7 @@
* \sa setConstant(), Constant(), class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void DenseBase<Derived>::fill(const Scalar& val)
{
setConstant(val);
}
@@ -344,7 +344,7 @@
* \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Derived& DenseBase<Derived>::setConstant(const Scalar& val)
{
return derived() = Constant(rows(), cols(), val);
}
@@ -472,7 +472,7 @@
* \sa Zero(), Zero(Index)
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero(Index rows, Index cols)
{
return Constant(rows, cols, Scalar(0));
@@ -495,7 +495,7 @@
* \sa Zero(), Zero(Index,Index)
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero(Index size)
{
return Constant(size, Scalar(0));
@@ -512,7 +512,7 @@
* \sa Zero(Index), Zero(Index,Index)
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero()
{
return Constant(Scalar(0));
@@ -628,7 +628,7 @@
* \sa Ones(), Ones(Index), isOnes(), class Ones
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones(Index rows, Index cols)
{
return Constant(rows, cols, Scalar(1));
@@ -651,7 +651,7 @@
* \sa Ones(), Ones(Index,Index), isOnes(), class Ones
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones(Index newSize)
{
return Constant(newSize, Scalar(1));
@@ -668,7 +668,7 @@
* \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones()
{
return Constant(Scalar(1));
@@ -780,7 +780,7 @@
* \sa Identity(), setIdentity(), isIdentity()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::IdentityReturnType
MatrixBase<Derived>::Identity(Index rows, Index cols)
{
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
@@ -797,7 +797,7 @@
* \sa Identity(Index,Index), setIdentity(), isIdentity()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::IdentityReturnType
MatrixBase<Derived>::Identity()
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
@@ -901,7 +901,7 @@
* \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i);
@@ -916,7 +916,7 @@
* \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return BasisReturnType(SquareMatrixType::Identity(),i);
@@ -929,7 +929,7 @@
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
{ return Derived::Unit(0); }
/** \returns an expression of the Y axis unit vector (0,1{,0}^*)
@@ -939,7 +939,7 @@
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
{ return Derived::Unit(1); }
/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*)
@@ -949,7 +949,7 @@
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
{ return Derived::Unit(2); }
/** \returns an expression of the W axis unit vector (0,0,0,1)
@@ -959,7 +959,7 @@
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
{ return Derived::Unit(3); }
/** \brief Set the coefficients of \c *this to the i-th unit (basis) vector
diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h
index ff7d0b9..0900ab1 100644
--- a/Eigen/src/Core/CwiseUnaryOp.h
+++ b/Eigen/src/Core/CwiseUnaryOp.h
@@ -63,7 +63,7 @@
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
typedef internal::remove_all_t<XprType> NestedExpression;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
: m_xpr(xpr), m_functor(func) {}
@@ -73,16 +73,16 @@
Index cols() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
/** \returns the functor representing the unary operation */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const UnaryOp& functor() const { return m_functor; }
/** \returns the nested expression */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const internal::remove_all_t<XprTypeNested>&
nestedExpression() const { return m_xpr; }
/** \returns the nested expression */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
internal::remove_all_t<XprTypeNested>&
nestedExpression() { return m_xpr; }
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index 6e17779..a5b590a 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -311,19 +311,19 @@
CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
typedef Transpose<Derived> TransposeReturnType;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
TransposeReturnType transpose();
typedef Transpose<const Derived> ConstTransposeReturnType;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const ConstTransposeReturnType transpose() const;
EIGEN_DEVICE_FUNC
void transposeInPlace();
- EIGEN_DEVICE_FUNC static const ConstantReturnType
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType
Constant(Index rows, Index cols, const Scalar& value);
- EIGEN_DEVICE_FUNC static const ConstantReturnType
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType
Constant(Index size, const Scalar& value);
- EIGEN_DEVICE_FUNC static const ConstantReturnType
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType
Constant(const Scalar& value);
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
@@ -336,25 +336,25 @@
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
LinSpaced(const Scalar& low, const Scalar& high);
- template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
+ template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func);
- template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
+ template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
NullaryExpr(Index size, const CustomNullaryOp& func);
- template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
+ template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
NullaryExpr(const CustomNullaryOp& func);
- EIGEN_DEVICE_FUNC static const ConstantReturnType Zero(Index rows, Index cols);
- EIGEN_DEVICE_FUNC static const ConstantReturnType Zero(Index size);
- EIGEN_DEVICE_FUNC static const ConstantReturnType Zero();
- EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index rows, Index cols);
- EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index size);
- EIGEN_DEVICE_FUNC static const ConstantReturnType Ones();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType Zero(Index rows, Index cols);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType Zero(Index size);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType Zero();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType Ones(Index rows, Index cols);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType Ones(Index size);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const ConstantReturnType Ones();
- EIGEN_DEVICE_FUNC void fill(const Scalar& value);
- EIGEN_DEVICE_FUNC Derived& setConstant(const Scalar& value);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void fill(const Scalar& value);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Derived& setConstant(const Scalar& value);
EIGEN_DEVICE_FUNC Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
EIGEN_DEVICE_FUNC Derived& setLinSpaced(const Scalar& low, const Scalar& high);
EIGEN_DEVICE_FUNC Derived& setZero();
@@ -392,7 +392,7 @@
*
* \warning Be careful with eval() and the auto C++ keyword, as detailed in this \link TopicPitfalls_auto_keyword page \endlink.
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE EvalReturnType eval() const
{
// Even though MSVC does not honor strong inlining when the return type
@@ -417,7 +417,7 @@
*
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void swap(PlainObjectBase<OtherDerived>& other)
{
eigen_assert(rows()==other.rows() && cols()==other.cols());
@@ -432,26 +432,26 @@
template<bool Enable> EIGEN_DEVICE_FUNC
inline std::conditional_t<Enable,ForceAlignedAccess<Derived>,Derived&> forceAlignedAccessIf();
- EIGEN_DEVICE_FUNC Scalar sum() const;
- EIGEN_DEVICE_FUNC Scalar mean() const;
- EIGEN_DEVICE_FUNC Scalar trace() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Scalar sum() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Scalar mean() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Scalar trace() const;
- EIGEN_DEVICE_FUNC Scalar prod() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Scalar prod() const;
template<int NaNPropagation>
- EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar minCoeff() const;
template<int NaNPropagation>
- EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar maxCoeff() const;
// By default, the fastest version with undefined NaN propagation semantics is
// used.
// TODO(rmlarsen): Replace with default template argument when we move to
// c++11 or beyond.
- EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar minCoeff() const {
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline typename internal::traits<Derived>::Scalar minCoeff() const {
return minCoeff<PropagateFast>();
}
- EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Scalar maxCoeff() const {
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline typename internal::traits<Derived>::Scalar maxCoeff() const {
return maxCoeff<PropagateFast>();
}
@@ -491,7 +491,7 @@
}
template<typename BinaryOp>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Scalar redux(const BinaryOp& func) const;
template<typename Visitor>
@@ -519,9 +519,9 @@
return derived().coeff(0,0);
}
- EIGEN_DEVICE_FUNC bool all() const;
- EIGEN_DEVICE_FUNC bool any() const;
- EIGEN_DEVICE_FUNC Index count() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool all() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool any() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index count() const;
typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
@@ -536,10 +536,10 @@
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
*/
//Code moved here due to a CUDA compiler bug
- EIGEN_DEVICE_FUNC inline ConstRowwiseReturnType rowwise() const {
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline ConstRowwiseReturnType rowwise() const {
return ConstRowwiseReturnType(derived());
}
- EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR RowwiseReturnType rowwise();
/** \returns a VectorwiseOp wrapper of *this broadcasting and partial reductions
*
@@ -548,10 +548,10 @@
*
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
*/
- EIGEN_DEVICE_FUNC inline ConstColwiseReturnType colwise() const {
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline ConstColwiseReturnType colwise() const {
return ConstColwiseReturnType(derived());
}
- EIGEN_DEVICE_FUNC ColwiseReturnType colwise();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR ColwiseReturnType colwise();
typedef CwiseNullaryOp<internal::scalar_random_op<Scalar>,PlainObject> RandomReturnType;
static const RandomReturnType Random(Index rows, Index cols);
@@ -661,7 +661,7 @@
protected:
EIGEN_DEFAULT_COPY_CONSTRUCTOR(DenseBase)
/** Default constructor. Do nothing. */
- EIGEN_DEVICE_FUNC DenseBase()
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseBase()
{
/* Just checks for self-consistency of the flags.
* Only do it when debugging Eigen, as this borders on paranoia and could slow compilation down
diff --git a/Eigen/src/Core/DenseCoeffsBase.h b/Eigen/src/Core/DenseCoeffsBase.h
index 7f0bcf4..9608bbb 100644
--- a/Eigen/src/Core/DenseCoeffsBase.h
+++ b/Eigen/src/Core/DenseCoeffsBase.h
@@ -95,7 +95,7 @@
*
* \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
{
eigen_internal_assert(row >= 0 && row < rows()
@@ -114,7 +114,7 @@
*
* \sa operator()(Index,Index), operator[](Index)
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
{
eigen_assert(row >= 0 && row < rows()
@@ -137,7 +137,7 @@
* \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType
coeff(Index index) const
{
@@ -156,7 +156,7 @@
* z() const, w() const
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType
operator[](Index index) const
{
@@ -176,7 +176,7 @@
* z() const, w() const
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType
operator()(Index index) const
{
@@ -186,13 +186,13 @@
/** equivalent to operator[](0). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType
x() const { return (*this)[0]; }
/** equivalent to operator[](1). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType
y() const
{
@@ -202,7 +202,7 @@
/** equivalent to operator[](2). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType
z() const
{
@@ -212,7 +212,7 @@
/** equivalent to operator[](3). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE CoeffReturnType
w() const
{
@@ -348,7 +348,7 @@
return internal::evaluator<Derived>(derived()).coeffRef(row,col);
}
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
coeffRefByOuterInner(Index outer, Index inner)
{
@@ -361,7 +361,7 @@
* \sa operator[](Index)
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
operator()(Index row, Index col)
{
@@ -386,7 +386,7 @@
* \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index)
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
coeffRef(Index index)
{
@@ -403,7 +403,7 @@
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
operator[](Index index)
{
@@ -422,7 +422,7 @@
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
operator()(Index index)
{
@@ -432,13 +432,13 @@
/** equivalent to operator[](0). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
x() { return (*this)[0]; }
/** equivalent to operator[](1). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
y()
{
@@ -448,7 +448,7 @@
/** equivalent to operator[](2). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
z()
{
@@ -458,7 +458,7 @@
/** equivalent to operator[](3). */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar&
w()
{
diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h
index 5e2763e..61c4862 100644
--- a/Eigen/src/Core/DenseStorage.h
+++ b/Eigen/src/Core/DenseStorage.h
@@ -27,7 +27,7 @@
struct constructor_without_unaligned_array_assert {};
template<typename T, int Size>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
void check_static_allocation_size()
{
// if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit
@@ -87,7 +87,7 @@
{
EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size];
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
plain_array()
{
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7);
@@ -106,7 +106,7 @@
{
EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size];
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
plain_array()
{
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
@@ -125,7 +125,7 @@
{
EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size];
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
plain_array()
{
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31);
@@ -144,7 +144,7 @@
{
EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
plain_array()
{
EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63);
@@ -162,7 +162,7 @@
struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
{
T array[1];
- EIGEN_DEVICE_FUNC plain_array() {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR plain_array() = default;
EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
};
@@ -211,7 +211,7 @@
{
internal::plain_array<T,Size,Options_> m_data;
public:
- EIGEN_DEVICE_FUNC DenseStorage() {
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseStorage() {
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
}
EIGEN_DEVICE_FUNC
@@ -241,27 +241,27 @@
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;}
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return Cols_;}
EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
- EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
- EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
- EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void resize(Index,Index,Index) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR const T *data() const { return m_data.array; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR T *data() { return m_data.array; }
};
// null matrix
template<typename T, int Rows_, int Cols_, int Options_> class DenseStorage<T, 0, Rows_, Cols_, Options_>
{
public:
- EIGEN_DEVICE_FUNC DenseStorage() {}
- EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {}
- EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) {}
- EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
- EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
- EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseStorage() {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseStorage(const DenseStorage&) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseStorage& operator=(const DenseStorage&) { return *this; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseStorage(Index,Index,Index) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void swap(DenseStorage& ) {}
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT {return Rows_;}
EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT {return Cols_;}
- EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
- EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
- EIGEN_DEVICE_FUNC const T *data() const { return 0; }
- EIGEN_DEVICE_FUNC T *data() { return 0; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void conservativeResize(Index,Index,Index) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void resize(Index,Index,Index) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR const T *data() const { return 0; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR T *data() { return 0; }
};
// more specializations for null matrices; these are necessary to resolve ambiguities
@@ -320,10 +320,10 @@
internal::plain_array<T,Size,Options_> m_data;
Index m_rows;
public:
- EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseStorage() : m_rows(0) {}
EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
- EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR DenseStorage(const DenseStorage& other)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows)
{
internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data);
@@ -344,12 +344,12 @@
internal::plain_array_helper::swap(m_data, m_rows * Cols_, other.m_data, other.m_rows * Cols_);
numext::swap(m_rows, other.m_rows);
}
- EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT {return m_rows;}
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT {return Cols_;}
- EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
- EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; }
- EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
- EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void resize(Index, Index rows, Index) { m_rows = rows; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR const T *data() const { return m_data.array; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR T *data() { return m_data.array; }
};
// dynamic-size matrix with fixed-size storage and fixed height
diff --git a/Eigen/src/Core/Diagonal.h b/Eigen/src/Core/Diagonal.h
index 4af17dd..ce4d259 100644
--- a/Eigen/src/Core/Diagonal.h
+++ b/Eigen/src/Core/Diagonal.h
@@ -71,7 +71,7 @@
typedef typename internal::dense_xpr_base<Diagonal>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index)
{
eigen_assert( a_index <= m_matrix.cols() && -a_index <= m_matrix.rows() );
@@ -79,7 +79,7 @@
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline Index rows() const
{
return m_index.value()<0 ? numext::mini<Index>(m_matrix.cols(),m_matrix.rows()+m_index.value())
@@ -146,14 +146,14 @@
return m_matrix.coeff(idx+rowOffset(), idx+colOffset());
}
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline const internal::remove_all_t<typename MatrixType::Nested>&
nestedExpression() const
{
return m_matrix;
}
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline Index index() const
{
return m_index.value();
@@ -185,7 +185,7 @@
*
* \sa class Diagonal */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename MatrixBase<Derived>::DiagonalReturnType
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline typename MatrixBase<Derived>::DiagonalReturnType
MatrixBase<Derived>::diagonal()
{
return DiagonalReturnType(derived());
@@ -193,7 +193,7 @@
/** This is the const version of diagonal(). */
template<typename Derived>
-EIGEN_DEVICE_FUNC inline
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline
const typename MatrixBase<Derived>::ConstDiagonalReturnType
MatrixBase<Derived>::diagonal() const
{
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h
index 0c13192..c48db0b 100644
--- a/Eigen/src/Core/Dot.h
+++ b/Eigen/src/Core/Dot.h
@@ -28,7 +28,7 @@
typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
typedef typename conj_prod::result_type ResScalar;
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE
+ EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
{
return a.template binaryExpr<conj_prod>(b).sum();
@@ -41,7 +41,7 @@
typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
typedef typename conj_prod::result_type ResScalar;
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE
+ EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
{
return a.transpose().template binaryExpr<conj_prod>(b).sum();
@@ -64,7 +64,7 @@
template<typename Derived>
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE
+EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
{
@@ -90,7 +90,7 @@
* \sa dot(), norm(), lpNorm()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
{
return numext::real((*this).cwiseAbs2().sum());
}
diff --git a/Eigen/src/Core/EigenBase.h b/Eigen/src/Core/EigenBase.h
index 105488d..01a25bc 100644
--- a/Eigen/src/Core/EigenBase.h
+++ b/Eigen/src/Core/EigenBase.h
@@ -44,14 +44,14 @@
typedef typename internal::traits<Derived>::StorageKind StorageKind;
/** \returns a reference to the derived object */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Derived& derived() { return *static_cast<Derived*>(this); }
/** \returns a const reference to the derived object */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const Derived& derived() const { return *static_cast<const Derived*>(this); }
- EIGEN_DEVICE_FUNC
- inline Derived& const_cast_derived() const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ Derived& const_cast_derived() const
{ return *static_cast<Derived*>(const_cast<EigenBase*>(this)); }
EIGEN_DEVICE_FUNC
inline const Derived& const_derived() const
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h
index 661a3c4..37e9117 100644
--- a/Eigen/src/Core/GeneralProduct.h
+++ b/Eigen/src/Core/GeneralProduct.h
@@ -396,7 +396,7 @@
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const Product<Derived, OtherDerived>
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
{
@@ -439,7 +439,7 @@
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const Product<Derived,OtherDerived,LazyProduct>
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
{
diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h
index 8119200..cbb64d9 100644
--- a/Eigen/src/Core/GenericPacketMath.h
+++ b/Eigen/src/Core/GenericPacketMath.h
@@ -59,6 +59,7 @@
HasMax = 1,
HasConj = 1,
HasSetLinear = 1,
+ HasSign = 1,
HasBlend = 0,
// This flag is used to indicate whether packet comparison is supported.
// pcmp_eq, pcmp_lt and pcmp_le should be defined for it to be true.
@@ -101,8 +102,7 @@
HasRound = 0,
HasRint = 0,
HasFloor = 0,
- HasCeil = 0,
- HasSign = 0
+ HasCeil = 0
};
};
@@ -179,7 +179,7 @@
*/
template<typename Packet>
struct is_scalar {
- typedef typename unpacket_traits<Packet>::type Scalar;
+ using Scalar = typename unpacket_traits<Packet>::type;
enum {
value = internal::is_same<Packet, Scalar>::value
};
@@ -214,10 +214,10 @@
preinterpret(const Packet& a); /* { return reinterpret_cast<const Target&>(a); } */
/** \internal \returns a + b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet
padd(const Packet& a, const Packet& b) { return a+b; }
// Avoid compiler warning for boolean algebra.
-template<> EIGEN_DEVICE_FUNC inline bool
+template<> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool
padd(const bool& a, const bool& b) { return a || b; }
/** \internal \returns a packet version of \a *from, (un-aligned masked add)
@@ -230,14 +230,14 @@
/** \internal \returns a - b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet
psub(const Packet& a, const Packet& b) { return a-b; }
/** \internal \returns -a (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet
pnegate(const Packet& a) { return -a; }
-template<> EIGEN_DEVICE_FUNC inline bool
+template<> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool
pnegate(const bool& a) { return !a; }
/** \internal \returns conj(a) (coeff-wise) */
@@ -245,14 +245,14 @@
pconj(const Packet& a) { return numext::conj(a); }
/** \internal \returns a * b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet
pmul(const Packet& a, const Packet& b) { return a*b; }
// Avoid compiler warning for boolean algebra.
-template<> EIGEN_DEVICE_FUNC inline bool
+template<> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool
pmul(const bool& a, const bool& b) { return a && b; }
/** \internal \returns a / b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet
pdiv(const Packet& a, const Packet& b) { return a/b; }
// In the generic case, memset to all one bits.
@@ -475,7 +475,7 @@
template<int NaNPropagation>
struct pminmax_impl {
template <typename Packet, typename Op>
- static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a, const Packet& b, Op op) {
+ static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet run(const Packet& a, const Packet& b, Op op) {
return op(a,b);
}
};
@@ -520,25 +520,25 @@
/** \internal \returns the min of \a a and \a b (coeff-wise).
If \a a or \b b is NaN, the return value is implementation defined. */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet
pmin(const Packet& a, const Packet& b) { return numext::mini(a,b); }
/** \internal \returns the min of \a a and \a b (coeff-wise).
NaNPropagation determines the NaN propagation semantics. */
template <int NaNPropagation, typename Packet>
-EIGEN_DEVICE_FUNC inline Packet pmin(const Packet& a, const Packet& b) {
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet pmin(const Packet& a, const Packet& b) {
return pminmax_impl<NaNPropagation>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet, (pmin<Packet>)));
}
/** \internal \returns the max of \a a and \a b (coeff-wise)
If \a a or \b b is NaN, the return value is implementation defined. */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet
pmax(const Packet& a, const Packet& b) { return numext::maxi(a, b); }
/** \internal \returns the max of \a a and \a b (coeff-wise).
NaNPropagation determines the NaN propagation semantics. */
template <int NaNPropagation, typename Packet>
-EIGEN_DEVICE_FUNC inline Packet pmax(const Packet& a, const Packet& b) {
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet pmax(const Packet& a, const Packet& b) {
return pminmax_impl<NaNPropagation>::run(a, b, EIGEN_BINARY_OP_NAN_PROPAGATION(Packet,(pmax<Packet>)));
}
@@ -921,6 +921,24 @@
template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
+template<typename Packet, typename EnableIf = void>
+struct psign_impl {
+ static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) {
+ return numext::sign(a);
+ }
+};
+
+/** \internal \returns the sign of \a a (coeff-wise) */
+template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+psign(const Packet& a) {
+ return psign_impl<Packet>::run(a);
+}
+
+template<> EIGEN_DEVICE_FUNC inline bool
+psign(const bool& a) {
+ return a;
+}
+
/** \internal \returns the first element of a packet */
template<typename Packet>
EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type
@@ -1029,28 +1047,28 @@
// FMA instructions.
/** \internal \returns a * b + c (coeff-wise) */
template <typename Packet>
-EIGEN_DEVICE_FUNC inline Packet pmadd(const Packet& a, const Packet& b,
+EIGEN_DEVICE_FUNC Packet pmadd(const Packet& a, const Packet& b,
const Packet& c) {
return padd(pmul(a, b), c);
}
/** \internal \returns a * b - c (coeff-wise) */
template <typename Packet>
-EIGEN_DEVICE_FUNC inline Packet pmsub(const Packet& a, const Packet& b,
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet pmsub(const Packet& a, const Packet& b,
const Packet& c) {
return psub(pmul(a, b), c);
}
/** \internal \returns -(a * b) + c (coeff-wise) */
template <typename Packet>
-EIGEN_DEVICE_FUNC inline Packet pnmadd(const Packet& a, const Packet& b,
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet pnmadd(const Packet& a, const Packet& b,
const Packet& c) {
return padd(pnegate(pmul(a, b)), c);
}
/** \internal \returns -(a * b) - c (coeff-wise) */
template <typename Packet>
-EIGEN_DEVICE_FUNC inline Packet pnmsub(const Packet& a, const Packet& b,
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Packet pnmsub(const Packet& a, const Packet& b,
const Packet& c) {
return psub(pnegate(pmul(a, b)), c);
}
diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h
index 53f9dfa..f8d00b1 100644
--- a/Eigen/src/Core/GlobalFunctions.h
+++ b/Eigen/src/Core/GlobalFunctions.h
@@ -101,30 +101,31 @@
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isfinite,scalar_isfinite_op,finite value test,\sa Eigen::isinf DOXCOMMA Eigen::isnan DOXCOMMA ArrayBase::isfinite)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sign,scalar_sign_op,sign (or 0),\sa ArrayBase::sign)
+ template <typename Derived, typename ScalarExponent>
+ using GlobalUnaryPowReturnType = std::enable_if_t<
+ !internal::is_arithmetic<typename NumTraits<Derived>::Real>::value &&
+ internal::is_arithmetic<typename NumTraits<ScalarExponent>::Real>::value,
+ CwiseUnaryOp<internal::scalar_unary_pow_op<typename Derived::Scalar, ScalarExponent>, const Derived> >;
+
/** \returns an expression of the coefficient-wise power of \a x to the given constant \a exponent.
- *
- * \tparam ScalarExponent is the scalar type of \a exponent. It must be compatible with the scalar type of the given expression (\c Derived::Scalar).
- *
- * \sa ArrayBase::pow()
- *
- * \relates ArrayBase
- */
+ *
+ * \tparam ScalarExponent is the scalar type of \a exponent. It must be compatible with the scalar type of the given
+ * expression (\c Derived::Scalar).
+ *
+ * \sa ArrayBase::pow()
+ *
+ * \relates ArrayBase
+ */
#ifdef EIGEN_PARSED_BY_DOXYGEN
- template<typename Derived,typename ScalarExponent>
- inline const CwiseBinaryOp<internal::scalar_pow_op<Derived::Scalar,ScalarExponent>,Derived,Constant<ScalarExponent> >
- pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent);
+ template <typename Derived, typename ScalarExponent>
+ EIGEN_DEVICE_FUNC inline const GlobalUnaryPowReturnType<Derived, ScalarExponent> pow(
+ const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent);
#else
- template <typename Derived,typename ScalarExponent>
- EIGEN_DEVICE_FUNC inline
- const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename internal::promote_scalar_arg<typename Derived::Scalar
- EIGEN_COMMA ScalarExponent EIGEN_COMMA
- EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent)>::type,pow)
- pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent)
- {
- typedef typename internal::promote_scalar_arg<typename Derived::Scalar,ScalarExponent,
- EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent)>::type PromotedExponent;
- return EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,PromotedExponent,pow)(x.derived(),
- typename internal::plain_constant_type<Derived,PromotedExponent>::type(x.derived().rows(), x.derived().cols(), internal::scalar_constant_op<PromotedExponent>(exponent)));
+ template <typename Derived, typename ScalarExponent>
+ EIGEN_DEVICE_FUNC inline const GlobalUnaryPowReturnType<Derived, ScalarExponent> pow(
+ const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent) {
+ return GlobalUnaryPowReturnType<Derived, ScalarExponent>(
+ x.derived(), internal::scalar_unary_pow_op<typename Derived::Scalar, ScalarExponent>(exponent));
}
#endif
diff --git a/Eigen/src/Core/IndexedView.h b/Eigen/src/Core/IndexedView.h
index c0907bf..f967301 100644
--- a/Eigen/src/Core/IndexedView.h
+++ b/Eigen/src/Core/IndexedView.h
@@ -191,12 +191,16 @@
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index row, Index col) const
{
+ eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
+ && m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
return m_argImpl.coeff(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Scalar& coeffRef(Index row, Index col)
{
+ eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
+ && m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
return m_argImpl.coeffRef(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
}
@@ -206,6 +210,8 @@
EIGEN_STATIC_ASSERT_LVALUE(XprType)
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
+ eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
+ && m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
}
@@ -214,6 +220,8 @@
{
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
+ eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
+ && m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
}
@@ -222,6 +230,8 @@
{
Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
+ eigen_assert(m_xpr.rowIndices()[row] >= 0 && m_xpr.rowIndices()[row] < m_xpr.nestedExpression().rows()
+ && m_xpr.colIndices()[col] >= 0 && m_xpr.colIndices()[col] < m_xpr.nestedExpression().cols());
return m_argImpl.coeff( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
}
diff --git a/Eigen/src/Core/Map.h b/Eigen/src/Core/Map.h
index 56d1ff8..fb4e817 100644
--- a/Eigen/src/Core/Map.h
+++ b/Eigen/src/Core/Map.h
@@ -103,8 +103,8 @@
typedef typename Base::PointerType PointerType;
typedef PointerType PointerArgType;
- EIGEN_DEVICE_FUNC
- inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline Index innerStride() const
@@ -127,8 +127,8 @@
* \param dataPtr pointer to the array to map
* \param stride optional Stride object, passing the strides.
*/
- EIGEN_DEVICE_FUNC
- explicit inline Map(PointerArgType dataPtr, const StrideType& stride = StrideType())
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ explicit Map(PointerArgType dataPtr, const StrideType& stride = StrideType())
: Base(cast_to_pointer_type(dataPtr)), m_stride(stride)
{
}
@@ -152,8 +152,8 @@
* \param cols the number of columns of the matrix expression
* \param stride optional Stride object, passing the strides.
*/
- EIGEN_DEVICE_FUNC
- inline Map(PointerArgType dataPtr, Index rows, Index cols, const StrideType& stride = StrideType())
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ Map(PointerArgType dataPtr, Index rows, Index cols, const StrideType& stride = StrideType())
: Base(cast_to_pointer_type(dataPtr), rows, cols), m_stride(stride)
{
}
diff --git a/Eigen/src/Core/MapBase.h b/Eigen/src/Core/MapBase.h
index bf8c163..5d7fee1 100644
--- a/Eigen/src/Core/MapBase.h
+++ b/Eigen/src/Core/MapBase.h
@@ -101,33 +101,33 @@
*
* \sa innerStride(), outerStride()
*/
- EIGEN_DEVICE_FUNC inline const Scalar* data() const { return m_data; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR const Scalar* data() const { return m_data; }
/** \copydoc PlainObjectBase::coeff(Index,Index) const */
- EIGEN_DEVICE_FUNC
- inline const Scalar& coeff(Index rowId, Index colId) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ const Scalar& coeff(Index rowId, Index colId) const
{
return m_data[colId * colStride() + rowId * rowStride()];
}
/** \copydoc PlainObjectBase::coeff(Index) const */
- EIGEN_DEVICE_FUNC
- inline const Scalar& coeff(Index index) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ const Scalar& coeff(Index index) const
{
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
return m_data[index * innerStride()];
}
/** \copydoc PlainObjectBase::coeffRef(Index,Index) const */
- EIGEN_DEVICE_FUNC
- inline const Scalar& coeffRef(Index rowId, Index colId) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ const Scalar& coeffRef(Index rowId, Index colId) const
{
return this->m_data[colId * colStride() + rowId * rowStride()];
}
/** \copydoc PlainObjectBase::coeffRef(Index) const */
- EIGEN_DEVICE_FUNC
- inline const Scalar& coeffRef(Index index) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ const Scalar& coeffRef(Index index) const
{
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
return this->m_data[index * innerStride()];
@@ -150,8 +150,8 @@
}
/** \internal Constructor for fixed size matrices or vectors */
- EIGEN_DEVICE_FUNC
- explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ explicit MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
checkSanity<Derived>();
@@ -171,8 +171,8 @@
}
/** \internal Constructor for dynamically sized matrices */
- EIGEN_DEVICE_FUNC
- inline MapBase(PointerType dataPtr, Index rows, Index cols)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ MapBase(PointerType dataPtr, Index rows, Index cols)
: m_data(dataPtr), m_rows(rows), m_cols(cols)
{
eigen_assert( (dataPtr == 0)
@@ -203,7 +203,7 @@
}
template<typename T>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
void checkSanity(std::enable_if_t<internal::traits<T>::Alignment==0,void*> = 0) const
{}
@@ -253,8 +253,8 @@
const Scalar
> ScalarWithConstIfNotLvalue;
- EIGEN_DEVICE_FUNC
- inline const Scalar* data() const { return this->m_data; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ const Scalar* data() const { return this->m_data; }
EIGEN_DEVICE_FUNC
inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error
@@ -286,9 +286,9 @@
(this->m_data + index * innerStride(), val);
}
- EIGEN_DEVICE_FUNC explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
- EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
- EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index rows, Index cols) : Base(dataPtr, rows, cols) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR explicit MapBase(PointerType dataPtr) : Base(dataPtr) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR MapBase(PointerType dataPtr, Index rows, Index cols) : Base(dataPtr, rows, cols) {}
EIGEN_DEVICE_FUNC
Derived& operator=(const MapBase& other)
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 59cc831..1c5fab0 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -71,8 +71,8 @@
struct real_default_impl
{
typedef typename NumTraits<Scalar>::Real RealScalar;
- EIGEN_DEVICE_FUNC
- static inline RealScalar run(const Scalar& x)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ static RealScalar run(const Scalar& x)
{
return x;
}
@@ -82,8 +82,8 @@
struct real_default_impl<Scalar,true>
{
typedef typename NumTraits<Scalar>::Real RealScalar;
- EIGEN_DEVICE_FUNC
- static inline RealScalar run(const Scalar& x)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ static RealScalar run(const Scalar& x)
{
using std::real;
return real(x);
@@ -229,6 +229,63 @@
typedef typename NumTraits<Scalar>::Real & type;
};
+
+/****************************************************************************
+* Implementation of sign *
+****************************************************************************/
+template<typename Scalar, bool IsComplex = (NumTraits<Scalar>::IsComplex!=0),
+ bool IsInteger = (NumTraits<Scalar>::IsInteger!=0)>
+struct sign_impl
+{
+ EIGEN_DEVICE_FUNC
+ static inline Scalar run(const Scalar& a)
+ {
+ return Scalar( (a>Scalar(0)) - (a<Scalar(0)) );
+ }
+};
+
+template<typename Scalar>
+struct sign_impl<Scalar, false, false>
+{
+ EIGEN_DEVICE_FUNC
+ static inline Scalar run(const Scalar& a)
+ {
+ return (std::isnan)(a) ? a : Scalar( (a>Scalar(0)) - (a<Scalar(0)) );
+ }
+};
+
+template<typename Scalar, bool IsInteger>
+struct sign_impl<Scalar, true, IsInteger>
+{
+ EIGEN_DEVICE_FUNC
+ static inline Scalar run(const Scalar& a)
+ {
+ using real_type = typename NumTraits<Scalar>::Real;
+ real_type aa = std::abs(a);
+ if (aa==real_type(0))
+ return Scalar(0);
+ aa = real_type(1)/aa;
+ return Scalar(a.real()*aa, a.imag()*aa );
+ }
+};
+
+// The sign function for bool is the identity.
+template<>
+struct sign_impl<bool, false, true>
+{
+ EIGEN_DEVICE_FUNC
+ static inline bool run(const bool& a)
+ {
+ return a;
+ }
+};
+
+template<typename Scalar>
+struct sign_retval
+{
+ typedef Scalar type;
+};
+
/****************************************************************************
* Implementation of conj *
****************************************************************************/
@@ -236,7 +293,7 @@
template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
struct conj_default_impl
{
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static inline Scalar run(const Scalar& x)
{
return x;
@@ -246,7 +303,7 @@
template<typename Scalar>
struct conj_default_impl<Scalar,true>
{
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static inline Scalar run(const Scalar& x)
{
using std::conj;
@@ -271,7 +328,7 @@
struct abs2_impl_default
{
typedef typename NumTraits<Scalar>::Real RealScalar;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static inline RealScalar run(const Scalar& x)
{
return x*x;
@@ -282,7 +339,7 @@
struct abs2_impl_default<Scalar, true> // IsComplex
{
typedef typename NumTraits<Scalar>::Real RealScalar;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static inline RealScalar run(const Scalar& x)
{
return x.real()*x.real() + x.imag()*x.imag();
@@ -293,8 +350,8 @@
struct abs2_impl
{
typedef typename NumTraits<Scalar>::Real RealScalar;
- EIGEN_DEVICE_FUNC
- static inline RealScalar run(const Scalar& x)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ static RealScalar run(const Scalar& x)
{
return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
}
@@ -376,8 +433,8 @@
struct norm1_default_impl<Scalar,true>
{
typedef typename NumTraits<Scalar>::Real RealScalar;
- EIGEN_DEVICE_FUNC
- static inline RealScalar run(const Scalar& x)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ static RealScalar run(const Scalar& x)
{
EIGEN_USING_STD(abs);
return abs(x.real()) + abs(x.imag());
@@ -423,8 +480,8 @@
template<typename OldType, typename NewType, typename EnableIf = void>
struct cast_impl
{
- EIGEN_DEVICE_FUNC
- static inline NewType run(const OldType& x)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ static NewType run(const OldType& x)
{
return static_cast<NewType>(x);
}
@@ -438,8 +495,8 @@
!NumTraits<OldType>::IsComplex && NumTraits<NewType>::IsComplex
>>
{
- EIGEN_DEVICE_FUNC
- static inline NewType run(const OldType& x)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ static NewType run(const OldType& x)
{
typedef typename NumTraits<NewType>::Real NewReal;
return static_cast<NewType>(static_cast<NewReal>(x));
@@ -449,8 +506,8 @@
// here, for once, we're plainly returning NewType: we don't want cast to do weird things.
template<typename OldType, typename NewType>
-EIGEN_DEVICE_FUNC
-inline NewType cast(const OldType& x)
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+NewType cast(const OldType& x)
{
return cast_impl<OldType, NewType>::run(x);
}
@@ -1077,7 +1134,7 @@
#if (!defined(EIGEN_GPUCC) || defined(EIGEN_CONSTEXPR_ARE_DEVICE_FUNC))
template<typename T>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
{
EIGEN_USING_STD(min)
@@ -1085,7 +1142,7 @@
}
template<typename T>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
{
EIGEN_USING_STD(max)
@@ -1093,7 +1150,7 @@
}
#else
template<typename T>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
{
return y < x ? y : x;
@@ -1123,7 +1180,7 @@
}
template<typename T>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
{
return x < y ? y : x;
@@ -1224,8 +1281,8 @@
template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
{
return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
}
@@ -1273,15 +1330,22 @@
}
template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
{
return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
}
template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+EIGEN_MATHFUNC_RETVAL(sign, Scalar) sign(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(sign, Scalar)::run(x);
+}
+
+template<typename Scalar>
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
{
return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
}
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index 23acd8a..f65c7a6 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -221,7 +221,7 @@
* remain row-vectors and vectors remain vectors.
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Matrix& operator=(const DenseBase<OtherDerived>& other)
{
return Base::_set(other);
@@ -234,14 +234,14 @@
* \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase<OtherDerived> &other)
{
return Base::operator=(other);
}
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue<OtherDerived>& func)
{
return Base::operator=(func);
@@ -257,7 +257,7 @@
*
* \sa resize(Index,Index)
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Matrix() : Base()
{
EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
@@ -269,7 +269,7 @@
: Base(internal::constructor_without_unaligned_array_assert())
{ EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Matrix(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
: Base(std::move(other)) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
@@ -287,7 +287,7 @@
* \sa Matrix(const std::initializer_list<std::initializer_list<Scalar>>&)
*/
template <typename... ArgTypes>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Matrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
: Base(a0, a1, a2, a3, args...) {}
@@ -312,7 +312,7 @@
*
* \sa Matrix(const Scalar& a0, const Scalar& a1, const Scalar& a2, const Scalar& a3, const ArgTypes&... args)
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
#ifndef EIGEN_PARSED_BY_DOXYGEN
@@ -400,7 +400,7 @@
/** \brief Copy constructor */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Matrix(const Matrix& other) : Base(other)
{ }
@@ -408,7 +408,7 @@
* \sa MatrixBase::operator=(const EigenBase<OtherDerived>&)
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other)
: Base(other.derived())
{ }
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index a5463b3..d5b78f3 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -144,11 +144,11 @@
// trouble with MSVC.
template <typename OtherDerived>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Derived& operator=(const DenseBase<OtherDerived>& other);
template <typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Derived& operator=(const EigenBase<OtherDerived>& other);
template<typename OtherDerived>
@@ -156,19 +156,19 @@
Derived& operator=(const ReturnByValue<OtherDerived>& other);
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Derived& operator+=(const MatrixBase<OtherDerived>& other);
template<typename OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Derived& operator-=(const MatrixBase<OtherDerived>& other);
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const Product<Derived,OtherDerived>
operator*(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const Product<Derived,OtherDerived,LazyProduct>
lazyProduct(const MatrixBase<OtherDerived> &other) const;
@@ -186,12 +186,17 @@
const Product<Derived, DiagonalDerived, LazyProduct>
operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
- template<typename OtherDerived>
+ template<typename SkewDerived>
EIGEN_DEVICE_FUNC
+ const Product<Derived, SkewDerived, LazyProduct>
+ operator*(const SkewSymmetricBase<SkewDerived> &skew) const;
+
+ template<typename OtherDerived>
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
dot(const MatrixBase<OtherDerived>& other) const;
- EIGEN_DEVICE_FUNC RealScalar squaredNorm() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR RealScalar squaredNorm() const;
EIGEN_DEVICE_FUNC RealScalar norm() const;
RealScalar stableNorm() const;
RealScalar blueNorm() const;
@@ -205,11 +210,11 @@
EIGEN_DEVICE_FUNC void adjointInPlace();
typedef Diagonal<Derived> DiagonalReturnType;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
DiagonalReturnType diagonal();
typedef Diagonal<const Derived> ConstDiagonalReturnType;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const ConstDiagonalReturnType diagonal() const;
template<int Index>
@@ -229,10 +234,10 @@
template<unsigned int Mode> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; };
template<unsigned int Mode>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
typename TriangularViewReturnType<Mode>::Type triangularView();
template<unsigned int Mode>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
typename ConstTriangularViewReturnType<Mode>::Type triangularView() const;
template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SelfAdjointView<Derived, UpLo> Type; };
@@ -247,18 +252,20 @@
const SparseView<Derived> sparseView(const Scalar& m_reference = Scalar(0),
const typename NumTraits<Scalar>::Real& m_epsilon = NumTraits<Scalar>::dummy_precision()) const;
- EIGEN_DEVICE_FUNC static const IdentityReturnType Identity();
- EIGEN_DEVICE_FUNC static const IdentityReturnType Identity(Index rows, Index cols);
- EIGEN_DEVICE_FUNC static const BasisReturnType Unit(Index size, Index i);
- EIGEN_DEVICE_FUNC static const BasisReturnType Unit(Index i);
- EIGEN_DEVICE_FUNC static const BasisReturnType UnitX();
- EIGEN_DEVICE_FUNC static const BasisReturnType UnitY();
- EIGEN_DEVICE_FUNC static const BasisReturnType UnitZ();
- EIGEN_DEVICE_FUNC static const BasisReturnType UnitW();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const IdentityReturnType Identity();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const IdentityReturnType Identity(Index rows, Index cols);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const BasisReturnType Unit(Index size, Index i);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const BasisReturnType Unit(Index i);
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const BasisReturnType UnitX();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const BasisReturnType UnitY();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const BasisReturnType UnitZ();
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static const BasisReturnType UnitW();
EIGEN_DEVICE_FUNC
const DiagonalWrapper<const Derived> asDiagonal() const;
const PermutationWrapper<const Derived> asPermutation() const;
+ EIGEN_DEVICE_FUNC
+ const SkewSymmetricWrapper<const Derived> asSkewSymmetric() const;
EIGEN_DEVICE_FUNC
Derived& setIdentity();
@@ -273,6 +280,8 @@
bool isUpperTriangular(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
bool isLowerTriangular(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+ bool isSkewSymmetric(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
+
template<typename OtherDerived>
bool isOrthogonal(const MatrixBase<OtherDerived>& other,
const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
@@ -283,7 +292,7 @@
* fuzzy comparison such as isApprox()
* \sa isApprox(), operator!= */
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC inline bool operator==(const MatrixBase<OtherDerived>& other) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline bool operator==(const MatrixBase<OtherDerived>& other) const
{ return cwiseEqual(other).all(); }
/** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other.
@@ -291,7 +300,7 @@
* fuzzy comparison such as isApprox()
* \sa isApprox(), operator== */
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline bool operator!=(const MatrixBase<OtherDerived>& other) const
{ return cwiseNotEqual(other).any(); }
NoAlias<Derived,Eigen::MatrixBase > EIGEN_DEVICE_FUNC noalias();
@@ -303,7 +312,7 @@
template<bool Enable> inline const Derived& forceAlignedAccessIf() const { return derived(); }
template<bool Enable> inline Derived& forceAlignedAccessIf() { return derived(); }
- EIGEN_DEVICE_FUNC Scalar trace() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Scalar trace() const;
template<int p> EIGEN_DEVICE_FUNC RealScalar lpNorm() const;
@@ -312,10 +321,10 @@
/** \returns an \link Eigen::ArrayBase Array \endlink expression of this matrix
* \sa ArrayBase::matrix() */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ArrayWrapper<Derived> array() { return ArrayWrapper<Derived>(derived()); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR ArrayWrapper<Derived> array() { return ArrayWrapper<Derived>(derived()); }
/** \returns a const \link Eigen::ArrayBase Array \endlink expression of this matrix
* \sa ArrayBase::matrix() */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArrayWrapper<const Derived> array() const { return ArrayWrapper<const Derived>(derived()); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const ArrayWrapper<const Derived> array() const { return ArrayWrapper<const Derived>(derived()); }
/////////// LU module ///////////
@@ -386,7 +395,7 @@
};
#endif // EIGEN_PARSED_BY_DOXYGEN
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
inline typename cross_product_return_type<OtherDerived>::type
#else
diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h
index 74edd2c..4f1f992 100644
--- a/Eigen/src/Core/NumTraits.h
+++ b/Eigen/src/Core/NumTraits.h
@@ -63,10 +63,10 @@
{
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static int run() {
- using std::log;
+ using std::log2;
using std::ceil;
typedef typename NumTraits<T>::Real Real;
- return int(ceil(-log(NumTraits<Real>::epsilon())/log(static_cast<Real>(2))));
+ return int(ceil(-log2(NumTraits<Real>::epsilon())));
}
};
diff --git a/Eigen/src/Core/PartialReduxEvaluator.h b/Eigen/src/Core/PartialReduxEvaluator.h
index 693fc35..818c7eb 100644
--- a/Eigen/src/Core/PartialReduxEvaluator.h
+++ b/Eigen/src/Core/PartialReduxEvaluator.h
@@ -169,7 +169,7 @@
Alignment = 0 // FIXME this will need to be improved once PartialReduxExpr is vectorized
};
- EIGEN_DEVICE_FUNC explicit evaluator(const XprType xpr)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR explicit evaluator(const XprType xpr)
: m_arg(xpr.nestedExpression()), m_functor(xpr.functor())
{
EIGEN_INTERNAL_CHECK_COST_VALUE(TraversalSize==Dynamic ? HugeCost : (TraversalSize==0 ? 1 : int(CostOpType::value)));
@@ -178,13 +178,13 @@
typedef typename XprType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const Scalar coeff(Index i, Index j) const
{
return coeff(Direction==Vertical ? j : i);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const Scalar coeff(Index index) const
{
return m_functor(m_arg.template subVector<DirectionType(Direction)>(index));
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h
index 222eaf5..5e32564 100644
--- a/Eigen/src/Core/PlainObjectBase.h
+++ b/Eigen/src/Core/PlainObjectBase.h
@@ -30,7 +30,7 @@
template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
template<typename Index>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static EIGEN_ALWAYS_INLINE void run(Index, Index)
{
}
@@ -146,9 +146,9 @@
EIGEN_STATIC_ASSERT((MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic), INVALID_MATRIX_TEMPLATE_PARAMETERS)
EIGEN_STATIC_ASSERT(((Options & (DontAlign|RowMajor)) == Options), INVALID_MATRIX_TEMPLATE_PARAMETERS)
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Base& base() { return *static_cast<Base*>(this); }
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const Base& base() const { return *static_cast<const Base*>(this); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
@@ -173,7 +173,7 @@
* provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
*
* See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
{
return m_storage.data()[index];
@@ -183,7 +183,7 @@
* provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
*
* See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const for details. */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
{
if(Flags & RowMajorBit)
@@ -196,7 +196,7 @@
* provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
*
* See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const for details. */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
{
return m_storage.data()[index];
@@ -204,7 +204,7 @@
/** This is the const version of coeffRef(Index,Index) which is thus synonym of coeff(Index,Index).
* It is provided for convenience. */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
{
if(Flags & RowMajorBit)
@@ -256,11 +256,11 @@
}
/** \returns a const pointer to the data array of this matrix */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const Scalar *data() const
{ return m_storage.data(); }
/** \returns a pointer to the data array of this matrix */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Scalar *data()
{ return m_storage.data(); }
/** Resizes \c *this to a \a rows x \a cols matrix.
@@ -279,7 +279,7 @@
*
* \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
*/
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
{
eigen_assert(internal::check_implication(RowsAtCompileTime!=Dynamic, rows==RowsAtCompileTime)
@@ -362,7 +362,7 @@
* remain row-vectors and vectors remain vectors.
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
{
const OtherDerived& other = _other.derived();
@@ -484,7 +484,7 @@
// by making all its constructor protected. See bug 1074.
protected:
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
{
// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
@@ -501,7 +501,7 @@
}
#endif
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT
: m_storage( std::move(other.m_storage) )
{
@@ -515,7 +515,7 @@
}
/** Copy constructor */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
: Base(), m_storage(other.m_storage) { }
EIGEN_DEVICE_FUNC
@@ -586,7 +586,7 @@
/** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
: m_storage()
{
@@ -619,7 +619,7 @@
* \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
{
_resize_to_match(other);
@@ -639,9 +639,9 @@
* \see class Map
*/
///@{
- static inline ConstMapType Map(const Scalar* data)
+ static EIGEN_CONSTEXPR ConstMapType Map(const Scalar* data)
{ return ConstMapType(data); }
- static inline MapType Map(Scalar* data)
+ static EIGEN_CONSTEXPR MapType Map(Scalar* data)
{ return MapType(data); }
static inline ConstMapType Map(const Scalar* data, Index size)
{ return ConstMapType(data, size); }
@@ -741,7 +741,7 @@
* remain row-vectors and vectors remain vectors.
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
{
#ifdef EIGEN_NO_AUTOMATIC_RESIZING
@@ -771,7 +771,7 @@
// aliasing is dealt once in internal::call_assignment
// so at this stage we have to assume aliasing... and resising has to be done later.
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
{
internal::call_assignment(this->derived(), other.derived());
@@ -797,7 +797,7 @@
}
template<typename T0, typename T1>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, std::enable_if_t<Base::SizeAtCompileTime!=2,T0>* = 0)
{
const bool t0_is_integer_alike = internal::is_valid_index_type<T0>::value;
@@ -809,7 +809,7 @@
}
template<typename T0, typename T1>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _init2(const T0& val0, const T1& val1, std::enable_if_t<Base::SizeAtCompileTime==2,T0>* = 0)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
@@ -818,7 +818,7 @@
}
template<typename T0, typename T1>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
std::enable_if_t< (!internal::is_same<Index,Scalar>::value)
&& (internal::is_same<T0,Index>::value)
@@ -847,7 +847,7 @@
// We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitly converted)
template<typename T>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _init1(const Scalar& val0, std::enable_if_t<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>* = 0)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
@@ -883,14 +883,14 @@
// Initialize an arbitrary matrix from an object convertible to the Derived type.
template<typename T>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _init1(const Derived& other){
this->_set_noalias(other);
}
// Initialize an arbitrary matrix from a generic Eigen expression
template<typename T, typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
this->derived() = other;
}
@@ -947,7 +947,7 @@
* of same type it is enough to swap the data pointers.
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void swap(DenseBase<OtherDerived> & other)
{
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
@@ -958,7 +958,7 @@
* \brief const version forwarded to DenseBase::swap
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void swap(DenseBase<OtherDerived> const & other)
{ Base::swap(other.derived()); }
@@ -1083,7 +1083,7 @@
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
struct matrix_swap_impl
{
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static EIGEN_STRONG_INLINE void run(MatrixTypeA& a, MatrixTypeB& b)
{
a.base().swap(b);
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 85842d1..9ce0880 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -92,7 +92,7 @@
typedef internal::remove_all_t<LhsNested> LhsNestedCleaned;
typedef internal::remove_all_t<RhsNested> RhsNestedCleaned;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
{
eigen_assert(lhs.cols() == rhs.rows()
@@ -105,9 +105,9 @@
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const LhsNestedCleaned& lhs() const { return m_lhs; }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const RhsNestedCleaned& rhs() const { return m_rhs; }
protected:
@@ -169,7 +169,7 @@
public:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Scalar coeff(Index row, Index col) const
{
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
@@ -177,7 +177,7 @@
return internal::evaluator<Derived>(derived()).coeff(row,col);
}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index i) const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Scalar coeff(Index i) const
{
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h
index 05ffa25..c496e7c 100644
--- a/Eigen/src/Core/ProductEvaluators.h
+++ b/Eigen/src/Core/ProductEvaluators.h
@@ -34,7 +34,7 @@
typedef Product<Lhs, Rhs, Options> XprType;
typedef product_evaluator<XprType> Base;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr) : Base(xpr) {}
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR explicit evaluator(const XprType& xpr) : Base(xpr) {}
};
// Catch "scalar * ( A * B )" and transform it to "(A*scalar) * B"
@@ -139,7 +139,7 @@
std::enable_if_t<(Options==DefaultProduct || Options==AliasFreeProduct)>>
{
typedef Product<Lhs,Rhs,Options> SrcXprType;
- static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
{
Index dstRows = src.rows();
@@ -314,7 +314,7 @@
};
template<typename Dst>
- static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
}
@@ -397,7 +397,7 @@
typedef typename Product<Lhs,Rhs>::Scalar Scalar;
template<typename Dst>
- static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
// Same as: dst.noalias() = lhs.lazyProduct(rhs);
// but easier on the compiler side
@@ -497,7 +497,7 @@
typedef typename XprType::Scalar Scalar;
typedef typename XprType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit product_evaluator(const XprType& xpr)
: m_lhs(xpr.lhs()),
m_rhs(xpr.rhs()),
@@ -603,7 +603,7 @@
&& (int(InnerSize) % packet_traits<Scalar>::size == 0)
};
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const CoeffReturnType coeff(Index row, Index col) const
{
return (m_lhs.row(row).transpose().cwiseProduct( m_rhs.col(col) )).sum();
}
@@ -1174,6 +1174,40 @@
}
};
+/***************************************************************************
+* skew symmetric products
+* for now we just call the generic implementation
+***************************************************************************/
+template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
+struct generic_product_impl<Lhs, Rhs, SkewSymmetricShape, MatrixShape, ProductTag>
+{
+ template<typename Dest>
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
+ {
+ generic_product_impl<typename Lhs::DenseMatrixType , Rhs, DenseShape, MatrixShape, ProductTag>::evalTo(dst, lhs, rhs);
+ }
+};
+
+template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
+struct generic_product_impl<Lhs, Rhs, MatrixShape, SkewSymmetricShape, ProductTag>
+{
+ template<typename Dest>
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
+ {
+ generic_product_impl<Lhs, typename Rhs::DenseMatrixType, MatrixShape, DenseShape, ProductTag>::evalTo(dst, lhs, rhs);
+ }
+};
+
+template<typename Lhs, typename Rhs, int ProductTag>
+struct generic_product_impl<Lhs, Rhs, SkewSymmetricShape, SkewSymmetricShape, ProductTag>
+{
+ template<typename Dest>
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
+ {
+ generic_product_impl<typename Lhs::DenseMatrixType, typename Rhs::DenseMatrixType, DenseShape, DenseShape, ProductTag>::evalTo(dst, lhs, rhs);
+ }
+};
+
} // end namespace internal
} // end namespace Eigen
diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h
index d3efad9..8a3bf5e 100644
--- a/Eigen/src/Core/Redux.h
+++ b/Eigen/src/Core/Redux.h
@@ -106,7 +106,7 @@
typedef typename Evaluator::Scalar Scalar;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static EIGEN_STRONG_INLINE Scalar run(const Evaluator &eval, const Func& func)
{
return func(redux_novec_unroller<Func, Evaluator, Start, HalfLength>::run(eval,func),
@@ -124,7 +124,7 @@
typedef typename Evaluator::Scalar Scalar;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static EIGEN_STRONG_INLINE Scalar run(const Evaluator &eval, const Func&)
{
return eval.coeffByOuterInner(outer, inner);
@@ -196,12 +196,11 @@
typedef typename Evaluator::Scalar Scalar;
template<typename XprType>
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar run(const Evaluator &eval, const Func& func, const XprType& xpr)
{
eigen_assert(xpr.rows()>0 && xpr.cols()>0 && "you are using an empty matrix");
- Scalar res;
- res = eval.coeffByOuterInner(0, 0);
+ Scalar res = eval.coeffByOuterInner(0, 0);
for(Index i = 1; i < xpr.innerSize(); ++i)
res = func(res, eval.coeffByOuterInner(0, i));
for(Index i = 1; i < xpr.outerSize(); ++i)
@@ -218,7 +217,7 @@
typedef redux_novec_unroller<Func,Evaluator, 0, Evaluator::SizeAtCompileTime> Base;
typedef typename Evaluator::Scalar Scalar;
template<typename XprType>
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Scalar run(const Evaluator &eval, const Func& func, const XprType& /*xpr*/)
{
return Base::run(eval,func);
@@ -361,7 +360,7 @@
typedef internal::evaluator<XprType_> Base;
public:
typedef XprType_ XprType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
explicit redux_evaluator(const XprType &xpr) : Base(xpr) {}
typedef typename XprType::Scalar Scalar;
@@ -377,16 +376,16 @@
SizeAtCompileTime = XprType::SizeAtCompileTime,
InnerSizeAtCompileTime = XprType::InnerSizeAtCompileTime
};
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
{ return Base::coeff(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
-
+
template<int LoadMode, typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
PacketType packetByOuterInner(Index outer, Index inner) const
{ return Base::template packet<LoadMode,PacketType>(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
-
+
};
} // end namespace internal
@@ -407,7 +406,7 @@
*/
template<typename Derived>
template<typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar
DenseBase<Derived>::redux(const Func& func) const
{
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
@@ -429,13 +428,13 @@
*/
template<typename Derived>
template<int NaNPropagation>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar
DenseBase<Derived>::minCoeff() const
{
return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar, NaNPropagation>());
}
-/** \returns the maximum of all coefficients of \c *this.
+/** \returns the maximum of all coefficients of \c *this.
* In case \c *this contains NaN, NaNPropagation determines the behavior:
* NaNPropagation == PropagateFast : undefined
* NaNPropagation == PropagateNaN : result is NaN
@@ -444,7 +443,7 @@
*/
template<typename Derived>
template<int NaNPropagation>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar
DenseBase<Derived>::maxCoeff() const
{
return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar, NaNPropagation>());
@@ -457,7 +456,7 @@
* \sa trace(), prod(), mean()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar
DenseBase<Derived>::sum() const
{
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
@@ -470,7 +469,7 @@
* \sa trace(), prod(), sum()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar
DenseBase<Derived>::mean() const
{
#ifdef __INTEL_COMPILER
@@ -491,7 +490,7 @@
* \sa sum(), mean(), trace()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar
DenseBase<Derived>::prod() const
{
if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
@@ -506,7 +505,7 @@
* \sa diagonal(), sum()
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::traits<Derived>::Scalar
MatrixBase<Derived>::trace() const
{
return derived().diagonal().sum();
diff --git a/Eigen/src/Core/Ref.h b/Eigen/src/Core/Ref.h
index 81de5f9..3948b8a 100644
--- a/Eigen/src/Core/Ref.h
+++ b/Eigen/src/Core/Ref.h
@@ -82,7 +82,7 @@
: this->rows();
}
- EIGEN_DEVICE_FUNC RefBase()
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR RefBase()
: Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
// Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
@@ -108,7 +108,7 @@
// Returns true if construction is valid, false if there is a stride mismatch,
// and fails if there is a size mismatch.
template<typename Expression>
- EIGEN_DEVICE_FUNC bool construct(Expression& expr)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool construct(Expression& expr)
{
// Check matrix sizes. If this is a compile-time vector, we do allow
// implicitly transposing.
@@ -338,7 +338,7 @@
EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
template<typename Derived>
- EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Ref(const DenseBase<Derived>& expr,
std::enable_if_t<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>* = 0)
{
// std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
@@ -359,7 +359,7 @@
protected:
template<typename Expression>
- EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void construct(const Expression& expr,internal::true_type)
{
// Check if we can use the underlying expr's storage directly, otherwise call the copy version.
if (!Base::construct(expr)) {
@@ -368,7 +368,7 @@
}
template<typename Expression>
- EIGEN_DEVICE_FUNC void construct(const Expression& expr, internal::false_type)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void construct(const Expression& expr, internal::false_type)
{
internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar,Scalar>());
Base::construct(m_object);
diff --git a/Eigen/src/Core/SkewSymmetricMatrix3.h b/Eigen/src/Core/SkewSymmetricMatrix3.h
new file mode 100644
index 0000000..7f6b5fd
--- /dev/null
+++ b/Eigen/src/Core/SkewSymmetricMatrix3.h
@@ -0,0 +1,412 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SKEWSYMMETRICMATRIX3_H
+#define EIGEN_SKEWSYMMETRICMATRIX3_H
+
+#include "./InternalHeaderCheck.h"
+
+namespace Eigen {
+
+/** \class SkewSymmetricBase
+ * \ingroup Core_Module
+ *
+ * \brief Base class for skew symmetric matrices and expressions
+ *
+ * This is the base class that is inherited by SkewSymmetricMatrix3 and related expression
+ * types, which internally use a three vector for storing the entries. SkewSymmetric
+ * types always represent square three times three matrices.
+ *
+ * This implementations follows class DiagonalMatrix
+ *
+ * \tparam Derived is the derived type, a SkewSymmetricMatrix3 or SkewSymmetricWrapper.
+ *
+ * \sa class SkewSymmetricMatrix3, class SkewSymmetricWrapper
+ */
+template<typename Derived>
+class SkewSymmetricBase : public EigenBase<Derived>
+{
+ public:
+ typedef typename internal::traits<Derived>::SkewSymmetricVectorType SkewSymmetricVectorType;
+ typedef typename SkewSymmetricVectorType::Scalar Scalar;
+ typedef typename SkewSymmetricVectorType::RealScalar RealScalar;
+ typedef typename internal::traits<Derived>::StorageKind StorageKind;
+ typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
+
+ enum {
+ RowsAtCompileTime = SkewSymmetricVectorType::SizeAtCompileTime,
+ ColsAtCompileTime = SkewSymmetricVectorType::SizeAtCompileTime,
+ MaxRowsAtCompileTime = SkewSymmetricVectorType::MaxSizeAtCompileTime,
+ MaxColsAtCompileTime = SkewSymmetricVectorType::MaxSizeAtCompileTime,
+ IsVectorAtCompileTime = 0,
+ Flags = NoPreferredStorageOrderBit
+ };
+
+ typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
+ typedef DenseMatrixType DenseType;
+ typedef SkewSymmetricMatrix3<Scalar> PlainObject;
+
+ /** \returns a reference to the derived object. */
+ EIGEN_DEVICE_FUNC
+ inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
+ /** \returns a const reference to the derived object. */
+ EIGEN_DEVICE_FUNC
+ inline Derived& derived() { return *static_cast<Derived*>(this); }
+
+ /**
+ * Constructs a dense matrix from \c *this. Note, this directly returns a dense matrix type,
+ * not an expression.
+ * \returns A dense matrix, with its entries set from the the derived object. */
+ EIGEN_DEVICE_FUNC
+ DenseMatrixType toDenseMatrix() const { return derived(); }
+
+ /** Determinant vanishes */
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ inline Scalar determinant() const { return 0; }
+
+ /** A.transpose() = -A */
+ EIGEN_DEVICE_FUNC
+ PlainObject transpose() const { return (-vector()).asSkewSymmetric(); }
+
+ /** \returns the exponential of this matrix using Rodrigues’ formula */
+ EIGEN_DEVICE_FUNC
+ DenseMatrixType exponential() const {
+ DenseMatrixType retVal = DenseMatrixType::Identity();
+ const SkewSymmetricVectorType& v = vector();
+ if (v.isZero()) {
+ return retVal;
+ }
+ const Scalar norm2 = v.squaredNorm();
+ const Scalar norm = numext::sqrt(norm2);
+ retVal += ((((1 - numext::cos(norm))/norm2)*derived())*derived()) + (numext::sin(norm)/norm)*derived().toDenseMatrix();
+ return retVal;
+ }
+
+ /** \returns a reference to the derived object's vector of coefficients. */
+ EIGEN_DEVICE_FUNC
+ inline const SkewSymmetricVectorType& vector() const { return derived().vector(); }
+ /** \returns a const reference to the derived object's vector of coefficients. */
+ EIGEN_DEVICE_FUNC
+ inline SkewSymmetricVectorType& vector() { return derived().vector(); }
+
+ /** \returns the number of rows. */
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ inline Index rows() const { return 3; }
+ /** \returns the number of columns. */
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ inline Index cols() const { return 3; }
+
+ /** \returns the matrix product of \c *this by the dense matrix, \a matrix */
+ template<typename MatrixDerived>
+ EIGEN_DEVICE_FUNC
+ Product<Derived,MatrixDerived,LazyProduct>
+ operator*(const MatrixBase<MatrixDerived> &matrix) const
+ {
+ return Product<Derived, MatrixDerived, LazyProduct>(derived(), matrix.derived());
+ }
+
+ /** \returns the matrix product of \c *this by the skew symmetric matrix, \a matrix */
+ template<typename MatrixDerived>
+ EIGEN_DEVICE_FUNC
+ Product<Derived,MatrixDerived,LazyProduct>
+ operator*(const SkewSymmetricBase<MatrixDerived> &matrix) const
+ {
+ return Product<Derived, MatrixDerived, LazyProduct>(derived(), matrix.derived());
+ }
+
+ template <typename OtherDerived>
+ using SkewSymmetricProductReturnType = SkewSymmetricWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(
+ SkewSymmetricVectorType, typename OtherDerived::SkewSymmetricVectorType, product)>;
+
+ /** \returns the wedge product of \c *this by the skew symmetric matrix \a other
+ * A wedge B = AB - BA */
+ template <typename OtherDerived>
+ EIGEN_DEVICE_FUNC SkewSymmetricProductReturnType<OtherDerived> wedge(
+ const SkewSymmetricBase<OtherDerived>& other) const {
+ return vector().cross(other.vector()).asSkewSymmetric();
+ }
+
+ using SkewSymmetricScaleReturnType =
+ SkewSymmetricWrapper<const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(SkewSymmetricVectorType, Scalar, product)>;
+
+ /** \returns the product of \c *this by the scalar \a scalar */
+ EIGEN_DEVICE_FUNC
+ inline SkewSymmetricScaleReturnType operator*(const Scalar& scalar) const {
+ return (vector() * scalar).asSkewSymmetric();
+ }
+
+ using ScaleSkewSymmetricReturnType =
+ SkewSymmetricWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar, SkewSymmetricVectorType, product)>;
+
+ /** \returns the product of a scalar and the skew symmetric matrix \a other */
+ EIGEN_DEVICE_FUNC
+ friend inline ScaleSkewSymmetricReturnType operator*(const Scalar& scalar, const SkewSymmetricBase& other) {
+ return (scalar * other.vector()).asSkewSymmetric();
+ }
+
+ template <typename OtherDerived>
+ using SkewSymmetricSumReturnType = SkewSymmetricWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(
+ SkewSymmetricVectorType, typename OtherDerived::SkewSymmetricVectorType, sum)>;
+
+ /** \returns the sum of \c *this and the skew symmetric matrix \a other */
+ template <typename OtherDerived>
+ EIGEN_DEVICE_FUNC inline SkewSymmetricSumReturnType<OtherDerived> operator+(
+ const SkewSymmetricBase<OtherDerived>& other) const {
+ return (vector() + other.vector()).asSkewSymmetric();
+ }
+
+ template <typename OtherDerived>
+ using SkewSymmetricDifferenceReturnType = SkewSymmetricWrapper<const EIGEN_CWISE_BINARY_RETURN_TYPE(
+ SkewSymmetricVectorType, typename OtherDerived::SkewSymmetricVectorType, difference)>;
+
+ /** \returns the difference of \c *this and the skew symmetric matrix \a other */
+ template <typename OtherDerived>
+ EIGEN_DEVICE_FUNC inline SkewSymmetricDifferenceReturnType<OtherDerived> operator-(
+ const SkewSymmetricBase<OtherDerived>& other) const {
+ return (vector() - other.vector()).asSkewSymmetric();
+ }
+};
+
+/** \class SkewSymmetricMatrix3
+ * \ingroup Core_Module
+ *
+ * \brief Represents a 3x3 skew symmetric matrix with its storage
+ *
+ * \tparam Scalar_ the type of coefficients
+ *
+ * \sa class SkewSymmetricBase, class SkewSymmetricWrapper
+ */
+
+namespace internal {
+template<typename Scalar_>
+struct traits<SkewSymmetricMatrix3<Scalar_> >
+ : traits<Matrix<Scalar_,3,3,0,3,3> >
+{
+ typedef Matrix<Scalar_,3,1,0,3,1> SkewSymmetricVectorType;
+ typedef SkewSymmetricShape StorageKind;
+ enum {
+ Flags = LvalueBit | NoPreferredStorageOrderBit | NestByRefBit
+ };
+};
+}
+template<typename Scalar_>
+class SkewSymmetricMatrix3
+ : public SkewSymmetricBase<SkewSymmetricMatrix3<Scalar_> >
+{
+ public:
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ typedef typename internal::traits<SkewSymmetricMatrix3>::SkewSymmetricVectorType SkewSymmetricVectorType;
+ typedef const SkewSymmetricMatrix3& Nested;
+ typedef Scalar_ Scalar;
+ typedef typename internal::traits<SkewSymmetricMatrix3>::StorageKind StorageKind;
+ typedef typename internal::traits<SkewSymmetricMatrix3>::StorageIndex StorageIndex;
+ #endif
+
+ protected:
+
+ SkewSymmetricVectorType m_vector;
+
+ public:
+
+ /** const version of vector(). */
+ EIGEN_DEVICE_FUNC
+ inline const SkewSymmetricVectorType& vector() const { return m_vector; }
+ /** \returns a reference to the stored vector of coefficients. */
+ EIGEN_DEVICE_FUNC
+ inline SkewSymmetricVectorType& vector() { return m_vector; }
+
+ /** Default constructor without initialization */
+ EIGEN_DEVICE_FUNC
+ inline SkewSymmetricMatrix3() {}
+
+ /** Constructor from three scalars */
+ EIGEN_DEVICE_FUNC
+ inline SkewSymmetricMatrix3(const Scalar& x, const Scalar& y, const Scalar& z) : m_vector(x,y,z) {}
+
+ /** \brief Constructs a SkewSymmetricMatrix3 from an r-value vector type */
+ EIGEN_DEVICE_FUNC
+ explicit inline SkewSymmetricMatrix3(SkewSymmetricVectorType&& vec) : m_vector(std::move(vec)) {}
+
+ /** generic constructor from expression of the coefficients */
+ template<typename OtherDerived>
+ EIGEN_DEVICE_FUNC
+ explicit inline SkewSymmetricMatrix3(const MatrixBase<OtherDerived>& other) : m_vector(other)
+ {}
+
+ /** Copy constructor. */
+ template<typename OtherDerived>
+ EIGEN_DEVICE_FUNC
+ inline SkewSymmetricMatrix3(const SkewSymmetricBase<OtherDerived>& other) : m_vector(other.vector()) {}
+
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
+ inline SkewSymmetricMatrix3(const SkewSymmetricMatrix3& other) : m_vector(other.vector()) {}
+ #endif
+
+ /** Copy operator. */
+ template<typename OtherDerived>
+ EIGEN_DEVICE_FUNC
+ SkewSymmetricMatrix3& operator=(const SkewSymmetricBase<OtherDerived>& other)
+ {
+ m_vector = other.vector();
+ return *this;
+ }
+
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ /** This is a special case of the templated operator=. Its purpose is to
+ * prevent a default operator= from hiding the templated operator=.
+ */
+ EIGEN_DEVICE_FUNC
+ SkewSymmetricMatrix3& operator=(const SkewSymmetricMatrix3& other)
+ {
+ m_vector = other.vector();
+ return *this;
+ }
+ #endif
+
+ typedef SkewSymmetricWrapper<const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, SkewSymmetricVectorType>>
+ InitializeReturnType;
+
+ /** Initializes a skew symmetric matrix with coefficients set to zero */
+ EIGEN_DEVICE_FUNC
+ static InitializeReturnType Zero() { return SkewSymmetricVectorType::Zero().asSkewSymmetric(); }
+
+ /** Sets all coefficients to zero. */
+ EIGEN_DEVICE_FUNC
+ inline void setZero() { m_vector.setZero(); }
+};
+
+/** \class SkewSymmetricWrapper
+ * \ingroup Core_Module
+ *
+ * \brief Expression of a skew symmetric matrix
+ *
+ * \tparam SkewSymmetricVectorType_ the type of the vector of coefficients
+ *
+ * This class is an expression of a skew symmetric matrix, but not storing its own vector of coefficients,
+ * instead wrapping an existing vector expression. It is the return type of MatrixBase::asSkewSymmetric()
+ * and most of the time this is the only way that it is used.
+ *
+ * \sa class SkewSymmetricMatrix3, class SkewSymmetricBase, MatrixBase::asSkewSymmetric()
+ */
+
+namespace internal {
+template<typename SkewSymmetricVectorType_>
+struct traits<SkewSymmetricWrapper<SkewSymmetricVectorType_> >
+{
+ typedef SkewSymmetricVectorType_ SkewSymmetricVectorType;
+ typedef typename SkewSymmetricVectorType::Scalar Scalar;
+ typedef typename SkewSymmetricVectorType::StorageIndex StorageIndex;
+ typedef SkewSymmetricShape StorageKind;
+ typedef typename traits<SkewSymmetricVectorType>::XprKind XprKind;
+ enum {
+ RowsAtCompileTime = SkewSymmetricVectorType::SizeAtCompileTime,
+ ColsAtCompileTime = SkewSymmetricVectorType::SizeAtCompileTime,
+ MaxRowsAtCompileTime = SkewSymmetricVectorType::MaxSizeAtCompileTime,
+ MaxColsAtCompileTime = SkewSymmetricVectorType::MaxSizeAtCompileTime,
+ Flags = (traits<SkewSymmetricVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit
+ };
+};
+}
+
+template<typename SkewSymmetricVectorType_>
+class SkewSymmetricWrapper
+ : public SkewSymmetricBase<SkewSymmetricWrapper<SkewSymmetricVectorType_> >, internal::no_assignment_operator
+{
+ public:
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ typedef SkewSymmetricVectorType_ SkewSymmetricVectorType;
+ typedef SkewSymmetricWrapper Nested;
+ #endif
+
+ /** Constructor from expression of coefficients to wrap. */
+ EIGEN_DEVICE_FUNC
+ explicit inline SkewSymmetricWrapper(SkewSymmetricVectorType& a_vector) : m_vector(a_vector) {}
+
+ /** \returns a const reference to the wrapped expression of coefficients. */
+ EIGEN_DEVICE_FUNC
+ const SkewSymmetricVectorType& vector() const { return m_vector; }
+
+ protected:
+ typename SkewSymmetricVectorType::Nested m_vector;
+};
+
+/** \returns a pseudo-expression of a skew symmetric matrix with *this as vector of coefficients
+ *
+ * \only_for_vectors
+ *
+ * \sa class SkewSymmetricWrapper, class SkewSymmetricMatrix3, vector(), isSkewSymmetric()
+ **/
+template<typename Derived>
+EIGEN_DEVICE_FUNC inline const SkewSymmetricWrapper<const Derived>
+MatrixBase<Derived>::asSkewSymmetric() const
+{
+ return SkewSymmetricWrapper<const Derived>(derived());
+}
+
+/** \returns true if *this is approximately equal to a skew symmetric matrix,
+ * within the precision given by \a prec.
+ */
+template<typename Derived>
+bool MatrixBase<Derived>::isSkewSymmetric(const RealScalar& prec) const
+{
+ if(cols() != rows()) return false;
+ return (this->transpose() + *this).isZero(prec);
+}
+
+/** \returns the matrix product of \c *this by the skew symmetric matrix \skew.
+ */
+template<typename Derived>
+template<typename SkewDerived>
+EIGEN_DEVICE_FUNC inline const Product<Derived, SkewDerived, LazyProduct>
+MatrixBase<Derived>::operator*(const SkewSymmetricBase<SkewDerived> &skew) const
+{
+ return Product<Derived, SkewDerived, LazyProduct>(derived(), skew.derived());
+}
+
+namespace internal {
+
+template<> struct storage_kind_to_shape<SkewSymmetricShape> { typedef SkewSymmetricShape Shape; };
+
+struct SkewSymmetric2Dense {};
+
+template<> struct AssignmentKind<DenseShape,SkewSymmetricShape> { typedef SkewSymmetric2Dense Kind; };
+
+// SkewSymmetric matrix to Dense assignment
+template< typename DstXprType, typename SrcXprType, typename Functor>
+struct Assignment<DstXprType, SrcXprType, Functor, SkewSymmetric2Dense>
+{
+ static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
+ {
+ if((dst.rows()!=3) || (dst.cols()!=3)) {
+ dst.resize(3, 3);
+ }
+ dst.diagonal().setZero();
+ const typename SrcXprType::SkewSymmetricVectorType v = src.vector();
+ dst(0, 1) = -v(2);
+ dst(1, 0) = v(2);
+ dst(0, 2) = v(1);
+ dst(2, 0) = -v(1);
+ dst(1, 2) = -v(0);
+ dst(2, 1) = v(0);
+ }
+
+ static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
+ { dst.vector() += src.vector(); }
+
+ static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
+ { dst.vector() -= src.vector(); }
+};
+
+} // namespace internal
+
+} // end namespace Eigen
+
+#endif // EIGEN_SKEWSYMMETRICMATRIX3_H
diff --git a/Eigen/src/Core/Solve.h b/Eigen/src/Core/Solve.h
index f77eac9..91f7c2f 100644
--- a/Eigen/src/Core/Solve.h
+++ b/Eigen/src/Core/Solve.h
@@ -67,15 +67,15 @@
typedef typename internal::traits<Solve>::PlainObject PlainObject;
typedef typename internal::traits<Solve>::StorageIndex StorageIndex;
- Solve(const Decomposition &dec, const RhsType &rhs)
+ EIGEN_CONSTEXPR Solve(const Decomposition &dec, const RhsType &rhs)
: m_dec(dec), m_rhs(rhs)
{}
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_dec.cols(); }
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
- EIGEN_DEVICE_FUNC const Decomposition& dec() const { return m_dec; }
- EIGEN_DEVICE_FUNC const RhsType& rhs() const { return m_rhs; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR const Decomposition& dec() const { return m_dec; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR const RhsType& rhs() const { return m_rhs; }
protected:
const Decomposition &m_dec;
@@ -139,7 +139,7 @@
struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense>
{
typedef Solve<DecType,RhsType> SrcXprType;
- static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
+ EIGEN_CONSTEXPR static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
{
Index dstRows = src.rows();
Index dstCols = src.cols();
diff --git a/Eigen/src/Core/SolveTriangular.h b/Eigen/src/Core/SolveTriangular.h
index 71d6f85..a92b14b 100644
--- a/Eigen/src/Core/SolveTriangular.h
+++ b/Eigen/src/Core/SolveTriangular.h
@@ -87,7 +87,7 @@
typedef blas_traits<Lhs> LhsProductTraits;
typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
- static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
+ static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void run(const Lhs& lhs, Rhs& rhs)
{
add_const_on_value_type_t<ActualLhsType> actualLhs = LhsProductTraits::extract(lhs);
@@ -120,7 +120,7 @@
DiagIndex = IsLower ? LoopIndex : Size - LoopIndex - 1,
StartIndex = IsLower ? 0 : DiagIndex+1
};
- static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
+ static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void run(const Lhs& lhs, Rhs& rhs)
{
if (LoopIndex>0)
rhs.coeffRef(DiagIndex) -= lhs.row(DiagIndex).template segment<LoopIndex>(StartIndex).transpose()
@@ -135,12 +135,12 @@
template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size>
struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,true> {
- static EIGEN_DEVICE_FUNC void run(const Lhs&, Rhs&) {}
+ static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void run(const Lhs&, Rhs&) {}
};
template<typename Lhs, typename Rhs, int Mode>
struct triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,1> {
- static EIGEN_DEVICE_FUNC void run(const Lhs& lhs, Rhs& rhs)
+ static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void run(const Lhs& lhs, Rhs& rhs)
{ triangular_solver_unroller<Lhs,Rhs,Mode,0,Rhs::SizeAtCompileTime>::run(lhs,rhs); }
};
@@ -166,7 +166,7 @@
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename MatrixType, unsigned int Mode>
template<int Side, typename OtherDerived>
-EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
{
OtherDerived& other = _other.const_cast_derived();
eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
diff --git a/Eigen/src/Core/Stride.h b/Eigen/src/Core/Stride.h
index 2832e80..3e1d85d 100644
--- a/Eigen/src/Core/Stride.h
+++ b/Eigen/src/Core/Stride.h
@@ -61,7 +61,7 @@
};
/** Default constructor, for use when strides are fixed at compile time */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Stride()
: m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
{
@@ -71,14 +71,14 @@
}
/** Constructor allowing to pass the strides at runtime */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Stride(Index outerStride, Index innerStride)
: m_outer(outerStride), m_inner(innerStride)
{
}
/** Copy constructor */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Stride(const Stride& other)
: m_outer(other.outer()), m_inner(other.inner())
{}
diff --git a/Eigen/src/Core/Swap.h b/Eigen/src/Core/Swap.h
index b2e7511..f5b5400 100644
--- a/Eigen/src/Core/Swap.h
+++ b/Eigen/src/Core/Swap.h
@@ -32,7 +32,7 @@
typedef typename Base::DstXprType DstXprType;
typedef swap_assign_op<Scalar> Functor;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
generic_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
: Base(dst, src, func, dstExpr)
{}
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 74650ef..45198e4 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -62,7 +62,7 @@
EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
typedef internal::remove_all_t<MatrixType> NestedExpression;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit EIGEN_STRONG_INLINE Transpose(MatrixType& matrix) : m_matrix(matrix) {}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
@@ -73,12 +73,12 @@
Index cols() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
/** \returns the nested expression */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const internal::remove_all_t<MatrixTypeNested>&
nestedExpression() const { return m_matrix; }
/** \returns the nested expression */
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
std::remove_reference_t<MatrixTypeNested>&
nestedExpression() { return m_matrix; }
@@ -127,9 +127,9 @@
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index innerStride() const { return derived().nestedExpression().innerStride(); }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
Index outerStride() const { return derived().nestedExpression().outerStride(); }
typedef std::conditional_t<
@@ -138,9 +138,9 @@
const Scalar
> ScalarWithConstIfNotLvalue;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const Scalar* data() const { return derived().nestedExpression().data(); }
// FIXME: shall we keep the const version of coeffRef?
@@ -179,7 +179,7 @@
*
* \sa transposeInPlace(), adjoint() */
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename DenseBase<Derived>::TransposeReturnType
DenseBase<Derived>::transpose()
{
@@ -192,7 +192,7 @@
*
* \sa transposeInPlace(), adjoint() */
template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const typename DenseBase<Derived>::ConstTransposeReturnType
DenseBase<Derived>::transpose() const
{
@@ -402,7 +402,7 @@
template<typename Scalar, bool DestIsTransposed, typename OtherDerived>
struct check_transpose_aliasing_run_time_selector
{
- static bool run(const Scalar* dest, const OtherDerived& src)
+ static EIGEN_CONSTEXPR bool run(const Scalar* dest, const OtherDerived& src)
{
return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src));
}
@@ -411,7 +411,7 @@
template<typename Scalar, bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
struct check_transpose_aliasing_run_time_selector<Scalar,DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
{
- static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
+ static EIGEN_CONSTEXPR bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
{
return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.lhs())))
|| ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.rhs())));
@@ -431,7 +431,7 @@
>
struct checkTransposeAliasing_impl
{
- static void run(const Derived& dst, const OtherDerived& other)
+ static void EIGEN_CONSTEXPR run(const Derived& dst, const OtherDerived& other)
{
eigen_assert((!check_transpose_aliasing_run_time_selector
<typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived>
@@ -445,12 +445,12 @@
template<typename Derived, typename OtherDerived>
struct checkTransposeAliasing_impl<Derived, OtherDerived, false>
{
- static void run(const Derived&, const OtherDerived&)
+ static EIGEN_CONSTEXPR void run(const Derived&, const OtherDerived&)
{
}
};
-template<typename Dst, typename Src>
+template<typename Dst, typename Src> EIGEN_CONSTEXPR
void check_for_aliasing(const Dst &dst, const Src &src)
{
if((!Dst::IsVectorAtCompileTime) && dst.rows()>1 && dst.cols()>1)
diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index c1bd13a..4abc6f3 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -53,7 +53,7 @@
typedef DenseMatrixType DenseType;
typedef Derived const& Nested;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline TriangularBase() { eigen_assert(!((int(Mode) & int(UnitDiag)) && (int(Mode) & int(ZeroDiag)))); }
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
@@ -66,7 +66,7 @@
inline Index innerStride() const EIGEN_NOEXCEPT { return derived().innerStride(); }
// dummy resize function
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
void resize(Index rows, Index cols)
{
EIGEN_UNUSED_VARIABLE(rows);
@@ -102,9 +102,9 @@
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline Derived& derived() { return *static_cast<Derived*>(this); }
#endif // not EIGEN_PARSED_BY_DOXYGEN
@@ -216,7 +216,7 @@
IsVectorAtCompileTime = false
};
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
{}
@@ -230,11 +230,11 @@
inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
/** \returns a const reference to the nested expression */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const NestedExpression& nestedExpression() const { return m_matrix; }
/** \returns a reference to the nested expression */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
NestedExpression& nestedExpression() { return m_matrix; }
typedef TriangularView<const MatrixConjugateReturnType,Mode> ConjugateReturnType;
@@ -280,7 +280,7 @@
}
template<typename Other>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline const Solve<TriangularView, Other>
solve(const MatrixBase<Other>& other) const
{ return Solve<TriangularView, Other>(*this, other.derived()); }
@@ -515,11 +515,11 @@
* See TriangularView:solve() for the details.
*/
template<int Side, typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
void solveInPlace(const MatrixBase<OtherDerived>& other) const;
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
void solveInPlace(const MatrixBase<OtherDerived>& other) const
{ return solveInPlace<OnTheLeft>(other); }
@@ -547,7 +547,7 @@
}
template<typename RhsType, typename DstType>
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
if(!internal::is_same_dense(dst,rhs))
dst = rhs;
@@ -641,7 +641,7 @@
*/
template<typename Derived>
template<unsigned int Mode>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
MatrixBase<Derived>::triangularView()
{
@@ -651,7 +651,7 @@
/** This is the const version of MatrixBase::triangularView() */
template<typename Derived>
template<unsigned int Mode>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
MatrixBase<Derived>::triangularView() const
{
@@ -734,7 +734,7 @@
{
typedef TriangularView<MatrixType,Mode> XprType;
typedef evaluator<internal::remove_all_t<MatrixType>> Base;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
};
@@ -770,7 +770,8 @@
typedef typename Base::AssignmentTraits AssignmentTraits;
- EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
+ triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
: Base(dst, src, func, dstExpr)
{}
@@ -784,14 +785,14 @@
using Base::assignCoeff;
#endif
- EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void assignDiagonalCoeff(Index id)
{
if(Mode==UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(1));
else if(Mode==ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(0));
else if(Mode==0) Base::assignCoeff(id,id);
}
- EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index row, Index col)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR void assignOppositeCoeff(Index row, Index col)
{
eigen_internal_assert(row!=col);
if(SetOpposite)
@@ -800,7 +801,7 @@
};
template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType, typename Functor>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
{
typedef evaluator<DstXprType> DstEvaluatorType;
@@ -853,7 +854,7 @@
template< typename DstXprType, typename SrcXprType, typename Functor>
struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
{
- EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
{
call_triangular_assignment_loop<SrcXprType::Mode, (int(SrcXprType::Mode) & int(SelfAdjoint)) == 0>(dst, src, func);
}
@@ -862,7 +863,7 @@
template< typename DstXprType, typename SrcXprType, typename Functor>
struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
{
- EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
{
call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
}
@@ -883,7 +884,7 @@
typedef typename Kernel::Scalar Scalar;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static inline void run(Kernel &kernel)
{
triangular_assignment_loop<Kernel, Mode, UnrollCount-1, SetOpposite>::run(kernel);
@@ -901,7 +902,7 @@
template<typename Kernel, unsigned int Mode, bool SetOpposite>
struct triangular_assignment_loop<Kernel, Mode, 0, SetOpposite>
{
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
static inline void run(Kernel &) {}
};
diff --git a/Eigen/src/Core/VectorBlock.h b/Eigen/src/Core/VectorBlock.h
index ee28da1..77a5c33 100644
--- a/Eigen/src/Core/VectorBlock.h
+++ b/Eigen/src/Core/VectorBlock.h
@@ -74,7 +74,7 @@
/** Dynamic-size constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
VectorBlock(VectorType& vector, Index start, Index size)
: Base(vector,
IsColVector ? start : 0, IsColVector ? 0 : start,
@@ -83,7 +83,7 @@
/** Fixed-size constructor
*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
VectorBlock(VectorType& vector, Index start)
: Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
{ }
diff --git a/Eigen/src/Core/VectorwiseOp.h b/Eigen/src/Core/VectorwiseOp.h
index b004f76..9692620 100644
--- a/Eigen/src/Core/VectorwiseOp.h
+++ b/Eigen/src/Core/VectorwiseOp.h
@@ -63,7 +63,7 @@
typedef typename internal::dense_xpr_base<PartialReduxExpr>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr)
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
: m_matrix(mat), m_functor(func) {}
@@ -72,10 +72,10 @@
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
Index cols() const EIGEN_NOEXCEPT { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
typename MatrixType::Nested nestedExpression() const { return m_matrix; }
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const MemberOp& functor() const { return m_functor; }
protected:
@@ -93,7 +93,7 @@
template<int Size> struct Cost { enum { value = COST }; }; \
enum { Vectorizable = VECTORIZABLE }; \
template<typename XprType> \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR \
ResultType operator()(const XprType& mat) const \
{ return mat.MEMBER(); } \
BinaryOp binaryFunc() const { return BinaryOp(); } \
@@ -265,11 +265,11 @@
}
public:
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
explicit inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {}
/** \internal */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline const ExpressionType& _expression() const { return m_matrix; }
#ifdef EIGEN_PARSED_BY_DOXYGEN
@@ -476,7 +476,7 @@
* Output: \verbinclude PartialRedux_sum.out
*
* \sa DenseBase::sum() */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const SumReturnType sum() const
{ return SumReturnType(_expression()); }
@@ -484,7 +484,7 @@
* of each column (or row) of the referenced expression.
*
* \sa DenseBase::mean() */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const MeanReturnType mean() const
{ return sum() / Scalar(Direction==Vertical?m_matrix.rows():m_matrix.cols()); }
@@ -493,7 +493,7 @@
* This expression can be assigned to a vector with entries of type \c bool.
*
* \sa DenseBase::all() */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const AllReturnType all() const
{ return AllReturnType(_expression()); }
@@ -502,7 +502,7 @@
* This expression can be assigned to a vector with entries of type \c bool.
*
* \sa DenseBase::any() */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const AnyReturnType any() const
{ return AnyReturnType(_expression()); }
@@ -515,7 +515,7 @@
* Output: \verbinclude PartialRedux_count.out
*
* \sa DenseBase::count() */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const CountReturnType count() const
{ return CountReturnType(_expression()); }
@@ -526,7 +526,7 @@
* Output: \verbinclude PartialRedux_prod.out
*
* \sa DenseBase::prod() */
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
const ProdReturnType prod() const
{ return ProdReturnType(_expression()); }
@@ -760,7 +760,7 @@
* \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::ColwiseReturnType
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR typename DenseBase<Derived>::ColwiseReturnType
DenseBase<Derived>::colwise()
{
return ColwiseReturnType(derived());
@@ -774,7 +774,7 @@
* \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
*/
template<typename Derived>
-EIGEN_DEVICE_FUNC inline typename DenseBase<Derived>::RowwiseReturnType
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR typename DenseBase<Derived>::RowwiseReturnType
DenseBase<Derived>::rowwise()
{
return RowwiseReturnType(derived());
diff --git a/Eigen/src/Core/arch/AVX/MathFunctions.h b/Eigen/src/Core/arch/AVX/MathFunctions.h
index bddd6aa..43aea54 100644
--- a/Eigen/src/Core/arch/AVX/MathFunctions.h
+++ b/Eigen/src/Core/arch/AVX/MathFunctions.h
@@ -34,6 +34,24 @@
template <>
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet8f
+pasin<Packet8f>(const Packet8f& _x) {
+ return pasin_float(_x);
+}
+
+template <>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet8f
+pacos<Packet8f>(const Packet8f& _x) {
+ return pacos_float(_x);
+}
+
+template <>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet8f
+patan<Packet8f>(const Packet8f& _x) {
+ return patan_float(_x);
+}
+
+template <>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet8f
plog<Packet8f>(const Packet8f& _x) {
return plog_float(_x);
}
diff --git a/Eigen/src/Core/arch/AVX/PacketMath.h b/Eigen/src/Core/arch/AVX/PacketMath.h
index e01913a..8f346f3 100644
--- a/Eigen/src/Core/arch/AVX/PacketMath.h
+++ b/Eigen/src/Core/arch/AVX/PacketMath.h
@@ -33,7 +33,9 @@
typedef __m256 Packet8f;
typedef eigen_packet_wrapper<__m256i, 0> Packet8i;
typedef __m256d Packet4d;
+#ifndef EIGEN_VECTORIZE_AVX512FP16
typedef eigen_packet_wrapper<__m128i, 2> Packet8h;
+#endif
typedef eigen_packet_wrapper<__m128i, 3> Packet8bf;
#ifdef EIGEN_VECTORIZE_AVX2
@@ -45,7 +47,9 @@
template<> struct is_arithmetic<__m256i> { enum { value = true }; };
template<> struct is_arithmetic<__m256d> { enum { value = true }; };
template<> struct is_arithmetic<Packet8i> { enum { value = true }; };
+#ifndef EIGEN_VECTORIZE_AVX512FP16
template<> struct is_arithmetic<Packet8h> { enum { value = true }; };
+#endif
template<> struct is_arithmetic<Packet8bf> { enum { value = true }; };
#ifdef EIGEN_VECTORIZE_AVX2
template<> struct is_arithmetic<Packet4l> { enum { value = true }; };
@@ -69,6 +73,9 @@
HasReciprocal = EIGEN_FAST_MATH,
HasSin = EIGEN_FAST_MATH,
HasCos = EIGEN_FAST_MATH,
+ HasACos = 1,
+ HasASin = 1,
+ HasATan = 1,
HasLog = 1,
HasLog1p = 1,
HasExpm1 = 1,
@@ -204,6 +211,7 @@
enum {
Vectorizable = 1,
AlignedOnScalar = 1,
+ HasCmp = 1,
size=8
};
};
@@ -218,6 +226,7 @@
enum {
Vectorizable = 1,
AlignedOnScalar = 1,
+ HasCmp = 1,
size=4,
// requires AVX512
@@ -625,7 +634,7 @@
}
template<> EIGEN_STRONG_INLINE Packet8f pmin<Packet8f>(const Packet8f& a, const Packet8f& b) {
-#if EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC < 63
+#if EIGEN_COMP_GNUC && EIGEN_COMP_GNUC < 63
// There appears to be a bug in GCC, by which the optimizer may flip
// the argument order in calls to _mm_min_ps/_mm_max_ps, so we have to
// resort to inline ASM here. This is supposed to be fixed in gcc6.3,
@@ -639,7 +648,7 @@
#endif
}
template<> EIGEN_STRONG_INLINE Packet4d pmin<Packet4d>(const Packet4d& a, const Packet4d& b) {
-#if EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC < 63
+#if EIGEN_COMP_GNUC && EIGEN_COMP_GNUC < 63
// See pmin above
Packet4d res;
asm("vminpd %[a], %[b], %[res]" : [res] "=x" (res) : [a] "x" (a), [b] "x" (b));
@@ -660,7 +669,7 @@
}
template<> EIGEN_STRONG_INLINE Packet8f pmax<Packet8f>(const Packet8f& a, const Packet8f& b) {
-#if EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC < 63
+#if EIGEN_COMP_GNUC && EIGEN_COMP_GNUC < 63
// See pmin above
Packet8f res;
asm("vmaxps %[a], %[b], %[res]" : [res] "=x" (res) : [a] "x" (a), [b] "x" (b));
@@ -671,7 +680,7 @@
#endif
}
template<> EIGEN_STRONG_INLINE Packet4d pmax<Packet4d>(const Packet4d& a, const Packet4d& b) {
-#if EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC < 63
+#if EIGEN_COMP_GNUC && EIGEN_COMP_GNUC < 63
// See pmin above
Packet4d res;
asm("vmaxpd %[a], %[b], %[res]" : [res] "=x" (res) : [a] "x" (a), [b] "x" (b));
@@ -691,6 +700,12 @@
#endif
}
+#ifdef EIGEN_VECTORIZE_AVX2
+template<> EIGEN_STRONG_INLINE Packet8i psign(const Packet8i& a) {
+ return _mm256_sign_epi32(_mm256_set1_epi32(1), a);
+}
+#endif
+
// Add specializations for min/max with prescribed NaN progation.
template<>
EIGEN_STRONG_INLINE Packet8f pmin<PropagateNumbers, Packet8f>(const Packet8f& a, const Packet8f& b) {
@@ -1334,21 +1349,37 @@
}
template<> EIGEN_STRONG_INLINE Packet8f pblend(const Selector<8>& ifPacket, const Packet8f& thenPacket, const Packet8f& elsePacket) {
+#ifdef EIGEN_VECTORIZE_AVX2
+ const __m256i zero = _mm256_setzero_si256();
+ const __m256i select = _mm256_set_epi32(ifPacket.select[7], ifPacket.select[6], ifPacket.select[5], ifPacket.select[4], ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
+ __m256i false_mask = _mm256_cmpeq_epi32(zero, select);
+ return _mm256_blendv_ps(thenPacket, elsePacket, _mm256_castsi256_ps(false_mask));
+#else
const __m256 zero = _mm256_setzero_ps();
const __m256 select = _mm256_set_ps(ifPacket.select[7], ifPacket.select[6], ifPacket.select[5], ifPacket.select[4], ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
__m256 false_mask = _mm256_cmp_ps(select, zero, _CMP_EQ_UQ);
return _mm256_blendv_ps(thenPacket, elsePacket, false_mask);
+#endif
}
+
template<> EIGEN_STRONG_INLINE Packet4d pblend(const Selector<4>& ifPacket, const Packet4d& thenPacket, const Packet4d& elsePacket) {
+#ifdef EIGEN_VECTORIZE_AVX2
+ const __m256i zero = _mm256_setzero_si256();
+ const __m256i select = _mm256_set_epi64x(ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
+ __m256i false_mask = _mm256_cmpeq_epi64(select, zero);
+ return _mm256_blendv_pd(thenPacket, elsePacket, _mm256_castsi256_pd(false_mask));
+#else
const __m256d zero = _mm256_setzero_pd();
const __m256d select = _mm256_set_pd(ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
__m256d false_mask = _mm256_cmp_pd(select, zero, _CMP_EQ_UQ);
return _mm256_blendv_pd(thenPacket, elsePacket, false_mask);
+#endif
}
// Packet math for Eigen::half
-
+#ifndef EIGEN_VECTORIZE_AVX512FP16
template<> struct unpacket_traits<Packet8h> { typedef Eigen::half type; enum {size=8, alignment=Aligned16, vectorizable=true, masked_load_available=false, masked_store_available=false}; typedef Packet8h half; };
+#endif
template<> EIGEN_STRONG_INLINE Packet8h pset1<Packet8h>(const Eigen::half& from) {
return _mm_set1_epi16(numext::bit_cast<numext::uint16_t>(from));
@@ -1495,6 +1526,7 @@
return _mm_xor_si128(a, sign_mask);
}
+#ifndef EIGEN_VECTORIZE_AVX512FP16
template<> EIGEN_STRONG_INLINE Packet8h padd<Packet8h>(const Packet8h& a, const Packet8h& b) {
Packet8f af = half2float(a);
Packet8f bf = half2float(b);
@@ -1522,6 +1554,7 @@
Packet8f rf = pdiv(af, bf);
return float2half(rf);
}
+#endif
template<> EIGEN_STRONG_INLINE Packet8h pgather<Eigen::half, Packet8h>(const Eigen::half* from, Index stride)
{
@@ -1550,11 +1583,14 @@
to[stride*7] = aux[7];
}
+
+#ifndef EIGEN_VECTORIZE_AVX512FP16
template<> EIGEN_STRONG_INLINE Eigen::half predux<Packet8h>(const Packet8h& a) {
Packet8f af = half2float(a);
float reduced = predux<Packet8f>(af);
return Eigen::half(reduced);
}
+#endif
template<> EIGEN_STRONG_INLINE Eigen::half predux_max<Packet8h>(const Packet8h& a) {
Packet8f af = half2float(a);
diff --git a/Eigen/src/Core/arch/AVX512/MathFunctions.h b/Eigen/src/Core/arch/AVX512/MathFunctions.h
index 6afcb4e..79a9043 100644
--- a/Eigen/src/Core/arch/AVX512/MathFunctions.h
+++ b/Eigen/src/Core/arch/AVX512/MathFunctions.h
@@ -259,6 +259,24 @@
template <>
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet16f
+pacos<Packet16f>(const Packet16f& _x) {
+ return pacos_float(_x);
+}
+
+template <>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet16f
+pasin<Packet16f>(const Packet16f& _x) {
+ return pasin_float(_x);
+}
+
+template <>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet16f
+patan<Packet16f>(const Packet16f& _x) {
+ return patan_float(_x);
+}
+
+template <>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet16f
ptanh<Packet16f>(const Packet16f& _x) {
return internal::generic_fast_tanh_float(_x);
}
diff --git a/Eigen/src/Core/arch/AVX512/PacketMath.h b/Eigen/src/Core/arch/AVX512/PacketMath.h
index aab066a..7b07149 100644
--- a/Eigen/src/Core/arch/AVX512/PacketMath.h
+++ b/Eigen/src/Core/arch/AVX512/PacketMath.h
@@ -40,7 +40,9 @@
typedef __m512 Packet16f;
typedef __m512i Packet16i;
typedef __m512d Packet8d;
+#ifndef EIGEN_VECTORIZE_AVX512FP16
typedef eigen_packet_wrapper<__m256i, 1> Packet16h;
+#endif
typedef eigen_packet_wrapper<__m256i, 2> Packet16bf;
template <>
@@ -56,6 +58,7 @@
enum { value = true };
};
+#ifndef EIGEN_VECTORIZE_AVX512FP16
template<> struct is_arithmetic<Packet16h> { enum { value = true }; };
template <>
@@ -100,6 +103,7 @@
HasRint = 1
};
};
+#endif
template<> struct packet_traits<float> : default_packet_traits
{
@@ -118,6 +122,9 @@
HasBlend = 0,
HasSin = EIGEN_FAST_MATH,
HasCos = EIGEN_FAST_MATH,
+ HasACos = 1,
+ HasASin = 1,
+ HasATan = 1,
#if EIGEN_HAS_AVX512_MATH
HasLog = 1,
HasLog1p = 1,
@@ -170,6 +177,7 @@
enum {
Vectorizable = 1,
AlignedOnScalar = 1,
+ HasCmp = 1,
size=16
};
};
@@ -196,12 +204,14 @@
enum { size = 16, alignment=Aligned64, vectorizable=true, masked_load_available=false, masked_store_available=false };
};
+#ifndef EIGEN_VECTORIZE_AVX512FP16
template<>
struct unpacket_traits<Packet16h> {
typedef Eigen::half type;
typedef Packet8h half;
enum {size=16, alignment=Aligned32, vectorizable=true, masked_load_available=false, masked_store_available=false};
};
+#endif
template <>
EIGEN_STRONG_INLINE Packet16f pset1<Packet16f>(const float& from) {
@@ -1881,60 +1891,11 @@
}
EIGEN_STRONG_INLINE Packet16f half2float(const Packet16h& a) {
-#ifdef EIGEN_HAS_FP16_C
return _mm512_cvtph_ps(a);
-#else
- EIGEN_ALIGN64 half aux[16];
- pstore(aux, a);
- float f0(aux[0]);
- float f1(aux[1]);
- float f2(aux[2]);
- float f3(aux[3]);
- float f4(aux[4]);
- float f5(aux[5]);
- float f6(aux[6]);
- float f7(aux[7]);
- float f8(aux[8]);
- float f9(aux[9]);
- float fa(aux[10]);
- float fb(aux[11]);
- float fc(aux[12]);
- float fd(aux[13]);
- float fe(aux[14]);
- float ff(aux[15]);
-
- return _mm512_set_ps(
- ff, fe, fd, fc, fb, fa, f9, f8, f7, f6, f5, f4, f3, f2, f1, f0);
-#endif
}
EIGEN_STRONG_INLINE Packet16h float2half(const Packet16f& a) {
-#ifdef EIGEN_HAS_FP16_C
return _mm512_cvtps_ph(a, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC);
-#else
- EIGEN_ALIGN64 float aux[16];
- pstore(aux, a);
- half h0(aux[0]);
- half h1(aux[1]);
- half h2(aux[2]);
- half h3(aux[3]);
- half h4(aux[4]);
- half h5(aux[5]);
- half h6(aux[6]);
- half h7(aux[7]);
- half h8(aux[8]);
- half h9(aux[9]);
- half ha(aux[10]);
- half hb(aux[11]);
- half hc(aux[12]);
- half hd(aux[13]);
- half he(aux[14]);
- half hf(aux[15]);
-
- return _mm256_set_epi16(
- hf.x, he.x, hd.x, hc.x, hb.x, ha.x, h9.x, h8.x,
- h7.x, h6.x, h5.x, h4.x, h3.x, h2.x, h1.x, h0.x);
-#endif
}
template<> EIGEN_STRONG_INLINE Packet16h ptrue(const Packet16h& a) {
@@ -2024,6 +1985,7 @@
return _mm256_xor_si256(a, sign_mask);
}
+#ifndef EIGEN_VECTORIZE_AVX512FP16
template<> EIGEN_STRONG_INLINE Packet16h padd<Packet16h>(const Packet16h& a, const Packet16h& b) {
Packet16f af = half2float(a);
Packet16f bf = half2float(b);
@@ -2057,6 +2019,8 @@
return half(predux(from_float));
}
+#endif
+
template <>
EIGEN_STRONG_INLINE Packet8h predux_half_dowto4<Packet16h>(const Packet16h& a) {
Packet8h lane0 = _mm256_extractf128_si256(a, 0);
diff --git a/Eigen/src/Core/arch/AVX512/PacketMathFP16.h b/Eigen/src/Core/arch/AVX512/PacketMathFP16.h
new file mode 100644
index 0000000..324d050
--- /dev/null
+++ b/Eigen/src/Core/arch/AVX512/PacketMathFP16.h
@@ -0,0 +1,870 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+//
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_PACKET_MATH_FP16_AVX512_H
+#define EIGEN_PACKET_MATH_FP16_AVX512_H
+
+#include "../../InternalHeaderCheck.h"
+
+namespace Eigen {
+
+namespace internal {
+
+// Disable the code for older versions of gcc that don't support many of the required avx512 math instrinsics.
+#if EIGEN_GNUC_AT_LEAST(5, 3) || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC >= 1923 || EIGEN_COMP_ICC >= 1900
+#define EIGEN_HAS_AVX512_MATH 1
+#else
+#define EIGEN_HAS_AVX512_MATH 0
+#endif
+
+typedef __m512h Packet32h;
+typedef eigen_packet_wrapper<__m256i, 1> Packet16h;
+typedef eigen_packet_wrapper<__m128i, 2> Packet8h;
+
+template <>
+struct is_arithmetic<Packet8h> {
+ enum { value = true };
+};
+
+template <>
+struct packet_traits<half> : default_packet_traits {
+ typedef Packet32h type;
+ typedef Packet16h half;
+ enum {
+ Vectorizable = 1,
+ AlignedOnScalar = 1,
+ size = 32,
+ HasHalfPacket = 1,
+
+ HasCmp = 1,
+ HasAdd = 1,
+ HasSub = 1,
+ HasMul = 1,
+ HasDiv = 1,
+ HasNegate = 1,
+ HasAbs = 1,
+ HasAbs2 = 0,
+ HasMin = 1,
+ HasMax = 1,
+ HasConj = 1,
+ HasSetLinear = 0,
+ // These ones should be implemented in future
+ HasLog = EIGEN_HAS_AVX512_MATH,
+ HasLog1p = EIGEN_HAS_AVX512_MATH,
+ HasExp = EIGEN_HAS_AVX512_MATH,
+ HasExpm1 = EIGEN_HAS_AVX512_MATH,
+ HasSqrt = EIGEN_HAS_AVX512_MATH,
+ HasRsqrt = EIGEN_HAS_AVX512_MATH,
+ HasBessel = 0, // EIGEN_HAS_AVX512_MATH,
+ HasNdtri = 0, // EIGEN_HAS_AVX512_MATH,
+ HasSin = EIGEN_FAST_MATH,
+ HasCos = EIGEN_FAST_MATH,
+ HasTanh = EIGEN_FAST_MATH,
+ HasErf = 0, // EIGEN_FAST_MATH,
+ HasBlend = 0,
+ HasRound = 1,
+ HasFloor = 1,
+ HasCeil = 1,
+ HasRint = 1
+ };
+};
+
+template <>
+struct unpacket_traits<Packet32h> {
+ typedef Eigen::half type;
+ typedef Packet16h half;
+ enum {
+ size = 32,
+ alignment = Aligned64,
+ vectorizable = true,
+ masked_load_available = false,
+ masked_store_available = false
+ };
+};
+
+template <>
+struct unpacket_traits<Packet16h> {
+ typedef Eigen::half type;
+ typedef Packet8h half;
+ enum {
+ size = 16,
+ alignment = Aligned32,
+ vectorizable = true,
+ masked_load_available = false,
+ masked_store_available = false
+ };
+};
+
+template <>
+struct unpacket_traits<Packet8h> {
+ typedef Eigen::half type;
+ typedef Packet8h half;
+ enum {
+ size = 8,
+ alignment = Aligned16,
+ vectorizable = true,
+ masked_load_available = false,
+ masked_store_available = false
+ };
+};
+
+// Memory functions
+
+// pset1
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pset1<Packet32h>(const Eigen::half& from) {
+ return _mm512_set1_ph(static_cast<_Float16>(from));
+}
+
+// pset1frombits
+template <>
+EIGEN_STRONG_INLINE Packet32h pset1frombits<Packet32h>(unsigned short from) {
+ return _mm512_castsi512_ph(_mm512_set1_epi16(from));
+}
+
+// pfirst
+
+template <>
+EIGEN_STRONG_INLINE Eigen::half pfirst<Packet32h>(const Packet32h& from) {
+#ifdef EIGEN_VECTORIZE_AVX512DQ
+ return half_impl::raw_uint16_to_half(
+ static_cast<unsigned short>(_mm256_extract_epi16(_mm512_extracti32x8_epi32(_mm512_castph_si512(from), 0), 0)));
+#else
+ Eigen::half dest[32];
+ _mm512_storeu_ph(dest, from);
+ return dest[0];
+#endif
+}
+
+// pload
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pload<Packet32h>(const Eigen::half* from) {
+ EIGEN_DEBUG_ALIGNED_LOAD return _mm512_load_ph(from);
+}
+
+// ploadu
+
+template <>
+EIGEN_STRONG_INLINE Packet32h ploadu<Packet32h>(const Eigen::half* from) {
+ EIGEN_DEBUG_UNALIGNED_LOAD return _mm512_loadu_ph(from);
+}
+
+// pstore
+
+template <>
+EIGEN_STRONG_INLINE void pstore<half>(Eigen::half* to, const Packet32h& from) {
+ EIGEN_DEBUG_ALIGNED_STORE _mm512_store_ph(to, from);
+}
+
+// pstoreu
+
+template <>
+EIGEN_STRONG_INLINE void pstoreu<half>(Eigen::half* to, const Packet32h& from) {
+ EIGEN_DEBUG_UNALIGNED_STORE _mm512_storeu_ph(to, from);
+}
+
+// ploaddup
+template <>
+EIGEN_STRONG_INLINE Packet32h ploaddup<Packet32h>(const Eigen::half* from) {
+ __m512h a = _mm512_castph256_ph512(_mm256_loadu_ph(from));
+ return _mm512_permutexvar_ph(_mm512_set_epi16(15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6,
+ 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0),
+ a);
+}
+
+// ploadquad
+template <>
+EIGEN_STRONG_INLINE Packet32h ploadquad<Packet32h>(const Eigen::half* from) {
+ __m512h a = _mm512_castph128_ph512(_mm_loadu_ph(from));
+ return _mm512_permutexvar_ph(
+ _mm512_set_epi16(7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0),
+ a);
+}
+
+// pabs
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pabs<Packet32h>(const Packet32h& a) {
+ return _mm512_abs_ph(a);
+}
+
+// pmin
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pmin<Packet32h>(const Packet32h& a, const Packet32h& b) {
+ return _mm512_min_ph(a, b);
+}
+
+// pmax
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pmax<Packet32h>(const Packet32h& a, const Packet32h& b) {
+ return _mm512_max_ph(a, b);
+}
+
+// plset
+template <>
+EIGEN_STRONG_INLINE Packet32h plset<Packet32h>(const half& a) {
+ return _mm512_add_ph(_mm512_set1_ph(a),
+ _mm512_set_ph(31.0f, 30.0f, 29.0f, 28.0f, 27.0f, 26.0f, 25.0f, 24.0f, 23.0f, 22.0f, 21.0f, 20.0f,
+ 19.0f, 18.0f, 17.0f, 16.0f, 15.0f, 14.0f, 13.0f, 12.0f, 11.0f, 10.0f, 9.0f, 8.0f,
+ 7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f));
+}
+
+// por
+
+template <>
+EIGEN_STRONG_INLINE Packet32h por(const Packet32h& a, const Packet32h& b) {
+ return _mm512_castsi512_ph(_mm512_or_si512(_mm512_castph_si512(a), _mm512_castph_si512(b)));
+}
+
+// pxor
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pxor(const Packet32h& a, const Packet32h& b) {
+ return _mm512_castsi512_ph(_mm512_xor_si512(_mm512_castph_si512(a), _mm512_castph_si512(b)));
+}
+
+// pand
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pand(const Packet32h& a, const Packet32h& b) {
+ return _mm512_castsi512_ph(_mm512_and_si512(_mm512_castph_si512(a), _mm512_castph_si512(b)));
+}
+
+// pandnot
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pandnot(const Packet32h& a, const Packet32h& b) {
+ return _mm512_castsi512_ph(_mm512_andnot_si512(_mm512_castph_si512(b), _mm512_castph_si512(a)));
+}
+
+// pselect
+
+template <>
+EIGEN_DEVICE_FUNC inline Packet32h pselect(const Packet32h& mask, const Packet32h& a, const Packet32h& b) {
+ __mmask32 mask32 = _mm512_cmp_epi16_mask(_mm512_castph_si512(mask), _mm512_setzero_epi32(), _MM_CMPINT_EQ);
+ return _mm512_mask_blend_ph(mask32, a, b);
+}
+
+// pcmp_eq
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pcmp_eq(const Packet32h& a, const Packet32h& b) {
+ __mmask32 mask = _mm512_cmp_ph_mask(a, b, _CMP_EQ_OQ);
+ return _mm512_castsi512_ph(_mm512_mask_set1_epi16(_mm512_set1_epi32(0), mask, 0xffffu));
+}
+
+// pcmp_le
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pcmp_le(const Packet32h& a, const Packet32h& b) {
+ __mmask32 mask = _mm512_cmp_ph_mask(a, b, _CMP_LE_OQ);
+ return _mm512_castsi512_ph(_mm512_mask_set1_epi16(_mm512_set1_epi32(0), mask, 0xffffu));
+}
+
+// pcmp_lt
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pcmp_lt(const Packet32h& a, const Packet32h& b) {
+ __mmask32 mask = _mm512_cmp_ph_mask(a, b, _CMP_LT_OQ);
+ return _mm512_castsi512_ph(_mm512_mask_set1_epi16(_mm512_set1_epi32(0), mask, 0xffffu));
+}
+
+// pcmp_lt_or_nan
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pcmp_lt_or_nan(const Packet32h& a, const Packet32h& b) {
+ __mmask32 mask = _mm512_cmp_ph_mask(a, b, _CMP_NGE_UQ);
+ return _mm512_castsi512_ph(_mm512_mask_set1_epi16(_mm512_set1_epi16(0), mask, 0xffffu));
+}
+
+// padd
+
+template <>
+EIGEN_STRONG_INLINE Packet32h padd<Packet32h>(const Packet32h& a, const Packet32h& b) {
+ return _mm512_add_ph(a, b);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h padd<Packet16h>(const Packet16h& a, const Packet16h& b) {
+ return _mm256_castph_si256(_mm256_add_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h padd<Packet8h>(const Packet8h& a, const Packet8h& b) {
+ return _mm_castph_si128(_mm_add_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b)));
+}
+
+// psub
+
+template <>
+EIGEN_STRONG_INLINE Packet32h psub<Packet32h>(const Packet32h& a, const Packet32h& b) {
+ return _mm512_sub_ph(a, b);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h psub<Packet16h>(const Packet16h& a, const Packet16h& b) {
+ return _mm256_castph_si256(_mm256_sub_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h psub<Packet8h>(const Packet8h& a, const Packet8h& b) {
+ return _mm_castph_si128(_mm_sub_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b)));
+}
+
+// pmul
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pmul<Packet32h>(const Packet32h& a, const Packet32h& b) {
+ return _mm512_mul_ph(a, b);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pmul<Packet16h>(const Packet16h& a, const Packet16h& b) {
+ return _mm256_castph_si256(_mm256_mul_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h pmul<Packet8h>(const Packet8h& a, const Packet8h& b) {
+ return _mm_castph_si128(_mm_mul_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b)));
+}
+
+// pdiv
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pdiv<Packet32h>(const Packet32h& a, const Packet32h& b) {
+ return _mm512_div_ph(a, b);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pdiv<Packet16h>(const Packet16h& a, const Packet16h& b) {
+ return _mm256_castph_si256(_mm256_div_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h pdiv<Packet8h>(const Packet8h& a, const Packet8h& b) {
+ return _mm_castph_si128(_mm_div_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b)));
+}
+
+// pround
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pround<Packet32h>(const Packet32h& a) {
+ // Work-around for default std::round rounding mode.
+
+ // Mask for the sign bit
+ const Packet32h signMask = pset1frombits<Packet32h>(static_cast<numext::uint16_t>(0x8000u));
+ // The largest half-preicision float less than 0.5
+ const Packet32h prev0dot5 = pset1frombits<Packet32h>(static_cast<numext::uint16_t>(0x37FFu));
+
+ return _mm512_roundscale_ph(padd(por(pand(a, signMask), prev0dot5), a), _MM_FROUND_TO_ZERO);
+}
+
+// print
+
+template <>
+EIGEN_STRONG_INLINE Packet32h print<Packet32h>(const Packet32h& a) {
+ return _mm512_roundscale_ph(a, _MM_FROUND_CUR_DIRECTION);
+}
+
+// pceil
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pceil<Packet32h>(const Packet32h& a) {
+ return _mm512_roundscale_ph(a, _MM_FROUND_TO_POS_INF);
+}
+
+// pfloor
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pfloor<Packet32h>(const Packet32h& a) {
+ return _mm512_roundscale_ph(a, _MM_FROUND_TO_NEG_INF);
+}
+
+// predux
+template <>
+EIGEN_STRONG_INLINE half predux<Packet32h>(const Packet32h& a) {
+ return (half)_mm512_reduce_add_ph(a);
+}
+
+template <>
+EIGEN_STRONG_INLINE half predux<Packet16h>(const Packet16h& a) {
+ return (half)_mm256_reduce_add_ph(_mm256_castsi256_ph(a));
+}
+
+template <>
+EIGEN_STRONG_INLINE half predux<Packet8h>(const Packet8h& a) {
+ return (half)_mm_reduce_add_ph(_mm_castsi128_ph(a));
+}
+
+// predux_half_dowto4
+template <>
+EIGEN_STRONG_INLINE Packet16h predux_half_dowto4<Packet32h>(const Packet32h& a) {
+#ifdef EIGEN_VECTORIZE_AVX512DQ
+ __m256i lowHalf = _mm256_castps_si256(_mm512_extractf32x8_ps(_mm512_castph_ps(a), 0));
+ __m256i highHalf = _mm256_castps_si256(_mm512_extractf32x8_ps(_mm512_castph_ps(a), 1));
+
+ return Packet16h(padd<Packet16h>(lowHalf, highHalf));
+#else
+ Eigen::half data[32];
+ _mm512_storeu_ph(data, a);
+
+ __m256i lowHalf = _mm256_castph_si256(_mm256_loadu_ph(data));
+ __m256i highHalf = _mm256_castph_si256(_mm256_loadu_ph(data + 16));
+
+ return Packet16h(padd<Packet16h>(lowHalf, highHalf));
+#endif
+}
+
+// predux_max
+
+// predux_min
+
+// predux_mul
+
+#ifdef EIGEN_VECTORIZE_FMA
+
+// pmadd
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pmadd(const Packet32h& a, const Packet32h& b, const Packet32h& c) {
+ return _mm512_fmadd_ph(a, b, c);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pmadd(const Packet16h& a, const Packet16h& b, const Packet16h& c) {
+ return _mm256_castph_si256(_mm256_fmadd_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b), _mm256_castsi256_ph(c)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h pmadd(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
+ return _mm_castph_si128(_mm_fmadd_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b), _mm_castsi128_ph(c)));
+}
+
+// pmsub
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pmsub(const Packet32h& a, const Packet32h& b, const Packet32h& c) {
+ return _mm512_fmsub_ph(a, b, c);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pmsub(const Packet16h& a, const Packet16h& b, const Packet16h& c) {
+ return _mm256_castph_si256(_mm256_fmsub_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b), _mm256_castsi256_ph(c)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h pmsub(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
+ return _mm_castph_si128(_mm_fmsub_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b), _mm_castsi128_ph(c)));
+}
+
+// pnmadd
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pnmadd(const Packet32h& a, const Packet32h& b, const Packet32h& c) {
+ return _mm512_fnmadd_ph(a, b, c);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pnmadd(const Packet16h& a, const Packet16h& b, const Packet16h& c) {
+ return _mm256_castph_si256(_mm256_fnmadd_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b), _mm256_castsi256_ph(c)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h pnmadd(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
+ return _mm_castph_si128(_mm_fnmadd_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b), _mm_castsi128_ph(c)));
+}
+
+// pnmsub
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pnmsub(const Packet32h& a, const Packet32h& b, const Packet32h& c) {
+ return _mm512_fnmsub_ph(a, b, c);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pnmsub(const Packet16h& a, const Packet16h& b, const Packet16h& c) {
+ return _mm256_castph_si256(_mm256_fnmsub_ph(_mm256_castsi256_ph(a), _mm256_castsi256_ph(b), _mm256_castsi256_ph(c)));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8h pnmsub(const Packet8h& a, const Packet8h& b, const Packet8h& c) {
+ return _mm_castph_si128(_mm_fnmsub_ph(_mm_castsi128_ph(a), _mm_castsi128_ph(b), _mm_castsi128_ph(c)));
+}
+
+#endif
+
+// pnegate
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pnegate<Packet32h>(const Packet32h& a) {
+ return _mm512_sub_ph(_mm512_set1_ph(0.0), a);
+}
+
+// pconj
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pconj<Packet32h>(const Packet32h& a) {
+ return a;
+}
+
+// psqrt
+
+template <>
+EIGEN_STRONG_INLINE Packet32h psqrt<Packet32h>(const Packet32h& a) {
+ return _mm512_sqrt_ph(a);
+}
+
+// prsqrt
+
+template <>
+EIGEN_STRONG_INLINE Packet32h prsqrt<Packet32h>(const Packet32h& a) {
+ return _mm512_rsqrt_ph(a);
+}
+
+// preciprocal
+
+template <>
+EIGEN_STRONG_INLINE Packet32h preciprocal<Packet32h>(const Packet32h& a) {
+ return _mm512_rcp_ph(a);
+}
+
+// ptranspose
+
+EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet32h, 32>& a) {
+ __m512i t[32];
+
+ EIGEN_UNROLL_LOOP
+ for (int i = 0; i < 16; i++) {
+ t[2 * i] = _mm512_unpacklo_epi16(_mm512_castph_si512(a.packet[2 * i]), _mm512_castph_si512(a.packet[2 * i + 1]));
+ t[2 * i + 1] =
+ _mm512_unpackhi_epi16(_mm512_castph_si512(a.packet[2 * i]), _mm512_castph_si512(a.packet[2 * i + 1]));
+ }
+
+ __m512i p[32];
+
+ EIGEN_UNROLL_LOOP
+ for (int i = 0; i < 8; i++) {
+ p[4 * i] = _mm512_unpacklo_epi32(t[4 * i], t[4 * i + 2]);
+ p[4 * i + 1] = _mm512_unpackhi_epi32(t[4 * i], t[4 * i + 2]);
+ p[4 * i + 2] = _mm512_unpacklo_epi32(t[4 * i + 1], t[4 * i + 3]);
+ p[4 * i + 3] = _mm512_unpackhi_epi32(t[4 * i + 1], t[4 * i + 3]);
+ }
+
+ __m512i q[32];
+
+ EIGEN_UNROLL_LOOP
+ for (int i = 0; i < 4; i++) {
+ q[8 * i] = _mm512_unpacklo_epi64(p[8 * i], p[8 * i + 4]);
+ q[8 * i + 1] = _mm512_unpackhi_epi64(p[8 * i], p[8 * i + 4]);
+ q[8 * i + 2] = _mm512_unpacklo_epi64(p[8 * i + 1], p[8 * i + 5]);
+ q[8 * i + 3] = _mm512_unpackhi_epi64(p[8 * i + 1], p[8 * i + 5]);
+ q[8 * i + 4] = _mm512_unpacklo_epi64(p[8 * i + 2], p[8 * i + 6]);
+ q[8 * i + 5] = _mm512_unpackhi_epi64(p[8 * i + 2], p[8 * i + 6]);
+ q[8 * i + 6] = _mm512_unpacklo_epi64(p[8 * i + 3], p[8 * i + 7]);
+ q[8 * i + 7] = _mm512_unpackhi_epi64(p[8 * i + 3], p[8 * i + 7]);
+ }
+
+ __m512i f[32];
+
+#define PACKET32H_TRANSPOSE_HELPER(X, Y) \
+ do { \
+ f[Y * 8] = _mm512_inserti32x4(f[Y * 8], _mm512_extracti32x4_epi32(q[X * 8], Y), X); \
+ f[Y * 8 + 1] = _mm512_inserti32x4(f[Y * 8 + 1], _mm512_extracti32x4_epi32(q[X * 8 + 1], Y), X); \
+ f[Y * 8 + 2] = _mm512_inserti32x4(f[Y * 8 + 2], _mm512_extracti32x4_epi32(q[X * 8 + 2], Y), X); \
+ f[Y * 8 + 3] = _mm512_inserti32x4(f[Y * 8 + 3], _mm512_extracti32x4_epi32(q[X * 8 + 3], Y), X); \
+ f[Y * 8 + 4] = _mm512_inserti32x4(f[Y * 8 + 4], _mm512_extracti32x4_epi32(q[X * 8 + 4], Y), X); \
+ f[Y * 8 + 5] = _mm512_inserti32x4(f[Y * 8 + 5], _mm512_extracti32x4_epi32(q[X * 8 + 5], Y), X); \
+ f[Y * 8 + 6] = _mm512_inserti32x4(f[Y * 8 + 6], _mm512_extracti32x4_epi32(q[X * 8 + 6], Y), X); \
+ f[Y * 8 + 7] = _mm512_inserti32x4(f[Y * 8 + 7], _mm512_extracti32x4_epi32(q[X * 8 + 7], Y), X); \
+ } while (false);
+
+ PACKET32H_TRANSPOSE_HELPER(0, 0);
+ PACKET32H_TRANSPOSE_HELPER(1, 1);
+ PACKET32H_TRANSPOSE_HELPER(2, 2);
+ PACKET32H_TRANSPOSE_HELPER(3, 3);
+
+ PACKET32H_TRANSPOSE_HELPER(1, 0);
+ PACKET32H_TRANSPOSE_HELPER(2, 0);
+ PACKET32H_TRANSPOSE_HELPER(3, 0);
+ PACKET32H_TRANSPOSE_HELPER(2, 1);
+ PACKET32H_TRANSPOSE_HELPER(3, 1);
+ PACKET32H_TRANSPOSE_HELPER(3, 2);
+
+ PACKET32H_TRANSPOSE_HELPER(0, 1);
+ PACKET32H_TRANSPOSE_HELPER(0, 2);
+ PACKET32H_TRANSPOSE_HELPER(0, 3);
+ PACKET32H_TRANSPOSE_HELPER(1, 2);
+ PACKET32H_TRANSPOSE_HELPER(1, 3);
+ PACKET32H_TRANSPOSE_HELPER(2, 3);
+
+#undef PACKET32H_TRANSPOSE_HELPER
+
+ EIGEN_UNROLL_LOOP
+ for (int i = 0; i < 32; i++) {
+ a.packet[i] = _mm512_castsi512_ph(f[i]);
+ }
+}
+
+EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock<Packet32h, 4>& a) {
+ __m512i p0, p1, p2, p3, t0, t1, t2, t3, a0, a1, a2, a3;
+ t0 = _mm512_unpacklo_epi16(_mm512_castph_si512(a.packet[0]), _mm512_castph_si512(a.packet[1]));
+ t1 = _mm512_unpackhi_epi16(_mm512_castph_si512(a.packet[0]), _mm512_castph_si512(a.packet[1]));
+ t2 = _mm512_unpacklo_epi16(_mm512_castph_si512(a.packet[2]), _mm512_castph_si512(a.packet[3]));
+ t3 = _mm512_unpackhi_epi16(_mm512_castph_si512(a.packet[2]), _mm512_castph_si512(a.packet[3]));
+
+ p0 = _mm512_unpacklo_epi32(t0, t2);
+ p1 = _mm512_unpackhi_epi32(t0, t2);
+ p2 = _mm512_unpacklo_epi32(t1, t3);
+ p3 = _mm512_unpackhi_epi32(t1, t3);
+
+ a0 = p0;
+ a1 = p1;
+ a2 = p2;
+ a3 = p3;
+
+ a0 = _mm512_inserti32x4(a0, _mm512_extracti32x4_epi32(p1, 0), 1);
+ a1 = _mm512_inserti32x4(a1, _mm512_extracti32x4_epi32(p0, 1), 0);
+
+ a0 = _mm512_inserti32x4(a0, _mm512_extracti32x4_epi32(p2, 0), 2);
+ a2 = _mm512_inserti32x4(a2, _mm512_extracti32x4_epi32(p0, 2), 0);
+
+ a0 = _mm512_inserti32x4(a0, _mm512_extracti32x4_epi32(p3, 0), 3);
+ a3 = _mm512_inserti32x4(a3, _mm512_extracti32x4_epi32(p0, 3), 0);
+
+ a1 = _mm512_inserti32x4(a1, _mm512_extracti32x4_epi32(p2, 1), 2);
+ a2 = _mm512_inserti32x4(a2, _mm512_extracti32x4_epi32(p1, 2), 1);
+
+ a2 = _mm512_inserti32x4(a2, _mm512_extracti32x4_epi32(p3, 2), 3);
+ a3 = _mm512_inserti32x4(a3, _mm512_extracti32x4_epi32(p2, 3), 2);
+
+ a1 = _mm512_inserti32x4(a1, _mm512_extracti32x4_epi32(p3, 1), 3);
+ a3 = _mm512_inserti32x4(a3, _mm512_extracti32x4_epi32(p1, 3), 1);
+
+ a.packet[0] = _mm512_castsi512_ph(a0);
+ a.packet[1] = _mm512_castsi512_ph(a1);
+ a.packet[2] = _mm512_castsi512_ph(a2);
+ a.packet[3] = _mm512_castsi512_ph(a3);
+}
+
+// preverse
+
+template <>
+EIGEN_STRONG_INLINE Packet32h preverse(const Packet32h& a) {
+ return _mm512_permutexvar_ph(_mm512_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31),
+ a);
+}
+
+// pscatter
+
+template <>
+EIGEN_STRONG_INLINE void pscatter<half, Packet32h>(half* to, const Packet32h& from, Index stride) {
+ EIGEN_ALIGN64 half aux[32];
+ pstore(aux, from);
+
+ EIGEN_UNROLL_LOOP
+ for (int i = 0; i < 32; i++) {
+ to[stride * i] = aux[i];
+ }
+}
+
+// pgather
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pgather<Eigen::half, Packet32h>(const Eigen::half* from, Index stride) {
+ return _mm512_castsi512_ph(_mm512_set_epi16(
+ from[31 * stride].x, from[30 * stride].x, from[29 * stride].x, from[28 * stride].x, from[27 * stride].x,
+ from[26 * stride].x, from[25 * stride].x, from[24 * stride].x, from[23 * stride].x, from[22 * stride].x,
+ from[21 * stride].x, from[20 * stride].x, from[19 * stride].x, from[18 * stride].x, from[17 * stride].x,
+ from[16 * stride].x, from[15 * stride].x, from[14 * stride].x, from[13 * stride].x, from[12 * stride].x,
+ from[11 * stride].x, from[10 * stride].x, from[9 * stride].x, from[8 * stride].x, from[7 * stride].x,
+ from[6 * stride].x, from[5 * stride].x, from[4 * stride].x, from[3 * stride].x, from[2 * stride].x,
+ from[1 * stride].x, from[0 * stride].x));
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pcos<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h psin<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h plog<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h plog2<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h plog1p<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h pexp<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h pexpm1<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h ptanh<Packet16h>(const Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h pfrexp<Packet16h>(const Packet16h&, Packet16h&);
+template <>
+EIGEN_STRONG_INLINE Packet16h pldexp<Packet16h>(const Packet16h&, const Packet16h&);
+
+EIGEN_STRONG_INLINE Packet32h combine2Packet16h(const Packet16h& a, const Packet16h& b) {
+ __m512d result = _mm512_undefined_pd();
+ result = _mm512_insertf64x4(result, _mm256_castsi256_pd(a), 0);
+ result = _mm512_insertf64x4(result, _mm256_castsi256_pd(b), 1);
+ return _mm512_castpd_ph(result);
+}
+
+EIGEN_STRONG_INLINE void extract2Packet16h(const Packet32h& x, Packet16h& a, Packet16h& b) {
+ a = _mm256_castpd_si256(_mm512_extractf64x4_pd(_mm512_castph_pd(x), 0));
+ b = _mm256_castpd_si256(_mm512_extractf64x4_pd(_mm512_castph_pd(x), 1));
+}
+
+// psin
+template <>
+EIGEN_STRONG_INLINE Packet32h psin<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = psin(low);
+ Packet16h highOut = psin(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// pcos
+template <>
+EIGEN_STRONG_INLINE Packet32h pcos<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = pcos(low);
+ Packet16h highOut = pcos(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// plog
+template <>
+EIGEN_STRONG_INLINE Packet32h plog<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = plog(low);
+ Packet16h highOut = plog(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// plog2
+template <>
+EIGEN_STRONG_INLINE Packet32h plog2<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = plog2(low);
+ Packet16h highOut = plog2(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// plog1p
+template <>
+EIGEN_STRONG_INLINE Packet32h plog1p<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = plog1p(low);
+ Packet16h highOut = plog1p(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// pexp
+template <>
+EIGEN_STRONG_INLINE Packet32h pexp<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = pexp(low);
+ Packet16h highOut = pexp(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// pexpm1
+template <>
+EIGEN_STRONG_INLINE Packet32h pexpm1<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = pexpm1(low);
+ Packet16h highOut = pexpm1(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// ptanh
+template <>
+EIGEN_STRONG_INLINE Packet32h ptanh<Packet32h>(const Packet32h& a) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h lowOut = ptanh(low);
+ Packet16h highOut = ptanh(high);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// pfrexp
+template <>
+EIGEN_STRONG_INLINE Packet32h pfrexp<Packet32h>(const Packet32h& a, Packet32h& exponent) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h exp1 = _mm256_undefined_si256();
+ Packet16h exp2 = _mm256_undefined_si256();
+
+ Packet16h lowOut = pfrexp(low, exp1);
+ Packet16h highOut = pfrexp(high, exp2);
+
+ exponent = combine2Packet16h(exp1, exp2);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+// pldexp
+template <>
+EIGEN_STRONG_INLINE Packet32h pldexp<Packet32h>(const Packet32h& a, const Packet32h& exponent) {
+ Packet16h low;
+ Packet16h high;
+ extract2Packet16h(a, low, high);
+
+ Packet16h exp1;
+ Packet16h exp2;
+ extract2Packet16h(exponent, exp1, exp2);
+
+ Packet16h lowOut = pldexp(low, exp1);
+ Packet16h highOut = pldexp(high, exp2);
+
+ return combine2Packet16h(lowOut, highOut);
+}
+
+} // end namespace internal
+} // end namespace Eigen
+
+#endif // EIGEN_PACKET_MATH_FP16_AVX512_H
\ No newline at end of file
diff --git a/Eigen/src/Core/arch/AVX512/TypeCasting.h b/Eigen/src/Core/arch/AVX512/TypeCasting.h
index d28cca2..62a7429 100644
--- a/Eigen/src/Core/arch/AVX512/TypeCasting.h
+++ b/Eigen/src/Core/arch/AVX512/TypeCasting.h
@@ -80,6 +80,8 @@
return a;
}
+#ifndef EIGEN_VECTORIZE_AVX512FP16
+
template <>
struct type_casting_traits<half, float> {
enum {
@@ -106,6 +108,8 @@
return float2half(a);
}
+#endif
+
template <>
struct type_casting_traits<bfloat16, float> {
enum {
@@ -132,6 +136,77 @@
return F32ToBf16(a);
}
+#ifdef EIGEN_VECTORIZE_AVX512FP16
+
+template <>
+struct type_casting_traits<half, float> {
+ enum {
+ VectorizedCast = 1,
+ SrcCoeffRatio = 1,
+ TgtCoeffRatio = 2
+ };
+};
+
+template <>
+struct type_casting_traits<float, half> {
+ enum {
+ VectorizedCast = 1,
+ SrcCoeffRatio = 2,
+ TgtCoeffRatio = 1
+ };
+};
+
+template <>
+EIGEN_STRONG_INLINE Packet16f pcast<Packet32h, Packet16f>(const Packet32h& a) {
+ // Discard second-half of input.
+ Packet16h low = _mm256_castpd_si256(_mm512_extractf64x4_pd(_mm512_castph_pd(a), 0));
+ return _mm512_cvtxph_ps(_mm256_castsi256_ph(low));
+}
+
+
+template <>
+EIGEN_STRONG_INLINE Packet32h pcast<Packet16f, Packet32h>(const Packet16f& a, const Packet16f& b) {
+ __m512d result = _mm512_undefined_pd();
+ result = _mm512_insertf64x4(result, _mm256_castsi256_pd(_mm512_cvtps_ph(a, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC)), 0);
+ result = _mm512_insertf64x4(result, _mm256_castsi256_pd(_mm512_cvtps_ph(b, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC)), 1);
+ return _mm512_castpd_ph(result);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet8f pcast<Packet16h, Packet8f>(const Packet16h& a) {
+ // Discard second-half of input.
+ Packet8h low = _mm_castps_si128(_mm256_extractf32x4_ps(_mm256_castsi256_ps(a), 0));
+ return _mm256_cvtxph_ps(_mm_castsi128_ph(low));
+}
+
+
+template <>
+EIGEN_STRONG_INLINE Packet16h pcast<Packet8f, Packet16h>(const Packet8f& a, const Packet8f& b) {
+ __m256d result = _mm256_undefined_pd();
+ result = _mm256_insertf64x2(result, _mm_castsi128_pd(_mm256_cvtps_ph(a, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC)), 0);
+ result = _mm256_insertf64x2(result, _mm_castsi128_pd(_mm256_cvtps_ph(b, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC)), 1);
+ return _mm256_castpd_si256(result);
+}
+
+template <>
+EIGEN_STRONG_INLINE Packet4f pcast<Packet8h, Packet4f>(const Packet8h& a) {
+ Packet8f full = _mm256_cvtxph_ps(_mm_castsi128_ph(a));
+ // Discard second-half of input.
+ return _mm256_extractf32x4_ps(full, 0);
+}
+
+
+template <>
+EIGEN_STRONG_INLINE Packet8h pcast<Packet4f, Packet8h>(const Packet4f& a, const Packet4f& b) {
+ __m256 result = _mm256_undefined_ps();
+ result = _mm256_insertf128_ps(result, a, 0);
+ result = _mm256_insertf128_ps(result, b, 1);
+ return _mm256_cvtps_ph(result, _MM_FROUND_TO_NEAREST_INT|_MM_FROUND_NO_EXC);
+}
+
+
+#endif
+
} // end namespace internal
} // end namespace Eigen
diff --git a/Eigen/src/Core/arch/AltiVec/Complex.h b/Eigen/src/Core/arch/AltiVec/Complex.h
index 6046035..46812f9 100644
--- a/Eigen/src/Core/arch/AltiVec/Complex.h
+++ b/Eigen/src/Core/arch/AltiVec/Complex.h
@@ -102,6 +102,7 @@
HasAbs2 = 0,
HasMin = 0,
HasMax = 0,
+ HasSqrt = 1,
#ifdef __VSX__
HasBlend = 1,
#endif
@@ -268,8 +269,13 @@
EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet2cf,2>& kernel)
{
+#ifdef __VSX__
Packet4f tmp = reinterpret_cast<Packet4f>(vec_mergeh(reinterpret_cast<Packet2d>(kernel.packet[0].v), reinterpret_cast<Packet2d>(kernel.packet[1].v)));
kernel.packet[1].v = reinterpret_cast<Packet4f>(vec_mergel(reinterpret_cast<Packet2d>(kernel.packet[0].v), reinterpret_cast<Packet2d>(kernel.packet[1].v)));
+#else
+ Packet4f tmp = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_HI);
+ kernel.packet[1].v = vec_perm(kernel.packet[0].v, kernel.packet[1].v, p16uc_TRANSPOSE64_LO);
+#endif
kernel.packet[0].v = tmp;
}
@@ -365,6 +371,7 @@
HasAbs2 = 0,
HasMin = 0,
HasMax = 0,
+ HasSqrt = 1,
HasSetLinear = 0
};
};
diff --git a/Eigen/src/Core/arch/AltiVec/MathFunctions.h b/Eigen/src/Core/arch/AltiVec/MathFunctions.h
index 977bfc2..fffd2e5 100644
--- a/Eigen/src/Core/arch/AltiVec/MathFunctions.h
+++ b/Eigen/src/Core/arch/AltiVec/MathFunctions.h
@@ -42,16 +42,32 @@
return pcos_float(_x);
}
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet4f pacos<Packet4f>(const Packet4f& _x)
+{
+ return pacos_float(_x);
+}
+
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet4f pasin<Packet4f>(const Packet4f& _x)
+{
+ return pasin_float(_x);
+}
+
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet4f patan<Packet4f>(const Packet4f& _x)
+{
+ return patan_float(_x);
+}
+
+#ifdef __VSX__
#ifndef EIGEN_COMP_CLANG
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet4f prsqrt<Packet4f>(const Packet4f& x)
{
return vec_rsqrt(x);
}
-#endif
-#ifdef __VSX__
-#ifndef EIGEN_COMP_CLANG
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet2d prsqrt<Packet2d>(const Packet2d& x)
{
@@ -76,6 +92,26 @@
{
return pexp_double(_x);
}
+
+template<> EIGEN_STRONG_INLINE Packet8bf psqrt<Packet8bf> (const Packet8bf& a){
+ BF16_TO_F32_UNARY_OP_WRAPPER(psqrt<Packet4f>, a);
+}
+
+#ifndef EIGEN_COMP_CLANG
+template<> EIGEN_STRONG_INLINE Packet8bf prsqrt<Packet8bf> (const Packet8bf& a){
+ BF16_TO_F32_UNARY_OP_WRAPPER(prsqrt<Packet4f>, a);
+}
+#endif
+#else
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet4f psqrt<Packet4f>(const Packet4f& x)
+{
+ Packet4f a;
+ for (Index i = 0; i < packet_traits<float>::size; i++) {
+ a[i] = numext::sqrt(x[i]);
+ }
+ return a;
+}
#endif
// Hyperbolic Tangent function.
diff --git a/Eigen/src/Core/arch/AltiVec/MatrixProduct.h b/Eigen/src/Core/arch/AltiVec/MatrixProduct.h
index 4cc0a94..3b3b558 100644
--- a/Eigen/src/Core/arch/AltiVec/MatrixProduct.h
+++ b/Eigen/src/Core/arch/AltiVec/MatrixProduct.h
@@ -1159,6 +1159,29 @@
}
}
+#ifdef USE_PARTIAL_PACKETS
+template<typename DataMapper, typename Packet, const Index accCols, bool Complex, Index N, bool full>
+EIGEN_ALWAYS_INLINE void bload_partial(PacketBlock<Packet,N*(Complex?2:1)>& acc, const DataMapper& res, Index row, Index elements)
+{
+ for (Index M = 0; M < N; M++) {
+ acc.packet[M] = res.template loadPacketPartial<Packet>(row, M, elements);
+ }
+ if (Complex && full) {
+ for (Index M = 0; M < N; M++) {
+ acc.packet[M+N] = res.template loadPacketPartial<Packet>(row + accCols, M, elements);
+ }
+ }
+}
+
+template<typename DataMapper, typename Packet, Index N>
+EIGEN_ALWAYS_INLINE void bstore_partial(PacketBlock<Packet,N>& acc, const DataMapper& res, Index row, Index elements)
+{
+ for (Index M = 0; M < N; M++) {
+ res.template storePacketPartial<Packet>(row, M, acc.packet[M], elements);
+ }
+}
+#endif
+
#ifdef _ARCH_PWR10
#define USE_P10_AND_PVIPR2_0 (EIGEN_COMP_LLVM || (__GNUC__ >= 11))
#else
@@ -1199,6 +1222,14 @@
#endif
}
+template<typename Packet, int N>
+EIGEN_ALWAYS_INLINE void bscale(PacketBlock<Packet,N>& acc, PacketBlock<Packet,N>& accZ, const Packet& pAlpha)
+{
+ for (int M = 0; M < N; M++) {
+ acc.packet[M] = pmadd<Packet>(pAlpha, accZ.packet[M], acc.packet[M]);
+ }
+}
+
// Scale the PacketBlock vectors by alpha.
template<typename Packet, int N, bool mask>
EIGEN_ALWAYS_INLINE void bscale(PacketBlock<Packet,N>& acc, PacketBlock<Packet,N>& accZ, const Packet& pAlpha, const Packet& pMask)
@@ -1209,9 +1240,7 @@
EIGEN_UNUSED_VARIABLE(pMask);
}
- for (int M = 0; M < N; M++) {
- acc.packet[M] = pmadd<Packet>(pAlpha, accZ.packet[M], acc.packet[M]);
- }
+ bscale<Packet, N>(acc, accZ, pAlpha);
}
template<typename Packet, int N, bool real>
@@ -1461,6 +1490,13 @@
MICRO_EXTRA_ROW<Scalar, Packet, accRows, remaining_rows>(lhs_ptr, rhs_ptr0, rhs_ptr1, rhs_ptr2, accZero0);
}
+#ifdef USE_PARTIAL_PACKETS
+ EIGEN_UNUSED_VARIABLE(rows);
+ EIGEN_UNUSED_VARIABLE(pMask);
+ bload_partial<DataMapper, Packet, 0, false, accRows>(acc, res, row, remaining_rows);
+ bscale<Packet,accRows>(acc, accZero0, pAlpha);
+ bstore_partial<DataMapper, Packet, accRows>(acc, res, row, remaining_rows);
+#else
bload<DataMapper, Packet, 0, ColMajor, false, accRows>(acc, res, row, 0);
if ((accRows == 1) || (rows >= accCols))
{
@@ -1474,6 +1510,7 @@
}
}
}
+#endif
}
#define MICRO_EXTRA(MICRO_EXTRA_UNROLL, value, is_col) \
@@ -1565,16 +1602,35 @@
#define MICRO_PREFETCH MICRO_UNROLL(MICRO_PREFETCH_ONE)
+#ifdef USE_PARTIAL_PACKETS
+#define MICRO_STORE_ONE(iter) \
+ if (unroll_factor > iter) { \
+ if (MICRO_NORMAL_PARTIAL(iter)) { \
+ bload<DataMapper, Packet, 0, ColMajor, false, accRows>(acc, res, row + iter*accCols, 0); \
+ bscale<Packet,accRows>(acc, accZero##iter, pAlpha); \
+ bstore<DataMapper, Packet, accRows>(acc, res, row + iter*accCols); \
+ } else { \
+ bload_partial<DataMapper, Packet, 0, false, accRows>(acc, res, row + iter*accCols, accCols2); \
+ bscale<Packet,accRows>(acc, accZero##iter, pAlpha); \
+ bstore_partial<DataMapper, Packet, accRows>(acc, res, row + iter*accCols, accCols2); \
+ } \
+ }
+#else
#define MICRO_STORE_ONE(iter) \
if (unroll_factor > iter) { \
bload<DataMapper, Packet, 0, ColMajor, false, accRows>(acc, res, row + iter*accCols, 0); \
bscale<Packet,accRows,!(MICRO_NORMAL(iter))>(acc, accZero##iter, pAlpha, pMask); \
bstore<DataMapper, Packet, accRows>(acc, res, row + iter*accCols); \
}
+#endif
#define MICRO_STORE MICRO_UNROLL(MICRO_STORE_ONE)
+#ifdef USE_PARTIAL_PACKETS
+template<int unroll_factor, typename Scalar, typename Packet, typename DataMapper, const Index accRows, const Index accCols, bool full>
+#else
template<int unroll_factor, typename Scalar, typename Packet, typename DataMapper, const Index accRows, const Index accCols, const Index accCols2>
+#endif
EIGEN_ALWAYS_INLINE void gemm_unrolled_iteration(
const DataMapper& res,
const Scalar* lhs_base,
@@ -1585,7 +1641,12 @@
Index strideB,
Index& row,
const Packet& pAlpha,
- const Packet& pMask)
+#ifdef USE_PARTIAL_PACKETS
+ Index accCols2
+#else
+ const Packet& pMask
+#endif
+ )
{
const Scalar* rhs_ptr0 = rhs_base, * rhs_ptr1 = NULL, * rhs_ptr2 = NULL;
const Scalar* lhs_ptr0 = NULL, * lhs_ptr1 = NULL, * lhs_ptr2 = NULL, * lhs_ptr3 = NULL, * lhs_ptr4 = NULL, * lhs_ptr5 = NULL, * lhs_ptr6 = NULL, * lhs_ptr7 = NULL;
@@ -1612,9 +1673,15 @@
MICRO_UPDATE
}
+#ifdef USE_PARTIAL_PACKETS
+#define MICRO_UNROLL_ITER2(N, M) \
+ gemm_unrolled_iteration<N + ((M) ? 1 : 0), Scalar, Packet, DataMapper, accRows, accCols, !M>(res3, lhs_base, rhs_base, depth, strideA, offsetA, strideB, row, pAlpha, M ? remaining_rows : accCols); \
+ if (M) return;
+#else
#define MICRO_UNROLL_ITER2(N, M) \
gemm_unrolled_iteration<N + ((M) ? 1 : 0), Scalar, Packet, DataMapper, accRows, accCols, M ? M : accCols>(res3, lhs_base, rhs_base, depth, strideA, offsetA, strideB, row, pAlpha, pMask); \
if (M) return;
+#endif
template<typename Scalar, typename Packet, typename DataMapper, const Index accRows, const Index accCols>
EIGEN_ALWAYS_INLINE void gemm_cols(
@@ -2094,22 +2161,22 @@
switch( (rows-row)/accCols ) {
#if MAX_COMPLEX_UNROLL > 4
case 4:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 4)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 4)
break;
#endif
#if MAX_COMPLEX_UNROLL > 3
case 3:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 3)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 3)
break;
#endif
#if MAX_COMPLEX_UNROLL > 2
case 2:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 2)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 2)
break;
#endif
#if MAX_COMPLEX_UNROLL > 1
case 1:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 1)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_UNROLL_ITER2, 1)
break;
#endif
default:
diff --git a/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h b/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h
index 70b95da..28868ca 100644
--- a/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h
+++ b/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h
@@ -5,6 +5,10 @@
#define EIGEN_POWER_PREFETCH(p)
#endif
+#ifdef _ARCH_PWR9
+#define USE_PARTIAL_PACKETS
+#endif
+
#include "../../InternalHeaderCheck.h"
namespace Eigen {
@@ -89,6 +93,17 @@
template<typename DataMapper, typename Packet, int N>
EIGEN_ALWAYS_INLINE void bstore(PacketBlock<Packet,N>& acc, const DataMapper& res, Index row);
+#ifdef USE_PARTIAL_PACKETS
+template<typename DataMapper, typename Packet, const Index accCols, bool Complex, Index N, bool full = true>
+EIGEN_ALWAYS_INLINE void bload_partial(PacketBlock<Packet,N*(Complex?2:1)>& acc, const DataMapper& res, Index row, Index elements);
+
+template<typename DataMapper, typename Packet, Index N>
+EIGEN_ALWAYS_INLINE void bstore_partial(PacketBlock<Packet,N>& acc, const DataMapper& res, Index row, Index elements);
+#endif
+
+template<typename Packet, int N>
+EIGEN_ALWAYS_INLINE void bscale(PacketBlock<Packet,N>& acc, PacketBlock<Packet,N>& accZ, const Packet& pAlpha);
+
template<typename Packet, int N, bool mask>
EIGEN_ALWAYS_INLINE void bscale(PacketBlock<Packet,N>& acc, PacketBlock<Packet,N>& accZ, const Packet& pAlpha, const Packet& pMask);
@@ -101,7 +116,7 @@
#define MICRO_NORMAL(iter) \
(accCols == accCols2) || (unroll_factor != (iter + 1))
-#define MICRO_UNROLL_ITER(func, N) \
+#define MICRO_UNROLL_ITER1(func, N) \
switch (remaining_rows) { \
default: \
func(N, 0) \
@@ -121,6 +136,22 @@
break; \
}
+#ifdef USE_PARTIAL_PACKETS
+#define MICRO_UNROLL_ITER(func, N) \
+ if (remaining_rows) { \
+ func(N, true); \
+ } else { \
+ func(N, false); \
+ }
+
+#define MICRO_NORMAL_PARTIAL(iter) \
+ full || (unroll_factor != (iter + 1))
+#else
+#define MICRO_UNROLL_ITER(func, N) MICRO_UNROLL_ITER1(func, N)
+#endif
+
+#define MICRO_COMPLEX_UNROLL_ITER(func, N) MICRO_UNROLL_ITER1(func, N)
+
#define MICRO_NORMAL_COLS(iter, a, b) ((MICRO_NORMAL(iter)) ? a : b)
#define MICRO_LOAD1(lhs_ptr, iter) \
@@ -161,9 +192,15 @@
#define MICRO_COMPLEX_PREFETCH_ONE(iter) MICRO_PREFETCH1(lhs_ptr_real, iter)
+#ifdef USE_PARTIAL_PACKETS
+#define MICRO_UPDATE_MASK
+#else
+#define MICRO_UPDATE_MASK EIGEN_UNUSED_VARIABLE(pMask);
+#endif
+
#define MICRO_UPDATE \
if (accCols == accCols2) { \
- EIGEN_UNUSED_VARIABLE(pMask); \
+ MICRO_UPDATE_MASK \
EIGEN_UNUSED_VARIABLE(offsetA); \
row += unroll_factor*accCols; \
}
diff --git a/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h b/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h
index 84ba115..aa1cbf8 100644
--- a/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h
+++ b/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h
@@ -39,18 +39,34 @@
__builtin_mma_xxsetaccz(acc);
}
+#ifdef USE_PARTIAL_PACKETS
+template<typename DataMapper, typename Packet, bool full>
+EIGEN_ALWAYS_INLINE void storeAccumulator(Index i, const DataMapper& data, const Packet& alpha, const Index elements, __vector_quad* acc)
+#else
template<typename DataMapper, typename Packet, const Index accCols, const Index accCols2>
EIGEN_ALWAYS_INLINE void storeAccumulator(Index i, const DataMapper& data, const Packet& alpha, const Packet& pMask, __vector_quad* acc)
+#endif
{
PacketBlock<Packet, 4> result;
__builtin_mma_disassemble_acc(&result.packet, acc);
PacketBlock<Packet, 4> tRes;
+#ifdef USE_PARTIAL_PACKETS
+ if (full) {
+ EIGEN_UNUSED_VARIABLE(elements);
+ bload<DataMapper, Packet, 0, ColMajor, false, 4>(tRes, data, i, 0);
+ bscale<Packet, 4>(tRes, result, alpha);
+ bstore<DataMapper, Packet, 4>(tRes, data, i);
+ } else {
+ bload_partial<DataMapper, Packet, 0, false, 4>(tRes, data, i, elements);
+ bscale<Packet, 4>(tRes, result, alpha);
+ bstore_partial<DataMapper, Packet, 4>(tRes, data, i, elements);
+ }
+#else
bload<DataMapper, Packet, 0, ColMajor, false, 4>(tRes, data, i, 0);
-
bscale<Packet, 4, (accCols != accCols2)>(tRes, result, alpha, pMask);
-
bstore<DataMapper, Packet, 4>(tRes, data, i);
+#endif
}
template<typename DataMapper, typename Packet, typename Packetc, const Index accCols, const Index accCols2>
@@ -270,14 +286,25 @@
#define MICRO_MMA_PREFETCH MICRO_MMA_UNROLL(MICRO_PREFETCH_ONE)
+#ifdef USE_PARTIAL_PACKETS
+#define MICRO_MMA_STORE_ONE(iter) \
+ if (unroll_factor > iter) { \
+ storeAccumulator<DataMapper, Packet, MICRO_NORMAL_PARTIAL(iter)>(row + iter*accCols, res, pAlpha, accCols2, &accZero##iter); \
+ }
+#else
#define MICRO_MMA_STORE_ONE(iter) \
if (unroll_factor > iter) { \
storeAccumulator<DataMapper, Packet, accCols, (unroll_factor != (iter + 1)) ? accCols : accCols2>(row + iter*accCols, res, pAlpha, pMask, &accZero##iter); \
}
+#endif
#define MICRO_MMA_STORE MICRO_MMA_UNROLL(MICRO_MMA_STORE_ONE)
+#ifdef USE_PARTIAL_PACKETS
+template<int unroll_factor, typename Scalar, typename Packet, typename RhsPacket, typename DataMapper, const Index accRows, const Index accCols, bool full>
+#else
template<int unroll_factor, typename Scalar, typename Packet, typename RhsPacket, typename DataMapper, const Index accRows, const Index accCols, const Index accCols2>
+#endif
EIGEN_ALWAYS_INLINE void gemm_unrolled_MMA_iteration(
const DataMapper& res,
const Scalar* lhs_base,
@@ -287,7 +314,12 @@
Index offsetA,
Index& row,
const Packet& pAlpha,
- const Packet& pMask)
+#ifdef USE_PARTIAL_PACKETS
+ Index accCols2
+#else
+ const Packet& pMask
+#endif
+ )
{
const Scalar* rhs_ptr = rhs_base;
const Scalar* lhs_ptr0 = NULL, * lhs_ptr1 = NULL, * lhs_ptr2 = NULL, * lhs_ptr3 = NULL, * lhs_ptr4 = NULL, * lhs_ptr5 = NULL, * lhs_ptr6 = NULL, * lhs_ptr7 = NULL;
@@ -312,9 +344,15 @@
MICRO_UPDATE
}
+#ifdef USE_PARTIAL_PACKETS
+#define MICRO_MMA_UNROLL_ITER2(N, M) \
+ gemm_unrolled_MMA_iteration<N + (M ? 1 : 0), Scalar, Packet, RhsPacket, DataMapper, accRows, accCols, !M>(res3, lhs_base, rhs_base, depth, strideA, offsetA, row, pAlpha, M ? remaining_rows : accCols); \
+ if (M) return;
+#else
#define MICRO_MMA_UNROLL_ITER2(N, M) \
gemm_unrolled_MMA_iteration<N + (M ? 1 : 0), Scalar, Packet, RhsPacket, DataMapper, accRows, accCols, M ? M : accCols>(res3, lhs_base, rhs_base, depth, strideA, offsetA, row, pAlpha, pMask); \
if (M) return;
+#endif
template<typename Scalar, typename Packet, typename RhsPacket, typename DataMapper, const Index accRows, const Index accCols>
EIGEN_ALWAYS_INLINE void gemmMMA_cols(
@@ -643,22 +681,22 @@
switch( (rows-row)/accCols ) {
#if MAX_COMPLEX_MMA_UNROLL > 4
case 4:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 4)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 4)
break;
#endif
#if MAX_COMPLEX_MMA_UNROLL > 3
case 3:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 3)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 3)
break;
#endif
#if MAX_COMPLEX_MMA_UNROLL > 2
case 2:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 2)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 2)
break;
#endif
#if MAX_COMPLEX_MMA_UNROLL > 1
case 1:
- MICRO_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 1)
+ MICRO_COMPLEX_UNROLL_ITER(MICRO_COMPLEX_MMA_UNROLL_ITER2, 1)
break;
#endif
default:
diff --git a/Eigen/src/Core/arch/AltiVec/PacketMath.h b/Eigen/src/Core/arch/AltiVec/PacketMath.h
index 4dd53f6..f030189 100644
--- a/Eigen/src/Core/arch/AltiVec/PacketMath.h
+++ b/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -168,6 +168,9 @@
HasAbs = 1,
HasSin = EIGEN_FAST_MATH,
HasCos = EIGEN_FAST_MATH,
+ HasACos = 1,
+ HasASin = 1,
+ HasATan = 1,
HasLog = 1,
HasExp = 1,
#ifdef __VSX__
@@ -177,16 +180,19 @@
#else
HasRsqrt = 0,
#endif
+ HasTanh = EIGEN_FAST_MATH,
+ HasErf = EIGEN_FAST_MATH,
+ HasRint = 1,
#else
HasSqrt = 0,
HasRsqrt = 0,
+ HasTanh = 0,
+ HasErf = 0,
+ HasRint = 0,
#endif
- HasTanh = EIGEN_FAST_MATH,
- HasErf = EIGEN_FAST_MATH,
HasRound = 1,
HasFloor = 1,
HasCeil = 1,
- HasRint = 1,
HasNegate = 1,
HasBlend = 1
};
@@ -219,16 +225,17 @@
#else
HasRsqrt = 0,
#endif
+ HasRint = 1,
#else
HasSqrt = 0,
HasRsqrt = 0,
- HasTanh = EIGEN_FAST_MATH,
- HasErf = EIGEN_FAST_MATH,
+ HasRint = 0,
#endif
+ HasTanh = 0,
+ HasErf = 0,
HasRound = 1,
HasFloor = 1,
HasCeil = 1,
- HasRint = 1,
HasNegate = 1,
HasBlend = 1
};
@@ -249,7 +256,8 @@
HasShift = 1,
HasMul = 1,
HasDiv = 0,
- HasBlend = 1
+ HasBlend = 1,
+ HasCmp = 1
};
};
@@ -267,7 +275,8 @@
HasSub = 1,
HasMul = 1,
HasDiv = 0,
- HasBlend = 1
+ HasBlend = 1,
+ HasCmp = 1
};
};
@@ -285,7 +294,8 @@
HasSub = 1,
HasMul = 1,
HasDiv = 0,
- HasBlend = 1
+ HasBlend = 1,
+ HasCmp = 1
};
};
@@ -303,7 +313,8 @@
HasSub = 1,
HasMul = 1,
HasDiv = 0,
- HasBlend = 1
+ HasBlend = 1,
+ HasCmp = 1
};
};
@@ -321,7 +332,8 @@
HasSub = 1,
HasMul = 1,
HasDiv = 0,
- HasBlend = 1
+ HasBlend = 1,
+ HasCmp = 1
};
};
@@ -513,6 +525,7 @@
eigen_assert(n + offset <= packet_size && "number of elements plus offset will read past end of packet");
const Index size = sizeof(__UNPACK_TYPE__(Packet));
#ifdef _ARCH_PWR9
+ EIGEN_UNUSED_VARIABLE(packet_size);
EIGEN_DEBUG_ALIGNED_LOAD
EIGEN_UNUSED_VARIABLE(from);
Packet load = vec_xl_len(const_cast<__UNPACK_TYPE__(Packet)*>(from), n * size);
@@ -645,6 +658,7 @@
eigen_assert(n + offset <= packet_size && "number of elements plus offset will write past end of packet");
const Index size = sizeof(__UNPACK_TYPE__(Packet));
#ifdef _ARCH_PWR9
+ EIGEN_UNUSED_VARIABLE(packet_size);
EIGEN_UNUSED_VARIABLE(to);
EIGEN_DEBUG_ALIGNED_STORE
Packet store = from;
@@ -1040,9 +1054,11 @@
template<> EIGEN_STRONG_INLINE Packet8s pmadd(const Packet8s& a, const Packet8s& b, const Packet8s& c) { return vec_madd(a,b,c); }
template<> EIGEN_STRONG_INLINE Packet8us pmadd(const Packet8us& a, const Packet8us& b, const Packet8us& c) { return vec_madd(a,b,c); }
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet4f pmsub(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vec_msub(a,b,c); }
template<> EIGEN_STRONG_INLINE Packet4f pnmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vec_nmsub(a,b,c); }
template<> EIGEN_STRONG_INLINE Packet4f pnmsub(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vec_nmadd(a,b,c); }
+#endif
template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b)
{
@@ -1087,19 +1103,29 @@
return vec_nor(c,c);
}
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet4i pcmp_le(const Packet4i& a, const Packet4i& b) { return reinterpret_cast<Packet4i>(vec_cmple(a,b)); }
+#endif
template<> EIGEN_STRONG_INLINE Packet4i pcmp_lt(const Packet4i& a, const Packet4i& b) { return reinterpret_cast<Packet4i>(vec_cmplt(a,b)); }
template<> EIGEN_STRONG_INLINE Packet4i pcmp_eq(const Packet4i& a, const Packet4i& b) { return reinterpret_cast<Packet4i>(vec_cmpeq(a,b)); }
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet8s pcmp_le(const Packet8s& a, const Packet8s& b) { return reinterpret_cast<Packet8s>(vec_cmple(a,b)); }
+#endif
template<> EIGEN_STRONG_INLINE Packet8s pcmp_lt(const Packet8s& a, const Packet8s& b) { return reinterpret_cast<Packet8s>(vec_cmplt(a,b)); }
template<> EIGEN_STRONG_INLINE Packet8s pcmp_eq(const Packet8s& a, const Packet8s& b) { return reinterpret_cast<Packet8s>(vec_cmpeq(a,b)); }
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet8us pcmp_le(const Packet8us& a, const Packet8us& b) { return reinterpret_cast<Packet8us>(vec_cmple(a,b)); }
+#endif
template<> EIGEN_STRONG_INLINE Packet8us pcmp_lt(const Packet8us& a, const Packet8us& b) { return reinterpret_cast<Packet8us>(vec_cmplt(a,b)); }
template<> EIGEN_STRONG_INLINE Packet8us pcmp_eq(const Packet8us& a, const Packet8us& b) { return reinterpret_cast<Packet8us>(vec_cmpeq(a,b)); }
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet16c pcmp_le(const Packet16c& a, const Packet16c& b) { return reinterpret_cast<Packet16c>(vec_cmple(a,b)); }
+#endif
template<> EIGEN_STRONG_INLINE Packet16c pcmp_lt(const Packet16c& a, const Packet16c& b) { return reinterpret_cast<Packet16c>(vec_cmplt(a,b)); }
template<> EIGEN_STRONG_INLINE Packet16c pcmp_eq(const Packet16c& a, const Packet16c& b) { return reinterpret_cast<Packet16c>(vec_cmpeq(a,b)); }
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet16uc pcmp_le(const Packet16uc& a, const Packet16uc& b) { return reinterpret_cast<Packet16uc>(vec_cmple(a,b)); }
+#endif
template<> EIGEN_STRONG_INLINE Packet16uc pcmp_lt(const Packet16uc& a, const Packet16uc& b) { return reinterpret_cast<Packet16uc>(vec_cmplt(a,b)); }
template<> EIGEN_STRONG_INLINE Packet16uc pcmp_eq(const Packet16uc& a, const Packet16uc& b) { return reinterpret_cast<Packet16uc>(vec_cmpeq(a,b)); }
@@ -1152,6 +1178,7 @@
}
template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(const Packet4f& a) { return vec_ceil(a); }
template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a) { return vec_floor(a); }
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet4f print<Packet4f>(const Packet4f& a)
{
Packet4f res;
@@ -1162,6 +1189,7 @@
return res;
}
+#endif
template<typename Packet> EIGEN_STRONG_INLINE Packet ploadu_common(const __UNPACK_TYPE__(Packet)* from)
{
@@ -1215,6 +1243,7 @@
eigen_assert(n <= packet_size && "number of elements will read past end of packet");
const Index size = sizeof(__UNPACK_TYPE__(Packet));
#ifdef _ARCH_PWR9
+ EIGEN_UNUSED_VARIABLE(packet_size);
EIGEN_DEBUG_ALIGNED_LOAD
EIGEN_DEBUG_UNALIGNED_LOAD
return vec_xl_len(const_cast<__UNPACK_TYPE__(Packet)*>(from), n * size);
@@ -1402,6 +1431,7 @@
eigen_assert(n <= packet_size && "number of elements will write past end of packet");
const Index size = sizeof(__UNPACK_TYPE__(Packet));
#ifdef _ARCH_PWR9
+ EIGEN_UNUSED_VARIABLE(packet_size);
EIGEN_DEBUG_UNALIGNED_STORE
vec_xst_len(from, to, n * size);
#else
@@ -1702,12 +1732,6 @@
BF16_TO_F32_BINARY_OP_WRAPPER(psub<Packet4f>, a, b);
}
-template<> EIGEN_STRONG_INLINE Packet8bf psqrt<Packet8bf> (const Packet8bf& a){
- BF16_TO_F32_UNARY_OP_WRAPPER(vec_sqrt, a);
-}
-template<> EIGEN_STRONG_INLINE Packet8bf prsqrt<Packet8bf> (const Packet8bf& a){
- BF16_TO_F32_UNARY_OP_WRAPPER(prsqrt<Packet4f>, a);
-}
template<> EIGEN_STRONG_INLINE Packet8bf pexp<Packet8bf> (const Packet8bf& a){
BF16_TO_F32_UNARY_OP_WRAPPER(pexp_float, a);
}
@@ -1751,9 +1775,11 @@
template<> EIGEN_STRONG_INLINE Packet8bf pround<Packet8bf> (const Packet8bf& a){
BF16_TO_F32_UNARY_OP_WRAPPER(pround<Packet4f>, a);
}
+#ifdef __VSX__
template<> EIGEN_STRONG_INLINE Packet8bf print<Packet8bf> (const Packet8bf& a){
BF16_TO_F32_UNARY_OP_WRAPPER(print<Packet4f>, a);
}
+#endif
template<> EIGEN_STRONG_INLINE Packet8bf pmadd(const Packet8bf& a, const Packet8bf& b, const Packet8bf& c) {
Packet4f a_even = Bf16ToF32Even(a);
Packet4f a_odd = Bf16ToF32Odd(a);
diff --git a/Eigen/src/Core/arch/Default/ConjHelper.h b/Eigen/src/Core/arch/Default/ConjHelper.h
index 6b5afe3..81c2819 100644
--- a/Eigen/src/Core/arch/Default/ConjHelper.h
+++ b/Eigen/src/Core/arch/Default/ConjHelper.h
@@ -47,16 +47,16 @@
template<> struct conj_if<true> {
template<typename T>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T operator()(const T& x) const { return numext::conj(x); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR T operator()(const T& x) const { return numext::conj(x); }
template<typename T>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T pconj(const T& x) const { return internal::pconj(x); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR T pconj(const T& x) const { return internal::pconj(x); }
};
template<> struct conj_if<false> {
template<typename T>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& operator()(const T& x) const { return x; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const T& operator()(const T& x) const { return x; }
template<typename T>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& pconj(const T& x) const { return x; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const T& pconj(const T& x) const { return x; }
};
// Generic Implementation, assume scalars since the packet-version is
@@ -93,11 +93,11 @@
struct conj_helper<Packet, Packet, ConjLhs, ConjRhs>
{
typedef Packet ResultType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmadd(const Packet& x, const Packet& y, const Packet& c) const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Packet pmadd(const Packet& x, const Packet& y, const Packet& c) const
{ return Eigen::internal::pmadd(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y), c); }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet pmul(const Packet& x, const Packet& y) const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Packet pmul(const Packet& x, const Packet& y) const
{ return Eigen::internal::pmul(conj_if<ConjLhs>().pconj(x), conj_if<ConjRhs>().pconj(y)); }
};
diff --git a/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h b/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
index 822113b..a8837b2 100644
--- a/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
+++ b/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
@@ -719,6 +719,151 @@
return psincos_float<false>(x);
}
+// Generic implementation of acos(x).
+template<typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet pacos_float(const Packet& x_in) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ static_assert(std::is_same<Scalar, float>::value, "Scalar type must be float");
+
+ const Packet cst_one = pset1<Packet>(Scalar(1));
+ const Packet cst_pi = pset1<Packet>(Scalar(EIGEN_PI));
+ const Packet p6 = pset1<Packet>(Scalar(2.26911413483321666717529296875e-3));
+ const Packet p5 = pset1<Packet>(Scalar(-1.1063250713050365447998046875e-2));
+ const Packet p4 = pset1<Packet>(Scalar(2.680264413356781005859375e-2));
+ const Packet p3 = pset1<Packet>(Scalar(-4.87488098442554473876953125e-2));
+ const Packet p2 = pset1<Packet>(Scalar(8.874166011810302734375e-2));
+ const Packet p1 = pset1<Packet>(Scalar(-0.2145837843418121337890625));
+ const Packet p0 = pset1<Packet>(Scalar(1.57079613208770751953125));
+
+ // For x in [0:1], we approximate acos(x)/sqrt(1-x), which is a smooth
+ // function, by a 6'th order polynomial.
+ // For x in [-1:0) we use that acos(-x) = pi - acos(x).
+ const Packet neg_mask = pcmp_lt(x_in, pzero(x_in));
+ Packet x = pabs(x_in);
+ const Packet invalid_mask = pcmp_lt(pset1<Packet>(1.0f), x);
+
+ // Evaluate the polynomial using Horner's rule:
+ // P(x) = p0 + x * (p1 + x * (p2 + ... (p5 + x * p6)) ... ) .
+ // We evaluate even and odd terms independently to increase
+ // instruction level parallelism.
+ Packet x2 = pmul(x_in,x_in);
+ Packet p_even = pmadd(p6, x2, p4);
+ Packet p_odd = pmadd(p5, x2, p3);
+ p_even = pmadd(p_even, x2, p2);
+ p_odd = pmadd(p_odd, x2, p1);
+ p_even = pmadd(p_even, x2, p0);
+ Packet p = pmadd(p_odd, x, p_even);
+
+ // The polynomial approximates acos(x)/sqrt(1-x), so
+ // multiply by sqrt(1-x) to get acos(x).
+ Packet denom = psqrt(psub(cst_one, x));
+ Packet result = pmul(denom, p);
+
+ // Undo mapping for negative arguments.
+ result = pselect(neg_mask, psub(cst_pi, result), result);
+ // Return NaN for arguments outside [-1:1].
+ return pselect(invalid_mask,
+ pset1<Packet>(std::numeric_limits<float>::quiet_NaN()),
+ result);
+}
+
+// Generic implementation of asin(x).
+template<typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet pasin_float(const Packet& x_in) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ static_assert(std::is_same<Scalar, float>::value, "Scalar type must be float");
+
+ // For |x| < 0.5 approximate asin(x)/x by an 8th order polynomial with
+ // even terms only.
+ const Packet p9 = pset1<Packet>(Scalar(5.08838854730129241943359375e-2f));
+ const Packet p7 = pset1<Packet>(Scalar(3.95139865577220916748046875e-2f));
+ const Packet p5 = pset1<Packet>(Scalar(7.550220191478729248046875e-2f));
+ const Packet p3 = pset1<Packet>(Scalar(0.16664917767047882080078125f));
+ const Packet p1 = pset1<Packet>(Scalar(1.00000011920928955078125f));
+
+ const Packet neg_mask = pcmp_lt(x_in, pzero(x_in));
+ Packet x = pabs(x_in);
+ const Packet invalid_mask = pcmp_lt(pset1<Packet>(1.0f), x);
+ // For arguments |x| > 0.5, we map x back to [0:0.5] using
+ // the transformation x_large = sqrt(0.5*(1-x)), and use the
+ // identity
+ // asin(x) = pi/2 - 2 * asin( sqrt( 0.5 * (1 - x)))
+ const Packet cst_half = pset1<Packet>(Scalar(0.5f));
+ const Packet cst_two = pset1<Packet>(Scalar(2));
+ Packet x_large = psqrt(pnmadd(cst_half, x, cst_half));
+ const Packet large_mask = pcmp_lt(cst_half, x);
+ x = pselect(large_mask, x_large, x);
+
+ // Compute polynomial.
+ // x * (p1 + x^2*(p3 + x^2*(p5 + x^2*(p7 + x^2*p9))))
+ Packet x2 = pmul(x, x);
+ Packet p = pmadd(p9, x2, p7);
+ p = pmadd(p, x2, p5);
+ p = pmadd(p, x2, p3);
+ p = pmadd(p, x2, p1);
+ p = pmul(p, x);
+
+ constexpr float kPiOverTwo = static_cast<float>(EIGEN_PI/2);
+ Packet p_large = pnmadd(cst_two, p, pset1<Packet>(kPiOverTwo));
+ p = pselect(large_mask, p_large, p);
+ // Flip the sign for negative arguments.
+ p = pselect(neg_mask, pnegate(p), p);
+
+ // Return NaN for arguments outside [-1:1].
+ return pselect(invalid_mask, pset1<Packet>(std::numeric_limits<float>::quiet_NaN()), p);
+}
+
+template<typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet patan_float(const Packet& x_in) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ static_assert(std::is_same<Scalar, float>::value, "Scalar type must be float");
+
+ const Packet cst_one = pset1<Packet>(1.0f);
+ constexpr float kPiOverTwo = static_cast<float>(EIGEN_PI/2);
+ const Packet cst_pi_over_two = pset1<Packet>(kPiOverTwo);
+ constexpr float kPiOverFour = static_cast<float>(EIGEN_PI/4);
+ const Packet cst_pi_over_four = pset1<Packet>(kPiOverFour);
+ const Packet cst_large = pset1<Packet>(2.4142135623730950488016887f); // tan(3*pi/8);
+ const Packet cst_medium = pset1<Packet>(0.4142135623730950488016887f); // tan(pi/8);
+ const Packet q0 = pset1<Packet>(-0.333329379558563232421875f);
+ const Packet q2 = pset1<Packet>(0.19977366924285888671875f);
+ const Packet q4 = pset1<Packet>(-0.13874518871307373046875f);
+ const Packet q6 = pset1<Packet>(8.044691383838653564453125e-2f);
+
+ const Packet neg_mask = pcmp_lt(x_in, pzero(x_in));
+ Packet x = pabs(x_in);
+
+ // Use the same range reduction strategy (to [0:tan(pi/8)]) as the
+ // Cephes library:
+ // "Large": For x >= tan(3*pi/8), use atan(1/x) = pi/2 - atan(x).
+ // "Medium": For x in [tan(pi/8) : tan(3*pi/8)),
+ // use atan(x) = pi/4 + atan((x-1)/(x+1)).
+ // "Small": For x < pi/8, approximate atan(x) directly by a polynomial
+ // calculated using Sollya.
+ const Packet large_mask = pcmp_lt(cst_large, x);
+ x = pselect(large_mask, preciprocal(x), x);
+ const Packet medium_mask = pandnot(pcmp_lt(cst_medium, x), large_mask);
+ x = pselect(medium_mask, pdiv(psub(x, cst_one), padd(x, cst_one)), x);
+
+ // Approximate atan(x) on [0:tan(pi/8)] by a polynomial of the form
+ // P(x) = x + x^3 * Q(x^2),
+ // where Q(x^2) is a cubic polynomial in x^2.
+ const Packet x2 = pmul(x, x);
+ const Packet x4 = pmul(x2, x2);
+ Packet q_odd = pmadd(q6, x4, q2);
+ Packet q_even = pmadd(q4, x4, q0);
+ const Packet q = pmadd(q_odd, x2, q_even);
+ Packet p = pmadd(q, pmul(x, x2), x);
+
+ // Apply transformations according to the range reduction masks.
+ p = pselect(large_mask, psub(cst_pi_over_two, p), p);
+ p = pselect(medium_mask, padd(cst_pi_over_four, p), p);
+ return pselect(neg_mask, pnegate(p), p);
+}
+
template<typename Packet>
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet pdiv_complex(const Packet& x, const Packet& y) {
@@ -852,6 +997,97 @@
pselect(is_real_inf, real_inf_result,result));
}
+
+template <typename Packet>
+struct psign_impl<
+ Packet,
+ std::enable_if_t<
+ !NumTraits<typename unpacket_traits<Packet>::type>::IsComplex &&
+ !NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>> {
+ static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) {
+ using Scalar = typename unpacket_traits<Packet>::type;
+ const Packet cst_one = pset1<Packet>(Scalar(1));
+ const Packet cst_minus_one = pset1<Packet>(Scalar(-1));
+ const Packet cst_zero = pzero(a);
+
+ const Packet not_nan_mask = pcmp_eq(a, a);
+ const Packet positive_mask = pcmp_lt(cst_zero, a);
+ const Packet positive = pand(positive_mask, cst_one);
+ const Packet negative_mask = pcmp_lt(a, cst_zero);
+ const Packet negative = pand(negative_mask, cst_minus_one);
+
+ return pselect(not_nan_mask, por(positive, negative), a);
+ }
+};
+
+template <typename Packet>
+struct psign_impl<
+ Packet, std::enable_if_t<
+ !NumTraits<typename unpacket_traits<Packet>::type>::IsComplex &&
+ NumTraits<typename unpacket_traits<Packet>::type>::IsSigned &&
+ NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>> {
+ static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) {
+ using Scalar = typename unpacket_traits<Packet>::type;
+ const Packet cst_one = pset1<Packet>(Scalar(1));
+ const Packet cst_minus_one = pset1<Packet>(Scalar(-1));
+ const Packet cst_zero = pzero(a);
+
+ const Packet positive_mask = pcmp_lt(cst_zero, a);
+ const Packet positive = pand(positive_mask, cst_one);
+ const Packet negative_mask = pcmp_lt(a, cst_zero);
+ const Packet negative = pand(negative_mask, cst_minus_one);
+
+ return por(positive, negative);
+ }
+};
+
+template <typename Packet>
+struct psign_impl<Packet, std::enable_if_t<!NumTraits<typename unpacket_traits<Packet>::type>::IsComplex &&
+ !NumTraits<typename unpacket_traits<Packet>::type>::IsSigned &&
+ NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>> {
+ static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) {
+ using Scalar = typename unpacket_traits<Packet>::type;
+ const Packet cst_one = pset1<Packet>(Scalar(1));
+ const Packet cst_zero = pzero(a);
+
+ const Packet zero_mask = pcmp_eq(cst_zero, a);
+ return pandnot(cst_one, zero_mask);
+ }
+};
+
+// \internal \returns the the sign of a complex number z, defined as z / abs(z).
+template <typename Packet>
+struct psign_impl<Packet, std::enable_if_t<NumTraits<typename unpacket_traits<Packet>::type>::IsComplex>> {
+ static EIGEN_DEVICE_FUNC inline Packet run(const Packet& a) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ typedef typename Scalar::value_type RealScalar;
+ typedef typename unpacket_traits<Packet>::as_real RealPacket;
+
+ // Step 1. Compute (for each element z = x + i*y in a)
+ // l = abs(z) = sqrt(x^2 + y^2).
+ // To avoid over- and underflow, we use the stable formula for each hypotenuse
+ // l = (zmin == 0 ? zmax : zmax * sqrt(1 + (zmin/zmax)**2)),
+ // where zmax = max(|x|, |y|), zmin = min(|x|, |y|),
+ RealPacket a_abs = pabs(a.v);
+ RealPacket a_abs_flip = pcplxflip(Packet(a_abs)).v;
+ RealPacket a_max = pmax(a_abs, a_abs_flip);
+ RealPacket a_min = pmin(a_abs, a_abs_flip);
+ RealPacket a_min_zero_mask = pcmp_eq(a_min, pzero(a_min));
+ RealPacket a_max_zero_mask = pcmp_eq(a_max, pzero(a_max));
+ RealPacket r = pdiv(a_min, a_max);
+ const RealPacket cst_one = pset1<RealPacket>(RealScalar(1));
+ RealPacket l = pmul(a_max, psqrt(padd(cst_one, pmul(r, r)))); // [l0, l0, l1, l1]
+ // Set l to a_max if a_min is zero, since the roundtrip sqrt(a_max^2) may be
+ // lossy.
+ l = pselect(a_min_zero_mask, a_max, l);
+ // Step 2 compute a / abs(a).
+ RealPacket sign_as_real = pandnot(pdiv(a.v, l), a_max_zero_mask);
+ Packet sign;
+ sign.v = sign_as_real;
+ return sign;
+ }
+};
+
// TODO(rmlarsen): The following set of utilities for double word arithmetic
// should perhaps be refactored as a separate file, since it would be generally
// useful for special function implementation etc. Writing the algorithms in
@@ -1021,32 +1257,23 @@
fast_twosum(p_hi_hi, p_hi_lo, p_lo_hi, p_lo_lo, p_hi, p_lo);
}
-// This function computes the reciprocal of a floating point number
-// with extra precision and returns the result as a double word.
+// This function implements the division of double word {x_hi, x_lo}
+// by float y. This is Algorithm 15 from "Tight and rigourous error bounds
+// for basic building blocks of double-word arithmetic", Joldes, Muller, & Popescu,
+// 2017. https://hal.archives-ouvertes.fr/hal-01351529
template <typename Packet>
-void doubleword_reciprocal(const Packet& x, Packet& recip_hi, Packet& recip_lo) {
- typedef typename unpacket_traits<Packet>::type Scalar;
- // 1. Approximate the reciprocal as the reciprocal of the high order element.
- Packet approx_recip = prsqrt(x);
- approx_recip = pmul(approx_recip, approx_recip);
-
- // 2. Run one step of Newton-Raphson iteration in double word arithmetic
- // to get the bottom half. The NR iteration for reciprocal of 'a' is
- // x_{i+1} = x_i * (2 - a * x_i)
-
- // -a*x_i
- Packet t1_hi, t1_lo;
- twoprod(pnegate(x), approx_recip, t1_hi, t1_lo);
- // 2 - a*x_i
- Packet t2_hi, t2_lo;
- fast_twosum(pset1<Packet>(Scalar(2)), t1_hi, t2_hi, t2_lo);
- Packet t3_hi, t3_lo;
- fast_twosum(t2_hi, padd(t2_lo, t1_lo), t3_hi, t3_lo);
- // x_i * (2 - a * x_i)
- twoprod(t3_hi, t3_lo, approx_recip, recip_hi, recip_lo);
+void doubleword_div_fp(const Packet& x_hi, const Packet& x_lo, const Packet& y,
+ Packet& z_hi, Packet& z_lo) {
+ const Packet t_hi = pdiv(x_hi, y);
+ Packet pi_hi, pi_lo;
+ twoprod(t_hi, y, pi_hi, pi_lo);
+ const Packet delta_hi = psub(x_hi, pi_hi);
+ const Packet delta_t = psub(delta_hi, pi_lo);
+ const Packet delta = padd(delta_t, x_lo);
+ const Packet t_lo = pdiv(delta, y);
+ fast_twosum(t_hi, t_lo, z_hi, z_lo);
}
-
// This function computes log2(x) and returns the result as a double word.
template <typename Scalar>
struct accurate_log2 {
@@ -1185,16 +1412,13 @@
const Packet cst_2_log2e_hi = pset1<Packet>(2.88539008177792677);
const Packet cst_2_log2e_lo = pset1<Packet>(4.07660016854549667e-17);
// c * (x - 1)
- Packet num_hi, num_lo;
- twoprod(cst_2_log2e_hi, cst_2_log2e_lo, psub(x, one), num_hi, num_lo);
- // TODO(rmlarsen): Investigate if using the division algorithm by
- // Muller et al. is faster/more accurate.
- // 1 / (x + 1)
- Packet denom_hi, denom_lo;
- doubleword_reciprocal(padd(x, one), denom_hi, denom_lo);
- // r = c * (x-1) / (x+1),
+ Packet t_hi, t_lo;
+ // t = c * (x-1)
+ twoprod(cst_2_log2e_hi, cst_2_log2e_lo, psub(x, one), t_hi, t_lo);
+ // r = c * (x-1) / (x+1),
Packet r_hi, r_lo;
- twoprod(num_hi, num_lo, denom_hi, denom_lo, r_hi, r_lo);
+ doubleword_div_fp(t_hi, t_lo, padd(x, one), r_hi, r_lo);
+
// r2 = r * r
Packet r2_hi, r2_lo;
twoprod(r_hi, r_lo, r_hi, r_lo, r2_hi, r2_lo);
@@ -1424,38 +1648,40 @@
}
// Generic implementation of pow(x,y).
-template<typename Packet>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet generic_pow(const Packet& x, const Packet& y) {
+template <typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_pow(const Packet& x, const Packet& y) {
typedef typename unpacket_traits<Packet>::type Scalar;
const Packet cst_pos_inf = pset1<Packet>(NumTraits<Scalar>::infinity());
+ const Packet cst_neg_inf = pset1<Packet>(-NumTraits<Scalar>::infinity());
const Packet cst_zero = pset1<Packet>(Scalar(0));
const Packet cst_one = pset1<Packet>(Scalar(1));
const Packet cst_nan = pset1<Packet>(NumTraits<Scalar>::quiet_NaN());
const Packet abs_x = pabs(x);
// Predicates for sign and magnitude of x.
- const Packet x_is_zero = pcmp_eq(x, cst_zero);
- const Packet x_is_neg = pcmp_lt(x, cst_zero);
+ const Packet abs_x_is_zero = pcmp_eq(abs_x, cst_zero);
+ const Packet x_has_signbit = pcmp_eq(por(pand(x, cst_neg_inf), cst_pos_inf), cst_neg_inf);
+ const Packet x_is_neg = pandnot(x_has_signbit, abs_x_is_zero);
+ const Packet x_is_neg_zero = pand(x_has_signbit, abs_x_is_zero);
const Packet abs_x_is_inf = pcmp_eq(abs_x, cst_pos_inf);
- const Packet abs_x_is_one = pcmp_eq(abs_x, cst_one);
+ const Packet abs_x_is_one = pcmp_eq(abs_x, cst_one);
const Packet abs_x_is_gt_one = pcmp_lt(cst_one, abs_x);
const Packet abs_x_is_lt_one = pcmp_lt(abs_x, cst_one);
- const Packet x_is_one = pandnot(abs_x_is_one, x_is_neg);
- const Packet x_is_neg_one = pand(abs_x_is_one, x_is_neg);
+ const Packet x_is_one = pandnot(abs_x_is_one, x_is_neg);
+ const Packet x_is_neg_one = pand(abs_x_is_one, x_is_neg);
const Packet x_is_nan = pandnot(ptrue(x), pcmp_eq(x, x));
// Predicates for sign and magnitude of y.
+ const Packet abs_y = pabs(y);
const Packet y_is_one = pcmp_eq(y, cst_one);
- const Packet y_is_zero = pcmp_eq(y, cst_zero);
+ const Packet abs_y_is_zero = pcmp_eq(abs_y, cst_zero);
const Packet y_is_neg = pcmp_lt(y, cst_zero);
- const Packet y_is_pos = pandnot(ptrue(y), por(y_is_zero, y_is_neg));
+ const Packet y_is_pos = pandnot(ptrue(y), por(abs_y_is_zero, y_is_neg));
const Packet y_is_nan = pandnot(ptrue(y), pcmp_eq(y, y));
- const Packet abs_y_is_inf = pcmp_eq(pabs(y), cst_pos_inf);
+ const Packet abs_y_is_inf = pcmp_eq(abs_y, cst_pos_inf);
EIGEN_CONSTEXPR Scalar huge_exponent =
- (NumTraits<Scalar>::max_exponent() * Scalar(EIGEN_LN2)) /
- NumTraits<Scalar>::epsilon();
+ (NumTraits<Scalar>::max_exponent() * Scalar(EIGEN_LN2)) / NumTraits<Scalar>::epsilon();
const Packet abs_y_is_huge = pcmp_le(pset1<Packet>(huge_exponent), pabs(y));
// Predicates for whether y is integer and/or even.
@@ -1464,39 +1690,31 @@
const Packet y_is_even = pcmp_eq(pround(y_div_2), y_div_2);
// Predicates encoding special cases for the value of pow(x,y)
- const Packet invalid_negative_x = pandnot(pandnot(pandnot(x_is_neg, abs_x_is_inf),
- y_is_int),
- abs_y_is_inf);
- const Packet pow_is_one = por(por(x_is_one, y_is_zero),
- pand(x_is_neg_one,
- por(abs_y_is_inf, pandnot(y_is_even, invalid_negative_x))));
+ const Packet invalid_negative_x = pandnot(pandnot(pandnot(x_is_neg, abs_x_is_inf), y_is_int), abs_y_is_inf);
const Packet pow_is_nan = por(invalid_negative_x, por(x_is_nan, y_is_nan));
- const Packet pow_is_zero = por(por(por(pand(x_is_zero, y_is_pos),
- pand(abs_x_is_inf, y_is_neg)),
- pand(pand(abs_x_is_lt_one, abs_y_is_huge),
- y_is_pos)),
- pand(pand(abs_x_is_gt_one, abs_y_is_huge),
- y_is_neg));
- const Packet pow_is_inf = por(por(por(pand(x_is_zero, y_is_neg),
- pand(abs_x_is_inf, y_is_pos)),
- pand(pand(abs_x_is_lt_one, abs_y_is_huge),
- y_is_neg)),
- pand(pand(abs_x_is_gt_one, abs_y_is_huge),
- y_is_pos));
+ const Packet pow_is_one =
+ por(por(x_is_one, abs_y_is_zero), pand(x_is_neg_one, por(abs_y_is_inf, pandnot(y_is_even, invalid_negative_x))));
+ const Packet pow_is_zero = por(por(por(pand(abs_x_is_zero, y_is_pos), pand(abs_x_is_inf, y_is_neg)),
+ pand(pand(abs_x_is_lt_one, abs_y_is_huge), y_is_pos)),
+ pand(pand(abs_x_is_gt_one, abs_y_is_huge), y_is_neg));
+ const Packet pow_is_inf = por(por(por(pand(abs_x_is_zero, y_is_neg), pand(abs_x_is_inf, y_is_pos)),
+ pand(pand(abs_x_is_lt_one, abs_y_is_huge), y_is_neg)),
+ pand(pand(abs_x_is_gt_one, abs_y_is_huge), y_is_pos));
+ const Packet inf_val =
+ pselect(pandnot(pand(por(pand(abs_x_is_inf, x_is_neg), pand(x_is_neg_zero, y_is_neg)), y_is_int), y_is_even),
+ cst_neg_inf, cst_pos_inf);
// General computation of pow(x,y) for positive x or negative x and integer y.
const Packet negate_pow_abs = pandnot(x_is_neg, y_is_even);
const Packet pow_abs = generic_pow_impl(abs_x, y);
- return pselect(y_is_one, x,
- pselect(pow_is_one, cst_one,
- pselect(pow_is_nan, cst_nan,
- pselect(pow_is_inf, cst_pos_inf,
- pselect(pow_is_zero, cst_zero,
- pselect(negate_pow_abs, pnegate(pow_abs), pow_abs))))));
+ return pselect(
+ y_is_one, x,
+ pselect(pow_is_one, cst_one,
+ pselect(pow_is_nan, cst_nan,
+ pselect(pow_is_inf, inf_val,
+ pselect(pow_is_zero, cst_zero, pselect(negate_pow_abs, pnegate(pow_abs), pow_abs))))));
}
-
-
/* polevl (modified for Eigen)
*
* Evaluate polynomial
@@ -1623,6 +1841,267 @@
}
};
+namespace unary_pow {
+template <typename ScalarExponent, bool IsIntegerAtCompileTime = NumTraits<ScalarExponent>::IsInteger>
+struct is_odd {
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ScalarExponent run(const ScalarExponent& x) {
+ ScalarExponent xdiv2 = x / ScalarExponent(2);
+ ScalarExponent floorxdiv2 = numext::floor(xdiv2);
+ return xdiv2 != floorxdiv2;
+ }
+};
+template <typename ScalarExponent>
+struct is_odd<ScalarExponent, true> {
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ScalarExponent run(const ScalarExponent& x) {
+ return x % ScalarExponent(2);
+ }
+};
+
+template <typename Packet, typename ScalarExponent,
+ bool BaseIsIntegerType = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
+struct do_div {
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x, const ScalarExponent& exponent) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ const Packet cst_pos_one = pset1<Packet>(Scalar(1));
+ return exponent < 0 ? pdiv(cst_pos_one, x) : x;
+ }
+};
+
+template <typename Packet, typename ScalarExponent>
+struct do_div<Packet, ScalarExponent, true> {
+ // pdiv not defined, nor necessary for integer base types
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x, const ScalarExponent& exponent) {
+ EIGEN_UNUSED_VARIABLE(exponent);
+ return x;
+ }
+};
+
+template <typename Packet, typename ScalarExponent>
+static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet int_pow(const Packet& x, const ScalarExponent& exponent) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ const Packet cst_pos_one = pset1<Packet>(Scalar(1));
+ if (exponent == 0) return cst_pos_one;
+ Packet result = x;
+ Packet y = cst_pos_one;
+ ScalarExponent m = numext::abs(exponent);
+ while (m > 1) {
+ bool odd = is_odd<ScalarExponent>::run(m);
+ if (odd) y = pmul(y, result);
+ result = pmul(result, result);
+ m = numext::floor(m / ScalarExponent(2));
+ }
+ result = pmul(y, result);
+ result = do_div<Packet, ScalarExponent>::run(result, exponent);
+ return result;
+}
+
+template <typename Packet>
+static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet gen_pow(const Packet& x,
+ const typename unpacket_traits<Packet>::type& exponent) {
+ const Packet exponent_packet = pset1<Packet>(exponent);
+ return generic_pow_impl(x, exponent_packet);
+}
+
+template <typename Packet, typename ScalarExponent>
+static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet handle_nonint_int_errors(const Packet& x, const Packet& powx,
+ const ScalarExponent& exponent) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+
+ // non-integer base, integer exponent case
+
+ const bool exponent_is_odd = is_odd<ScalarExponent>::run(exponent);
+ const bool exponent_is_neg = exponent < 0;
+
+ const Packet exp_is_odd = exponent_is_odd ? ptrue(x) : pzero(x);
+ const Packet exp_is_neg = exponent_is_neg ? ptrue(x) : pzero(x);
+
+ const Scalar pos_zero = Scalar(0);
+ const Scalar neg_zero = -Scalar(0);
+ const Scalar pos_one = Scalar(1);
+ const Scalar pos_inf = NumTraits<Scalar>::infinity();
+ const Scalar neg_inf = -NumTraits<Scalar>::infinity();
+
+ const Packet cst_pos_zero = pset1<Packet>(pos_zero);
+ const Packet cst_neg_zero = pset1<Packet>(neg_zero);
+ const Packet cst_pos_one = pset1<Packet>(pos_one);
+ const Packet cst_pos_inf = pset1<Packet>(pos_inf);
+ const Packet cst_neg_inf = pset1<Packet>(neg_inf);
+
+ const Packet abs_x = pabs(x);
+ const Packet abs_x_is_zero = pcmp_eq(abs_x, cst_pos_zero);
+ const Packet abs_x_is_one = pcmp_eq(abs_x, cst_pos_one);
+ const Packet abs_x_is_inf = pcmp_eq(abs_x, cst_pos_inf);
+
+ const Packet x_has_signbit = pcmp_eq(por(pand(x, cst_neg_inf), cst_pos_inf), cst_neg_inf);
+ const Packet x_is_neg = pandnot(x_has_signbit, abs_x_is_zero);
+ const Packet x_is_neg_zero = pand(x_has_signbit, abs_x_is_zero);
+
+ if (exponent == 0) {
+ return cst_pos_one;
+ }
+
+ Packet pow_is_pos_inf = pand(pandnot(abs_x_is_zero, x_is_neg_zero), pand(exp_is_odd, exp_is_neg));
+ pow_is_pos_inf = por(pow_is_pos_inf, pand(abs_x_is_zero, pandnot(exp_is_neg, exp_is_odd)));
+ pow_is_pos_inf = por(pow_is_pos_inf, pand(pand(abs_x_is_inf, x_is_neg), pandnot(pnot(exp_is_neg), exp_is_odd)));
+ pow_is_pos_inf = por(pow_is_pos_inf, pandnot(pandnot(abs_x_is_inf, x_is_neg), exp_is_neg));
+
+ Packet pow_is_neg_inf = pand(x_is_neg_zero, pand(exp_is_neg, exp_is_odd));
+ pow_is_neg_inf = por(pow_is_neg_inf, pand(pand(abs_x_is_inf, x_is_neg), pandnot(exp_is_odd, exp_is_neg)));
+
+ Packet pow_is_pos_zero = pandnot(abs_x_is_zero, exp_is_neg);
+ pow_is_pos_zero = por(pow_is_pos_zero, pand(pand(abs_x_is_inf, x_is_neg), pandnot(exp_is_neg, exp_is_odd)));
+ pow_is_pos_zero = por(pow_is_pos_zero, pand(pandnot(abs_x_is_inf, x_is_neg), exp_is_neg));
+
+ Packet pow_is_neg_zero = pand(x_is_neg_zero, pandnot(exp_is_odd, exp_is_neg));
+ pow_is_neg_zero = por(pow_is_neg_zero, pand(pand(abs_x_is_inf, x_is_neg), pand(exp_is_odd, exp_is_neg)));
+
+ Packet result = pselect(pow_is_neg_inf, cst_neg_inf, powx);
+ result = pselect(pow_is_neg_zero, cst_neg_zero, result);
+ result = pselect(pow_is_pos_zero, cst_pos_zero, result);
+ result = pselect(pow_is_pos_inf, cst_pos_inf, result);
+ result = pselect(pandnot(abs_x_is_one, x_is_neg), cst_pos_one, result);
+ return result;
+}
+
+template <typename Packet, typename ScalarExponent>
+static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet handle_nonint_nonint_errors(const Packet& x, const Packet& powx,
+ const ScalarExponent& exponent) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+
+ // non-integer base and exponent case
+
+ const bool exponent_is_fin = (numext::isfinite)(exponent);
+ const bool exponent_is_nan = (numext::isnan)(exponent);
+ const bool exponent_is_neg = exponent < 0;
+ const bool exponent_is_inf = !exponent_is_fin && !exponent_is_nan;
+
+ const Packet exp_is_neg = exponent_is_neg ? ptrue(x) : pzero(x);
+ const Packet exp_is_inf = exponent_is_inf ? ptrue(x) : pzero(x);
+
+ const Scalar pos_zero = Scalar(0);
+ const Scalar pos_one = Scalar(1);
+ const Scalar pos_inf = NumTraits<Scalar>::infinity();
+ const Scalar neg_inf = -NumTraits<Scalar>::infinity();
+ const Scalar nan = NumTraits<Scalar>::quiet_NaN();
+
+ const Packet cst_pos_zero = pset1<Packet>(pos_zero);
+ const Packet cst_pos_one = pset1<Packet>(pos_one);
+ const Packet cst_pos_inf = pset1<Packet>(pos_inf);
+ const Packet cst_neg_inf = pset1<Packet>(neg_inf);
+ const Packet cst_nan = pset1<Packet>(nan);
+
+ const Packet abs_x = pabs(x);
+ const Packet abs_x_is_zero = pcmp_eq(abs_x, cst_pos_zero);
+ const Packet abs_x_is_lt_one = pcmp_lt(abs_x, cst_pos_one);
+ const Packet abs_x_is_gt_one = pcmp_lt(cst_pos_one, abs_x);
+ const Packet abs_x_is_one = pcmp_eq(abs_x, cst_pos_one);
+ const Packet abs_x_is_inf = pcmp_eq(abs_x, cst_pos_inf);
+
+ const Packet x_has_signbit = pcmp_eq(por(pand(x, cst_neg_inf), cst_pos_inf), cst_neg_inf);
+ const Packet x_is_neg = pandnot(x_has_signbit, abs_x_is_zero);
+
+ if (exponent_is_nan) {
+ return pselect(pandnot(abs_x_is_one, x_is_neg), cst_pos_one, cst_nan);
+ }
+
+ Packet pow_is_pos_zero = pandnot(abs_x_is_zero, exp_is_neg);
+ pow_is_pos_zero = por(pow_is_pos_zero, pand(abs_x_is_gt_one, pand(exp_is_inf, exp_is_neg)));
+ pow_is_pos_zero = por(pow_is_pos_zero, pand(abs_x_is_lt_one, pandnot(exp_is_inf, exp_is_neg)));
+ pow_is_pos_zero = por(pow_is_pos_zero, pand(abs_x_is_inf, exp_is_neg));
+
+ const Packet pow_is_pos_one = pand(abs_x_is_one, exp_is_inf);
+
+ Packet pow_is_pos_inf = pand(abs_x_is_zero, exp_is_neg);
+ pow_is_pos_inf = por(pow_is_pos_inf, pand(abs_x_is_lt_one, pand(exp_is_inf, exp_is_neg)));
+ pow_is_pos_inf = por(pow_is_pos_inf, pand(abs_x_is_gt_one, pandnot(exp_is_inf, exp_is_neg)));
+ pow_is_pos_inf = por(pow_is_pos_inf, pandnot(abs_x_is_inf, exp_is_neg));
+
+ const Packet pow_is_nan = pandnot(pandnot(x_is_neg, abs_x_is_inf), exp_is_inf);
+
+ Packet result = pselect(pow_is_pos_inf, cst_pos_inf, powx);
+ result = pselect(pow_is_pos_one, cst_pos_one, result);
+ result = pselect(pow_is_pos_zero, cst_pos_zero, result);
+ result = pselect(pow_is_nan, cst_nan, result);
+ result = pselect(pandnot(abs_x_is_one, x_is_neg), cst_pos_one, result);
+ return result;
+}
+
+template <typename Packet, typename ScalarExponent>
+static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet handle_int_int(const Packet& x, const ScalarExponent& exponent) {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+
+ // integer base, integer exponent case
+
+ // This routine handles negative and very large positive exponents
+ // Signed integer overflow and divide by zero is undefined behavior
+ // Unsigned intgers do not overflow
+
+ const bool exponent_is_odd = unary_pow::is_odd<ScalarExponent>::run(exponent);
+
+ const Scalar zero = Scalar(0);
+ const Scalar pos_one = Scalar(1);
+
+ const Packet cst_zero = pset1<Packet>(zero);
+ const Packet cst_pos_one = pset1<Packet>(pos_one);
+
+ const Packet abs_x = pabs(x);
+
+ const Packet pow_is_zero = exponent < 0 ? pcmp_lt(cst_pos_one, abs_x) : pzero(x);
+ const Packet pow_is_one = pcmp_eq(cst_pos_one, abs_x);
+ const Packet pow_is_neg = exponent_is_odd ? pcmp_lt(x, cst_zero) : pzero(x);
+
+ Packet result = pselect(pow_is_zero, cst_zero, x);
+ result = pselect(pandnot(pow_is_one, pow_is_neg), cst_pos_one, result);
+ result = pselect(pand(pow_is_one, pow_is_neg), pnegate(cst_pos_one), result);
+ return result;
+}
+} // end namespace unary_pow
+
+template <typename Packet, typename ScalarExponent,
+ bool BaseIsIntegerType = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger,
+ bool ExponentIsIntegerType = NumTraits<ScalarExponent>::IsInteger>
+struct unary_pow_impl;
+
+template <typename Packet, typename ScalarExponent>
+struct unary_pow_impl<Packet, ScalarExponent, false, false> {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x, const ScalarExponent& exponent) {
+ const bool exponent_is_integer = (numext::isfinite)(exponent) && numext::round(exponent) == exponent;
+ if (exponent_is_integer) {
+ Packet result = unary_pow::int_pow(x, exponent);
+ result = unary_pow::handle_nonint_int_errors(x, result, exponent);
+ return result;
+ } else {
+ Packet result = unary_pow::gen_pow(x, exponent);
+ result = unary_pow::handle_nonint_nonint_errors(x, result, exponent);
+ return result;
+ }
+ }
+};
+
+template <typename Packet, typename ScalarExponent>
+struct unary_pow_impl<Packet, ScalarExponent, false, true> {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x, const ScalarExponent& exponent) {
+ Packet result = unary_pow::int_pow(x, exponent);
+ result = unary_pow::handle_nonint_int_errors(x, result, exponent);
+ return result;
+ }
+};
+
+template <typename Packet, typename ScalarExponent>
+struct unary_pow_impl<Packet, ScalarExponent, true, true> {
+ typedef typename unpacket_traits<Packet>::type Scalar;
+ static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x, const ScalarExponent& exponent) {
+ if (exponent < 0 || exponent > NumTraits<Scalar>::digits()) {
+ return unary_pow::handle_int_int(x, exponent);
+ }
+ else {
+ return unary_pow::int_pow(x, exponent);
+ }
+ }
+};
+
} // end namespace internal
} // end namespace Eigen
diff --git a/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h b/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
index 962cb14..de6fd95 100644
--- a/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
+++ b/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
@@ -89,6 +89,21 @@
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet pcos_float(const Packet& x);
+/** \internal \returns asin(x) for single precision float */
+template<typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet pasin_float(const Packet& x);
+
+/** \internal \returns acos(x) for single precision float */
+template<typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet pacos_float(const Packet& x);
+
+/** \internal \returns atan(x) for single precision float */
+template<typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet patan_float(const Packet& x);
+
/** \internal \returns sqrt(x) for complex types */
template<typename Packet>
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
diff --git a/Eigen/src/Core/arch/Default/Half.h b/Eigen/src/Core/arch/Default/Half.h
index 2bcdf6c..d58b6a3 100644
--- a/Eigen/src/Core/arch/Default/Half.h
+++ b/Eigen/src/Core/arch/Default/Half.h
@@ -37,7 +37,6 @@
#define EIGEN_HALF_H
#include "../../InternalHeaderCheck.h"
-#include <sstream>
#if defined(EIGEN_HAS_GPU_FP16) || defined(EIGEN_HAS_ARM64_FP16_SCALAR_ARITHMETIC)
// When compiling with GPU support, the "__half_raw" base class as well as
diff --git a/Eigen/src/Core/arch/GPU/PacketMath.h b/Eigen/src/Core/arch/GPU/PacketMath.h
index e147fd1..e2bcf48 100644
--- a/Eigen/src/Core/arch/GPU/PacketMath.h
+++ b/Eigen/src/Core/arch/GPU/PacketMath.h
@@ -176,11 +176,22 @@
const float& b) {
return __int_as_float(a < b ? 0xffffffffu : 0u);
}
+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double lt_mask(const double& a,
const double& b) {
return __longlong_as_double(a < b ? 0xffffffffffffffffull : 0ull);
}
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float le_mask(const float& a,
+ const float& b) {
+ return __int_as_float(a <= b ? 0xffffffffu : 0u);
+}
+
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double le_mask(const double& a,
+ const double& b) {
+ return __longlong_as_double(a <= b ? 0xffffffffffffffffull : 0ull);
+}
+
template <>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float4 pand<float4>(const float4& a,
const float4& b) {
@@ -242,6 +253,12 @@
lt_mask(a.w, b.w));
}
template <>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float4 pcmp_le<float4>(const float4& a,
+ const float4& b) {
+ return make_float4(le_mask(a.x, b.x), le_mask(a.y, b.y), le_mask(a.z, b.z),
+ le_mask(a.w, b.w));
+}
+template <>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double2
pcmp_eq<double2>(const double2& a, const double2& b) {
return make_double2(eq_mask(a.x, b.x), eq_mask(a.y, b.y));
@@ -251,6 +268,11 @@
pcmp_lt<double2>(const double2& a, const double2& b) {
return make_double2(lt_mask(a.x, b.x), lt_mask(a.y, b.y));
}
+template <>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double2
+pcmp_le<double2>(const double2& a, const double2& b) {
+ return make_double2(le_mask(a.x, b.x), le_mask(a.y, b.y));
+}
#endif // defined(EIGEN_CUDA_ARCH) || defined(EIGEN_HIPCC) || (defined(EIGEN_CUDACC) && EIGEN_COMP_CLANG && !EIGEN_COMP_NVCC)
template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float4 plset<float4>(const float& a) {
@@ -676,6 +698,19 @@
return __halves2half2(eq1, eq2);
}
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pcmp_le(const half2& a,
+ const half2& b) {
+ half true_half = half_impl::raw_uint16_to_half(0xffffu);
+ half false_half = half_impl::raw_uint16_to_half(0x0000u);
+ half a1 = __low2half(a);
+ half a2 = __high2half(a);
+ half b1 = __low2half(b);
+ half b2 = __high2half(b);
+ half eq1 = __half2float(a1) <= __half2float(b1) ? true_half : false_half;
+ half eq2 = __half2float(a2) <= __half2float(b2) ? true_half : false_half;
+ return __halves2half2(eq1, eq2);
+}
+
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pand(const half2& a,
const half2& b) {
half a1 = __low2half(a);
@@ -1258,6 +1293,34 @@
}
template <>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
+pcmp_lt<Packet4h2>(const Packet4h2& a, const Packet4h2& b) {
+ Packet4h2 r;
+ half2* r_alias = reinterpret_cast<half2*>(&r);
+ const half2* a_alias = reinterpret_cast<const half2*>(&a);
+ const half2* b_alias = reinterpret_cast<const half2*>(&b);
+ r_alias[0] = pcmp_lt(a_alias[0], b_alias[0]);
+ r_alias[1] = pcmp_lt(a_alias[1], b_alias[1]);
+ r_alias[2] = pcmp_lt(a_alias[2], b_alias[2]);
+ r_alias[3] = pcmp_lt(a_alias[3], b_alias[3]);
+ return r;
+}
+
+template <>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2
+pcmp_le<Packet4h2>(const Packet4h2& a, const Packet4h2& b) {
+ Packet4h2 r;
+ half2* r_alias = reinterpret_cast<half2*>(&r);
+ const half2* a_alias = reinterpret_cast<const half2*>(&a);
+ const half2* b_alias = reinterpret_cast<const half2*>(&b);
+ r_alias[0] = pcmp_le(a_alias[0], b_alias[0]);
+ r_alias[1] = pcmp_le(a_alias[1], b_alias[1]);
+ r_alias[2] = pcmp_le(a_alias[2], b_alias[2]);
+ r_alias[3] = pcmp_le(a_alias[3], b_alias[3]);
+ return r;
+}
+
+template <>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4h2 pand<Packet4h2>(
const Packet4h2& a, const Packet4h2& b) {
Packet4h2 r;
diff --git a/Eigen/src/Core/arch/NEON/MathFunctions.h b/Eigen/src/Core/arch/NEON/MathFunctions.h
index c424cb2..445572f 100644
--- a/Eigen/src/Core/arch/NEON/MathFunctions.h
+++ b/Eigen/src/Core/arch/NEON/MathFunctions.h
@@ -34,6 +34,21 @@
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet4f pcos<Packet4f>(const Packet4f& x)
{ return pcos_float(x); }
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet2f pacos<Packet2f>(const Packet2f& x)
+{ return pacos_float(x); }
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet4f pacos<Packet4f>(const Packet4f& x)
+{ return pacos_float(x); }
+
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet2f pasin<Packet2f>(const Packet2f& x)
+{ return pasin_float(x); }
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet4f pasin<Packet4f>(const Packet4f& x)
+{ return pasin_float(x); }
+
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet2f patan<Packet2f>(const Packet2f& x)
+{ return patan_float(x); }
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet4f patan<Packet4f>(const Packet4f& x)
+{ return patan_float(x); }
+
// Hyperbolic Tangent function.
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet2f ptanh<Packet2f>(const Packet2f& x)
{ return internal::generic_fast_tanh_float(x); }
diff --git a/Eigen/src/Core/arch/NEON/PacketMath.h b/Eigen/src/Core/arch/NEON/PacketMath.h
index 33af653..9ef83d4 100644
--- a/Eigen/src/Core/arch/NEON/PacketMath.h
+++ b/Eigen/src/Core/arch/NEON/PacketMath.h
@@ -198,6 +198,9 @@
HasSin = EIGEN_FAST_MATH,
HasCos = EIGEN_FAST_MATH,
+ HasACos = 1,
+ HasASin = 1,
+ HasATan = 1,
HasLog = 1,
HasExp = 1,
HasSqrt = 1,
diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h
index ff6653b..8e8a0a4 100644
--- a/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ b/Eigen/src/Core/arch/SSE/MathFunctions.h
@@ -75,6 +75,24 @@
return pcos_float(_x);
}
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet4f pacos<Packet4f>(const Packet4f& _x)
+{
+ return pacos_float(_x);
+}
+
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet4f pasin<Packet4f>(const Packet4f& _x)
+{
+ return pasin_float(_x);
+}
+
+template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
+Packet4f patan<Packet4f>(const Packet4f& _x)
+{
+ return patan_float(_x);
+}
+
// Notice that for newer processors, it is counterproductive to use Newton
// iteration for square root. In particular, Skylake and Zen2 processors
// have approximately doubled throughput of the _mm_sqrt_ps instruction
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index e896040..0fa4394 100644
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -139,6 +139,9 @@
HasReciprocal = EIGEN_FAST_MATH,
HasSin = EIGEN_FAST_MATH,
HasCos = EIGEN_FAST_MATH,
+ HasACos = 1,
+ HasASin = 1,
+ HasATan = 1,
HasLog = 1,
HasLog1p = 1,
HasExpm1 = 1,
@@ -155,7 +158,8 @@
#ifdef EIGEN_VECTORIZE_SSE4_1
HasRound = 1,
#endif
- HasRint = 1
+ HasRint = 1,
+ HasSign = 0 // The manually vectorized version is slightly slower for SSE.
};
};
template <>
@@ -190,6 +194,7 @@
enum {
Vectorizable = 1,
AlignedOnScalar = 1,
+ HasCmp = 1,
size=4,
HasShift = 1,
@@ -206,7 +211,7 @@
AlignedOnScalar = 1,
HasHalfPacket = 0,
size=16,
-
+
HasAdd = 1,
HasSub = 1,
HasShift = 0,
@@ -217,7 +222,8 @@
HasMin = 0,
HasMax = 0,
HasConj = 0,
- HasSqrt = 1
+ HasSqrt = 1,
+ HasSign = 0 // Don't try to vectorize psign<bool> = identity.
};
};
diff --git a/Eigen/src/Core/arch/SYCL/PacketMath.h b/Eigen/src/Core/arch/SYCL/PacketMath.h
index 92accc8..5bc3235 100644
--- a/Eigen/src/Core/arch/SYCL/PacketMath.h
+++ b/Eigen/src/Core/arch/SYCL/PacketMath.h
@@ -477,25 +477,19 @@
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet sycl_pcmp_le(const Packet &a,
const Packet &b) {
- return ((a <= b)
- .template convert<typename unpacket_traits<Packet>::type,
- cl::sycl::rounding_mode::automatic>());
+ return (a <= b).template as<Packet>();
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet sycl_pcmp_lt(const Packet &a,
const Packet &b) {
- return ((a < b)
- .template convert<typename unpacket_traits<Packet>::type,
- cl::sycl::rounding_mode::automatic>());
+ return (a < b).template as<Packet>();
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet sycl_pcmp_eq(const Packet &a,
const Packet &b) {
- return ((a == b)
- .template convert<typename unpacket_traits<Packet>::type,
- cl::sycl::rounding_mode::automatic>());
+ return (a == b).template as<Packet>();
}
#define SYCL_PCMP(OP, TYPE) \
@@ -513,76 +507,6 @@
SYCL_PCMP(eq, cl::sycl::cl_double2)
#undef SYCL_PCMP
-template <typename T> struct convert_to_integer;
-
-template <> struct convert_to_integer<float> {
- using type = std::int32_t;
- using packet_type = cl::sycl::cl_int4;
-};
-template <> struct convert_to_integer<double> {
- using type = std::int64_t;
- using packet_type = cl::sycl::cl_long2;
-};
-
-template <typename PacketIn>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename convert_to_integer<
- typename unpacket_traits<PacketIn>::type>::packet_type
-vector_as_int(const PacketIn &p) {
- return (
- p.template convert<typename convert_to_integer<
- typename unpacket_traits<PacketIn>::type>::type,
- cl::sycl::rounding_mode::automatic>());
-}
-
-template <typename packetOut, typename PacketIn>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE packetOut
-convert_vector(const PacketIn &p) {
- return (p.template convert<typename unpacket_traits<packetOut>::type,
- cl::sycl::rounding_mode::automatic>());
-}
-
-#define SYCL_PAND(TYPE) \
- template <> \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TYPE pand<TYPE>(const TYPE &a, \
- const TYPE &b) { \
- return convert_vector<TYPE>(vector_as_int(a) & vector_as_int(b)); \
- }
-SYCL_PAND(cl::sycl::cl_float4)
-SYCL_PAND(cl::sycl::cl_double2)
-#undef SYCL_PAND
-
-#define SYCL_POR(TYPE) \
- template <> \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TYPE por<TYPE>(const TYPE &a, \
- const TYPE &b) { \
- return convert_vector<TYPE>(vector_as_int(a) | vector_as_int(b)); \
- }
-
-SYCL_POR(cl::sycl::cl_float4)
-SYCL_POR(cl::sycl::cl_double2)
-#undef SYCL_POR
-
-#define SYCL_PXOR(TYPE) \
- template <> \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TYPE pxor<TYPE>(const TYPE &a, \
- const TYPE &b) { \
- return convert_vector<TYPE>(vector_as_int(a) ^ vector_as_int(b)); \
- }
-
-SYCL_PXOR(cl::sycl::cl_float4)
-SYCL_PXOR(cl::sycl::cl_double2)
-#undef SYCL_PXOR
-
-#define SYCL_PANDNOT(TYPE) \
- template <> \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TYPE pandnot<TYPE>(const TYPE &a, \
- const TYPE &b) { \
- return convert_vector<TYPE>(vector_as_int(a) & (~vector_as_int(b))); \
- }
-SYCL_PANDNOT(cl::sycl::cl_float4)
-SYCL_PANDNOT(cl::sycl::cl_double2)
-#undef SYCL_PANDNOT
-
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void ptranspose(
PacketBlock<cl::sycl::cl_float4, 4>& kernel) {
float tmp = kernel.packet[0].y();
diff --git a/Eigen/src/Core/functors/AssignmentFunctors.h b/Eigen/src/Core/functors/AssignmentFunctors.h
index c9d80e6..26fa251 100644
--- a/Eigen/src/Core/functors/AssignmentFunctors.h
+++ b/Eigen/src/Core/functors/AssignmentFunctors.h
@@ -21,8 +21,7 @@
*
*/
template<typename DstScalar,typename SrcScalar> struct assign_op {
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
template<int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
@@ -45,8 +44,7 @@
*
*/
template<typename DstScalar,typename SrcScalar> struct add_assign_op {
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a += b; }
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a += b; }
template<int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
@@ -137,8 +135,7 @@
*
*/
template<typename Scalar> struct swap_assign_op {
-
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const
{
#ifdef EIGEN_GPUCC
// FIXME is there some kind of cuda::swap?
diff --git a/Eigen/src/Core/functors/BinaryFunctors.h b/Eigen/src/Core/functors/BinaryFunctors.h
index 094acb4..1a77a67 100644
--- a/Eigen/src/Core/functors/BinaryFunctors.h
+++ b/Eigen/src/Core/functors/BinaryFunctors.h
@@ -39,7 +39,7 @@
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::padd(a,b); }
@@ -58,7 +58,7 @@
template<>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_sum_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a || b; }
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR bool scalar_sum_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a || b; }
/** \internal
@@ -71,11 +71,11 @@
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_product_op>::ReturnType result_type;
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
- scalar_product_op() {
+ EIGEN_CONSTEXPR scalar_product_op() {
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pmul(a,b); }
@@ -93,7 +93,7 @@
};
template<>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_product_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a && b; }
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR bool scalar_product_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a && b; }
/** \internal
@@ -111,7 +111,7 @@
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_conj_product_op>::ReturnType result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const
{ return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
template<typename Packet>
@@ -135,7 +135,7 @@
struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_min_op>::ReturnType result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
return internal::pmin<NaNPropagation>(a, b);
}
template<typename Packet>
@@ -167,7 +167,7 @@
struct scalar_max_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_max_op>::ReturnType result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
return internal::pmax<NaNPropagation>(a,b);
}
template<typename Packet>
@@ -218,7 +218,7 @@
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
{
typedef bool result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a==b;}
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a==b;}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pcmp_eq(a,b); }
@@ -363,7 +363,7 @@
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::psub(a,b); }
@@ -390,7 +390,7 @@
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
#endif
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pdiv(a,b); }
diff --git a/Eigen/src/Core/functors/NullaryFunctors.h b/Eigen/src/Core/functors/NullaryFunctors.h
index e099d4a..ec86aeb 100644
--- a/Eigen/src/Core/functors/NullaryFunctors.h
+++ b/Eigen/src/Core/functors/NullaryFunctors.h
@@ -18,9 +18,9 @@
template<typename Scalar>
struct scalar_constant_op {
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() () const { return m_other; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR scalar_constant_op(const Scalar& other) : m_other(other) { }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const Scalar operator() () const { return m_other; }
template<typename PacketType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const { return internal::pset1<PacketType>(m_other); }
const Scalar m_other;
@@ -32,7 +32,7 @@
template<typename Scalar> struct scalar_identity_op {
template<typename IndexType>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType row, IndexType col) const { return row==col ? Scalar(1) : Scalar(0); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const Scalar operator() (IndexType row, IndexType col) const { return row==col ? Scalar(1) : Scalar(0); }
};
template<typename Scalar>
struct functor_traits<scalar_identity_op<Scalar> >
diff --git a/Eigen/src/Core/functors/StlFunctors.h b/Eigen/src/Core/functors/StlFunctors.h
index 5971075..7da5016 100644
--- a/Eigen/src/Core/functors/StlFunctors.h
+++ b/Eigen/src/Core/functors/StlFunctors.h
@@ -20,7 +20,7 @@
template<typename T = void>
struct equal_to {
typedef bool result_type;
- EIGEN_DEVICE_FUNC bool operator()(const T& lhs, const T& rhs) const {
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const {
return lhs == rhs;
}
};
@@ -28,7 +28,7 @@
template<typename T = void>
struct not_equal_to {
typedef bool result_type;
- EIGEN_DEVICE_FUNC bool operator()(const T& lhs, const T& rhs) const {
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const {
return lhs != rhs;
}
};
diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h
index fafb533..39b7be7 100644
--- a/Eigen/src/Core/functors/UnaryFunctors.h
+++ b/Eigen/src/Core/functors/UnaryFunctors.h
@@ -22,7 +22,7 @@
* \sa class CwiseUnaryOp, MatrixBase::operator-
*/
template<typename Scalar> struct scalar_opposite_op {
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
{ return internal::pnegate(a); }
@@ -88,7 +88,7 @@
*/
template<typename Scalar> struct scalar_abs2_op {
typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_DEVICE_FUNC
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
@@ -154,7 +154,7 @@
template<typename Scalar, typename NewType>
struct scalar_cast_op {
typedef NewType result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
};
template<typename Scalar, typename NewType>
struct functor_traits<scalar_cast_op<Scalar,NewType> >
@@ -916,45 +916,20 @@
* \brief Template functor to compute the signum of a scalar
* \sa class CwiseUnaryOp, Cwise::sign()
*/
-template<typename Scalar,bool is_complex=(NumTraits<Scalar>::IsComplex!=0), bool is_integer=(NumTraits<Scalar>::IsInteger!=0) > struct scalar_sign_op;
template<typename Scalar>
-struct scalar_sign_op<Scalar, false, true> {
+struct scalar_sign_op {
EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
{
- return Scalar( (a>Scalar(0)) - (a<Scalar(0)) );
+ return numext::sign(a);
}
- //TODO
- //template <typename Packet>
- //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
+
+ template <typename Packet>
+ EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const {
+ return internal::psign(a);
+ }
};
template<typename Scalar>
-struct scalar_sign_op<Scalar, false, false> {
- EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
- {
- return (numext::isnan)(a) ? a : Scalar( (a>Scalar(0)) - (a<Scalar(0)) );
- }
- //TODO
- //template <typename Packet>
- //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
-};
-
-template<typename Scalar, bool is_integer>
-struct scalar_sign_op<Scalar,true, is_integer> {
- EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
- {
- typedef typename NumTraits<Scalar>::Real real_type;
- real_type aa = numext::abs(a);
- if (aa==real_type(0))
- return Scalar(0);
- aa = real_type(1)/aa;
- return Scalar(a.real()*aa, a.imag()*aa );
- }
- //TODO
- //template <typename Packet>
- //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
-};
-template<typename Scalar>
struct functor_traits<scalar_sign_op<Scalar> >
{ enum {
Cost =
@@ -1095,6 +1070,97 @@
};
};
+template <typename Scalar, typename ExponentScalar,
+ bool IsBaseInteger = NumTraits<Scalar>::IsInteger,
+ bool IsExponentInteger = NumTraits<ExponentScalar>::IsInteger,
+ bool IsBaseComplex = NumTraits<Scalar>::IsComplex,
+ bool IsExponentComplex = NumTraits<ExponentScalar>::IsComplex>
+struct scalar_unary_pow_op {
+ typedef typename internal::promote_scalar_arg<
+ Scalar, ExponentScalar,
+ internal::has_ReturnType<ScalarBinaryOpTraits<Scalar,ExponentScalar,scalar_unary_pow_op> >::value>::type PromotedExponent;
+ typedef typename ScalarBinaryOpTraits<Scalar, PromotedExponent, scalar_unary_pow_op>::ReturnType result_type;
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_unary_pow_op(const ExponentScalar& exponent) : m_exponent(exponent) {}
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const Scalar& a) const {
+ EIGEN_USING_STD(pow);
+ return static_cast<result_type>(pow(a, m_exponent));
+ }
+
+ private:
+ const ExponentScalar m_exponent;
+ scalar_unary_pow_op() {}
+};
+
+template <typename T>
+constexpr int exponent_digits() {
+ return CHAR_BIT * sizeof(T) - NumTraits<T>::digits() - NumTraits<T>::IsSigned;
+}
+
+template<typename From, typename To>
+struct is_floating_exactly_representable {
+ // TODO(rmlarsen): Add radix to NumTraits and enable this check.
+ // (NumTraits<To>::radix == NumTraits<From>::radix) &&
+ static constexpr bool value = (exponent_digits<To>() >= exponent_digits<From>() &&
+ NumTraits<To>::digits() >= NumTraits<From>::digits());
+};
+
+
+// Specialization for real, non-integer types, non-complex types.
+template <typename Scalar, typename ExponentScalar>
+struct scalar_unary_pow_op<Scalar, ExponentScalar, false, false, false, false> {
+ template <bool IsExactlyRepresentable = is_floating_exactly_representable<ExponentScalar, Scalar>::value>
+ std::enable_if_t<IsExactlyRepresentable, void> check_is_representable() const {}
+
+ // Issue a deprecation warning if we do a narrowing conversion on the exponent.
+ template <bool IsExactlyRepresentable = is_floating_exactly_representable<ExponentScalar, Scalar>::value>
+ EIGEN_DEPRECATED std::enable_if_t<!IsExactlyRepresentable, void> check_is_representable() const {}
+
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+ scalar_unary_pow_op(const ExponentScalar& exponent) : m_exponent(static_cast<Scalar>(exponent)) {
+ check_is_representable();
+ }
+
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& a) const {
+ EIGEN_USING_STD(pow);
+ return static_cast<Scalar>(pow(a, m_exponent));
+ }
+ template <typename Packet>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const {
+ return unary_pow_impl<Packet, Scalar>::run(a, m_exponent);
+ }
+
+ private:
+ const Scalar m_exponent;
+ scalar_unary_pow_op() {}
+};
+
+template <typename Scalar, typename ExponentScalar, bool BaseIsInteger>
+struct scalar_unary_pow_op<Scalar, ExponentScalar, BaseIsInteger, true, false, false> {
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_unary_pow_op(const ExponentScalar& exponent) : m_exponent(exponent) {}
+ // TODO: error handling logic for complex^real_integer
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& a) const {
+ return unary_pow_impl<Scalar, ExponentScalar>::run(a, m_exponent);
+ }
+ template <typename Packet>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const {
+ return unary_pow_impl<Packet, ExponentScalar>::run(a, m_exponent);
+ }
+
+ private:
+ const ExponentScalar m_exponent;
+ scalar_unary_pow_op() {}
+};
+
+template <typename Scalar, typename ExponentScalar>
+struct functor_traits<scalar_unary_pow_op<Scalar, ExponentScalar>> {
+ enum {
+ GenPacketAccess = functor_traits<scalar_pow_op<Scalar, ExponentScalar>>::PacketAccess,
+ IntPacketAccess = !NumTraits<Scalar>::IsComplex && packet_traits<Scalar>::HasMul && (packet_traits<Scalar>::HasDiv || NumTraits<Scalar>::IsInteger) && packet_traits<Scalar>::HasCmp,
+ PacketAccess = NumTraits<ExponentScalar>::IsInteger ? IntPacketAccess : (IntPacketAccess && GenPacketAccess),
+ Cost = functor_traits<scalar_pow_op<Scalar, ExponentScalar>>::Cost
+ };
+};
+
} // end namespace internal
} // end namespace Eigen
diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h
index 56473a9..d023b3b 100644
--- a/Eigen/src/Core/util/BlasUtil.h
+++ b/Eigen/src/Core/util/BlasUtil.h
@@ -292,7 +292,7 @@
}
template<typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index n, Index /*offset*/) const {
+ 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);
}
@@ -302,7 +302,7 @@
}
template<typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, const PacketType &p, Index n, Index /*offset*/) const {
+ 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);
}
@@ -343,7 +343,7 @@
}
template<typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketType loadPacketPartial(Index i, Index j, Index n, Index /*offset*/) const {
+ 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);
}
@@ -358,7 +358,7 @@
}
template<typename PacketType>
- EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacketPartial(Index i, Index j, const PacketType &p, Index n, Index /*offset*/) const {
+ 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);
}
@@ -487,8 +487,8 @@
ExtractType,
typename ExtractType_::PlainObject
> DirectLinearAccessType;
- static inline EIGEN_DEVICE_FUNC ExtractType extract(const XprType& x) { return x; }
- static inline EIGEN_DEVICE_FUNC const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
+ static inline EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR ExtractType extract(const XprType& x) { return x; }
+ static inline EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
};
// pop conjugate
@@ -576,7 +576,7 @@
enum {
IsTransposed = Base::IsTransposed ? 0 : 1
};
- static inline ExtractType extract(const XprType& x) { return ExtractType(Base::extract(x.nestedExpression())); }
+ static inline EIGEN_CONSTEXPR ExtractType extract(const XprType& x) { return ExtractType(Base::extract(x.nestedExpression())); }
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); }
};
@@ -587,7 +587,7 @@
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 EIGEN_CONSTEXPR static const typename T::Scalar* run(const T& m)
{
return blas_traits<T>::extract(m).data();
}
@@ -599,7 +599,7 @@
};
template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE const typename T::Scalar* extract_data(const T& m)
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE EIGEN_CONSTEXPR const typename T::Scalar* extract_data(const T& m)
{
return extract_data_selector<T>::run(m);
}
diff --git a/Eigen/src/Core/util/ConfigureVectorization.h b/Eigen/src/Core/util/ConfigureVectorization.h
index e473215..7c1a08b 100644
--- a/Eigen/src/Core/util/ConfigureVectorization.h
+++ b/Eigen/src/Core/util/ConfigureVectorization.h
@@ -270,6 +270,17 @@
#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
diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h
index 4457f4f..0175087 100644
--- a/Eigen/src/Core/util/Constants.h
+++ b/Eigen/src/Core/util/Constants.h
@@ -533,6 +533,7 @@
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"; } };
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index a696961..503d651 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -90,6 +90,9 @@
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;
@@ -196,8 +199,12 @@
template<typename Scalar> struct scalar_random_op;
template<typename Scalar> struct scalar_constant_op;
template<typename Scalar> struct scalar_identity_op;
-template<typename Scalar,bool is_complex, bool is_integer> struct scalar_sign_op;
-template<typename Scalar,typename ScalarExponent> struct scalar_pow_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;
diff --git a/Eigen/src/Core/util/IntegralConstant.h b/Eigen/src/Core/util/IntegralConstant.h
index ea275bd..b00fb9c 100644
--- a/Eigen/src/Core/util/IntegralConstant.h
+++ b/Eigen/src/Core/util/IntegralConstant.h
@@ -161,7 +161,7 @@
static const int value = N;
};
-template<typename T> EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) { return x; }
+template<typename T> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index get_runtime_value(const T &x) { return x; }
// Cleanup integer/FixedInt/VariableAndFixedInt/etc types:
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index cb583ee..7261921 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -914,6 +914,22 @@
#define EIGEN_UNUSED
#endif
+#if EIGEN_COMP_GNUC
+ #define EIGEN_PRAGMA(tokens) _Pragma(#tokens)
+ #define EIGEN_DIAGNOSTICS(tokens) EIGEN_PRAGMA(GCC diagnostic tokens)
+ #define EIGEN_DIAGNOSTICS_OFF(msc, gcc) EIGEN_DIAGNOSTICS(gcc)
+#elif EIGEN_COMP_MSVC
+ #define EIGEN_PRAGMA(tokens) __pragma(tokens)
+ #define EIGEN_DIAGNOSTICS(tokens) EIGEN_PRAGMA(warning(tokens))
+ #define EIGEN_DIAGNOSTICS_OFF(msc, gcc) EIGEN_DIAGNOSTICS(msc)
+#else
+ #define EIGEN_PRAGMA(tokens)
+ #define EIGEN_DIAGNOSTICS(tokens)
+ #define EIGEN_DIAGNOSTICS_OFF(msc, gcc)
+#endif
+
+#define EIGEN_DISABLE_DEPRECATED_WARNING EIGEN_DIAGNOSTICS_OFF(disable : 4996, ignored "-Wdeprecated-declarations")
+
// Suppresses 'unused variable' warnings.
namespace Eigen {
namespace internal {
@@ -1052,13 +1068,13 @@
#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
using Base::operator =; \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \
template <typename OtherDerived> \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const DenseBase<OtherDerived>& other) { Base::operator=(other.derived()); return *this; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Derived& operator=(const DenseBase<OtherDerived>& other) { Base::operator=(other.derived()); return *this; }
#else
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
using Base::operator =; \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Derived& operator=(const Derived& other) \
{ \
Base::operator=(other); \
return *this; \
@@ -1091,11 +1107,14 @@
*
* Hiding the default destructor lead to problems in C++03 mode together with boost::multiprecision
*/
+#if defined(EIGEN_GPUCC)
#define EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(Derived) \
- EIGEN_DEVICE_FUNC Derived() = default; \
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Derived() = default; \
EIGEN_DEVICE_FUNC ~Derived() = default;
-
-
+#else
+#define EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(Derived) \
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Derived() = default;
+#endif
@@ -1152,7 +1171,7 @@
#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,OPNAME) \
template<typename OtherDerived> \
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,OPNAME) \
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,OPNAME) \
(METHOD)(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \
return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,OPNAME)(derived(), other.derived()); \
@@ -1170,7 +1189,7 @@
const typename internal::plain_constant_type<EXPR,SCALAR>::type, const EXPR>
#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(METHOD,OPNAME) \
- template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
+ template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR \
const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,Scalar,T)>::type,OPNAME)\
(METHOD)(const T& scalar) const { \
typedef typename internal::promote_scalar_arg<Scalar,T,EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,Scalar,T)>::type PromotedT; \
@@ -1179,7 +1198,7 @@
}
#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHELEFT(METHOD,OPNAME) \
- template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE friend \
+ template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR friend \
const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,T,Scalar)>::type,Derived,OPNAME) \
(METHOD)(const T& scalar, const StorageBaseType& matrix) { \
typedef typename internal::promote_scalar_arg<Scalar,T,EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,T,Scalar)>::type PromotedT; \
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 9823fa3..385f4f4 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -229,6 +229,11 @@
if (!result && new_size)
throw_std_bad_alloc();
+#ifdef EIGEN_RUNTIME_NO_MALLOC
+ if (result != ptr)
+ check_that_malloc_is_allowed();
+#endif
+
return result;
}
@@ -295,7 +300,7 @@
/** \internal Constructs the elements of an array.
* The \a size parameter tells on how many objects to call the constructor of T.
*/
-template<typename T> EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *ptr, std::size_t size)
+template<typename T> EIGEN_DEVICE_FUNC inline T* default_construct_elements_of_array(T *ptr, std::size_t size)
{
std::size_t i=0;
EIGEN_TRY
@@ -310,6 +315,42 @@
return ptr;
}
+/** \internal Copy-constructs the elements of an array.
+ * The \a size parameter tells on how many objects to copy.
+ */
+template<typename T> EIGEN_DEVICE_FUNC inline T* copy_construct_elements_of_array(T *ptr, const T* src, std::size_t size)
+{
+ std::size_t i=0;
+ EIGEN_TRY
+ {
+ for (i = 0; i < size; ++i) ::new (ptr + i) T(*(src + i));
+ }
+ EIGEN_CATCH(...)
+ {
+ destruct_elements_of_array(ptr, i);
+ EIGEN_THROW;
+ }
+ return ptr;
+}
+
+/** \internal Move-constructs the elements of an array.
+ * The \a size parameter tells on how many objects to move.
+ */
+template<typename T> EIGEN_DEVICE_FUNC inline T* move_construct_elements_of_array(T *ptr, T* src, std::size_t size)
+{
+ std::size_t i=0;
+ EIGEN_TRY
+ {
+ for (i = 0; i < size; ++i) ::new (ptr + i) T(std::move(*(src + i)));
+ }
+ EIGEN_CATCH(...)
+ {
+ destruct_elements_of_array(ptr, i);
+ EIGEN_THROW;
+ }
+ return ptr;
+}
+
/*****************************************************************************
*** Implementation of aligned new/delete-like functions ***
*****************************************************************************/
@@ -328,10 +369,10 @@
template<typename T> EIGEN_DEVICE_FUNC inline T* aligned_new(std::size_t size)
{
check_size_for_overflow<T>(size);
- T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
+ T *result = static_cast<T*>(aligned_malloc(sizeof(T)*size));
EIGEN_TRY
{
- return construct_elements_of_array(result, size);
+ return default_construct_elements_of_array(result, size);
}
EIGEN_CATCH(...)
{
@@ -344,10 +385,10 @@
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new(std::size_t size)
{
check_size_for_overflow<T>(size);
- T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
+ T *result = static_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
EIGEN_TRY
{
- return construct_elements_of_array(result, size);
+ return default_construct_elements_of_array(result, size);
}
EIGEN_CATCH(...)
{
@@ -379,21 +420,32 @@
{
check_size_for_overflow<T>(new_size);
check_size_for_overflow<T>(old_size);
- if(new_size < old_size)
- destruct_elements_of_array(pts+new_size, old_size-new_size);
- T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
- if(new_size > old_size)
+
+ // If elements need to be explicitly initialized, we cannot simply realloc
+ // (or memcpy) the memory block - each element needs to be reconstructed.
+ // Otherwise, objects that contain internal pointers like mpfr or
+ // AnnoyingScalar can be pointing to the wrong thing.
+ T* result = static_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*new_size));
+ EIGEN_TRY
{
- EIGEN_TRY
- {
- construct_elements_of_array(result+old_size, new_size-old_size);
+ // Move-construct initial elements.
+ std::size_t copy_size = (std::min)(old_size, new_size);
+ move_construct_elements_of_array(result, pts, copy_size);
+
+ // Default-construct remaining elements.
+ if (new_size > old_size) {
+ default_construct_elements_of_array(result + copy_size, new_size - old_size);
}
- EIGEN_CATCH(...)
- {
- conditional_aligned_free<Align>(result);
- EIGEN_THROW;
- }
+
+ // Delete old elements.
+ conditional_aligned_delete<T, Align>(pts, old_size);
}
+ EIGEN_CATCH(...)
+ {
+ conditional_aligned_free<Align>(result);
+ EIGEN_THROW;
+ }
+
return result;
}
@@ -403,12 +455,12 @@
if(size==0)
return 0; // short-cut. Also fixes Bug 884
check_size_for_overflow<T>(size);
- T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
+ T *result = static_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
if(NumTraits<T>::RequireInitialization)
{
EIGEN_TRY
{
- construct_elements_of_array(result, size);
+ default_construct_elements_of_array(result, size);
}
EIGEN_CATCH(...)
{
@@ -421,24 +473,13 @@
template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(T* pts, std::size_t new_size, std::size_t old_size)
{
+ if (NumTraits<T>::RequireInitialization) {
+ return conditional_aligned_realloc_new<T, Align>(pts, new_size, old_size);
+ }
+
check_size_for_overflow<T>(new_size);
check_size_for_overflow<T>(old_size);
- if(NumTraits<T>::RequireInitialization && (new_size < old_size))
- destruct_elements_of_array(pts+new_size, old_size-new_size);
- T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
- if(NumTraits<T>::RequireInitialization && (new_size > old_size))
- {
- EIGEN_TRY
- {
- construct_elements_of_array(result+old_size, new_size-old_size);
- }
- EIGEN_CATCH(...)
- {
- conditional_aligned_free<Align>(result);
- EIGEN_THROW;
- }
- }
- return result;
+ return static_cast<T*>(conditional_aligned_realloc<Align>(static_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
}
template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete_auto(T *ptr, std::size_t size)
@@ -612,7 +653,7 @@
: m_ptr(ptr), m_size(size), m_deallocate(dealloc)
{
if(NumTraits<T>::RequireInitialization && m_ptr)
- Eigen::internal::construct_elements_of_array(m_ptr, size);
+ Eigen::internal::default_construct_elements_of_array(m_ptr, size);
}
EIGEN_DEVICE_FUNC
~aligned_stack_memory_handler()
@@ -663,7 +704,7 @@
m_deallocate(ptr==0)
{
if(NumTraits<Scalar>::RequireInitialization && object.data())
- Eigen::internal::construct_elements_of_array(object.data(), object.size());
+ Eigen::internal::default_construct_elements_of_array(object.data(), object.size());
object = xpr;
}
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index ba8a7f1..1aa41ab 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -113,7 +113,7 @@
{
public:
EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(variable_if_dynamic)
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
T value() { return T(Value); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
@@ -126,10 +126,10 @@
{
T m_value;
public:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value = 0) EIGEN_NO_THROW : m_value(value) {}
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator T() const { return m_value; }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR explicit variable_if_dynamic(T value = 0) EIGEN_NO_THROW : m_value(value) {}
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR T value() const { return m_value; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR operator T() const { return m_value; }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void setValue(T value) { m_value = value; }
};
/** \internal like variable_if_dynamic but for DynamicIndex
@@ -137,7 +137,7 @@
template<typename T, int Value> class variable_if_dynamicindex
{
public:
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
+ EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
T value() { return T(Value); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
@@ -270,6 +270,11 @@
typedef typename T::PlainObject type;
};
+template<typename T> struct plain_matrix_type<T,SkewSymmetricShape>
+{
+ typedef typename T::PlainObject type;
+};
+
template<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
{
typedef Matrix<typename traits<T>::Scalar,
@@ -316,6 +321,11 @@
typedef typename plain_matrix_type<T>::type type;
};
+template<typename T> struct eval<T,SkewSymmetricShape>
+{
+ typedef typename plain_matrix_type<T>::type type;
+};
+
// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
template<typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
struct eval<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>, Dense>
@@ -554,6 +564,12 @@
template <int ProductTag> struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { typedef Dense ret; };
template <int ProductTag> struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { typedef Dense ret; };
+template <typename A, int ProductTag> struct product_promote_storage_type<A, SkewSymmetricShape, ProductTag> { typedef A ret; };
+template <typename B, int ProductTag> struct product_promote_storage_type<SkewSymmetricShape, B, ProductTag> { typedef B ret; };
+template <int ProductTag> struct product_promote_storage_type<Dense, SkewSymmetricShape, ProductTag> { typedef Dense ret; };
+template <int ProductTag> struct product_promote_storage_type<SkewSymmetricShape, Dense, ProductTag> { typedef Dense ret; };
+template <int ProductTag> struct product_promote_storage_type<SkewSymmetricShape, SkewSymmetricShape, ProductTag> { typedef Dense ret; };
+
template <typename A, int ProductTag> struct product_promote_storage_type<A, PermutationStorage, ProductTag> { typedef A ret; };
template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B, ProductTag> { typedef B ret; };
template <int ProductTag> struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { typedef Dense ret; };
@@ -659,7 +675,7 @@
};
template<typename T1, typename T2>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
bool is_same_dense(const T1 &mat1, const T2 &mat2, std::enable_if_t<possibly_same_dense<T1,T2>::value> * = 0)
{
return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
diff --git a/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
index b2bb974..d62c411 100644
--- a/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
+++ b/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
@@ -121,8 +121,8 @@
: m_eivec(),
m_alphas(),
m_betas(),
- m_valuesOkay(false),
- m_vectorsOkay(false),
+ m_computeEigenvectors(false),
+ m_isInitialized(false),
m_realQZ()
{}
@@ -136,8 +136,8 @@
: m_eivec(size, size),
m_alphas(size),
m_betas(size),
- m_valuesOkay(false),
- m_vectorsOkay(false),
+ m_computeEigenvectors(false),
+ m_isInitialized(false),
m_realQZ(size),
m_tmp(size)
{}
@@ -158,8 +158,8 @@
: m_eivec(A.rows(), A.cols()),
m_alphas(A.cols()),
m_betas(A.cols()),
- m_valuesOkay(false),
- m_vectorsOkay(false),
+ m_computeEigenvectors(false),
+ m_isInitialized(false),
m_realQZ(A.cols()),
m_tmp(A.cols())
{
@@ -179,7 +179,8 @@
* \sa eigenvalues()
*/
EigenvectorsType eigenvectors() const {
- eigen_assert(m_vectorsOkay && "Eigenvectors for GeneralizedEigenSolver were not calculated.");
+ eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute eigenvectors");
+ eigen_assert(m_computeEigenvectors && "Eigenvectors for GeneralizedEigenSolver were not calculated");
return m_eivec;
}
@@ -203,7 +204,7 @@
*/
EigenvalueType eigenvalues() const
{
- eigen_assert(m_valuesOkay && "GeneralizedEigenSolver is not initialized.");
+ eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute eigenvalues.");
return EigenvalueType(m_alphas,m_betas);
}
@@ -214,7 +215,7 @@
* \sa betas(), eigenvalues() */
const ComplexVectorType& alphas() const
{
- eigen_assert(m_valuesOkay && "GeneralizedEigenSolver is not initialized.");
+ eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute alphas.");
return m_alphas;
}
@@ -225,7 +226,7 @@
* \sa alphas(), eigenvalues() */
const VectorType& betas() const
{
- eigen_assert(m_valuesOkay && "GeneralizedEigenSolver is not initialized.");
+ eigen_assert(info() == Success && "GeneralizedEigenSolver failed to compute betas.");
return m_betas;
}
@@ -256,7 +257,7 @@
ComputationInfo info() const
{
- eigen_assert(m_valuesOkay && "EigenSolver is not initialized.");
+ eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
return m_realQZ.info();
}
@@ -276,7 +277,8 @@
EigenvectorsType m_eivec;
ComplexVectorType m_alphas;
VectorType m_betas;
- bool m_valuesOkay, m_vectorsOkay;
+ bool m_computeEigenvectors;
+ bool m_isInitialized;
RealQZ<MatrixType> m_realQZ;
ComplexVectorType m_tmp;
};
@@ -289,8 +291,6 @@
using std::abs;
eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
Index size = A.cols();
- m_valuesOkay = false;
- m_vectorsOkay = false;
// Reduce to generalized real Schur form:
// A = Q S Z and B = Q T Z
m_realQZ.compute(A, B, computeEigenvectors);
@@ -403,10 +403,9 @@
i += 2;
}
}
-
- m_valuesOkay = true;
- m_vectorsOkay = computeEigenvectors;
}
+ m_computeEigenvectors = computeEigenvectors;
+ m_isInitialized = true;
return *this;
}
diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h
index dc6a762..c140831 100644
--- a/Eigen/src/Geometry/OrthoMethods.h
+++ b/Eigen/src/Geometry/OrthoMethods.h
@@ -29,7 +29,7 @@
template<typename Derived>
template<typename OtherDerived>
#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename MatrixBase<Derived>::template cross_product_return_type<OtherDerived>::type
#else
typename MatrixBase<Derived>::PlainObject
diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h
index 0aca4c4..7394dea 100644
--- a/Eigen/src/Geometry/Quaternion.h
+++ b/Eigen/src/Geometry/Quaternion.h
@@ -65,34 +65,34 @@
/** \returns the \c x coefficient */
- EIGEN_DEVICE_FUNC inline CoeffReturnType x() const { return this->derived().coeffs().coeff(0); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline CoeffReturnType x() const { return this->derived().coeffs().coeff(0); }
/** \returns the \c y coefficient */
- EIGEN_DEVICE_FUNC inline CoeffReturnType y() const { return this->derived().coeffs().coeff(1); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline CoeffReturnType y() const { return this->derived().coeffs().coeff(1); }
/** \returns the \c z coefficient */
- EIGEN_DEVICE_FUNC inline CoeffReturnType z() const { return this->derived().coeffs().coeff(2); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline CoeffReturnType z() const { return this->derived().coeffs().coeff(2); }
/** \returns the \c w coefficient */
- EIGEN_DEVICE_FUNC inline CoeffReturnType w() const { return this->derived().coeffs().coeff(3); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline CoeffReturnType w() const { return this->derived().coeffs().coeff(3); }
/** \returns a reference to the \c x coefficient (if Derived is a non-const lvalue) */
- EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType x() { return this->derived().coeffs().x(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline NonConstCoeffReturnType x() { return this->derived().coeffs().x(); }
/** \returns a reference to the \c y coefficient (if Derived is a non-const lvalue) */
- EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType y() { return this->derived().coeffs().y(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline NonConstCoeffReturnType y() { return this->derived().coeffs().y(); }
/** \returns a reference to the \c z coefficient (if Derived is a non-const lvalue) */
- EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType z() { return this->derived().coeffs().z(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline NonConstCoeffReturnType z() { return this->derived().coeffs().z(); }
/** \returns a reference to the \c w coefficient (if Derived is a non-const lvalue) */
- EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType w() { return this->derived().coeffs().w(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline NonConstCoeffReturnType w() { return this->derived().coeffs().w(); }
/** \returns a read-only vector expression of the imaginary part (x,y,z) */
- EIGEN_DEVICE_FUNC inline const VectorBlock<const Coefficients,3> vec() const { return coeffs().template head<3>(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline const VectorBlock<const Coefficients,3> vec() const { return coeffs().template head<3>(); }
/** \returns a vector expression of the imaginary part (x,y,z) */
EIGEN_DEVICE_FUNC inline VectorBlock<Coefficients,3> vec() { return coeffs().template head<3>(); }
/** \returns a read-only vector expression of the coefficients (x,y,z,w) */
- EIGEN_DEVICE_FUNC inline const typename internal::traits<Derived>::Coefficients& coeffs() const { return derived().coeffs(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline const typename internal::traits<Derived>::Coefficients& coeffs() const { return derived().coeffs(); }
/** \returns a vector expression of the coefficients (x,y,z,w) */
- EIGEN_DEVICE_FUNC inline typename internal::traits<Derived>::Coefficients& coeffs() { return derived().coeffs(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline typename internal::traits<Derived>::Coefficients& coeffs() { return derived().coeffs(); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE QuaternionBase<Derived>& operator=(const QuaternionBase<Derived>& other);
template<class OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const QuaternionBase<OtherDerived>& other);
@@ -105,12 +105,12 @@
// { return operator=<Derived>(other); }
EIGEN_DEVICE_FUNC Derived& operator=(const AngleAxisType& aa);
- template<class OtherDerived> EIGEN_DEVICE_FUNC Derived& operator=(const MatrixBase<OtherDerived>& m);
+ template<class OtherDerived> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Derived& operator=(const MatrixBase<OtherDerived>& m);
/** \returns a quaternion representing an identity rotation
* \sa MatrixBase::Identity()
*/
- EIGEN_DEVICE_FUNC static inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); }
+ EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); }
/** \sa QuaternionBase::Identity(), MatrixBase::setIdentity()
*/
@@ -119,7 +119,7 @@
/** \returns the squared norm of the quaternion's coefficients
* \sa QuaternionBase::norm(), MatrixBase::squaredNorm()
*/
- EIGEN_DEVICE_FUNC inline Scalar squaredNorm() const { return coeffs().squaredNorm(); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Scalar squaredNorm() const { return coeffs().squaredNorm(); }
/** \returns the norm of the quaternion's coefficients
* \sa QuaternionBase::squaredNorm(), MatrixBase::norm()
@@ -138,12 +138,12 @@
* corresponds to the cosine of half the angle between the two rotations.
* \sa angularDistance()
*/
- template<class OtherDerived> EIGEN_DEVICE_FUNC inline Scalar dot(const QuaternionBase<OtherDerived>& other) const { return coeffs().dot(other.coeffs()); }
+ template<class OtherDerived> EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Scalar dot(const QuaternionBase<OtherDerived>& other) const { return coeffs().dot(other.coeffs()); }
template<class OtherDerived> EIGEN_DEVICE_FUNC Scalar angularDistance(const QuaternionBase<OtherDerived>& other) const;
/** \returns an equivalent 3x3 rotation matrix */
- EIGEN_DEVICE_FUNC inline Matrix3 toRotationMatrix() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Matrix3 toRotationMatrix() const;
/** \returns the quaternion which transform \a a into \a b through a rotation */
template<typename Derived1, typename Derived2>
@@ -153,7 +153,7 @@
template<class OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator*= (const QuaternionBase<OtherDerived>& q);
/** \returns the quaternion describing the inverse rotation */
- EIGEN_DEVICE_FUNC Quaternion<Scalar> inverse() const;
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Quaternion<Scalar> inverse() const;
/** \returns the conjugated quaternion */
EIGEN_DEVICE_FUNC Quaternion<Scalar> conjugate() const;
@@ -165,7 +165,7 @@
* fuzzy comparison such as isApprox()
* \sa isApprox(), operator!= */
template<class OtherDerived>
- EIGEN_DEVICE_FUNC inline bool operator==(const QuaternionBase<OtherDerived>& other) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline bool operator==(const QuaternionBase<OtherDerived>& other) const
{ return coeffs() == other.coeffs(); }
/** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other.
@@ -173,7 +173,7 @@
* fuzzy comparison such as isApprox()
* \sa isApprox(), operator== */
template<class OtherDerived>
- EIGEN_DEVICE_FUNC inline bool operator!=(const QuaternionBase<OtherDerived>& other) const
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline bool operator!=(const QuaternionBase<OtherDerived>& other) const
{ return coeffs() != other.coeffs(); }
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
@@ -185,7 +185,7 @@
{ return coeffs().isApprox(other.coeffs(), prec); }
/** return the result vector of \a v through the rotation*/
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const;
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Vector3 _transformVector(const Vector3& v) const;
#ifdef EIGEN_PARSED_BY_DOXYGEN
/** \returns \c *this with scalar type casted to \a NewScalarType
@@ -199,14 +199,14 @@
#else
template<typename NewScalarType>
- EIGEN_DEVICE_FUNC inline
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline
std::enable_if_t<internal::is_same<Scalar,NewScalarType>::value,const Derived&> cast() const
{
return derived();
}
template<typename NewScalarType>
- EIGEN_DEVICE_FUNC inline
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline
std::enable_if_t<!internal::is_same<Scalar,NewScalarType>::value,Quaternion<NewScalarType> > cast() const
{
return Quaternion<NewScalarType>(coeffs().template cast<NewScalarType>());
@@ -296,10 +296,10 @@
* while internally the coefficients are stored in the following order:
* [\c x, \c y, \c z, \c w]
*/
- EIGEN_DEVICE_FUNC inline Quaternion(const Scalar& w, const Scalar& x, const Scalar& y, const Scalar& z) : m_coeffs(x, y, z, w){}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Quaternion(const Scalar& w, const Scalar& x, const Scalar& y, const Scalar& z) : m_coeffs(x, y, z, w){}
/** Constructs and initialize a quaternion from the array data */
- EIGEN_DEVICE_FUNC explicit inline Quaternion(const Scalar* data) : m_coeffs(data) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline explicit Quaternion(const Scalar* data) : m_coeffs(data) {}
/** Copy constructor */
template<class Derived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Quaternion(const QuaternionBase<Derived>& other) { this->Base::operator=(other); }
@@ -312,11 +312,11 @@
* - a 4D vector expression representing quaternion coefficients in the order [\c x, \c y, \c z, \c w].
*/
template<typename Derived>
- EIGEN_DEVICE_FUNC explicit inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
+ EIGEN_DEVICE_FUNC explicit EIGEN_CONSTEXPR inline Quaternion(const MatrixBase<Derived>& other) { *this = other; }
/** Explicit copy constructor with scalar conversion */
template<typename OtherScalar, int OtherOptions>
- EIGEN_DEVICE_FUNC explicit inline Quaternion(const Quaternion<OtherScalar, OtherOptions>& other)
+ EIGEN_DEVICE_FUNC explicit EIGEN_CONSTEXPR Quaternion(const Quaternion<OtherScalar, OtherOptions>& other)
{ m_coeffs = other.coeffs().template cast<Scalar>(); }
// We define a copy constructor, which means we don't get an implicit move constructor or assignment operator.
@@ -337,8 +337,8 @@
template<typename Derived1, typename Derived2>
EIGEN_DEVICE_FUNC static Quaternion FromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b);
- EIGEN_DEVICE_FUNC inline Coefficients& coeffs() { return m_coeffs;}
- EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs;}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Coefficients& coeffs() { return m_coeffs;}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline const Coefficients& coeffs() const { return m_coeffs;}
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(NeedsAlignment))
@@ -415,9 +415,9 @@
* \code *coeffs == {x, y, z, w} \endcode
*
* If the template parameter Options_ is set to #Aligned, then the pointer coeffs must be aligned. */
- EIGEN_DEVICE_FUNC explicit EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
+ EIGEN_DEVICE_FUNC explicit EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
- EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs;}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline const Coefficients& coeffs() const { return m_coeffs;}
protected:
const Coefficients m_coeffs;
@@ -452,10 +452,10 @@
* \code *coeffs == {x, y, z, w} \endcode
*
* If the template parameter Options_ is set to #Aligned, then the pointer coeffs must be aligned. */
- EIGEN_DEVICE_FUNC explicit EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {}
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR explicit EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {}
- EIGEN_DEVICE_FUNC inline Coefficients& coeffs() { return m_coeffs; }
- EIGEN_DEVICE_FUNC inline const Coefficients& coeffs() const { return m_coeffs; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Coefficients& coeffs() { return m_coeffs; }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline const Coefficients& coeffs() const { return m_coeffs; }
protected:
Coefficients m_coeffs;
@@ -483,7 +483,7 @@
namespace internal {
template<int Arch, class Derived1, class Derived2, typename Scalar> struct quat_product
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
return Quaternion<Scalar>
(
a.w() * b.w() - a.x() * b.x() - a.y() * b.y() - a.z() * b.z(),
@@ -524,7 +524,7 @@
* - Via a Matrix3: 24 + 15n
*/
template <class Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename QuaternionBase<Derived>::Vector3
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename QuaternionBase<Derived>::Vector3
QuaternionBase<Derived>::_transformVector(const Vector3& v) const
{
// Note that this algorithm comes from the optimization by hand
@@ -573,7 +573,7 @@
template<class Derived>
template<class MatrixDerived>
-EIGEN_DEVICE_FUNC inline Derived& QuaternionBase<Derived>::operator=(const MatrixBase<MatrixDerived>& xpr)
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Derived& QuaternionBase<Derived>::operator=(const MatrixBase<MatrixDerived>& xpr)
{
EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename MatrixDerived::Scalar>::value),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
@@ -585,7 +585,7 @@
* be normalized, otherwise the result is undefined.
*/
template<class Derived>
-EIGEN_DEVICE_FUNC inline typename QuaternionBase<Derived>::Matrix3
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline typename QuaternionBase<Derived>::Matrix3
QuaternionBase<Derived>::toRotationMatrix(void) const
{
// NOTE if inlined, then gcc 4.2 and 4.4 get rid of the temporary (not gcc 4.3 !!)
@@ -714,7 +714,7 @@
* \sa QuaternionBase::conjugate()
*/
template <class Derived>
-EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar> QuaternionBase<Derived>::inverse() const
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Quaternion<typename internal::traits<Derived>::Scalar> QuaternionBase<Derived>::inverse() const
{
// FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite() ??
Scalar n2 = this->squaredNorm();
@@ -731,12 +731,12 @@
namespace internal {
template<int Arch, class Derived, typename Scalar> struct quat_conj
{
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived>& q){
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Quaternion<Scalar> run(const QuaternionBase<Derived>& q){
return Quaternion<Scalar>(q.w(),-q.x(),-q.y(),-q.z());
}
};
}
-
+
/** \returns the conjugate of the \c *this which is equal to the multiplicative inverse
* if the quaternion is normalized.
* The conjugate of a quaternion represents the opposite rotation.
@@ -854,7 +854,7 @@
struct quaternionbase_assign_impl<Other,4,1>
{
typedef typename Other::Scalar Scalar;
- template<class Derived> EIGEN_DEVICE_FUNC static inline void run(QuaternionBase<Derived>& q, const Other& vec)
+ template<class Derived> EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR inline void run(QuaternionBase<Derived>& q, const Other& vec)
{
q.coeffs() = vec;
}
diff --git a/Eigen/src/Geometry/RotationBase.h b/Eigen/src/Geometry/RotationBase.h
index f21277f..73fcf7f 100644
--- a/Eigen/src/Geometry/RotationBase.h
+++ b/Eigen/src/Geometry/RotationBase.h
@@ -40,8 +40,8 @@
typedef Matrix<Scalar,Dim,1> VectorType;
public:
- EIGEN_DEVICE_FUNC inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
- EIGEN_DEVICE_FUNC inline Derived& derived() { return *static_cast<Derived*>(this); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
+ EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Derived& derived() { return *static_cast<Derived*>(this); }
/** \returns an equivalent rotation matrix */
EIGEN_DEVICE_FUNC inline RotationMatrixType toRotationMatrix() const { return derived().toRotationMatrix(); }
@@ -69,7 +69,7 @@
* - a vector of size Dim
*/
template<typename OtherDerived>
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename internal::rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR typename internal::rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType
operator*(const EigenBase<OtherDerived>& e) const
{ return internal::rotation_base_generic_product_selector<Derived,OtherDerived>::run(derived(), e.derived()); }
@@ -125,7 +125,7 @@
{
enum { Dim = RotationDerived::Dim };
typedef Matrix<typename RotationDerived::Scalar,Dim,1> ReturnType;
- EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE ReturnType run(const RotationDerived& r, const OtherVectorType& v)
+ EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE EIGEN_CONSTEXPR ReturnType run(const RotationDerived& r, const OtherVectorType& v)
{
return r._transformVector(v);
}
diff --git a/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
index b60f34d..5a7dbc7 100644
--- a/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
+++ b/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
@@ -31,8 +31,6 @@
const Preconditioner& precond, Index& iters,
typename Dest::RealScalar& tol_error)
{
- using std::sqrt;
- using std::abs;
typedef typename Dest::RealScalar RealScalar;
typedef typename Dest::Scalar Scalar;
typedef Matrix<Scalar,Dynamic,1> VectorType;
@@ -58,7 +56,7 @@
if (residualNorm2 < threshold)
{
iters = 0;
- tol_error = sqrt(residualNorm2 / rhsNorm2);
+ tol_error = numext::sqrt(residualNorm2 / rhsNorm2);
return;
}
@@ -88,7 +86,7 @@
p = z + beta * p; // update search direction
i++;
}
- tol_error = sqrt(residualNorm2 / rhsNorm2);
+ tol_error = numext::sqrt(residualNorm2 / rhsNorm2);
iters = i;
}
diff --git a/Eigen/src/Jacobi/Jacobi.h b/Eigen/src/Jacobi/Jacobi.h
index 852a385..5d96989 100644
--- a/Eigen/src/Jacobi/Jacobi.h
+++ b/Eigen/src/Jacobi/Jacobi.h
@@ -344,15 +344,18 @@
{
static inline void run(Scalar *x, Index incrx, Scalar *y, Index incry, Index size, OtherScalar c, OtherScalar s)
{
- enum {
- PacketSize = packet_traits<Scalar>::size,
- OtherPacketSize = packet_traits<OtherScalar>::size
- };
typedef typename packet_traits<Scalar>::type Packet;
typedef typename packet_traits<OtherScalar>::type OtherPacket;
+ enum {
+ RequiredAlignment = plain_enum_max(unpacket_traits<Packet>::alignment,
+ unpacket_traits<OtherPacket>::alignment),
+ PacketSize = packet_traits<Scalar>::size,
+ OtherPacketSize = packet_traits<OtherScalar>::size
+ };
+
/*** dynamic-size vectorized paths ***/
- if(SizeAtCompileTime == Dynamic && ((incrx==1 && incry==1) || PacketSize == 1))
+ if(size >= 2 * PacketSize && SizeAtCompileTime == Dynamic && ((incrx == 1 && incry == 1) || PacketSize == 1))
{
// both vectors are sequentially stored in memory => vectorization
enum { Peeling = 2 };
@@ -423,11 +426,11 @@
}
/*** fixed-size vectorized path ***/
- else if(SizeAtCompileTime != Dynamic && MinAlignment>0) // FIXME should be compared to the required alignment
+ else if(SizeAtCompileTime != Dynamic && MinAlignment >= RequiredAlignment)
{
const OtherPacket pc = pset1<OtherPacket>(c);
const OtherPacket ps = pset1<OtherPacket>(s);
- conj_helper<OtherPacket,Packet,NumTraits<OtherPacket>::IsComplex,false> pcj;
+ conj_helper<OtherPacket,Packet,NumTraits<OtherScalar>::IsComplex,false> pcj;
conj_helper<OtherPacket,Packet,false,false> pm;
Scalar* EIGEN_RESTRICT px = x;
Scalar* EIGEN_RESTRICT py = y;
@@ -452,11 +455,11 @@
template<typename VectorX, typename VectorY, typename OtherScalar>
EIGEN_DEVICE_FUNC
-void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
+void inline apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
{
typedef typename VectorX::Scalar Scalar;
- const bool Vectorizable = (int(VectorX::Flags) & int(VectorY::Flags) & PacketAccessBit)
- && (int(packet_traits<Scalar>::size) == int(packet_traits<OtherScalar>::size));
+ constexpr bool Vectorizable = (int(evaluator<VectorX>::Flags) & int(evaluator<VectorY>::Flags) & PacketAccessBit) &&
+ (int(packet_traits<Scalar>::size) == int(packet_traits<OtherScalar>::size));
eigen_assert(xpr_x.size() == xpr_y.size());
Index size = xpr_x.size();
diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index fec5321..c906997 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -219,6 +219,21 @@
return m_colsPermutation;
}
+ /** \returns the determinant of the matrix of which
+ * *this is the QR decomposition. It has only linear complexity
+ * (that is, O(n) where n is the dimension of the square matrix)
+ * as the QR decomposition has already been computed.
+ *
+ * \note This is only for square matrices.
+ *
+ * \warning a determinant can be very big or small, so for matrices
+ * of large enough dimension, there is a risk of overflow/underflow.
+ * One way to work around that is to use logAbsDeterminant() instead.
+ *
+ * \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
+ */
+ typename MatrixType::Scalar determinant() const;
+
/** \returns the absolute value of the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
@@ -230,7 +245,7 @@
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
- * \sa logAbsDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -244,7 +259,7 @@
* \note This method is useful to work around the risk of overflow/underflow that's inherent
* to determinant computation.
*
- * \sa absDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -442,10 +457,20 @@
bool m_isInitialized, m_usePrescribedThreshold;
RealScalar m_prescribedThreshold, m_maxpivot;
Index m_nonzero_pivots;
- Index m_det_pq;
+ Index m_det_p;
};
template<typename MatrixType>
+typename MatrixType::Scalar ColPivHouseholderQR<MatrixType>::determinant() const
+{
+ eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
+ eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
+ Scalar detQ;
+ internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
+ return m_qr.diagonal().prod() * detQ * Scalar(m_det_p);
+}
+
+template<typename MatrixType>
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::absDeterminant() const
{
using std::abs;
@@ -574,7 +599,7 @@
for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k)
m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k)));
- m_det_pq = (number_of_transpositions%2) ? -1 : 1;
+ m_det_p = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;
}
diff --git a/Eigen/src/QR/CompleteOrthogonalDecomposition.h b/Eigen/src/QR/CompleteOrthogonalDecomposition.h
index bfaaa93..02583a2 100644
--- a/Eigen/src/QR/CompleteOrthogonalDecomposition.h
+++ b/Eigen/src/QR/CompleteOrthogonalDecomposition.h
@@ -197,6 +197,21 @@
return m_cpqr.colsPermutation();
}
+ /** \returns the determinant of the matrix of which
+ * *this is the complete orthogonal decomposition. It has only linear
+ * complexity (that is, O(n) where n is the dimension of the square matrix)
+ * as the complete orthogonal decomposition has already been computed.
+ *
+ * \note This is only for square matrices.
+ *
+ * \warning a determinant can be very big or small, so for matrices
+ * of large enough dimension, there is a risk of overflow/underflow.
+ * One way to work around that is to use logAbsDeterminant() instead.
+ *
+ * \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
+ */
+ typename MatrixType::Scalar determinant() const;
+
/** \returns the absolute value of the determinant of the matrix of which
* *this is the complete orthogonal decomposition. It has only linear
* complexity (that is, O(n) where n is the dimension of the square matrix)
@@ -208,7 +223,7 @@
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
- * \sa logAbsDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -223,7 +238,7 @@
* \note This method is useful to work around the risk of overflow/underflow
* that's inherent to determinant computation.
*
- * \sa absDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -408,6 +423,12 @@
};
template <typename MatrixType>
+typename MatrixType::Scalar
+CompleteOrthogonalDecomposition<MatrixType>::determinant() const {
+ return m_cpqr.determinant();
+}
+
+template <typename MatrixType>
typename MatrixType::RealScalar
CompleteOrthogonalDecomposition<MatrixType>::absDeterminant() const {
return m_cpqr.absDeterminant();
diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h
index dcb9e1a..ec7e19b 100644
--- a/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/Eigen/src/QR/FullPivHouseholderQR.h
@@ -210,6 +210,21 @@
return m_rows_transpositions;
}
+ /** \returns the determinant of the matrix of which
+ * *this is the QR decomposition. It has only linear complexity
+ * (that is, O(n) where n is the dimension of the square matrix)
+ * as the QR decomposition has already been computed.
+ *
+ * \note This is only for square matrices.
+ *
+ * \warning a determinant can be very big or small, so for matrices
+ * of large enough dimension, there is a risk of overflow/underflow.
+ * One way to work around that is to use logAbsDeterminant() instead.
+ *
+ * \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
+ */
+ typename MatrixType::Scalar determinant() const;
+
/** \returns the absolute value of the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
@@ -221,7 +236,7 @@
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
- * \sa logAbsDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -235,7 +250,7 @@
* \note This method is useful to work around the risk of overflow/underflow that's inherent
* to determinant computation.
*
- * \sa absDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -419,10 +434,20 @@
RealScalar m_prescribedThreshold, m_maxpivot;
Index m_nonzero_pivots;
RealScalar m_precision;
- Index m_det_pq;
+ Index m_det_p;
};
template<typename MatrixType>
+typename MatrixType::Scalar FullPivHouseholderQR<MatrixType>::determinant() const
+{
+ eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
+ eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
+ Scalar detQ;
+ internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
+ return m_qr.diagonal().prod() * detQ * Scalar(m_det_p);
+}
+
+template<typename MatrixType>
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const
{
using std::abs;
@@ -531,7 +556,7 @@
for(Index k = 0; k < size; ++k)
m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k));
- m_det_pq = (number_of_transpositions%2) ? -1 : 1;
+ m_det_p = (number_of_transpositions%2) ? -1 : 1;
m_isInitialized = true;
}
diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h
index 5e67463..abfefd1 100644
--- a/Eigen/src/QR/HouseholderQR.h
+++ b/Eigen/src/QR/HouseholderQR.h
@@ -184,6 +184,21 @@
return *this;
}
+ /** \returns the determinant of the matrix of which
+ * *this is the QR decomposition. It has only linear complexity
+ * (that is, O(n) where n is the dimension of the square matrix)
+ * as the QR decomposition has already been computed.
+ *
+ * \note This is only for square matrices.
+ *
+ * \warning a determinant can be very big or small, so for matrices
+ * of large enough dimension, there is a risk of overflow/underflow.
+ * One way to work around that is to use logAbsDeterminant() instead.
+ *
+ * \sa absDeterminant(), logAbsDeterminant(), MatrixBase::determinant()
+ */
+ typename MatrixType::Scalar determinant() const;
+
/** \returns the absolute value of the determinant of the matrix of which
* *this is the QR decomposition. It has only linear complexity
* (that is, O(n) where n is the dimension of the square matrix)
@@ -195,7 +210,7 @@
* of large enough dimension, there is a risk of overflow/underflow.
* One way to work around that is to use logAbsDeterminant() instead.
*
- * \sa logAbsDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), logAbsDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar absDeterminant() const;
@@ -209,7 +224,7 @@
* \note This method is useful to work around the risk of overflow/underflow that's inherent
* to determinant computation.
*
- * \sa absDeterminant(), MatrixBase::determinant()
+ * \sa determinant(), absDeterminant(), MatrixBase::determinant()
*/
typename MatrixType::RealScalar logAbsDeterminant() const;
@@ -242,6 +257,57 @@
bool m_isInitialized;
};
+namespace internal {
+
+/** \internal */
+template<typename HCoeffs, typename Scalar, bool IsComplex>
+struct householder_determinant
+{
+ static void run(const HCoeffs& hCoeffs, Scalar& out_det)
+ {
+ out_det = Scalar(1);
+ Index size = hCoeffs.rows();
+ for (Index i = 0; i < size; i ++)
+ {
+ // For each valid reflection Q_n,
+ // det(Q_n) = - conj(h_n) / h_n
+ // where h_n is the Householder coefficient.
+ if (hCoeffs(i) != Scalar(0))
+ out_det *= - numext::conj(hCoeffs(i)) / hCoeffs(i);
+ }
+ }
+};
+
+/** \internal */
+template<typename HCoeffs, typename Scalar>
+struct householder_determinant<HCoeffs, Scalar, false>
+{
+ static void run(const HCoeffs& hCoeffs, Scalar& out_det)
+ {
+ bool negated = false;
+ Index size = hCoeffs.rows();
+ for (Index i = 0; i < size; i ++)
+ {
+ // Each valid reflection negates the determinant.
+ if (hCoeffs(i) != Scalar(0))
+ negated ^= true;
+ }
+ out_det = negated ? Scalar(-1) : Scalar(1);
+ }
+};
+
+} // end namespace internal
+
+template<typename MatrixType>
+typename MatrixType::Scalar HouseholderQR<MatrixType>::determinant() const
+{
+ eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
+ eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
+ Scalar detQ;
+ internal::householder_determinant<HCoeffsType, Scalar, NumTraits<Scalar>::IsComplex>::run(m_hCoeffs, detQ);
+ return m_qr.diagonal().prod() * detQ;
+}
+
template<typename MatrixType>
typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const
{
diff --git a/Eigen/src/SVD/BDCSVD.h b/Eigen/src/SVD/BDCSVD.h
index f9e0c62..0949442 100644
--- a/Eigen/src/SVD/BDCSVD.h
+++ b/Eigen/src/SVD/BDCSVD.h
@@ -57,6 +57,9 @@
}
};
+EIGEN_DIAGNOSTICS(push)
+EIGEN_DISABLE_DEPRECATED_WARNING
+
template <typename MatrixType>
struct allocate_small_svd<MatrixType, 0> {
static void run(JacobiSVD<MatrixType>& smallSvd, Index rows, Index cols, unsigned int computationOptions) {
@@ -64,6 +67,8 @@
}
};
+EIGEN_DIAGNOSTICS(pop)
+
} // end namespace internal
/** \ingroup SVD_Module
diff --git a/Eigen/src/SparseCore/CompressedStorage.h b/Eigen/src/SparseCore/CompressedStorage.h
index 1f7aeb5..733b1aa 100644
--- a/Eigen/src/SparseCore/CompressedStorage.h
+++ b/Eigen/src/SparseCore/CompressedStorage.h
@@ -71,8 +71,8 @@
~CompressedStorage()
{
- delete[] m_values;
- delete[] m_indices;
+ conditional_aligned_delete_auto<Scalar, true>(m_values, m_allocatedSize);
+ conditional_aligned_delete_auto<StorageIndex, true>(m_indices, m_allocatedSize);
}
void reserve(Index size)
@@ -180,24 +180,13 @@
{
if (m_allocatedSize<m_size+1)
{
- m_allocatedSize = 2*(m_size+1);
- internal::scoped_array<Scalar> newValues(m_allocatedSize);
- internal::scoped_array<StorageIndex> newIndices(m_allocatedSize);
-
- // copy first chunk
- internal::smart_copy(m_values, m_values +id, newValues.ptr());
- internal::smart_copy(m_indices, m_indices+id, newIndices.ptr());
-
- // copy the rest
- if(m_size>id)
- {
- internal::smart_copy(m_values +id, m_values +m_size, newValues.ptr() +id+1);
- internal::smart_copy(m_indices+id, m_indices+m_size, newIndices.ptr()+id+1);
- }
- std::swap(m_values,newValues.ptr());
- std::swap(m_indices,newIndices.ptr());
+ Index newAllocatedSize = 2 * (m_size + 1);
+ m_values = conditional_aligned_realloc_new_auto<Scalar, true>(m_values, newAllocatedSize, m_allocatedSize);
+ m_indices =
+ conditional_aligned_realloc_new_auto<StorageIndex, true>(m_indices, newAllocatedSize, m_allocatedSize);
+ m_allocatedSize = newAllocatedSize;
}
- else if(m_size>id)
+ if(m_size>id)
{
internal::smart_memmove(m_values +id, m_values +m_size, m_values +id+1);
internal::smart_memmove(m_indices+id, m_indices+m_size, m_indices+id+1);
@@ -233,15 +222,8 @@
EIGEN_SPARSE_COMPRESSED_STORAGE_REALLOCATE_PLUGIN
#endif
eigen_internal_assert(size!=m_allocatedSize);
- internal::scoped_array<Scalar> newValues(size);
- internal::scoped_array<StorageIndex> newIndices(size);
- Index copySize = (std::min)(size, m_size);
- if (copySize>0) {
- internal::smart_copy(m_values, m_values+copySize, newValues.ptr());
- internal::smart_copy(m_indices, m_indices+copySize, newIndices.ptr());
- }
- std::swap(m_values,newValues.ptr());
- std::swap(m_indices,newIndices.ptr());
+ m_values = conditional_aligned_realloc_new_auto<Scalar, true>(m_values, size, m_allocatedSize);
+ m_indices = conditional_aligned_realloc_new_auto<StorageIndex, true>(m_indices, size, m_allocatedSize);
m_allocatedSize = size;
}
diff --git a/Eigen/src/SparseCore/SparseAssign.h b/Eigen/src/SparseCore/SparseAssign.h
index 63d69ad..29f6af4 100644
--- a/Eigen/src/SparseCore/SparseAssign.h
+++ b/Eigen/src/SparseCore/SparseAssign.h
@@ -80,12 +80,18 @@
const bool transpose = (DstEvaluatorType::Flags & RowMajorBit) != (SrcEvaluatorType::Flags & RowMajorBit);
const Index outerEvaluationSize = (SrcEvaluatorType::Flags&RowMajorBit) ? src.rows() : src.cols();
+
+ Index reserveSize = 0;
+ for (Index j = 0; j < outerEvaluationSize; ++j)
+ for (typename SrcEvaluatorType::InnerIterator it(srcEvaluator, j); it; ++it)
+ reserveSize++;
+
if ((!transpose) && src.isRValue())
{
// eval without temporary
dst.resize(src.rows(), src.cols());
dst.setZero();
- dst.reserve((std::min)(src.rows()*src.cols(), (std::max)(src.rows(),src.cols())*2));
+ dst.reserve(reserveSize);
for (Index j=0; j<outerEvaluationSize; ++j)
{
dst.startVec(j);
@@ -109,7 +115,7 @@
DstXprType temp(src.rows(), src.cols());
- temp.reserve((std::min)(src.rows()*src.cols(), (std::max)(src.rows(),src.cols())*2));
+ temp.reserve(reserveSize);
for (Index j=0; j<outerEvaluationSize; ++j)
{
temp.startVec(j);
diff --git a/Eigen/src/SparseCore/SparseCompressedBase.h b/Eigen/src/SparseCore/SparseCompressedBase.h
index b3c716d..ede5766 100644
--- a/Eigen/src/SparseCore/SparseCompressedBase.h
+++ b/Eigen/src/SparseCore/SparseCompressedBase.h
@@ -196,8 +196,7 @@
}
}
- explicit InnerIterator(const SparseCompressedBase& mat)
- : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(0), m_id(0), m_end(mat.nonZeros())
+ explicit InnerIterator(const SparseCompressedBase& mat) : InnerIterator(mat, Index(0))
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
}
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h
index 5e0c178..fdac443 100644
--- a/Eigen/src/SparseCore/SparseMatrix.h
+++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -302,8 +302,7 @@
{
Index totalReserveSize = 0;
// turn the matrix into non-compressed mode
- m_innerNonZeros = static_cast<StorageIndex*>(std::malloc(m_outerSize * sizeof(StorageIndex)));
- if (!m_innerNonZeros) internal::throw_std_bad_alloc();
+ m_innerNonZeros = internal::conditional_aligned_new_auto<StorageIndex, true>(m_outerSize);
// temporarily use m_innerSizes to hold the new starting points.
StorageIndex* newOuterIndex = m_innerNonZeros;
@@ -336,8 +335,7 @@
}
else
{
- StorageIndex* newOuterIndex = static_cast<StorageIndex*>(std::malloc((m_outerSize+1)*sizeof(StorageIndex)));
- if (!newOuterIndex) internal::throw_std_bad_alloc();
+ StorageIndex* newOuterIndex = internal::conditional_aligned_new_auto<StorageIndex, true>(m_outerSize + 1);
StorageIndex count = 0;
for(Index j=0; j<m_outerSize; ++j)
@@ -365,7 +363,7 @@
}
std::swap(m_outerIndex, newOuterIndex);
- std::free(newOuterIndex);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(newOuterIndex, m_outerSize + 1);
}
}
@@ -488,7 +486,7 @@
m_outerIndex[j+1] = m_outerIndex[j] + m_innerNonZeros[j];
oldStart = nextOldStart;
}
- std::free(m_innerNonZeros);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
m_innerNonZeros = 0;
m_data.resize(m_outerIndex[m_outerSize]);
m_data.squeeze();
@@ -499,7 +497,7 @@
{
if(m_innerNonZeros != 0)
return;
- m_innerNonZeros = static_cast<StorageIndex*>(std::malloc(m_outerSize * sizeof(StorageIndex)));
+ m_innerNonZeros = internal::conditional_aligned_new_auto<StorageIndex, true>(m_outerSize);
for (Index i = 0; i < m_outerSize; i++)
{
m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
@@ -569,9 +567,8 @@
if (m_innerNonZeros)
{
// Resize m_innerNonZeros
- StorageIndex *newInnerNonZeros = static_cast<StorageIndex*>(std::realloc(m_innerNonZeros, (m_outerSize + outerChange) * sizeof(StorageIndex)));
- if (!newInnerNonZeros) internal::throw_std_bad_alloc();
- m_innerNonZeros = newInnerNonZeros;
+ m_innerNonZeros = internal::conditional_aligned_realloc_new_auto<StorageIndex, true>(
+ m_innerNonZeros, m_outerSize + outerChange, m_outerSize);
for(Index i=m_outerSize; i<m_outerSize+outerChange; i++)
m_innerNonZeros[i] = 0;
@@ -579,8 +576,7 @@
else if (innerChange < 0)
{
// Inner size decreased: allocate a new m_innerNonZeros
- m_innerNonZeros = static_cast<StorageIndex*>(std::malloc((m_outerSize + outerChange) * sizeof(StorageIndex)));
- if (!m_innerNonZeros) internal::throw_std_bad_alloc();
+ m_innerNonZeros = internal::conditional_aligned_new_auto<StorageIndex, true>(m_outerSize + outerChange);
for(Index i = 0; i < m_outerSize + (std::min)(outerChange, Index(0)); i++)
m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i];
for(Index i = m_outerSize; i < m_outerSize + outerChange; i++)
@@ -604,9 +600,8 @@
if (outerChange == 0)
return;
- StorageIndex *newOuterIndex = static_cast<StorageIndex*>(std::realloc(m_outerIndex, (m_outerSize + outerChange + 1) * sizeof(StorageIndex)));
- if (!newOuterIndex) internal::throw_std_bad_alloc();
- m_outerIndex = newOuterIndex;
+ m_outerIndex = internal::conditional_aligned_realloc_new_auto<StorageIndex, true>(
+ m_outerIndex, m_outerSize + outerChange + 1, m_outerSize + 1);
if (outerChange > 0)
{
StorageIndex lastIdx = m_outerSize == 0 ? 0 : m_outerIndex[m_outerSize];
@@ -630,15 +625,13 @@
m_data.clear();
if (m_outerSize != outerSize || m_outerSize==0)
{
- std::free(m_outerIndex);
- m_outerIndex = static_cast<StorageIndex*>(std::malloc((outerSize + 1) * sizeof(StorageIndex)));
- if (!m_outerIndex) internal::throw_std_bad_alloc();
-
+ m_outerIndex = internal::conditional_aligned_realloc_new_auto<StorageIndex, true>(m_outerIndex, outerSize + 1,
+ m_outerSize + 1);
m_outerSize = outerSize;
}
if(m_innerNonZeros)
{
- std::free(m_innerNonZeros);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
m_innerNonZeros = 0;
}
std::fill_n(m_outerIndex, m_outerSize + 1, StorageIndex(0));
@@ -746,7 +739,7 @@
Eigen::Map<IndexVector>(this->m_data.indexPtr(), rows()).setLinSpaced(0, StorageIndex(rows()-1));
Eigen::Map<ScalarVector>(this->m_data.valuePtr(), rows()).setOnes();
Eigen::Map<IndexVector>(this->m_outerIndex, rows()+1).setLinSpaced(0, StorageIndex(rows()));
- std::free(m_innerNonZeros);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
m_innerNonZeros = 0;
}
inline SparseMatrix& operator=(const SparseMatrix& other)
@@ -786,6 +779,7 @@
template<typename OtherDerived>
EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other);
+#ifndef EIGEN_NO_IO
friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m)
{
EIGEN_DBG_SPARSE(
@@ -830,12 +824,13 @@
s << static_cast<const SparseMatrixBase<SparseMatrix>&>(m);
return s;
}
+#endif
/** Destructor */
inline ~SparseMatrix()
{
- std::free(m_outerIndex);
- std::free(m_innerNonZeros);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(m_outerIndex, m_outerSize + 1);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
}
/** Overloaded for performance */
@@ -853,7 +848,7 @@
resize(other.rows(), other.cols());
if(m_innerNonZeros)
{
- std::free(m_innerNonZeros);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
m_innerNonZeros = 0;
}
}
@@ -1152,7 +1147,7 @@
m_outerIndex[m_outerSize] = count;
// turn the matrix into compressed form
- std::free(m_innerNonZeros);
+ internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
m_innerNonZeros = 0;
m_data.resize(m_outerIndex[m_outerSize]);
}
@@ -1247,8 +1242,7 @@
m_data.reserve(2*m_innerSize);
// turn the matrix into non-compressed mode
- m_innerNonZeros = static_cast<StorageIndex*>(std::malloc(m_outerSize * sizeof(StorageIndex)));
- if(!m_innerNonZeros) internal::throw_std_bad_alloc();
+ m_innerNonZeros = internal::conditional_aligned_new_auto<StorageIndex, true>(m_outerSize);
std::fill(m_innerNonZeros, m_innerNonZeros + m_outerSize, StorageIndex(0));
@@ -1261,8 +1255,7 @@
else
{
// turn the matrix into non-compressed mode
- m_innerNonZeros = static_cast<StorageIndex*>(std::malloc(m_outerSize * sizeof(StorageIndex)));
- if(!m_innerNonZeros) internal::throw_std_bad_alloc();
+ m_innerNonZeros = internal::conditional_aligned_new_auto<StorageIndex, true>(m_outerSize);
for(Index j=0; j<m_outerSize; ++j)
m_innerNonZeros[j] = m_outerIndex[j+1]-m_outerIndex[j];
}
diff --git a/Eigen/src/SparseCore/SparseMatrixBase.h b/Eigen/src/SparseCore/SparseMatrixBase.h
index 3665888..dc78c2e 100644
--- a/Eigen/src/SparseCore/SparseMatrixBase.h
+++ b/Eigen/src/SparseCore/SparseMatrixBase.h
@@ -214,7 +214,7 @@
inline void assignGeneric(const OtherDerived& other);
public:
-
+#ifndef EIGEN_NO_IO
friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
{
typedef typename Derived::Nested Nested;
@@ -263,6 +263,7 @@
}
return s;
}
+#endif
template<typename OtherDerived>
Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h
index 7d7034f..ebbadb5 100644
--- a/Eigen/src/SparseCore/SparseVector.h
+++ b/Eigen/src/SparseCore/SparseVector.h
@@ -353,6 +353,7 @@
}
#endif
+#ifndef EIGEN_NO_IO
friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
{
for (Index i=0; i<m.nonZeros(); ++i)
@@ -360,6 +361,7 @@
s << std::endl;
return s;
}
+#endif
/** Destructor */
inline ~SparseVector() {}
diff --git a/Eigen/src/SparseLU/SparseLU.h b/Eigen/src/SparseLU/SparseLU.h
index 6fc7d33..9fd7e25 100644
--- a/Eigen/src/SparseLU/SparseLU.h
+++ b/Eigen/src/SparseLU/SparseLU.h
@@ -754,10 +754,13 @@
info = Base::pivotL(jj, m_diagpivotthresh, m_perm_r.indices(), iperm_c.indices(), pivrow, m_glu);
if ( info )
{
- m_lastError = "THE MATRIX IS STRUCTURALLY SINGULAR ... ZERO COLUMN AT ";
+ m_lastError = "THE MATRIX IS STRUCTURALLY SINGULAR";
+#ifndef EIGEN_NO_IO
std::ostringstream returnInfo;
- returnInfo << info;
+ returnInfo << " ... ZERO COLUMN AT ";
+ returnInfo << info;
m_lastError += returnInfo.str();
+#endif
m_info = NumericalIssue;
m_factorizationIsOk = false;
return;
@@ -816,6 +819,31 @@
m_mapL.template solveTransposedInPlace<Conjugate>(X);
}
+ SparseMatrix<Scalar, ColMajor, Index> toSparse() const {
+ ArrayXi colCount = ArrayXi::Ones(cols());
+ for (Index i = 0; i < cols(); i++) {
+ typename MappedSupernodalType::InnerIterator iter(m_mapL, i);
+ for (; iter; ++iter) {
+ if (iter.row() > iter.col()) {
+ colCount(iter.col())++;
+ }
+ }
+ }
+ SparseMatrix<Scalar, ColMajor, Index> sL(rows(), cols());
+ sL.reserve(colCount);
+ for (Index i = 0; i < cols(); i++) {
+ sL.insert(i, i) = 1.0;
+ typename MappedSupernodalType::InnerIterator iter(m_mapL, i);
+ for (; iter; ++iter) {
+ if (iter.row() > iter.col()) {
+ sL.insert(iter.row(), iter.col()) = iter.value();
+ }
+ }
+ }
+ sL.makeCompressed();
+ return sL;
+ }
+
const MappedSupernodalType& m_mapL;
};
@@ -915,6 +943,32 @@
}// End For U-solve
}
+ SparseMatrix<Scalar, RowMajor, Index> toSparse() {
+ ArrayXi rowCount = ArrayXi::Zero(rows());
+ for (Index i = 0; i < cols(); i++) {
+ typename MatrixLType::InnerIterator iter(m_mapL, i);
+ for (; iter; ++iter) {
+ if (iter.row() <= iter.col()) {
+ rowCount(iter.row())++;
+ }
+ }
+ }
+
+ SparseMatrix<Scalar, RowMajor, Index> sU(rows(), cols());
+ sU.reserve(rowCount);
+ for (Index i = 0; i < cols(); i++) {
+ typename MatrixLType::InnerIterator iter(m_mapL, i);
+ for (; iter; ++iter) {
+ if (iter.row() <= iter.col()) {
+ sU.insert(iter.row(), iter.col()) = iter.value();
+ }
+ }
+ }
+ sU.makeCompressed();
+ const SparseMatrix<Scalar, RowMajor, Index> u = m_mapU; // convert to RowMajor
+ sU += u;
+ return sU;
+ }
const MatrixLType& m_mapL;
const MatrixUType& m_mapU;
diff --git a/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/Eigen/src/plugins/ArrayCwiseBinaryOps.h
index a4dbfbc..ce9bcf6 100644
--- a/Eigen/src/plugins/ArrayCwiseBinaryOps.h
+++ b/Eigen/src/plugins/ArrayCwiseBinaryOps.h
@@ -134,41 +134,21 @@
*/
EIGEN_MAKE_CWISE_BINARY_OP(pow,pow)
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(pow,pow)
-#else
-/** \returns an expression of the coefficients of \c *this rasied to the constant power \a exponent
- *
- * \tparam T is the scalar type of \a exponent. It must be compatible with the scalar type of the given expression.
- *
- * This function computes the coefficient-wise power. The function MatrixBase::pow() in the
- * unsupported module MatrixFunctions computes the matrix power.
- *
- * Example: \include Cwise_pow.cpp
- * Output: \verbinclude Cwise_pow.out
- *
- * \sa ArrayBase::pow(ArrayBase), square(), cube(), exp(), log()
- */
-template<typename T>
-const CwiseBinaryOp<internal::scalar_pow_op<Scalar,T>,Derived,Constant<T> > pow(const T& exponent) const;
-#endif
-
-
// TODO code generating macros could be moved to Macros.h and could include generation of documentation
#define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \
template<typename OtherDerived> \
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, typename OtherDerived::Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived> \
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, typename OtherDerived::Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived> \
OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, typename OtherDerived::Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived>(derived(), other.derived()); \
}\
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar, internal::cmp_ ## COMPARATOR>, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const Cmp ## COMPARATOR ## ReturnType \
OP(const Scalar& s) const { \
return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \
} \
-EIGEN_DEVICE_FUNC friend EIGEN_STRONG_INLINE const RCmp ## COMPARATOR ## ReturnType \
+EIGEN_DEVICE_FUNC friend EIGEN_STRONG_INLINE EIGEN_CONSTEXPR const RCmp ## COMPARATOR ## ReturnType \
OP(const Scalar& s, const EIGEN_CURRENT_STORAGE_BASE_CLASS<Derived>& d) { \
return Derived::PlainObject::Constant(d.rows(), d.cols(), s).OP(d); \
}
diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h
index 13c55f4..b2d9331 100644
--- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h
+++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h
@@ -694,3 +694,32 @@
{
return NdtriReturnType(derived());
}
+
+template <typename ScalarExponent>
+using UnaryPowReturnType =
+ std::enable_if_t<internal::is_arithmetic<typename NumTraits<ScalarExponent>::Real>::value,
+ CwiseUnaryOp<internal::scalar_unary_pow_op<Scalar, ScalarExponent>, const Derived>>;
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN
+template <typename ScalarExponent>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const UnaryPowReturnType<ScalarExponent> pow(
+ const ScalarExponent& exponent) const {
+ return UnaryPowReturnType<ScalarExponent>(derived(), internal::scalar_unary_pow_op<Scalar, ScalarExponent>(exponent));
+#else
+/** \returns an expression of the coefficients of \c *this rasied to the constant power \a exponent
+ *
+ * \tparam T is the scalar type of \a exponent. It must be compatible with the scalar type of the given expression.
+ *
+ * This function computes the coefficient-wise power. The function MatrixBase::pow() in the
+ * unsupported module MatrixFunctions computes the matrix power.
+ *
+ * Example: \include Cwise_pow.cpp
+ * Output: \verbinclude Cwise_pow.out
+ *
+ * \sa ArrayBase::pow(ArrayBase), square(), cube(), exp(), log()
+ */
+template <typename ScalarExponent>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const UnaryPowReturnType<ScalarExponent> pow(
+ const ScalarExponent& exponent) const;
+#endif
+}
diff --git a/Eigen/src/plugins/BlockMethods.h b/Eigen/src/plugins/BlockMethods.h
index 68b9413..a93fbec 100644
--- a/Eigen/src/plugins/BlockMethods.h
+++ b/Eigen/src/plugins/BlockMethods.h
@@ -87,7 +87,7 @@
/// \sa class Block, fix, fix<N>(int)
///
template<typename NRowsType, typename NColsType>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
#else
@@ -101,7 +101,7 @@
/// This is the const version of block(Index,Index,NRowsType,NColsType)
template<typename NRowsType, typename NColsType>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
const typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
#else
@@ -133,7 +133,7 @@
/// \sa block(Index,Index,NRowsType,NColsType), class Block
///
template<typename NRowsType, typename NColsType>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
typename FixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
#else
@@ -147,7 +147,7 @@
/// This is the const version of topRightCorner(NRowsType, NColsType).
template<typename NRowsType, typename NColsType>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
#ifndef EIGEN_PARSED_BY_DOXYGEN
const typename ConstFixedBlockXpr<internal::get_fixed_value<NRowsType>::value,internal::get_fixed_value<NColsType>::value>::Type
#else
@@ -1023,7 +1023,7 @@
/// \sa block(Index,Index,NRowsType,NColsType), class Block
///
template<int NRows, int NCols>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename FixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol)
{
return typename FixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol);
@@ -1031,7 +1031,7 @@
/// This is the const version of block<>(Index, Index). */
template<int NRows, int NCols>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol) const
{
return typename ConstFixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol);
@@ -1093,14 +1093,14 @@
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
/**
* \sa row(), class Block */
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
ColXpr col(Index i)
{
return ColXpr(derived(), i);
}
/// This is the const version of col().
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
ConstColXpr col(Index i) const
{
return ConstColXpr(derived(), i);
@@ -1114,14 +1114,14 @@
EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
/**
* \sa col(), class Block */
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
RowXpr row(Index i)
{
return RowXpr(derived(), i);
}
/// This is the const version of row(). */
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
ConstRowXpr row(Index i) const
{
return ConstRowXpr(derived(), i);
@@ -1293,7 +1293,7 @@
/// \sa segment(Index,NType), class Block
///
template<int N>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename FixedSegmentReturnType<N>::Type segment(Index start, Index n = N)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -1302,7 +1302,7 @@
/// This is the const version of segment<int>(Index).
template<int N>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename ConstFixedSegmentReturnType<N>::Type segment(Index start, Index n = N) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -1334,7 +1334,7 @@
/// This is the const version of head<int>().
template<int N>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
typename ConstFixedSegmentReturnType<N>::Type head(Index n = N) const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -1426,7 +1426,7 @@
/** This is the const version of subVector(Index) */
template<DirectionType Direction>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
std::conditional_t<Direction==Vertical,ConstColXpr,ConstRowXpr>
subVector(Index i) const
{
diff --git a/Eigen/src/plugins/CommonCwiseBinaryOps.h b/Eigen/src/plugins/CommonCwiseBinaryOps.h
index 2f50329..591902e 100644
--- a/Eigen/src/plugins/CommonCwiseBinaryOps.h
+++ b/Eigen/src/plugins/CommonCwiseBinaryOps.h
@@ -38,7 +38,7 @@
* \sa class CwiseBinaryOp, operator+(), operator-(), cwiseProduct()
*/
template<typename CustomBinaryOp, typename OtherDerived>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
binaryExpr(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const
{
diff --git a/Eigen/src/plugins/CommonCwiseUnaryOps.h b/Eigen/src/plugins/CommonCwiseUnaryOps.h
index 390759c..3d52535 100644
--- a/Eigen/src/plugins/CommonCwiseUnaryOps.h
+++ b/Eigen/src/plugins/CommonCwiseUnaryOps.h
@@ -40,7 +40,7 @@
///
EIGEN_DOC_UNARY_ADDONS(operator-,opposite)
///
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline const NegativeReturnType
operator-() const { return NegativeReturnType(derived()); }
@@ -57,7 +57,7 @@
/// \sa class CwiseUnaryOp
///
template<typename NewType>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
typename CastXpr<NewType>::Type
cast() const
{
diff --git a/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/Eigen/src/plugins/MatrixCwiseBinaryOps.h
index 46fe08c..533383e 100644
--- a/Eigen/src/plugins/MatrixCwiseBinaryOps.h
+++ b/Eigen/src/plugins/MatrixCwiseBinaryOps.h
@@ -18,7 +18,7 @@
* \sa class CwiseBinaryOp, cwiseAbs2
*/
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,product)
cwiseProduct(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
{
@@ -38,7 +38,7 @@
* \sa cwiseNotEqual(), isApprox(), isMuchSmallerThan()
*/
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline const CwiseBinaryOp<numext::equal_to<Scalar>, const Derived, const OtherDerived>
cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
{
@@ -58,7 +58,7 @@
* \sa cwiseEqual(), isApprox(), isMuchSmallerThan()
*/
template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline const CwiseBinaryOp<numext::not_equal_to<Scalar>, const Derived, const OtherDerived>
cwiseNotEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
{
diff --git a/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/Eigen/src/plugins/MatrixCwiseUnaryOps.h
index 0514d8f..dc578f6 100644
--- a/Eigen/src/plugins/MatrixCwiseUnaryOps.h
+++ b/Eigen/src/plugins/MatrixCwiseUnaryOps.h
@@ -41,7 +41,7 @@
///
/// \sa cwiseAbs()
///
-EIGEN_DEVICE_FUNC
+EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
EIGEN_STRONG_INLINE const CwiseAbs2ReturnType
cwiseAbs2() const { return CwiseAbs2ReturnType(derived()); }
@@ -93,3 +93,13 @@
EIGEN_DEVICE_FUNC
inline const CwiseArgReturnType
cwiseArg() const { return CwiseArgReturnType(derived()); }
+
+template <typename ScalarExponent>
+using CwisePowReturnType =
+ std::enable_if_t<internal::is_arithmetic<typename NumTraits<ScalarExponent>::Real>::value,
+ CwiseUnaryOp<internal::scalar_unary_pow_op<Scalar, ScalarExponent>, const Derived>>;
+
+template <typename ScalarExponent>
+EIGEN_DEVICE_FUNC inline const CwisePowReturnType<ScalarExponent> cwisePow(const ScalarExponent& exponent) const {
+ return CwisePowReturnType<ScalarExponent>(derived(), internal::scalar_unary_pow_op<Scalar, ScalarExponent>(exponent));
+}
diff --git a/bench/spbench/CMakeLists.txt b/bench/spbench/CMakeLists.txt
index b186004..75c36b0 100644
--- a/bench/spbench/CMakeLists.txt
+++ b/bench/spbench/CMakeLists.txt
@@ -1,7 +1,7 @@
-set(BLAS_FOUND TRUE)
-set(LAPACK_FOUND TRUE)
+set(BLAS_FOUND EIGEN_BUILD_BLAS)
+set(LAPACK_FOUND EIGEN_BUILD_LAPACK)
set(BLAS_LIBRARIES eigen_blas_static)
set(LAPACK_LIBRARIES eigen_lapack_static)
diff --git a/debug/msvc/eigen.natvis b/debug/msvc/eigen.natvis
index da89857..22cf346 100644
--- a/debug/msvc/eigen.natvis
+++ b/debug/msvc/eigen.natvis
@@ -1,235 +1,235 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
-
- <!-- Fixed x Fixed Matrix -->
- <Type Name="Eigen::Matrix<*,*,*,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,-1,-1,*,*,*>"/>
- <DisplayString>[{$T2}, {$T3}] (fixed matrix)</DisplayString>
- <Expand>
- <ArrayItems Condition="Flags%2"> <!-- row major layout -->
- <Rank>2</Rank>
- <Size>$i==0 ? $T2 : $T3</Size>
- <ValuePointer>m_storage.m_data.array</ValuePointer>
- </ArrayItems>
- <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
- <Direction>Backward</Direction>
- <Rank>2</Rank>
- <Size>$i==0 ? $T2 : $T3</Size>
- <ValuePointer>m_storage.m_data.array</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
-
- <!-- 2 x 2 Matrix -->
- <Type Name="Eigen::Matrix<*,2,2,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,2,2,*,*,*>"/>
- <DisplayString>[2, 2] (fixed matrix)</DisplayString>
- <Expand>
- <Synthetic Name="[row 0]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 0]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[2]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 1]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 1]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[3]})</DisplayString>
- </Synthetic>
- </Expand>
- </Type>
-
- <!-- 3 x 3 Matrix -->
- <Type Name="Eigen::Matrix<*,3,3,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,3,3,*,*,*>"/>
- <DisplayString>[3, 3] (fixed matrix)</DisplayString>
- <Expand>
- <Synthetic Name="[row 0]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 0]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[3]}, {m_storage.m_data.array[6]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 1]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[3]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[5]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 1]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[7]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 2]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[6]}, {m_storage.m_data.array[7]}, {m_storage.m_data.array[8]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 2]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[8]})</DisplayString>
- </Synthetic>
- </Expand>
- </Type>
-
- <!-- 4 x 4 Matrix -->
- <Type Name="Eigen::Matrix<*,4,4,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,4,4,*,*,*>"/>
- <DisplayString>[4, 4] (fixed matrix)</DisplayString>
- <Expand>
- <Synthetic Name="[row 0]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 0]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[8]}, {m_storage.m_data.array[12]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 1]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[4]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[6]}, {m_storage.m_data.array[7]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 1]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[9]}, {m_storage.m_data.array[13]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 2]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[8]}, {m_storage.m_data.array[9]}, {m_storage.m_data.array[10]}, {m_storage.m_data.array[11]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 2]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[6]}, {m_storage.m_data.array[10]}, {m_storage.m_data.array[14]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 3]" Condition="Flags%2">
- <DisplayString>({m_storage.m_data.array[12]}, {m_storage.m_data.array[13]}, {m_storage.m_data.array[14]}, {m_storage.m_data.array[15]})</DisplayString>
- </Synthetic>
- <Synthetic Name="[row 3]" Condition="!(Flags%2)">
- <DisplayString>({m_storage.m_data.array[3]}, {m_storage.m_data.array[7]}, {m_storage.m_data.array[11]}, {m_storage.m_data.array[15]})</DisplayString>
- </Synthetic>
- </Expand>
- </Type>
-
- <!-- Dynamic x Dynamic Matrix -->
- <Type Name="Eigen::Matrix<*,-1,-1,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,-1,-1,*,*,*>"/>
- <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
- <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}, {m_storage.m_cols}] (dynamic matrix)</DisplayString>
- <Expand>
- <ArrayItems Condition="Flags%2"> <!-- row major layout -->
- <Rank>2</Rank>
- <Size>$i==0 ? m_storage.m_rows : m_storage.m_cols</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
- <Direction>Backward</Direction>
- <Rank>2</Rank>
- <Size>$i==0 ? m_storage.m_rows : m_storage.m_cols</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
-
- <!-- Fixed x Dynamic Matrix -->
- <Type Name="Eigen::Matrix<*,*,-1,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,*,-1,*,*,*>"/>
- <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
- <DisplayString Condition="m_storage.m_data != 0">[{$T2}, {m_storage.m_cols}] (dynamic column matrix)</DisplayString>
- <Expand>
- <ArrayItems Condition="Flags%2"> <!-- row major layout -->
- <Rank>2</Rank>
- <Size>$i==0 ? $T2 : m_storage.m_cols</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
- <Direction>Backward</Direction>
- <Rank>2</Rank>
- <Size>$i==0 ? $T2 : m_storage.m_cols</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
-
- <!-- Dynamic x Fixed Matrix -->
- <Type Name="Eigen::Matrix<*,-1,*,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,-1,*,*,*,*>"/>
- <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
- <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}, {$T2}] (dynamic row matrix)</DisplayString>
- <Expand>
- <ArrayItems Condition="Flags%2"> <!-- row major layout -->
- <Rank>2</Rank>
- <Size>$i==0 ? m_storage.m_rows : $T2</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
- <Direction>Backward</Direction>
- <Rank>2</Rank>
- <Size>$i==0 ? m_storage.m_rows : $T2</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
-
- <!-- Dynamic Column Vector -->
- <Type Name="Eigen::Matrix<*,1,-1,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,1,-1,*,*,*>"/>
- <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
- <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_cols}] (dynamic column vector)</DisplayString>
- <Expand>
- <Item Name="[size]">m_storage.m_cols</Item>
- <ArrayItems>
- <Size>m_storage.m_cols</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
-
- <!-- Dynamic Row Vector -->
- <Type Name="Eigen::Matrix<*,-1,1,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,-1,1,*,*,*>"/>
- <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
- <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}] (dynamic row vector)</DisplayString>
- <Expand>
- <Item Name="[size]">m_storage.m_rows</Item>
- <ArrayItems>
- <Size>m_storage.m_rows</Size>
- <ValuePointer>m_storage.m_data</ValuePointer>
- </ArrayItems>
- </Expand>
- </Type>
-
- <!-- Fixed Vector -->
- <Type Name="Eigen::Matrix<*,1,1,*,*,*>">
- <AlternativeType Name="Eigen::Array<*,1,1,*,*,*>"/>
- <DisplayString>[1] ({m_storage.m_data.array[0]})</DisplayString>
- <Expand>
- <Item Name="[x]">m_storage.m_data.array[0]</Item>
- </Expand>
- </Type>
-
- <Type Name="Eigen::Matrix<*,2,1,*,*,*>">
- <AlternativeType Name="Eigen::Matrix<*,1,2,*,*,*>"/>
- <AlternativeType Name="Eigen::Array<*,2,1,*,*,*>"/>
- <AlternativeType Name="Eigen::Array<*,1,2,*,*,*>"/>
- <DisplayString>[2] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]})</DisplayString>
- <Expand>
- <Item Name="[x]">m_storage.m_data.array[0]</Item>
- <Item Name="[y]">m_storage.m_data.array[1]</Item>
- </Expand>
- </Type>
-
- <Type Name="Eigen::Matrix<*,3,1,*,*,*>">
- <AlternativeType Name="Eigen::Matrix<*,1,3,*,*,*>"/>
- <AlternativeType Name="Eigen::Array<*,3,1,*,*,*>"/>
- <AlternativeType Name="Eigen::Array<*,1,3,*,*,*>"/>
- <DisplayString>[3] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]})</DisplayString>
- <Expand>
- <Item Name="[x]">m_storage.m_data.array[0]</Item>
- <Item Name="[y]">m_storage.m_data.array[1]</Item>
- <Item Name="[z]">m_storage.m_data.array[2]</Item>
- </Expand>
- </Type>
-
- <Type Name="Eigen::Matrix<*,4,1,*,*,*>">
- <AlternativeType Name="Eigen::Matrix<*,1,4,*,*,*>"/>
- <AlternativeType Name="Eigen::Array<*,4,1,*,*,*>"/>
- <AlternativeType Name="Eigen::Array<*,1,4,*,*,*>"/>
- <DisplayString>[4] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString>
- <Expand>
- <Item Name="[x]">m_storage.m_data.array[0]</Item>
- <Item Name="[y]">m_storage.m_data.array[1]</Item>
- <Item Name="[z]">m_storage.m_data.array[2]</Item>
- <Item Name="[w]">m_storage.m_data.array[3]</Item>
- </Expand>
- </Type>
-
-</AutoVisualizer>
+<?xml version="1.0" encoding="utf-8"?>
+
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+ <!-- Fixed x Fixed Matrix -->
+ <Type Name="Eigen::Matrix<*,*,*,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,-1,-1,*,*,*>"/>
+ <DisplayString>[{$T2}, {$T3}] (fixed matrix)</DisplayString>
+ <Expand>
+ <ArrayItems Condition="Flags%2"> <!-- row major layout -->
+ <Rank>2</Rank>
+ <Size>$i==0 ? $T2 : $T3</Size>
+ <ValuePointer>m_storage.m_data.array</ValuePointer>
+ </ArrayItems>
+ <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
+ <Direction>Backward</Direction>
+ <Rank>2</Rank>
+ <Size>$i==0 ? $T2 : $T3</Size>
+ <ValuePointer>m_storage.m_data.array</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <!-- 2 x 2 Matrix -->
+ <Type Name="Eigen::Matrix<*,2,2,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,2,2,*,*,*>"/>
+ <DisplayString>[2, 2] (fixed matrix)</DisplayString>
+ <Expand>
+ <Synthetic Name="[row 0]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 0]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[2]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 1]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 1]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[3]})</DisplayString>
+ </Synthetic>
+ </Expand>
+ </Type>
+
+ <!-- 3 x 3 Matrix -->
+ <Type Name="Eigen::Matrix<*,3,3,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,3,3,*,*,*>"/>
+ <DisplayString>[3, 3] (fixed matrix)</DisplayString>
+ <Expand>
+ <Synthetic Name="[row 0]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 0]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[3]}, {m_storage.m_data.array[6]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 1]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[3]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[5]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 1]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[7]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 2]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[6]}, {m_storage.m_data.array[7]}, {m_storage.m_data.array[8]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 2]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[8]})</DisplayString>
+ </Synthetic>
+ </Expand>
+ </Type>
+
+ <!-- 4 x 4 Matrix -->
+ <Type Name="Eigen::Matrix<*,4,4,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,4,4,*,*,*>"/>
+ <DisplayString>[4, 4] (fixed matrix)</DisplayString>
+ <Expand>
+ <Synthetic Name="[row 0]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 0]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[8]}, {m_storage.m_data.array[12]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 1]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[4]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[6]}, {m_storage.m_data.array[7]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 1]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[9]}, {m_storage.m_data.array[13]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 2]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[8]}, {m_storage.m_data.array[9]}, {m_storage.m_data.array[10]}, {m_storage.m_data.array[11]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 2]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[6]}, {m_storage.m_data.array[10]}, {m_storage.m_data.array[14]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 3]" Condition="Flags%2">
+ <DisplayString>({m_storage.m_data.array[12]}, {m_storage.m_data.array[13]}, {m_storage.m_data.array[14]}, {m_storage.m_data.array[15]})</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[row 3]" Condition="!(Flags%2)">
+ <DisplayString>({m_storage.m_data.array[3]}, {m_storage.m_data.array[7]}, {m_storage.m_data.array[11]}, {m_storage.m_data.array[15]})</DisplayString>
+ </Synthetic>
+ </Expand>
+ </Type>
+
+ <!-- Dynamic x Dynamic Matrix -->
+ <Type Name="Eigen::Matrix<*,-1,-1,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,-1,-1,*,*,*>"/>
+ <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
+ <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}, {m_storage.m_cols}] (dynamic matrix)</DisplayString>
+ <Expand>
+ <ArrayItems Condition="Flags%2"> <!-- row major layout -->
+ <Rank>2</Rank>
+ <Size>$i==0 ? m_storage.m_rows : m_storage.m_cols</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
+ <Direction>Backward</Direction>
+ <Rank>2</Rank>
+ <Size>$i==0 ? m_storage.m_rows : m_storage.m_cols</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <!-- Fixed x Dynamic Matrix -->
+ <Type Name="Eigen::Matrix<*,*,-1,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,*,-1,*,*,*>"/>
+ <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
+ <DisplayString Condition="m_storage.m_data != 0">[{$T2}, {m_storage.m_cols}] (dynamic column matrix)</DisplayString>
+ <Expand>
+ <ArrayItems Condition="Flags%2"> <!-- row major layout -->
+ <Rank>2</Rank>
+ <Size>$i==0 ? $T2 : m_storage.m_cols</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
+ <Direction>Backward</Direction>
+ <Rank>2</Rank>
+ <Size>$i==0 ? $T2 : m_storage.m_cols</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <!-- Dynamic x Fixed Matrix -->
+ <Type Name="Eigen::Matrix<*,-1,*,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,-1,*,*,*,*>"/>
+ <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
+ <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}, {$T2}] (dynamic row matrix)</DisplayString>
+ <Expand>
+ <ArrayItems Condition="Flags%2"> <!-- row major layout -->
+ <Rank>2</Rank>
+ <Size>$i==0 ? m_storage.m_rows : $T2</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ <ArrayItems Condition="!(Flags%2)"> <!-- column major layout -->
+ <Direction>Backward</Direction>
+ <Rank>2</Rank>
+ <Size>$i==0 ? m_storage.m_rows : $T2</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <!-- Dynamic Column Vector -->
+ <Type Name="Eigen::Matrix<*,1,-1,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,1,-1,*,*,*>"/>
+ <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
+ <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_cols}] (dynamic column vector)</DisplayString>
+ <Expand>
+ <Item Name="[size]">m_storage.m_cols</Item>
+ <ArrayItems>
+ <Size>m_storage.m_cols</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <!-- Dynamic Row Vector -->
+ <Type Name="Eigen::Matrix<*,-1,1,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,-1,1,*,*,*>"/>
+ <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString>
+ <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}] (dynamic row vector)</DisplayString>
+ <Expand>
+ <Item Name="[size]">m_storage.m_rows</Item>
+ <ArrayItems>
+ <Size>m_storage.m_rows</Size>
+ <ValuePointer>m_storage.m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <!-- Fixed Vector -->
+ <Type Name="Eigen::Matrix<*,1,1,*,*,*>">
+ <AlternativeType Name="Eigen::Array<*,1,1,*,*,*>"/>
+ <DisplayString>[1] ({m_storage.m_data.array[0]})</DisplayString>
+ <Expand>
+ <Item Name="[x]">m_storage.m_data.array[0]</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="Eigen::Matrix<*,2,1,*,*,*>">
+ <AlternativeType Name="Eigen::Matrix<*,1,2,*,*,*>"/>
+ <AlternativeType Name="Eigen::Array<*,2,1,*,*,*>"/>
+ <AlternativeType Name="Eigen::Array<*,1,2,*,*,*>"/>
+ <DisplayString>[2] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]})</DisplayString>
+ <Expand>
+ <Item Name="[x]">m_storage.m_data.array[0]</Item>
+ <Item Name="[y]">m_storage.m_data.array[1]</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="Eigen::Matrix<*,3,1,*,*,*>">
+ <AlternativeType Name="Eigen::Matrix<*,1,3,*,*,*>"/>
+ <AlternativeType Name="Eigen::Array<*,3,1,*,*,*>"/>
+ <AlternativeType Name="Eigen::Array<*,1,3,*,*,*>"/>
+ <DisplayString>[3] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]})</DisplayString>
+ <Expand>
+ <Item Name="[x]">m_storage.m_data.array[0]</Item>
+ <Item Name="[y]">m_storage.m_data.array[1]</Item>
+ <Item Name="[z]">m_storage.m_data.array[2]</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="Eigen::Matrix<*,4,1,*,*,*>">
+ <AlternativeType Name="Eigen::Matrix<*,1,4,*,*,*>"/>
+ <AlternativeType Name="Eigen::Array<*,4,1,*,*,*>"/>
+ <AlternativeType Name="Eigen::Array<*,1,4,*,*,*>"/>
+ <DisplayString>[4] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString>
+ <Expand>
+ <Item Name="[x]">m_storage.m_data.array[0]</Item>
+ <Item Name="[y]">m_storage.m_data.array[1]</Item>
+ <Item Name="[z]">m_storage.m_data.array[2]</Item>
+ <Item Name="[w]">m_storage.m_data.array[3]</Item>
+ </Expand>
+ </Type>
+
+</AutoVisualizer>
diff --git a/debug/msvc/eigen_autoexp_part.dat b/debug/msvc/eigen_autoexp_part.dat
index 35ef580..273c10d 100644
--- a/debug/msvc/eigen_autoexp_part.dat
+++ b/debug/msvc/eigen_autoexp_part.dat
@@ -1,295 +1,295 @@
-; ***************************************************************
-; * Eigen Visualizer
-; *
-; * Author: Hauke Heibel <hauke.heibel@gmail.com>
-; *
-; * Support the enhanced debugging of the following Eigen
-; * types (*: any, +:fixed dimension) :
-; *
-; * - Eigen::Matrix<*,4,1,*,*,*> and Eigen::Matrix<*,1,4,*,*,*>
-; * - Eigen::Matrix<*,3,1,*,*,*> and Eigen::Matrix<*,1,3,*,*,*>
-; * - Eigen::Matrix<*,2,1,*,*,*> and Eigen::Matrix<*,1,2,*,*,*>
-; * - Eigen::Matrix<*,-1,-1,*,*,*>
-; * - Eigen::Matrix<*,+,-1,*,*,*>
-; * - Eigen::Matrix<*,-1,+,*,*,*>
-; * - Eigen::Matrix<*,+,+,*,*,*>
-; *
-; * Matrices are displayed properly independently of the memory
-; * alignment (RowMajor vs. ColMajor).
-; *
-; * This file is distributed WITHOUT ANY WARRANTY. Please ensure
-; * that your original autoexp.dat file is copied to a safe
-; * place before proceeding with its modification.
-; ***************************************************************
-
-[Visualizer]
-
-; Fixed size 4-vectors
-Eigen::Matrix<*,4,1,*,*,*>|Eigen::Matrix<*,1,4,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- x : ($c.m_storage.m_data.array)[0],
- y : ($c.m_storage.m_data.array)[1],
- z : ($c.m_storage.m_data.array)[2],
- w : ($c.m_storage.m_data.array)[3]
- )
- )
-
- preview
- (
- #(
- "[",
- 4,
- "](",
- #array(expr: $e.m_storage.m_data.array[$i], size: 4),
- ")"
- )
- )
-}
-
-; Fixed size 3-vectors
-Eigen::Matrix<*,3,1,*,*,*>|Eigen::Matrix<*,1,3,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- x : ($c.m_storage.m_data.array)[0],
- y : ($c.m_storage.m_data.array)[1],
- z : ($c.m_storage.m_data.array)[2]
- )
- )
-
- preview
- (
- #(
- "[",
- 3,
- "](",
- #array(expr: $e.m_storage.m_data.array[$i], size: 3),
- ")"
- )
- )
-}
-
-; Fixed size 2-vectors
-Eigen::Matrix<*,2,1,*,*,*>|Eigen::Matrix<*,1,2,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- x : ($c.m_storage.m_data.array)[0],
- y : ($c.m_storage.m_data.array)[1]
- )
- )
-
- preview
- (
- #(
- "[",
- 2,
- "](",
- #array(expr: $e.m_storage.m_data.array[$i], size: 2),
- ")"
- )
- )
-}
-
-; Fixed size 1-vectors
-Eigen::Matrix<*,1,1,*,*,*>|Eigen::Matrix<*,1,1,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- x : ($c.m_storage.m_data.array)[0]
- )
- )
-
- preview
- (
- #(
- "[",
- 1,
- "](",
- #array(expr: $e.m_storage.m_data.array[$i], size: 1),
- ")"
- )
- )
-}
-
-; Dynamic matrices (ColMajor and RowMajor support)
-Eigen::Matrix<*,-1,-1,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- rows: $c.m_storage.m_rows,
- cols: $c.m_storage.m_cols,
- ; Check for RowMajorBit
- #if ($c.Flags & 0x1) (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.m_storage.m_cols + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)],
- size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols
- )
- ) #else (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data)[$i],
- size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols
- )
- )
- )
- )
-
- preview
- (
- #(
- "[",
- $c.m_storage.m_rows,
- ",",
- $c.m_storage.m_cols,
- "](",
- #array(
- expr : [($c.m_storage.m_data)[$i],g],
- size : $c.m_storage.m_rows*$c.m_storage.m_cols
- ),
- ")"
- )
- )
-}
-
-; Fixed rows, dynamic columns matrix (ColMajor and RowMajor support)
-Eigen::Matrix<*,*,-1,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- rows: $c.RowsAtCompileTime,
- cols: $c.m_storage.m_cols,
- ; Check for RowMajorBit
- #if ($c.Flags & 0x1) (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data)[($i % $c.RowsAtCompileTime)*$c.m_storage.m_cols + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)],
- size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols
- )
- ) #else (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data)[$i],
- size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols
- )
- )
- )
- )
-
- preview
- (
- #(
- "[",
- $c.RowsAtCompileTime,
- ",",
- $c.m_storage.m_cols,
- "](",
- #array(
- expr : [($c.m_storage.m_data)[$i],g],
- size : $c.RowsAtCompileTime*$c.m_storage.m_cols
- ),
- ")"
- )
- )
-}
-
-; Dynamic rows, fixed columns matrix (ColMajor and RowMajor support)
-Eigen::Matrix<*,-1,*,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- rows: $c.m_storage.m_rows,
- cols: $c.ColsAtCompileTime,
- ; Check for RowMajorBit
- #if ($c.Flags & 0x1) (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.ColsAtCompileTime + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)],
- size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime
- )
- ) #else (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data)[$i],
- size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime
- )
- )
- )
- )
-
- preview
- (
- #(
- "[",
- $c.m_storage.m_rows,
- ",",
- $c.ColsAtCompileTime,
- "](",
- #array(
- expr : [($c.m_storage.m_data)[$i],g],
- size : $c.m_storage.m_rows*$c.ColsAtCompileTime
- ),
- ")"
- )
- )
-}
-
-; Fixed size matrix (ColMajor and RowMajor support)
-Eigen::Matrix<*,*,*,*,*,*>{
- children
- (
- #(
- [internals]: [$c,!],
- rows: $c.RowsAtCompileTime,
- cols: $c.ColsAtCompileTime,
- ; Check for RowMajorBit
- #if ($c.Flags & 0x1) (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data.array)[($i % $c.RowsAtCompileTime)*$c.ColsAtCompileTime + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)],
- size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime
- )
- ) #else (
- #array(
- rank: 2,
- base: 0,
- expr: ($c.m_storage.m_data.array)[$i],
- size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime
- )
- )
- )
- )
-
- preview
- (
- #(
- "[",
- $c.RowsAtCompileTime,
- ",",
- $c.ColsAtCompileTime,
- "](",
- #array(
- expr : [($c.m_storage.m_data.array)[$i],g],
- size : $c.RowsAtCompileTime*$c.ColsAtCompileTime
- ),
- ")"
- )
- )
-}
+; ***************************************************************
+; * Eigen Visualizer
+; *
+; * Author: Hauke Heibel <hauke.heibel@gmail.com>
+; *
+; * Support the enhanced debugging of the following Eigen
+; * types (*: any, +:fixed dimension) :
+; *
+; * - Eigen::Matrix<*,4,1,*,*,*> and Eigen::Matrix<*,1,4,*,*,*>
+; * - Eigen::Matrix<*,3,1,*,*,*> and Eigen::Matrix<*,1,3,*,*,*>
+; * - Eigen::Matrix<*,2,1,*,*,*> and Eigen::Matrix<*,1,2,*,*,*>
+; * - Eigen::Matrix<*,-1,-1,*,*,*>
+; * - Eigen::Matrix<*,+,-1,*,*,*>
+; * - Eigen::Matrix<*,-1,+,*,*,*>
+; * - Eigen::Matrix<*,+,+,*,*,*>
+; *
+; * Matrices are displayed properly independently of the memory
+; * alignment (RowMajor vs. ColMajor).
+; *
+; * This file is distributed WITHOUT ANY WARRANTY. Please ensure
+; * that your original autoexp.dat file is copied to a safe
+; * place before proceeding with its modification.
+; ***************************************************************
+
+[Visualizer]
+
+; Fixed size 4-vectors
+Eigen::Matrix<*,4,1,*,*,*>|Eigen::Matrix<*,1,4,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0],
+ y : ($c.m_storage.m_data.array)[1],
+ z : ($c.m_storage.m_data.array)[2],
+ w : ($c.m_storage.m_data.array)[3]
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ 4,
+ "](",
+ #array(expr: $e.m_storage.m_data.array[$i], size: 4),
+ ")"
+ )
+ )
+}
+
+; Fixed size 3-vectors
+Eigen::Matrix<*,3,1,*,*,*>|Eigen::Matrix<*,1,3,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0],
+ y : ($c.m_storage.m_data.array)[1],
+ z : ($c.m_storage.m_data.array)[2]
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ 3,
+ "](",
+ #array(expr: $e.m_storage.m_data.array[$i], size: 3),
+ ")"
+ )
+ )
+}
+
+; Fixed size 2-vectors
+Eigen::Matrix<*,2,1,*,*,*>|Eigen::Matrix<*,1,2,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0],
+ y : ($c.m_storage.m_data.array)[1]
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ 2,
+ "](",
+ #array(expr: $e.m_storage.m_data.array[$i], size: 2),
+ ")"
+ )
+ )
+}
+
+; Fixed size 1-vectors
+Eigen::Matrix<*,1,1,*,*,*>|Eigen::Matrix<*,1,1,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ x : ($c.m_storage.m_data.array)[0]
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ 1,
+ "](",
+ #array(expr: $e.m_storage.m_data.array[$i], size: 1),
+ ")"
+ )
+ )
+}
+
+; Dynamic matrices (ColMajor and RowMajor support)
+Eigen::Matrix<*,-1,-1,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.m_storage.m_rows,
+ cols: $c.m_storage.m_cols,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.m_storage.m_cols + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[$i],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.m_storage.m_rows,
+ ",",
+ $c.m_storage.m_cols,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data)[$i],g],
+ size : $c.m_storage.m_rows*$c.m_storage.m_cols
+ ),
+ ")"
+ )
+ )
+}
+
+; Fixed rows, dynamic columns matrix (ColMajor and RowMajor support)
+Eigen::Matrix<*,*,-1,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.RowsAtCompileTime,
+ cols: $c.m_storage.m_cols,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[($i % $c.RowsAtCompileTime)*$c.m_storage.m_cols + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[$i],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.RowsAtCompileTime,
+ ",",
+ $c.m_storage.m_cols,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data)[$i],g],
+ size : $c.RowsAtCompileTime*$c.m_storage.m_cols
+ ),
+ ")"
+ )
+ )
+}
+
+; Dynamic rows, fixed columns matrix (ColMajor and RowMajor support)
+Eigen::Matrix<*,-1,*,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.m_storage.m_rows,
+ cols: $c.ColsAtCompileTime,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.ColsAtCompileTime + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data)[$i],
+ size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.m_storage.m_rows,
+ ",",
+ $c.ColsAtCompileTime,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data)[$i],g],
+ size : $c.m_storage.m_rows*$c.ColsAtCompileTime
+ ),
+ ")"
+ )
+ )
+}
+
+; Fixed size matrix (ColMajor and RowMajor support)
+Eigen::Matrix<*,*,*,*,*,*>{
+ children
+ (
+ #(
+ [internals]: [$c,!],
+ rows: $c.RowsAtCompileTime,
+ cols: $c.ColsAtCompileTime,
+ ; Check for RowMajorBit
+ #if ($c.Flags & 0x1) (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data.array)[($i % $c.RowsAtCompileTime)*$c.ColsAtCompileTime + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime
+ )
+ ) #else (
+ #array(
+ rank: 2,
+ base: 0,
+ expr: ($c.m_storage.m_data.array)[$i],
+ size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime
+ )
+ )
+ )
+ )
+
+ preview
+ (
+ #(
+ "[",
+ $c.RowsAtCompileTime,
+ ",",
+ $c.ColsAtCompileTime,
+ "](",
+ #array(
+ expr : [($c.m_storage.m_data.array)[$i],g],
+ size : $c.RowsAtCompileTime*$c.ColsAtCompileTime
+ ),
+ ")"
+ )
+ )
+}
diff --git a/doc/TutorialSlicingIndexing.dox b/doc/TutorialSlicingIndexing.dox
index 2fad692..8b067df 100644
--- a/doc/TutorialSlicingIndexing.dox
+++ b/doc/TutorialSlicingIndexing.dox
@@ -130,12 +130,12 @@
</tr>
<tr>
<td>Bottom-right corner of A of size \c m times \c n</td>
- <td>\code v(lastN(m), lastN(n)) \endcode</td>
+ <td>\code A(lastN(m), lastN(n)) \endcode</td>
<td>\code A.bottomRightCorner(m,n) \endcode</td>
</tr>
<tr>
<td>Bottom-right corner of A of size \c m times \c n</td>
- <td>\code v(lastN(m), lastN(n)) \endcode</td>
+ <td>\code A(lastN(m), lastN(n)) \endcode</td>
<td>\code A.bottomRightCorner(m,n) \endcode</td>
</tr>
<tr>
diff --git a/doc/TutorialSparse.dox b/doc/TutorialSparse.dox
index 77a08da..a00bacd 100644
--- a/doc/TutorialSparse.dox
+++ b/doc/TutorialSparse.dox
@@ -44,8 +44,8 @@
and one of its possible sparse, \b column \b major representation:
<table class="manual">
-<tr><td>Values:</td> <td>22</td><td>7</td><td>_</td><td>3</td><td>5</td><td>14</td><td>_</td><td>_</td><td>1</td><td>_</td><td>17</td><td>8</td></tr>
-<tr><td>InnerIndices:</td> <td> 1</td><td>2</td><td>_</td><td>0</td><td>2</td><td> 4</td><td>_</td><td>_</td><td>2</td><td>_</td><td> 1</td><td>4</td></tr>
+<tr><td>Values:</td> <td>22</td><td>7</td><td>_</td><td>3</td><td>5</td><td>_</td><td>14</td><td>_</td><td>1</td><td>_</td><td>17</td><td>8</td></tr>
+<tr><td>InnerIndices:</td> <td> 1</td><td>2</td><td>_</td><td>0</td><td>2</td><td>_</td><td>4</td><td>_</td><td>2</td><td>_</td><td> 1</td><td>4</td></tr>
</table>
<table class="manual">
<tr><td>OuterStarts:</td><td>0</td><td>3</td><td>5</td><td>8</td><td>10</td><td>\em 12 </td></tr>
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9d7893a..7d6f978 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -42,45 +42,53 @@
set(SPARSE_LIBS " ")
find_package(CHOLMOD)
-if(CHOLMOD_FOUND)
+if(CHOLMOD_FOUND AND EIGEN_BUILD_BLAS AND EIGEN_BUILD_LAPACK)
add_definitions("-DEIGEN_CHOLMOD_SUPPORT")
include_directories(${CHOLMOD_INCLUDES})
set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES})
set(CHOLMOD_ALL_LIBS ${CHOLMOD_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES})
ei_add_property(EIGEN_TESTED_BACKENDS "CHOLMOD, ")
+
+ ei_add_test(cholmod_support "" "${CHOLMOD_ALL_LIBS}")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "CHOLMOD, ")
endif()
find_package(UMFPACK)
-if(UMFPACK_FOUND)
+if(UMFPACK_FOUND AND EIGEN_BUILD_BLAS)
add_definitions("-DEIGEN_UMFPACK_SUPPORT")
include_directories(${UMFPACK_INCLUDES})
set(SPARSE_LIBS ${SPARSE_LIBS} ${UMFPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
set(UMFPACK_ALL_LIBS ${UMFPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
ei_add_property(EIGEN_TESTED_BACKENDS "UMFPACK, ")
+
+ ei_add_test(umfpack_support "" "${UMFPACK_ALL_LIBS}")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "UMFPACK, ")
endif()
find_package(KLU)
-if(KLU_FOUND)
+if(KLU_FOUND AND EIGEN_BUILD_BLAS)
add_definitions("-DEIGEN_KLU_SUPPORT")
include_directories(${KLU_INCLUDES})
set(SPARSE_LIBS ${SPARSE_LIBS} ${KLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
set(KLU_ALL_LIBS ${KLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
ei_add_property(EIGEN_TESTED_BACKENDS "KLU, ")
+
+ ei_add_test(klu_support "" "${KLU_ALL_LIBS}")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "KLU, ")
endif()
find_package(SuperLU 4.0)
-if(SuperLU_FOUND)
+if(SuperLU_FOUND AND EIGEN_BUILD_BLAS)
add_definitions("-DEIGEN_SUPERLU_SUPPORT")
include_directories(${SUPERLU_INCLUDES})
set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
set(SUPERLU_ALL_LIBS ${SUPERLU_LIBRARIES} ${EIGEN_BLAS_LIBRARIES})
ei_add_property(EIGEN_TESTED_BACKENDS "SuperLU, ")
+
+ ei_add_test(superlu_support "" "${SUPERLU_ALL_LIBS}")
else()
ei_add_property(EIGEN_MISSING_BACKENDS "SuperLU, ")
endif()
@@ -124,7 +132,7 @@
endif()
find_package(SPQR)
-if(SPQR_FOUND AND CHOLMOD_FOUND AND (EIGEN_Fortran_COMPILER_WORKS OR LAPACK_FOUND) )
+if(SPQR_FOUND AND CHOLMOD_FOUND AND EIGEN_BUILD_BLAS AND EIGEN_BUILD_LAPACK AND (EIGEN_Fortran_COMPILER_WORKS OR LAPACK_FOUND) )
add_definitions("-DEIGEN_SPQR_SUPPORT")
include_directories(${SPQR_INCLUDES})
set(SPQR_ALL_LIBS ${SPQR_LIBRARIES} ${CHOLMOD_LIBRARIES} ${EIGEN_LAPACK_LIBRARIES} ${EIGEN_BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
@@ -178,6 +186,7 @@
ei_add_test(vectorization_logic)
ei_add_test(basicstuff)
ei_add_test(constructor)
+ei_add_test(compile_time_evaluation)
ei_add_test(linearstructure)
ei_add_test(integer_types)
ei_add_test(unalignedcount)
@@ -198,6 +207,7 @@
ei_add_test(product_large)
ei_add_test(product_extra)
ei_add_test(diagonalmatrices)
+ei_add_test(skew_symmetric_matrix3)
ei_add_test(adjoint)
ei_add_test(diagonal)
ei_add_test(miscmatrices)
@@ -323,22 +333,6 @@
ei_add_test(qtvector "" "${QT_QTCORE_LIBRARY}")
endif()
-if(UMFPACK_FOUND)
- ei_add_test(umfpack_support "" "${UMFPACK_ALL_LIBS}")
-endif()
-
-if(KLU_FOUND OR SuiteSparse_FOUND)
- ei_add_test(klu_support "" "${KLU_ALL_LIBS}")
-endif()
-
-if(SUPERLU_FOUND)
- ei_add_test(superlu_support "" "${SUPERLU_ALL_LIBS}")
-endif()
-
-if(CHOLMOD_FOUND)
- ei_add_test(cholmod_support "" "${CHOLMOD_ALL_LIBS}")
-endif()
-
if(PARDISO_FOUND)
ei_add_test(pardiso_support "" "${PARDISO_ALL_LIBS}")
endif()
@@ -347,7 +341,7 @@
ei_add_test(pastix_support "" "${PASTIX_ALL_LIBS}")
endif()
-if(SPQR_FOUND AND CHOLMOD_FOUND)
+if(SPQR_FOUND AND CHOLMOD_FOUND AND EIGEN_BUILD_BLAS AND EIGEN_BUILD_LAPACK)
ei_add_test(spqr_support "" "${SPQR_ALL_LIBS}")
endif()
diff --git a/test/array_cwise.cpp b/test/array_cwise.cpp
index 298351e..319eba3 100644
--- a/test/array_cwise.cpp
+++ b/test/array_cwise.cpp
@@ -72,16 +72,181 @@
for (int j = 0; j < num_cases; ++j) {
Scalar e = static_cast<Scalar>(std::pow(x(i,j), y(i,j)));
Scalar a = actual(i, j);
- bool fail = !(a==e) && !internal::isApprox(a, e, tol) && !((numext::isnan)(a) && (numext::isnan)(e));
- all_pass &= !fail;
- if (fail) {
+ bool success = (a==e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) || ((numext::isnan)(a) && (numext::isnan)(e));
+ all_pass &= success;
+ if (!success) {
std::cout << "pow(" << x(i,j) << "," << y(i,j) << ") = " << a << " != " << e << std::endl;
}
}
}
+
+ typedef typename internal::make_integer<Scalar>::type Int_t;
+
+ // ensure both vectorized and non-vectorized paths taken
+ Index test_size = 2 * internal::packet_traits<Scalar>::size + 1;
+
+ Array<Scalar, Dynamic, 1> eigenPow(test_size);
+ for (int i = 0; i < num_cases; ++i) {
+ Array<Scalar, Dynamic, 1> bases = x.col(i);
+ for (Scalar abs_exponent : abs_vals){
+ for (Scalar exponent : {-abs_exponent, abs_exponent}){
+ // test floating point exponent code path
+ eigenPow.setZero();
+ eigenPow = bases.pow(exponent);
+ for (int j = 0; j < num_repeats; j++){
+ Scalar e = static_cast<Scalar>(std::pow(bases(j), exponent));
+ Scalar a = eigenPow(j);
+ bool success = (a == e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) || ((numext::isnan)(a) && (numext::isnan)(e));
+ all_pass &= success;
+ if (!success) {
+ std::cout << "pow(" << x(i, j) << "," << y(i, j) << ") = " << a << " != " << e << std::endl;
+ }
+ }
+ // test integer exponent code path
+ bool exponent_is_integer = (numext::isfinite)(exponent) && (numext::round(exponent) == exponent) && (numext::abs(exponent) < static_cast<Scalar>(NumTraits<Int_t>::highest()));
+ if (exponent_is_integer)
+ {
+ Int_t exponent_as_int = static_cast<Int_t>(exponent);
+ eigenPow.setZero();
+ eigenPow = bases.pow(exponent_as_int);
+ for (int j = 0; j < num_repeats; j++){
+ Scalar e = static_cast<Scalar>(std::pow(bases(j), exponent));
+ Scalar a = eigenPow(j);
+ bool success = (a == e) || ((numext::isfinite)(e) && internal::isApprox(a, e, tol)) || ((numext::isnan)(a) && (numext::isnan)(e));
+ all_pass &= success;
+ if (!success) {
+ std::cout << "pow(" << x(i, j) << "," << y(i, j) << ") = " << a << " != " << e << std::endl;
+ }
+ }
+ }
+ }
+ }
+ }
+
VERIFY(all_pass);
}
+template <typename Scalar, typename ScalarExponent>
+Scalar calc_overflow_threshold(const ScalarExponent exponent) {
+ EIGEN_USING_STD(exp2);
+ EIGEN_USING_STD(log2);
+ EIGEN_STATIC_ASSERT((NumTraits<Scalar>::digits() < 2 * NumTraits<double>::digits()), BASE_TYPE_IS_TOO_BIG);
+
+ if (exponent < 2)
+ return NumTraits<Scalar>::highest();
+ else {
+ // base^e <= highest ==> base <= 2^(log2(highest)/e)
+ // For floating-point types, consider the bound for integer values that can be reproduced exactly = 2 ^ digits
+ double highest_bits = numext::mini(static_cast<double>(NumTraits<Scalar>::digits()),
+ static_cast<double>(log2(NumTraits<Scalar>::highest())));
+ return static_cast<Scalar>(
+ numext::floor(exp2(highest_bits / static_cast<double>(exponent))));
+ }
+}
+
+template <typename Base, typename Exponent, bool ExpIsInteger = NumTraits<Exponent>::IsInteger>
+struct ref_pow {
+ static Base run(Base base, Exponent exponent) {
+ EIGEN_USING_STD(pow);
+ return pow(base, static_cast<Base>(exponent));
+ }
+};
+
+template <typename Base, typename Exponent>
+struct ref_pow<Base, Exponent, true> {
+ static Base run(Base base, Exponent exponent) {
+ EIGEN_USING_STD(pow);
+ return pow(base, exponent);
+ }
+};
+
+template <typename Base, typename Exponent>
+void test_exponent(Exponent exponent) {
+ const Base max_abs_bases = static_cast<Base>(10000);
+ // avoid integer overflow in Base type
+ Base threshold = calc_overflow_threshold<Base, Exponent>(numext::abs(exponent));
+ // avoid numbers that can't be verified with std::pow
+ double double_threshold = calc_overflow_threshold<double, Exponent>(numext::abs(exponent));
+ // use the lesser of these two thresholds
+ Base testing_threshold =
+ static_cast<double>(threshold) < double_threshold ? threshold : static_cast<Base>(double_threshold);
+ // test both vectorized and non-vectorized code paths
+ const Index array_size = 2 * internal::packet_traits<Base>::size + 1;
+
+ Base max_base = numext::mini(testing_threshold, max_abs_bases);
+ Base min_base = NumTraits<Base>::IsSigned ? -max_base : Base(0);
+
+ ArrayX<Base> x(array_size), y(array_size);
+ bool all_pass = true;
+ for (Base base = min_base; base <= max_base; base++) {
+ if (exponent < 0 && base == 0) continue;
+ x.setConstant(base);
+ y = x.pow(exponent);
+ for (Base a : y) {
+ Base e = ref_pow<Base, Exponent>::run(base, exponent);
+ bool pass = (a == e);
+ if (!NumTraits<Base>::IsInteger) {
+ pass = pass || (((numext::isfinite)(e) && internal::isApprox(a, e)) ||
+ ((numext::isnan)(a) && (numext::isnan)(e)));
+ }
+ all_pass &= pass;
+ if (!pass) {
+ std::cout << "pow(" << base << "," << exponent << ") = " << a << " != " << e << std::endl;
+ }
+ }
+ }
+ VERIFY(all_pass);
+}
+
+template <typename Base, typename Exponent>
+void unary_pow_test() {
+ Exponent max_exponent = static_cast<Exponent>(NumTraits<Base>::digits());
+ Exponent min_exponent = static_cast<Exponent>(NumTraits<Exponent>::IsSigned ? -max_exponent : 0);
+
+ for (Exponent exponent = min_exponent; exponent < max_exponent; ++exponent) {
+ test_exponent<Base, Exponent>(exponent);
+ }
+};
+
+void mixed_pow_test() {
+ // The following cases will test promoting a smaller exponent type
+ // to a wider base type.
+ unary_pow_test<double, int>();
+ unary_pow_test<double, float>();
+ unary_pow_test<float, half>();
+ unary_pow_test<double, half>();
+ unary_pow_test<float, bfloat16>();
+ unary_pow_test<double, bfloat16>();
+
+ // Although in the following cases the exponent cannot be represented exactly
+ // in the base type, we do not perform a conversion, but implement
+ // the operation using repeated squaring.
+ unary_pow_test<float, int>();
+ unary_pow_test<double, long long>();
+
+ // The following cases will test promoting a wider exponent type
+ // to a narrower base type. This should compile but generate a
+ // deprecation warning:
+ unary_pow_test<float, double>();
+}
+
+void int_pow_test() {
+ unary_pow_test<int, int>();
+ unary_pow_test<unsigned int, unsigned int>();
+ unary_pow_test<long long, long long>();
+ unary_pow_test<unsigned long long, unsigned long long>();
+
+ // Although in the following cases the exponent cannot be represented exactly
+ // in the base type, we do not perform a conversion, but implement the
+ // operation using repeated squaring.
+ unary_pow_test<long long, int>();
+ unary_pow_test<int, unsigned int>();
+ unary_pow_test<unsigned int, int>();
+ unary_pow_test<long long, unsigned long long>();
+ unary_pow_test<unsigned long long, long long>();
+ unary_pow_test<long long, int>();
+}
+
template<typename ArrayType> void array(const ArrayType& m)
{
typedef typename ArrayType::Scalar Scalar;
@@ -92,8 +257,20 @@
Index rows = m.rows();
Index cols = m.cols();
- ArrayType m1 = ArrayType::Random(rows, cols),
- m2 = ArrayType::Random(rows, cols),
+ ArrayType m1 = ArrayType::Random(rows, cols);
+ if (NumTraits<RealScalar>::IsInteger && NumTraits<RealScalar>::IsSigned
+ && !NumTraits<Scalar>::IsComplex) {
+ // Here we cap the size of the values in m1 such that pow(3)/cube()
+ // doesn't overflow and result in undefined behavior. Notice that because
+ // pow(int, int) promotes its inputs and output to double (according to
+ // the C++ standard), we have to make sure that the result fits in 53 bits
+ // for int64,
+ RealScalar max_val =
+ numext::mini(RealScalar(std::cbrt(NumTraits<RealScalar>::highest())),
+ RealScalar(std::cbrt(1LL << 53)))/2;
+ m1.array() = (m1.abs().array() <= max_val).select(m1, Scalar(max_val));
+ }
+ ArrayType m2 = ArrayType::Random(rows, cols),
m3(rows, cols);
ArrayType m4 = m1; // copy constructor
VERIFY_IS_APPROX(m1, m4);
@@ -119,23 +296,23 @@
VERIFY_IS_APPROX(m3, m1 - s1);
// scalar operators via Maps
- m3 = m1;
- ArrayType::Map(m1.data(), m1.rows(), m1.cols()) -= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
- VERIFY_IS_APPROX(m1, m3 - m2);
+ m3 = m1; m4 = m1;
+ ArrayType::Map(m4.data(), m4.rows(), m4.cols()) -= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
+ VERIFY_IS_APPROX(m4, m3 - m2);
- m3 = m1;
- ArrayType::Map(m1.data(), m1.rows(), m1.cols()) += ArrayType::Map(m2.data(), m2.rows(), m2.cols());
- VERIFY_IS_APPROX(m1, m3 + m2);
+ m3 = m1; m4 = m1;
+ ArrayType::Map(m4.data(), m4.rows(), m4.cols()) += ArrayType::Map(m2.data(), m2.rows(), m2.cols());
+ VERIFY_IS_APPROX(m4, m3 + m2);
- m3 = m1;
- ArrayType::Map(m1.data(), m1.rows(), m1.cols()) *= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
- VERIFY_IS_APPROX(m1, m3 * m2);
+ m3 = m1; m4 = m1;
+ ArrayType::Map(m4.data(), m4.rows(), m4.cols()) *= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
+ VERIFY_IS_APPROX(m4, m3 * m2);
- m3 = m1;
+ m3 = m1; m4 = m1;
m2 = ArrayType::Random(rows,cols);
m2 = (m2==0).select(1,m2);
- ArrayType::Map(m1.data(), m1.rows(), m1.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
- VERIFY_IS_APPROX(m1, m3 / m2);
+ ArrayType::Map(m4.data(), m4.rows(), m4.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols());
+ VERIFY_IS_APPROX(m4, m3 / m2);
// reductions
VERIFY_IS_APPROX(m1.abs().colwise().sum().sum(), m1.abs().sum());
@@ -461,6 +638,7 @@
VERIFY_IS_APPROX(m3, m1);
}
+
template<typename ArrayType> void array_complex(const ArrayType& m)
{
typedef typename ArrayType::Scalar Scalar;
@@ -694,6 +872,11 @@
CALL_SUBTEST_4( array_complex(ArrayXXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );
}
+ for(int i = 0; i < g_repeat; i++) {
+ CALL_SUBTEST_6( int_pow_test() );
+ CALL_SUBTEST_7( mixed_pow_test() );
+ }
+
VERIFY((internal::is_same< internal::global_math_functions_filtering_base<int>::type, int >::value));
VERIFY((internal::is_same< internal::global_math_functions_filtering_base<float>::type, float >::value));
VERIFY((internal::is_same< internal::global_math_functions_filtering_base<Array2i>::type, ArrayBase<Array2i> >::value));
diff --git a/test/compile_time_evaluation.cpp b/test/compile_time_evaluation.cpp
new file mode 100644
index 0000000..6ed0a4a
--- /dev/null
+++ b/test/compile_time_evaluation.cpp
@@ -0,0 +1,288 @@
+// main.h adds instrumentation which breaks constexpr so we do not run any tests in here,
+// this is strictly compile-time.
+#include <Eigen/Dense>
+#include <Eigen/Geometry>
+
+using namespace Eigen;
+
+template<int Blah>
+struct AssertConstexpr {};
+#define assert_constexpr(expr) \
+ do { \
+ (void) AssertConstexpr<(expr, 1)>(); \
+ } while (false)
+
+constexpr bool zeroSized()
+{
+ constexpr Matrix<float, 0, 0> m0;
+ static_assert(m0.size() == 0, "");
+
+ constexpr Matrix<float, 0, 0> m1;
+ static_assert(m0 == m1, "");
+ static_assert(!(m0 != m1), "");
+
+ constexpr Array<int, 0, 0> a0;
+ static_assert(a0.size() == 0, "");
+
+ constexpr Array<int, 0, 0> a1;
+ static_assert((a0 == a1).all(), "");
+ static_assert((a0 != a1).count() == 0, "");
+
+ constexpr Array<float, 0, 0> af;
+ static_assert(m0 == af.matrix(), "");
+ static_assert((m0.array() == af).all(), "");
+ static_assert(m0.array().matrix() == m0, "");
+
+ return true;
+}
+
+static_assert(zeroSized(), "");
+
+static constexpr double static_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+constexpr bool maps()
+{
+ constexpr Map<const Vector4d> m(static_data);
+ static_assert(m(0) == 1, "");
+ constexpr Map<const Array<double, 4, 1>> a(static_data);
+ static_assert(m == a.matrix(), "");
+ static_assert(m.size() == 4, "");
+ static_assert(a.size() == 4, "");
+ static_assert(m.rows() == 4 && m.cols() == 1, "");
+ return true;
+}
+
+static_assert(maps(), "");
+
+constexpr bool nc_maps()
+{
+ bool result = true;
+
+ double d[] = {1, 2, 3, 4};
+ Map<Vector4d> m(d);
+ result = result && (m.x() == 1 && m.y() == 2 && m.z() == 3 && m.w() == 4);
+
+ float array[3] = {};
+ auto v = Vector3f::Map(array);
+ v.fill(10);
+ result = result && (v.array() == 10).all();
+
+ return result;
+}
+
+constexpr bool blocks()
+{
+ constexpr Map<const Matrix2d> m(static_data);
+ constexpr auto block = m.block<2,1>(0, 1);
+
+ constexpr Map<const Vector2d> v(static_data + 2);
+ static_assert(block == v, "");
+
+ return true;
+}
+
+static_assert(blocks(), "");
+
+constexpr bool diagonal_row_columns()
+{
+ constexpr Map<const Matrix2d> m(static_data);
+ static_assert(m.block<2,1>(0, 1) == m.col(1), "");
+ static_assert(m.block<1,2>(1, 0) == m.row(1), "");
+ static_assert(m.diagonal()(0) == 1 && m.diagonal()(1) == 4, "");
+ return true;
+}
+
+static_assert(diagonal_row_columns(), "");
+
+static constexpr int static_data_antisym[] = {
+ 0, 1, -1,
+ -1, 0, 1,
+ 1, -1, 0 };
+
+constexpr bool transpose_unaryminus()
+{
+ constexpr Map<const Matrix<int, 3, 3>> m(static_data_antisym);
+
+ static_assert(m.transpose() == -m, "");
+ static_assert(-m.transpose() == m, "");
+ static_assert((-m).transpose() == m, "");
+
+ static_assert(m.transpose() != m, "");
+ static_assert(-m.transpose() != -m, "");
+ static_assert((-m).transpose() != -m, "");
+
+ return true;
+}
+
+static_assert(transpose_unaryminus(), "");
+
+constexpr bool reductions()
+{
+ constexpr Map<const Matrix<int, 3, 3>> m(static_data_antisym);
+ static_assert(m.size() == 9, "");
+
+ return true;
+}
+
+static_assert(reductions(), "");
+
+constexpr bool scalar_mult_div()
+{
+ constexpr Map<const Matrix2d> m(static_data);
+
+ static_assert((m * 2)(0,0) == 2, "");
+ static_assert((m / 2)(1,1) == 2*m(0,0), "");
+
+ constexpr double c = 8;
+ static_assert((m * c)(0,0) == 8, "");
+ static_assert((m.array() / c).matrix() == 1/c * m, "");
+ return true;
+}
+
+static_assert(scalar_mult_div(), "");
+
+constexpr bool constant_identity()
+{
+ static_assert(Matrix3f::Zero()(0,0) == 0, "");
+ static_assert(Matrix4d::Ones()(3,3) == 1, "");
+ static_assert(Matrix2i::Identity()(0,0) == 1 && Matrix2i::Identity()(1,0) == 0, "");
+ static_assert(Matrix<float, Dynamic, Dynamic>::Ones(2,3).size() == 6, "");
+ static_assert(Matrix<float, Dynamic, 1>::Zero(10).rows() == 10, "");
+
+ return true;
+}
+
+static_assert(constant_identity(), "");
+
+constexpr bool dynamic_basics()
+{
+ // This verifies that we only calculate the entry that we need.
+ static_assert(Matrix<double, Dynamic, Dynamic>::Identity(50000,50000).array()(25,25) == 1, "");
+
+ static_assert(Matrix4d::Identity().block(1,1,2,2)(0,1) == 0, "");
+ static_assert(MatrixXf::Identity(50,50).transpose() == MatrixXf::Identity(50, 50), "");
+
+ constexpr Map<const MatrixXi> dynMap(static_data_antisym, 3, 3);
+ constexpr Map<const Matrix3i> staticMap(static_data_antisym);
+ static_assert(dynMap == staticMap, "");
+ static_assert(dynMap.transpose() != staticMap, "");
+ // e.g. this hits an assertion at compile-time that would otherwise fail at runtime.
+ //static_assert(dynMap != staticMap.block(1,2,0,0));
+
+ return true;
+}
+
+static_assert(dynamic_basics(), "");
+
+constexpr bool sums()
+{
+ constexpr Map<const Matrix<double, 4, 4>> m(static_data);
+ constexpr auto b(m.block<2,2>(0,0)); // 1 2 5 6
+ constexpr Map<const Matrix2d> m2(static_data); // 1 2 3 4
+
+ static_assert((b + m2).col(0) == 2*Map<const Vector2d>(static_data), "");
+ static_assert(b + m2 == m2 + b, "");
+
+ static_assert((b - m2).col(0) == Vector2d::Zero(), "");
+ static_assert((b - m2).col(1) == 2*Vector2d::Ones(), "");
+
+ static_assert((2*b - m2).col(0) == b.col(0), "");
+ static_assert((b - 2*m2).col(0) == -b.col(0), "");
+
+ static_assert((b - m2 + b + m2 - 2*b) == Matrix2d::Zero(), "");
+
+ return true;
+}
+
+static_assert(sums(), "");
+
+constexpr bool unit_vectors()
+{
+ static_assert(Vector4d::UnitX()(0) == 1, "");
+ static_assert(Vector4d::UnitY()(1) == 1, "");
+ static_assert(Vector4d::UnitZ()(2) == 1, "");
+ static_assert(Vector4d::UnitW()(3) == 1, "");
+
+ static_assert(Vector4d::UnitX().dot(Vector4d::UnitX()) == 1, "");
+ static_assert(Vector4d::UnitX().dot(Vector4d::UnitY()) == 0, "");
+ static_assert((Vector4d::UnitX() + Vector4d::UnitZ()).dot(Vector4d::UnitY() + Vector4d::UnitW()) == 0, "");
+
+ return true;
+}
+
+static_assert(unit_vectors(), "");
+
+constexpr bool construct_from_other()
+{
+ return true;
+}
+
+static_assert(construct_from_other(), "");
+
+constexpr bool construct_from_values()
+{
+ return true;
+}
+
+static_assert(construct_from_values(), "");
+
+constexpr bool triangular()
+{
+ bool result = true;
+
+ return result;
+}
+
+static_assert(triangular(), "");
+
+constexpr bool nc_construct_from_values()
+{
+ bool result = true;
+
+ return result;
+}
+
+constexpr bool nc_crossproduct()
+{
+ bool result = true;
+ return result;
+}
+
+constexpr bool nc_cast()
+{
+ bool result = true;
+
+ return result;
+}
+
+constexpr bool nc_product()
+{
+ bool result = true;
+ return result;
+}
+
+static constexpr double static_data_quat[] = { 0, 1, 1, 0 };
+
+constexpr bool nc_quat_mult()
+{
+ bool result = static_data_quat[3] == 0; // Silence warning about unused with C++14
+
+ return result;
+}
+
+// Run tests that aren't explicitly constexpr.
+constexpr bool test_nc()
+{
+ assert_constexpr(nc_maps());
+ assert_constexpr(nc_construct_from_values());
+ assert_constexpr(nc_crossproduct());
+ assert_constexpr(nc_cast());
+ assert_constexpr(nc_product());
+ assert_constexpr(nc_quat_mult());
+ return true;
+}
+
+int main()
+{
+ return !test_nc();
+}
diff --git a/test/eigensolver_generalized_real.cpp b/test/eigensolver_generalized_real.cpp
index 95ed431..a0c99b1 100644
--- a/test/eigensolver_generalized_real.cpp
+++ b/test/eigensolver_generalized_real.cpp
@@ -85,6 +85,42 @@
}
}
+template<typename MatrixType>
+void generalized_eigensolver_assert() {
+ GeneralizedEigenSolver<MatrixType> eig;
+ // all raise assert if uninitialized
+ VERIFY_RAISES_ASSERT(eig.info());
+ VERIFY_RAISES_ASSERT(eig.eigenvectors());
+ VERIFY_RAISES_ASSERT(eig.eigenvalues());
+ VERIFY_RAISES_ASSERT(eig.alphas());
+ VERIFY_RAISES_ASSERT(eig.betas());
+
+ // none raise assert after compute called
+ eig.compute(MatrixType::Random(20, 20), MatrixType::Random(20, 20));
+ VERIFY(eig.info() == Success);
+ eig.eigenvectors();
+ eig.eigenvalues();
+ eig.alphas();
+ eig.betas();
+
+ // eigenvectors() raises assert, if eigenvectors were not requested
+ eig.compute(MatrixType::Random(20, 20), MatrixType::Random(20, 20), false);
+ VERIFY(eig.info() == Success);
+ VERIFY_RAISES_ASSERT(eig.eigenvectors());
+ eig.eigenvalues();
+ eig.alphas();
+ eig.betas();
+
+ // all except info raise assert if realQZ did not converge
+ eig.setMaxIterations(0); // force real QZ to fail.
+ eig.compute(MatrixType::Random(20, 20), MatrixType::Random(20, 20));
+ VERIFY(eig.info() == NoConvergence);
+ VERIFY_RAISES_ASSERT(eig.eigenvectors());
+ VERIFY_RAISES_ASSERT(eig.eigenvalues());
+ VERIFY_RAISES_ASSERT(eig.alphas());
+ VERIFY_RAISES_ASSERT(eig.betas());
+}
+
EIGEN_DECLARE_TEST(eigensolver_generalized_real)
{
for(int i = 0; i < g_repeat; i++) {
@@ -98,6 +134,7 @@
CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(2,2)) );
CALL_SUBTEST_3( generalized_eigensolver_real(Matrix<double,1,1>()) );
CALL_SUBTEST_4( generalized_eigensolver_real(Matrix2d()) );
+ CALL_SUBTEST_5( generalized_eigensolver_assert<MatrixXd>() );
TEST_SET_BUT_UNUSED_VARIABLE(s)
}
}
diff --git a/test/jacobi.cpp b/test/jacobi.cpp
index 5604797..273b94d 100644
--- a/test/jacobi.cpp
+++ b/test/jacobi.cpp
@@ -65,6 +65,11 @@
CALL_SUBTEST_3(( jacobi<Matrix4cf, float>() ));
CALL_SUBTEST_3(( jacobi<Matrix4cf, std::complex<float> >() ));
+ CALL_SUBTEST_1(( jacobi<Matrix<float, 3, 3, RowMajor>, float>() ));
+ CALL_SUBTEST_2(( jacobi<Matrix<double, 4, 4, RowMajor>, double>() ));
+ CALL_SUBTEST_3(( jacobi<Matrix<std::complex<float>, 4, 4, RowMajor>, float>() ));
+ CALL_SUBTEST_3(( jacobi<Matrix<std::complex<float>, 4, 4, RowMajor>, std::complex<float> >() ));
+
int r = internal::random<int>(2, internal::random<int>(1,EIGEN_TEST_MAX_SIZE)/2),
c = internal::random<int>(2, internal::random<int>(1,EIGEN_TEST_MAX_SIZE)/2);
CALL_SUBTEST_4(( jacobi<MatrixXf, float>(MatrixXf(r,c)) ));
diff --git a/test/mixingtypes.cpp b/test/mixingtypes.cpp
index f836722..fe760b7 100644
--- a/test/mixingtypes.cpp
+++ b/test/mixingtypes.cpp
@@ -113,11 +113,12 @@
VERIFY_MIX_SCALAR(scd - vd.array() , scd - vd.template cast<complex<double> >().array());
// check scalar powers
- VERIFY_MIX_SCALAR( pow(vcf.array(), sf), Eigen::pow(vcf.array(), complex<float>(sf)) );
- VERIFY_MIX_SCALAR( vcf.array().pow(sf) , Eigen::pow(vcf.array(), complex<float>(sf)) );
+ // NOTE: scalar exponents use a unary op.
+ VERIFY_IS_APPROX( pow(vcf.array(), sf), Eigen::pow(vcf.array(), complex<float>(sf)) );
+ VERIFY_IS_APPROX( vcf.array().pow(sf) , Eigen::pow(vcf.array(), complex<float>(sf)) );
VERIFY_MIX_SCALAR( pow(sd, vcd.array()), Eigen::pow(complex<double>(sd), vcd.array()) );
- VERIFY_MIX_SCALAR( Eigen::pow(vf.array(), scf), Eigen::pow(vf.template cast<complex<float> >().array(), scf) );
- VERIFY_MIX_SCALAR( vf.array().pow(scf) , Eigen::pow(vf.template cast<complex<float> >().array(), scf) );
+ VERIFY_IS_APPROX( Eigen::pow(vf.array(), scf), Eigen::pow(vf.template cast<complex<float> >().array(), scf) );
+ VERIFY_IS_APPROX( vf.array().pow(scf) , Eigen::pow(vf.template cast<complex<float> >().array(), scf) );
VERIFY_MIX_SCALAR( Eigen::pow(scd, vd.array()), Eigen::pow(scd, vd.template cast<complex<double> >().array()) );
// check dot product
diff --git a/test/packetmath.cpp b/test/packetmath.cpp
index 163ef47..d7c7c9c 100644
--- a/test/packetmath.cpp
+++ b/test/packetmath.cpp
@@ -37,7 +37,7 @@
}
template <typename T>
inline T REF_NMSUB(const T& a, const T& b, const T& c) {
- return (-a * b) - c;
+ return (-a * b) - c;
}
template <typename T>
inline T REF_DIV(const T& a, const T& b) {
@@ -527,6 +527,7 @@
CHECK_CWISE1_IF(PacketTraits::HasNegate, internal::negate, internal::pnegate);
CHECK_CWISE1_IF(PacketTraits::HasReciprocal, REF_RECIPROCAL, internal::preciprocal);
CHECK_CWISE1(numext::conj, internal::pconj);
+ CHECK_CWISE1_IF(PacketTraits::HasSign, numext::sign, internal::psign);
for (int offset = 0; offset < 3; ++offset) {
@@ -680,9 +681,20 @@
CHECK_CWISE1_IF(PacketTraits::HasRsqrt, numext::rsqrt, internal::prsqrt);
CHECK_CWISE3_IF(true, REF_MADD, internal::pmadd);
if (!std::is_same<Scalar, bool>::value && NumTraits<Scalar>::IsSigned) {
+ CHECK_CWISE3_IF(true, REF_NMSUB, internal::pnmsub);
+ }
+
+ // For pmsub, pnmadd, the values can cancel each other to become near zero,
+ // which can lead to very flaky tests. Here we ensure the signs are such that
+ // they do not cancel.
+ for (int i = 0; i < PacketSize; ++i) {
+ data1[i] = numext::abs(internal::random<Scalar>());
+ data1[i + PacketSize] = numext::abs(internal::random<Scalar>());
+ data1[i + 2 * PacketSize] = -numext::abs(internal::random<Scalar>());
+ }
+ if (!std::is_same<Scalar, bool>::value && NumTraits<Scalar>::IsSigned) {
CHECK_CWISE3_IF(true, REF_MSUB, internal::pmsub);
CHECK_CWISE3_IF(true, REF_NMADD, internal::pnmadd);
- CHECK_CWISE3_IF(true, REF_NMSUB, internal::pnmsub);
}
}
@@ -805,6 +817,7 @@
CHECK_CWISE1_EXACT_IF(PacketTraits::HasCeil, numext::ceil, internal::pceil);
CHECK_CWISE1_EXACT_IF(PacketTraits::HasFloor, numext::floor, internal::pfloor);
CHECK_CWISE1_EXACT_IF(PacketTraits::HasRint, numext::rint, internal::print);
+ CHECK_CWISE1_IF(PacketTraits::HasSign, numext::sign, internal::psign);
packetmath_boolean_mask_ops_real<Scalar,Packet>();
@@ -1329,6 +1342,7 @@
data1[i] = Scalar(internal::random<RealScalar>(), internal::random<RealScalar>());
}
CHECK_CWISE1_N(numext::sqrt, internal::psqrt, size);
+ CHECK_CWISE1_IF(PacketTraits::HasSign, numext::sign, internal::psign);
// Test misc. corner cases.
const RealScalar zero = RealScalar(0);
diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp
index 3eb061d..333322f 100644
--- a/test/prec_inverse_4x4.cpp
+++ b/test/prec_inverse_4x4.cpp
@@ -13,7 +13,6 @@
template<typename MatrixType> void inverse_permutation_4x4()
{
- typedef typename MatrixType::Scalar Scalar;
Vector4i indices(0,1,2,3);
for(int i = 0; i < 24; ++i)
{
diff --git a/test/qr.cpp b/test/qr.cpp
index c38e343..36f3121 100644
--- a/test/qr.cpp
+++ b/test/qr.cpp
@@ -75,15 +75,17 @@
// now construct a matrix with prescribed determinant
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
- RealScalar absdet = abs(m1.diagonal().prod());
+ Scalar det = m1.diagonal().prod();
+ RealScalar absdet = abs(det);
m3 = qr.householderQ(); // get a unitary
- m1 = m3 * m1 * m3;
+ m1 = m3 * m1 * m3.adjoint();
qr.compute(m1);
VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
// This test is tricky if the determinant becomes too small.
// Since we generate random numbers with magnitude range [0,1], the average determinant is 0.5^size
- VERIFY_IS_MUCH_SMALLER_THAN( abs(absdet-qr.absDeterminant()), numext::maxi(RealScalar(pow(0.5,size)),numext::maxi<RealScalar>(abs(absdet),abs(qr.absDeterminant()))) );
-
+ RealScalar tol = numext::maxi(RealScalar(pow(0.5,size)), numext::maxi<RealScalar>(abs(absdet), abs(qr.absDeterminant())));
+ VERIFY_IS_MUCH_SMALLER_THAN(abs(det - qr.determinant()), tol);
+ VERIFY_IS_MUCH_SMALLER_THAN(abs(absdet - qr.absDeterminant()), tol);
}
template<typename MatrixType> void qr_verify_assert()
@@ -96,6 +98,7 @@
VERIFY_RAISES_ASSERT(qr.transpose().solve(tmp))
VERIFY_RAISES_ASSERT(qr.adjoint().solve(tmp))
VERIFY_RAISES_ASSERT(qr.householderQ())
+ VERIFY_RAISES_ASSERT(qr.determinant())
VERIFY_RAISES_ASSERT(qr.absDeterminant())
VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
}
diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp
index e251671..4185f51 100644
--- a/test/qr_colpivoting.cpp
+++ b/test/qr_colpivoting.cpp
@@ -273,10 +273,12 @@
// now construct a matrix with prescribed determinant
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
- RealScalar absdet = abs(m1.diagonal().prod());
+ Scalar det = m1.diagonal().prod();
+ RealScalar absdet = abs(det);
m3 = qr.householderQ(); // get a unitary
- m1 = m3 * m1 * m3;
+ m1 = m3 * m1 * m3.adjoint();
qr.compute(m1);
+ VERIFY_IS_APPROX(det, qr.determinant());
VERIFY_IS_APPROX(absdet, qr.absDeterminant());
VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
}
@@ -296,6 +298,7 @@
VERIFY_RAISES_ASSERT(qr.isSurjective())
VERIFY_RAISES_ASSERT(qr.isInvertible())
VERIFY_RAISES_ASSERT(qr.inverse())
+ VERIFY_RAISES_ASSERT(qr.determinant())
VERIFY_RAISES_ASSERT(qr.absDeterminant())
VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
}
@@ -315,6 +318,7 @@
VERIFY_RAISES_ASSERT(cod.isSurjective())
VERIFY_RAISES_ASSERT(cod.isInvertible())
VERIFY_RAISES_ASSERT(cod.pseudoInverse())
+ VERIFY_RAISES_ASSERT(cod.determinant())
VERIFY_RAISES_ASSERT(cod.absDeterminant())
VERIFY_RAISES_ASSERT(cod.logAbsDeterminant())
}
diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp
index f2d8cb3..cca9a8c 100644
--- a/test/qr_fullpivoting.cpp
+++ b/test/qr_fullpivoting.cpp
@@ -98,10 +98,12 @@
// now construct a matrix with prescribed determinant
m1.setZero();
for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
- RealScalar absdet = abs(m1.diagonal().prod());
+ Scalar det = m1.diagonal().prod();
+ RealScalar absdet = abs(det);
m3 = qr.matrixQ(); // get a unitary
- m1 = m3 * m1 * m3;
+ m1 = m3 * m1 * m3.adjoint();
qr.compute(m1);
+ VERIFY_IS_APPROX(det, qr.determinant());
VERIFY_IS_APPROX(absdet, qr.absDeterminant());
VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
}
@@ -121,6 +123,7 @@
VERIFY_RAISES_ASSERT(qr.isSurjective())
VERIFY_RAISES_ASSERT(qr.isInvertible())
VERIFY_RAISES_ASSERT(qr.inverse())
+ VERIFY_RAISES_ASSERT(qr.determinant())
VERIFY_RAISES_ASSERT(qr.absDeterminant())
VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
}
diff --git a/test/skew_symmetric_matrix3.cpp b/test/skew_symmetric_matrix3.cpp
new file mode 100644
index 0000000..6dad003
--- /dev/null
+++ b/test/skew_symmetric_matrix3.cpp
@@ -0,0 +1,217 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include "main.h"
+#include <Eigen/LU>
+
+namespace {
+template <typename Scalar>
+void constructors() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ const Vector v = Vector::Random();
+ // l-value
+ const SkewSymmetricMatrix3<Scalar> s1(v);
+ const Vector& v1 = s1.vector();
+ VERIFY_IS_APPROX(v1, v);
+ VERIFY(s1.cols() == 3);
+ VERIFY(s1.rows() == 3);
+
+ // r-value
+ const SkewSymmetricMatrix3<Scalar> s2(std::move(v));
+ VERIFY_IS_APPROX(v1, s2.vector());
+ VERIFY_IS_APPROX(s1.toDenseMatrix(), s2.toDenseMatrix());
+
+ // from scalars
+ SkewSymmetricMatrix3<Scalar> s4(v1(0), v1(1), v1(2));
+ VERIFY_IS_APPROX(v1, s4.vector());
+
+ // constructors with four vectors do not compile
+ // Matrix<Scalar, 4, 1> vector4 = Matrix<Scalar, 4, 1>::Random();
+ // SkewSymmetricMatrix3<Scalar> s5(vector4);
+}
+
+template <typename Scalar>
+void assignments() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ typedef Matrix<Scalar, 3, 3> SquareMatrix;
+
+ const Vector v = Vector::Random();
+
+ // assign to square matrix
+ SquareMatrix sq;
+ sq = v.asSkewSymmetric();
+ VERIFY(sq.isSkewSymmetric());
+
+ // assign to skew symmetric matrix
+ SkewSymmetricMatrix3<Scalar> sk;
+ sk = v.asSkewSymmetric();
+ VERIFY_IS_APPROX(v, sk.vector());
+}
+
+template <typename Scalar>
+void plusMinus() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ typedef Matrix<Scalar, 3, 3> SquareMatrix;
+
+ const Vector v1 = Vector::Random();
+ const Vector v2 = Vector::Random();
+
+ SquareMatrix sq1;
+ sq1 = v1.asSkewSymmetric();
+ SquareMatrix sq2;
+ sq2 = v2.asSkewSymmetric();
+
+ SkewSymmetricMatrix3<Scalar> sk1;
+ sk1 = v1.asSkewSymmetric();
+ SkewSymmetricMatrix3<Scalar> sk2;
+ sk2 = v2.asSkewSymmetric();
+
+ VERIFY_IS_APPROX((sk1 + sk2).toDenseMatrix(), sq1 + sq2);
+ VERIFY_IS_APPROX((sk1 - sk2).toDenseMatrix(), sq1 - sq2);
+
+ SquareMatrix sq3 = v1.asSkewSymmetric();
+ VERIFY_IS_APPROX( sq3 = v1.asSkewSymmetric() + v2.asSkewSymmetric(), sq1 + sq2);
+ VERIFY_IS_APPROX( sq3 = v1.asSkewSymmetric() - v2.asSkewSymmetric(), sq1 - sq2);
+ VERIFY_IS_APPROX( sq3 = v1.asSkewSymmetric() - 2*v2.asSkewSymmetric() + v1.asSkewSymmetric(), sq1 - 2*sq2 + sq1);
+
+ VERIFY_IS_APPROX((sk1 + sk1).vector(), 2*v1);
+ VERIFY((sk1 - sk1).vector().isZero());
+ VERIFY((sk1 - sk1).toDenseMatrix().isZero());
+}
+
+
+template <typename Scalar>
+void multiplyScale() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ typedef Matrix<Scalar, 3, 3> SquareMatrix;
+
+ const Vector v1 = Vector::Random();
+ SquareMatrix sq1;
+ sq1 = v1.asSkewSymmetric();
+ SkewSymmetricMatrix3<Scalar> sk1;
+ sk1 = v1.asSkewSymmetric();
+
+ const Scalar s1 = internal::random<Scalar>();
+ VERIFY_IS_APPROX(SkewSymmetricMatrix3<Scalar>(sk1*s1).vector(), sk1.vector() * s1);
+ VERIFY_IS_APPROX(SkewSymmetricMatrix3<Scalar>(s1*sk1).vector(), s1 * sk1.vector());
+ VERIFY_IS_APPROX(sq1 * (sk1 * s1), (sq1 * sk1) * s1);
+
+ const Vector v2 = Vector::Random();
+ SquareMatrix sq2;
+ sq2 = v2.asSkewSymmetric();
+ SkewSymmetricMatrix3<Scalar> sk2;
+ sk2 = v2.asSkewSymmetric();
+ VERIFY_IS_APPROX(sk1*sk2, sq1*sq2);
+
+ // null space
+ VERIFY((sk1*v1).isZero());
+ VERIFY((sk2*v2).isZero());
+}
+
+template<typename Matrix>
+void skewSymmetricMultiplication(const Matrix& m) {
+ typedef Eigen::Matrix<typename Matrix::Scalar, 3, 1> Vector;
+ const Vector v = Vector::Random();
+ const Matrix m1 = Matrix::Random(m.rows(), m.cols());
+ const SkewSymmetricMatrix3<typename Matrix::Scalar> sk = v.asSkewSymmetric();
+ VERIFY_IS_APPROX(m1.transpose() * (sk * m1), (m1.transpose() * sk) * m1);
+ VERIFY((m1.transpose() * (sk * m1)).isSkewSymmetric());
+}
+
+template <typename Scalar>
+void traceAndDet() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ const Vector v = Vector::Random();
+ // this does not work, values larger than 1.e-08 can be seen
+ //VERIFY_IS_APPROX(sq.determinant(), static_cast<Scalar>(0));
+ VERIFY_IS_APPROX(v.asSkewSymmetric().determinant(), static_cast<Scalar>(0));
+ VERIFY_IS_APPROX(v.asSkewSymmetric().toDenseMatrix().trace(), static_cast<Scalar>(0));
+}
+
+template <typename Scalar>
+void transpose() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ const Vector v = Vector::Random();
+ // By definition of a skew symmetric matrix: A^T = -A
+ VERIFY_IS_APPROX(v.asSkewSymmetric().toDenseMatrix().transpose(), v.asSkewSymmetric().transpose().toDenseMatrix());
+ VERIFY_IS_APPROX(v.asSkewSymmetric().transpose().vector(), (-v).asSkewSymmetric().vector());
+}
+
+template <typename Scalar>
+void exponentialIdentity() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ const Vector v1 = Vector::Zero();
+ VERIFY(v1.asSkewSymmetric().exponential().isIdentity());
+
+ Vector v2 = Vector::Random();
+ v2.normalize();
+ VERIFY((2*EIGEN_PI*v2).asSkewSymmetric().exponential().isIdentity());
+
+ Vector v3;
+ const auto precision = static_cast<Scalar>(1.1)*NumTraits<Scalar>::dummy_precision();
+ v3 << 0, 0, precision;
+ VERIFY(v3.asSkewSymmetric().exponential().isIdentity(precision));
+}
+
+template <typename Scalar>
+void exponentialOrthogonality() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ typedef Matrix<Scalar, 3, 3> SquareMatrix;
+ const Vector v = Vector::Random();
+ SquareMatrix sq = v.asSkewSymmetric().exponential();
+ VERIFY(sq.isUnitary());
+}
+
+template <typename Scalar>
+void exponentialRotation() {
+ typedef Matrix<Scalar, 3, 1> Vector;
+ typedef Matrix<Scalar, 3, 3> SquareMatrix;
+
+ // rotation axis is invariant
+ const Vector v1 = Vector::Random();
+ const SquareMatrix r1 = v1.asSkewSymmetric().exponential();
+ VERIFY_IS_APPROX(r1*v1, v1);
+
+ // rotate around z-axis
+ Vector v2;
+ v2 << 0, 0, EIGEN_PI;
+ const SquareMatrix r2 = v2.asSkewSymmetric().exponential();
+ VERIFY_IS_APPROX(r2*(Vector() << 1,0,0).finished(), (Vector() << -1,0,0).finished());
+ VERIFY_IS_APPROX(r2*(Vector() << 0,1,0).finished(), (Vector() << 0,-1,0).finished());
+}
+
+
+} // namespace
+
+
+EIGEN_DECLARE_TEST(skew_symmetric_matrix3)
+{
+ for(int i = 0; i < g_repeat; i++) {
+ CALL_SUBTEST_1(constructors<float>());
+ CALL_SUBTEST_1(constructors<double>());
+ CALL_SUBTEST_1(assignments<float>());
+ CALL_SUBTEST_1(assignments<double>());
+
+ CALL_SUBTEST_2(plusMinus<float>());
+ CALL_SUBTEST_2(plusMinus<double>());
+ CALL_SUBTEST_2(multiplyScale<float>());
+ CALL_SUBTEST_2(multiplyScale<double>());
+ CALL_SUBTEST_2(skewSymmetricMultiplication(MatrixXf(3,internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
+ CALL_SUBTEST_2(skewSymmetricMultiplication(MatrixXd(3,internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));
+ CALL_SUBTEST_2(traceAndDet<float>());
+ CALL_SUBTEST_2(traceAndDet<double>());
+ CALL_SUBTEST_2(transpose<float>());
+ CALL_SUBTEST_2(transpose<double>());
+
+ CALL_SUBTEST_3(exponentialIdentity<float>());
+ CALL_SUBTEST_3(exponentialIdentity<double>());
+ CALL_SUBTEST_3(exponentialOrthogonality<float>());
+ CALL_SUBTEST_3(exponentialOrthogonality<double>());
+ CALL_SUBTEST_3(exponentialRotation<float>());
+ CALL_SUBTEST_3(exponentialRotation<double>());
+ }
+}
diff --git a/test/sparse_block.cpp b/test/sparse_block.cpp
index 2b19ac5..955aa60 100644
--- a/test/sparse_block.cpp
+++ b/test/sparse_block.cpp
@@ -288,6 +288,25 @@
VERIFY_IS_APPROX(m3, refMat3);
}
}
+
+ // Explicit inner iterator.
+ {
+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);
+ SparseMatrixType m2(rows, cols);
+ initSparse<Scalar>(density, refMat2, m2);
+
+ Index j0 =internal::random<Index>(0, outer - 1);
+ auto v = innervec(m2, j0);
+
+ typename decltype(v)::InnerIterator block_iterator(v);
+ typename SparseMatrixType::InnerIterator matrix_iterator(m2, j0);
+ while (block_iterator) {
+ VERIFY_IS_EQUAL(block_iterator.index(), matrix_iterator.index());
+ ++block_iterator;
+ ++matrix_iterator;
+ }
+
+ }
}
EIGEN_DECLARE_TEST(sparse_block)
diff --git a/test/zerosized.cpp b/test/zerosized.cpp
index 07afd0f..86aa5eb 100644
--- a/test/zerosized.cpp
+++ b/test/zerosized.cpp
@@ -47,7 +47,7 @@
if (MatrixType::RowsAtCompileTime == Dynamic && MatrixType::ColsAtCompileTime == Dynamic)
{
- MatrixType t2(0, 0), t3(t1);
+ MatrixType t2(0, 0);
VERIFY(t2.rows() == 0);
VERIFY(t2.cols() == 0);
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
index 4a6edb1..a4ac2ad 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h
@@ -331,10 +331,12 @@
return choose(Cond<NumTraits<CoeffReturnType>::IsComplex>(), unaryExpr(internal::scalar_conjugate_op<Scalar>()), derived());
}
- EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_pow_op<Scalar,Scalar> >, const Derived>
- pow(Scalar exponent) const {
- return unaryExpr(internal::bind2nd_op<internal::scalar_pow_op<Scalar,Scalar> >(exponent));
+ template<typename ScalarExponent>
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const std::enable_if_t<internal::is_arithmetic<typename NumTraits<ScalarExponent>::Real>::value,
+ TensorCwiseUnaryOp<internal::scalar_unary_pow_op<Scalar, ScalarExponent>, const Derived>>
+ pow(ScalarExponent exponent) const
+ {
+ return unaryExpr(internal::scalar_unary_pow_op<Scalar, ScalarExponent>(exponent));
}
EIGEN_DEVICE_FUNC
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h
index 65d69c3..dc97d21 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h
@@ -243,7 +243,7 @@
template <typename... T>
EIGEN_DEVICE_FUNC static constexpr bool value_known_statically(const Index i, const IndexTuple<T...>& t) {
- return ((i == Idx) & is_compile_time_constant<typename IndexTupleExtractor<Idx, T...>::ValType>::value) ||
+ return ((i == Idx) && is_compile_time_constant<typename IndexTupleExtractor<Idx, T...>::ValType>::value) ||
tuple_coeff<Idx-1, ValueT>::value_known_statically(i, t);
}
diff --git a/unsupported/Eigen/SparseExtra b/unsupported/Eigen/SparseExtra
index 2fa8f9f..f4920de 100644
--- a/unsupported/Eigen/SparseExtra
+++ b/unsupported/Eigen/SparseExtra
@@ -33,6 +33,7 @@
*
* This module contains some experimental features extending the sparse module:
* - A RandomSetter which is a wrapper object allowing to set/update a sparse matrix with random access.
+ * - A SparseInverse which calculates a sparse subset of the inverse of a sparse matrix corresponding to nonzeros of the input
* - MatrixMarket format(https://math.nist.gov/MatrixMarket/formats.html) readers and writers for sparse and dense matrices.
*
* \code
@@ -42,6 +43,7 @@
#include "src/SparseExtra/RandomSetter.h"
+#include "src/SparseExtra/SparseInverse.h"
#include "src/SparseExtra/MarketIO.h"
diff --git a/unsupported/Eigen/src/SparseExtra/SparseInverse.h b/unsupported/Eigen/src/SparseExtra/SparseInverse.h
new file mode 100644
index 0000000..c8a4920
--- /dev/null
+++ b/unsupported/Eigen/src/SparseExtra/SparseInverse.h
@@ -0,0 +1,231 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2022 Julian Kent <jkflying@gmail.com>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SPARSEINVERSE_H
+#define EIGEN_SPARSEINVERSE_H
+
+#include "./InternalHeaderCheck.h"
+
+#include "../../../../Eigen/Sparse"
+#include "../../../../Eigen/SparseLU"
+
+namespace Eigen {
+
+/**
+ * @brief Kahan algorithm based accumulator
+ *
+ * The Kahan sum algorithm guarantees to bound the error from floating point
+ * accumulation to a fixed value, regardless of the number of accumulations
+ * performed. Naive accumulation accumulates errors O(N), and pairwise O(logN).
+ * However pairwise also requires O(logN) memory while Kahan summation requires
+ * O(1) memory, but 4x the operations / latency.
+ *
+ * NB! Do not enable associative math optimizations, they may cause the Kahan
+ * summation to be optimized out leaving you with naive summation again.
+ *
+ */
+template <typename Scalar>
+class KahanSum {
+ // Straighforward Kahan summation for accurate accumulation of a sum of numbers
+ Scalar _sum{};
+ Scalar _correction{};
+
+ public:
+ Scalar value() { return _sum; }
+
+ void operator+=(Scalar increment) {
+ const Scalar correctedIncrement = increment + _correction;
+ const Scalar previousSum = _sum;
+ _sum += correctedIncrement;
+ _correction = correctedIncrement - (_sum - previousSum);
+ }
+};
+template <typename Scalar, Index Width = 16>
+class FABSum {
+ // https://epubs.siam.org/doi/pdf/10.1137/19M1257780
+ // Fast and Accurate Blocked Summation
+ // Uses naive summation for the fast sum, and Kahan summation for the accurate sum
+ // Theoretically SIMD sum could be changed to a tree sum which would improve accuracy
+ // over naive summation
+ KahanSum<Scalar> _totalSum;
+ Matrix<Scalar, Width, 1> _block;
+ Index _blockUsed{};
+
+ public:
+ Scalar value() { return _block.topRows(_blockUsed).sum() + _totalSum.value(); }
+
+ void operator+=(Scalar increment) {
+ _block(_blockUsed++, 0) = increment;
+ if (_blockUsed == Width) {
+ _totalSum += _block.sum();
+ _blockUsed = 0;
+ }
+ }
+};
+
+/**
+ * @brief computes an accurate dot product on two sparse vectors
+ *
+ * Uses an accurate summation algorithm for the accumulator in order to
+ * compute an accurate dot product for two sparse vectors.
+ *
+ */
+template <typename Derived, typename OtherDerived>
+typename Derived::Scalar accurateDot(const SparseMatrixBase<Derived>& A, const SparseMatrixBase<OtherDerived>& other) {
+ typedef typename Derived::Scalar Scalar;
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived, OtherDerived)
+ static_assert(internal::is_same<Scalar, typename OtherDerived::Scalar>::value, "mismatched types");
+
+ internal::evaluator<Derived> thisEval(A.derived());
+ typename Derived::ReverseInnerIterator i(thisEval, 0);
+
+ internal::evaluator<OtherDerived> otherEval(other.derived());
+ typename OtherDerived::ReverseInnerIterator j(otherEval, 0);
+
+ FABSum<Scalar> res;
+ while (i && j) {
+ if (i.index() == j.index()) {
+ res += numext::conj(i.value()) * j.value();
+ --i;
+ --j;
+ } else if (i.index() > j.index())
+ --i;
+ else
+ --j;
+ }
+ return res.value();
+}
+
+/**
+ * @brief calculate sparse subset of inverse of sparse matrix
+ *
+ * This class returns a sparse subset of the inverse of the input matrix.
+ * The nonzeros correspond to the nonzeros of the input, plus any additional
+ * elements required due to fill-in of the internal LU factorization. This is
+ * is minimized via a applying a fill-reducing permutation as part of the LU
+ * factorization.
+ *
+ * If there are specific entries of the input matrix which you need inverse
+ * values for, which are zero for the input, you need to insert entries into
+ * the input sparse matrix for them to be calculated.
+ *
+ * Due to the sensitive nature of matrix inversion, particularly on large
+ * matrices which are made possible via sparsity, high accuracy dot products
+ * based on Kahan summation are used to reduce numerical error. If you still
+ * encounter numerical errors you may with to equilibrate your matrix before
+ * calculating the inverse, as well as making sure it is actually full rank.
+ */
+template <typename Scalar>
+class SparseInverse {
+ public:
+ typedef SparseMatrix<Scalar, ColMajor> MatrixType;
+ typedef SparseMatrix<Scalar, RowMajor> RowMatrixType;
+
+ SparseInverse() {}
+
+ /**
+ * @brief This Constructor is for if you already have a factored SparseLU and would like to use it to calculate a
+ * sparse inverse.
+ *
+ * Just call this constructor with your already factored SparseLU class and you can directly call the .inverse()
+ * method to get the result.
+ */
+ SparseInverse(const SparseLU<MatrixType>& slu) { _result = computeInverse(slu); }
+
+ /**
+ * @brief Calculate the sparse inverse from a given sparse input
+ */
+ SparseInverse& compute(const SparseMatrix<Scalar>& A) {
+ SparseLU<MatrixType> slu;
+ slu.compute(A);
+ _result = computeInverse(slu);
+ return *this;
+ }
+
+ /**
+ * @brief return the already-calculated sparse inverse, or a 0x0 matrix if it could not be computed
+ */
+ const MatrixType& inverse() const { return _result; }
+
+ /**
+ * @brief Internal function to calculate the sparse inverse in a functional way
+ * @return A sparse inverse representation, or, if the decomposition didn't complete, a 0x0 matrix.
+ */
+ static MatrixType computeInverse(const SparseLU<MatrixType>& slu) {
+ if (slu.info() != Success) {
+ return MatrixType(0, 0);
+ }
+
+ // Extract from SparseLU and decompose into L, inverse D and U terms
+ Matrix<Scalar, Dynamic, 1> invD;
+ RowMatrixType Upper;
+ {
+ RowMatrixType DU = slu.matrixU().toSparse();
+ invD = DU.diagonal().cwiseInverse();
+ Upper = (invD.asDiagonal() * DU).template triangularView<StrictlyUpper>();
+ }
+ MatrixType Lower = slu.matrixL().toSparse().template triangularView<StrictlyLower>();
+
+ // Compute the inverse and reapply the permutation matrix from the LU decomposition
+ return slu.colsPermutation().transpose() * computeInverse(Upper, invD, Lower) * slu.rowsPermutation();
+ }
+
+ /**
+ * @brief Internal function to calculate the inverse from strictly upper, diagonal and strictly lower components
+ */
+ static MatrixType computeInverse(const RowMatrixType& Upper, const Matrix<Scalar, Dynamic, 1>& inverseDiagonal,
+ const MatrixType& Lower) {
+ // Calculate the 'minimal set', which is the nonzeros of (L+U).transpose()
+ // It could be zeroed, but we will overwrite all non-zeros anyways.
+ MatrixType colInv = Lower.transpose().template triangularView<UnitUpper>();
+ colInv += Upper.transpose();
+
+ // We also need rowmajor representation in order to do efficient row-wise dot products
+ RowMatrixType rowInv = Upper.transpose().template triangularView<UnitLower>();
+ rowInv += Lower.transpose();
+
+ // Use the Takahashi algorithm to build the supporting elements of the inverse
+ // upwards and to the left, from the bottom right element, 1 col/row at a time
+ for (Index recurseLevel = Upper.cols() - 1; recurseLevel >= 0; recurseLevel--) {
+ const auto& col = Lower.col(recurseLevel);
+ const auto& row = Upper.row(recurseLevel);
+
+ // Calculate the inverse values for the nonzeros in this column
+ typename MatrixType::ReverseInnerIterator colIter(colInv, recurseLevel);
+ for (; recurseLevel < colIter.index(); --colIter) {
+ const Scalar element = -accurateDot(col, rowInv.row(colIter.index()));
+ colIter.valueRef() = element;
+ rowInv.coeffRef(colIter.index(), recurseLevel) = element;
+ }
+
+ // Calculate the inverse values for the nonzeros in this row
+ typename RowMatrixType::ReverseInnerIterator rowIter(rowInv, recurseLevel);
+ for (; recurseLevel < rowIter.index(); --rowIter) {
+ const Scalar element = -accurateDot(row, colInv.col(rowIter.index()));
+ rowIter.valueRef() = element;
+ colInv.coeffRef(recurseLevel, rowIter.index()) = element;
+ }
+
+ // And finally the diagonal, which corresponds to both row and col iterator now
+ const Scalar diag = inverseDiagonal(recurseLevel) - accurateDot(row, colInv.col(recurseLevel));
+ rowIter.valueRef() = diag;
+ colIter.valueRef() = diag;
+ }
+
+ return colInv;
+ }
+
+ private:
+ MatrixType _result;
+};
+
+} // namespace Eigen
+#endif
diff --git a/unsupported/test/cxx11_tensor_builtins_sycl.cpp b/unsupported/test/cxx11_tensor_builtins_sycl.cpp
index df142fe..27a8254 100644
--- a/unsupported/test/cxx11_tensor_builtins_sycl.cpp
+++ b/unsupported/test/cxx11_tensor_builtins_sycl.cpp
@@ -86,7 +86,8 @@
{
/* Assignment(out, Operator(out)) */
Tensor<DataType, 3, DataLayout, int64_t> out(tensor_range);
- out = out.random() + DataType(0.01);
+ // Offset with 1 to avoid tiny output (< 1e-6) as they can easily fail.
+ out = out.random() + DataType(1);
Tensor<DataType, 3, DataLayout, int64_t> reference(out);
DataType *gpu_data_out = static_cast<DataType *>(
sycl_device.allocate(out.size() * sizeof(DataType)));
diff --git a/unsupported/test/cxx11_tensor_math_sycl.cpp b/unsupported/test/cxx11_tensor_math_sycl.cpp
index 03cf0a8..029653e 100644
--- a/unsupported/test/cxx11_tensor_math_sycl.cpp
+++ b/unsupported/test/cxx11_tensor_math_sycl.cpp
@@ -94,12 +94,8 @@
auto sycl_device = Eigen::SyclDevice(&queueInterface);
test_tanh_sycl<DataType, RowMajor, int64_t>(sycl_device);
test_tanh_sycl<DataType, ColMajor, int64_t>(sycl_device);
- // Sigmoid broke for SYCL as of 0b5873 because of missing functions in PacketMath.h.
- // Disable the test for now.
-#if 0
test_sigmoid_sycl<DataType, RowMajor, int64_t>(sycl_device);
test_sigmoid_sycl<DataType, ColMajor, int64_t>(sycl_device);
-#endif
}
EIGEN_DECLARE_TEST(cxx11_tensor_math_sycl) {
diff --git a/unsupported/test/cxx11_tensor_random_sycl.cpp b/unsupported/test/cxx11_tensor_random_sycl.cpp
index 6c83894..14a7c48 100644
--- a/unsupported/test/cxx11_tensor_random_sycl.cpp
+++ b/unsupported/test/cxx11_tensor_random_sycl.cpp
@@ -37,14 +37,8 @@
gpu_out.device(sycl_device)=gpu_out.random();
sycl_device.memcpyDeviceToHost(out.data(), d_out,out_bytes);
- for(IndexType i=1; i<sizeDim0; i++)
- for(IndexType j=1; j<sizeDim1; j++)
- {
- VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j));
- VERIFY_IS_NOT_EQUAL(out(i,j), out(i,j-1));
- VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j-1)); }
- // For now we just check thes code doesn't crash.
+ // For now we just check the code doesn't crash.
// TODO: come up with a valid test of randomness
sycl_device.deallocate(d_out);
}
@@ -66,16 +60,8 @@
Eigen::internal::NormalRandomGenerator<DataType> gen(true);
gpu_out.device(sycl_device)=gpu_out.random(gen);
sycl_device.memcpyDeviceToHost(out.data(), d_out,out_bytes);
- for(IndexType i=1; i<sizeDim0; i++)
- for(IndexType j=1; j<sizeDim1; j++)
- {
- VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j));
- VERIFY_IS_NOT_EQUAL(out(i,j), out(i,j-1));
- VERIFY_IS_NOT_EQUAL(out(i,j), out(i-1,j-1));
- }
-
- // For now we just check thes code doesn't crash.
+ // For now we just check the code doesn't crash.
// TODO: come up with a valid test of randomness
sycl_device.deallocate(d_out);
}
diff --git a/unsupported/test/sparse_extra.cpp b/unsupported/test/sparse_extra.cpp
index 744545b..5512871 100644
--- a/unsupported/test/sparse_extra.cpp
+++ b/unsupported/test/sparse_extra.cpp
@@ -164,6 +164,48 @@
VERIFY_IS_EQUAL(m1,m2);
}
+template <typename Scalar>
+void check_sparse_inverse() {
+ typedef SparseMatrix<Scalar> MatrixType;
+
+ Matrix<Scalar, -1, -1> A;
+ A.resize(1000, 1000);
+ A.fill(0);
+ A.setIdentity();
+ A.col(0).array() += 1;
+ A.row(0).array() += 2;
+ A.col(2).array() += 3;
+ A.row(7).array() += 3;
+ A.col(9).array() += 3;
+ A.block(3, 4, 4, 2).array() += 9;
+ A.middleRows(10, 50).array() += 3;
+ A.middleCols(50, 50).array() += 40;
+ A.block(500, 300, 40, 20).array() += 10;
+ A.transposeInPlace();
+
+ Eigen::SparseLU<MatrixType> slu;
+ slu.compute(A.sparseView());
+ Matrix<Scalar, -1, -1> Id(A.rows(), A.cols());
+ Id.setIdentity();
+ Matrix<Scalar, -1, -1> inv = slu.solve(Id);
+
+ const MatrixType sparseInv = Eigen::SparseInverse<Scalar>().compute(A.sparseView()).inverse();
+
+ Scalar sumdiff = 0; // Check the diff only of the non-zero elements
+ for (Eigen::Index j = 0; j < A.cols(); j++) {
+ for (typename MatrixType::InnerIterator iter(sparseInv, j); iter; ++iter) {
+ const Scalar diff = std::abs(inv(iter.row(), iter.col()) - iter.value());
+ VERIFY_IS_APPROX_OR_LESS_THAN(diff, 1e-11);
+
+ if (iter.value() != 0) {
+ sumdiff += diff;
+ }
+ }
+ }
+
+ VERIFY_IS_APPROX_OR_LESS_THAN(sumdiff, 1e-10);
+}
+
EIGEN_DECLARE_TEST(sparse_extra)
{
for(int i = 0; i < g_repeat; i++) {
@@ -200,6 +242,8 @@
CALL_SUBTEST_5( (check_marketio_vector<Matrix<std::complex<float>,Dynamic,1> >()) );
CALL_SUBTEST_5( (check_marketio_vector<Matrix<std::complex<double>,Dynamic,1> >()) );
+ CALL_SUBTEST_6((check_sparse_inverse<double>()));
+
TEST_SET_BUT_UNUSED_VARIABLE(s);
}
}