From 015aeaf87b94aefeebc18af786201f07581fc768 Mon Sep 17 00:00:00 2001 From: Marco Livesu Date: Thu, 18 Apr 2024 14:08:24 +0200 Subject: [PATCH] update Eigen (to version 3.4.0) --- external/eigen/CMakeLists.txt | 3 + external/eigen/Eigen/src/Core/Dot.h | 2 +- .../eigen/Eigen/src/Core/GenericPacketMath.h | 220 +- external/eigen/Eigen/src/Core/Map.h | 2 +- external/eigen/Eigen/src/Core/MathFunctions.h | 4 +- external/eigen/Eigen/src/Core/Solve.h | 2 +- .../eigen/Eigen/src/Core/arch/AVX/Complex.h | 12 +- .../Eigen/src/Core/arch/AVX/PacketMath.h | 11 +- .../Eigen/src/Core/arch/AVX512/Complex.h | 44 +- .../Eigen/src/Core/arch/AVX512/PacketMath.h | 18 +- .../Eigen/src/Core/arch/AltiVec/Complex.h | 14 +- .../src/Core/arch/AltiVec/MatrixProduct.h | 18 +- .../Core/arch/AltiVec/MatrixProductCommon.h | 2 +- .../src/Core/arch/AltiVec/MatrixProductMMA.h | 8 +- .../Eigen/src/Core/arch/AltiVec/PacketMath.h | 41 +- .../Eigen/src/Core/arch/Default/BFloat16.h | 7 - .../arch/Default/GenericPacketMathFunctions.h | 20 - .../Default/GenericPacketMathFunctionsFwd.h | 6 - .../eigen/Eigen/src/Core/arch/MSA/Complex.h | 11 +- .../eigen/Eigen/src/Core/arch/NEON/Complex.h | 27 +- .../eigen/Eigen/src/Core/arch/SSE/Complex.h | 12 +- .../Eigen/src/Core/arch/ZVector/Complex.h | 16 +- .../Eigen/src/Core/functors/StlFunctors.h | 30 + .../Core/products/GeneralBlockPanelKernel.h | 2 +- .../eigen/Eigen/src/Core/util/Constants.h | 2 +- .../src/Core/util/DisableStupidWarnings.h | 3 - external/eigen/Eigen/src/Core/util/Macros.h | 12 +- external/eigen/Eigen/src/Core/util/Meta.h | 13 +- .../eigen/Eigen/src/Core/util/XprHelper.h | 14 +- .../src/Eigenvalues/SelfAdjointEigenSolver.h | 7 +- .../src/Eigenvalues/Tridiagonalization.h | 20 +- external/eigen/Eigen/src/LU/InverseImpl.h | 30 +- external/eigen/Eigen/src/SVD/JacobiSVD.h | 24 +- .../eigen/Eigen/src/SparseCore/SparseMatrix.h | 11 +- .../Eigen/src/plugins/ArrayCwiseUnaryOps.h | 39 + .../Eigen/src/plugins/CommonCwiseUnaryOps.h | 43 - .../Eigen/src/plugins/MatrixCwiseBinaryOps.h | 8 +- .../eigen/bench/tensors/tensor_benchmarks.h | 6 +- .../tensors/tensor_contract_sycl_bench.cc | 6 +- external/eigen/blas/CMakeLists.txt | 25 +- external/eigen/cmake/FindBLAS.cmake | 5 +- external/eigen/cmake/FindBLASEXT.cmake | 28 +- external/eigen/cmake/FindComputeCpp.cmake | 3 +- external/eigen/cmake/FindFFTW.cmake | 3 +- external/eigen/cmake/FindHWLOC.cmake | 5 +- external/eigen/cmake/FindLAPACK.cmake | 7 +- external/eigen/cmake/FindMPREAL.cmake | 103 + external/eigen/cmake/FindPTSCOTCH.cmake | 33 +- external/eigen/cmake/FindPastix.cmake | 36 +- external/eigen/cmake/FindScotch.cmake | 5 +- external/eigen/cmake/FindTriSYCL.cmake | 67 +- external/eigen/doc/LeastSquares.dox | 15 +- .../doc/TopicLinearAlgebraDecompositions.dox | 16 +- .../eigen/doc/TutorialBlockOperations.dox | 14 + external/eigen/doc/TutorialLinearAlgebra.dox | 69 +- external/eigen/doc/TutorialSparse.dox | 2 +- .../Tridiagonalization_decomposeInPlace.cpp | 3 +- external/eigen/lapack/CMakeLists.txt | 30 +- external/eigen/test/AnnoyingScalar.h | 6 +- external/eigen/test/CMakeLists.txt | 1 - external/eigen/test/OffByOneScalar.h | 28 - external/eigen/test/array_cwise.cpp | 37 + external/eigen/test/bfloat16_float.cpp | 89 - external/eigen/test/conservative_resize.cpp | 6 +- external/eigen/test/geo_hyperplane.cpp | 5 - external/eigen/test/geo_parametrizedline.cpp | 5 - external/eigen/test/geo_quaternion.cpp | 8 - external/eigen/test/geo_transformations.cpp | 5 - external/eigen/test/gpu_basic.cu | 15 +- external/eigen/test/jacobisvd.cpp | 3 + external/eigen/test/main.h | 55 +- external/eigen/test/solverbase.h | 4 - external/eigen/test/sparse_block.cpp | 3 +- external/eigen/test/svd_common.h | 15 +- external/eigen/test/unalignedassert.cpp | 180 - .../Eigen/CXX11/src/Tensor/README.md | 6 +- .../CXX11/src/Tensor/TensorContraction.h | 4 +- .../CXX11/src/Tensor/TensorContractionGpu.h | 4 +- .../src/Tensor/TensorContractionThreadPool.h | 4 +- .../CXX11/src/Tensor/TensorDeviceDefault.h | 11 - .../Eigen/CXX11/src/Tensor/TensorDeviceGpu.h | 39 - .../Eigen/CXX11/src/Tensor/TensorDeviceSycl.h | 67 +- .../CXX11/src/Tensor/TensorDeviceThreadPool.h | 5 - .../src/Tensor/TensorGpuHipCudaDefines.h | 2 - .../src/Tensor/TensorGpuHipCudaUndefines.h | 1 - .../Eigen/src/AutoDiff/AutoDiffScalar.h | 50 +- .../Eigen/src/Skyline/SkylineMatrix.h | 16 +- .../Eigen/src/Skyline/SkylineStorage.h | 10 +- .../doc/examples/SYCL/CMakeLists.txt | 3 +- .../eigen/unsupported/test/CMakeLists.txt | 14 +- .../unsupported/test/cxx11_tensor_assign.cpp | 18 +- .../unsupported/test/cxx11_tensor_device.cu | 44 - .../test/cxx11_tensor_device_sycl.cpp | 45 +- .../eigen/unsupported/test/mpreal/mpreal.h | 3184 ----------------- .../eigen/unsupported/test/mpreal_support.cpp | 1 + .../eigen/unsupported/test/sparse_extra.cpp | 17 + 96 files changed, 981 insertions(+), 4268 deletions(-) create mode 100644 external/eigen/cmake/FindMPREAL.cmake delete mode 100644 external/eigen/test/OffByOneScalar.h delete mode 100644 external/eigen/test/unalignedassert.cpp delete mode 100644 external/eigen/unsupported/test/mpreal/mpreal.h diff --git a/external/eigen/CMakeLists.txt b/external/eigen/CMakeLists.txt index bd1af32b..f3e69b84 100644 --- a/external/eigen/CMakeLists.txt +++ b/external/eigen/CMakeLists.txt @@ -88,6 +88,9 @@ else() ei_add_cxx_compiler_flag("-std=c++03") endif() +# Determine if we should build shared libraries on this platform. +get_cmake_property(EIGEN_BUILD_SHARED_LIBS TARGET_SUPPORTS_SHARED_LIBS) + ############################################################################# # find how to link to the standard libraries # ############################################################################# diff --git a/external/eigen/Eigen/src/Core/Dot.h b/external/eigen/Eigen/src/Core/Dot.h index 41a8cb43..5c3441b9 100644 --- a/external/eigen/Eigen/src/Core/Dot.h +++ b/external/eigen/Eigen/src/Core/Dot.h @@ -86,7 +86,7 @@ MatrixBase::dot(const MatrixBase& other) const //---------- implementation of L2 norm and related functions ---------- -/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm. +/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the squared Frobenius norm. * In both cases, it consists in the sum of the square of all the matrix entries. * For vectors, this is also equals to the dot product of \c *this with itself. * diff --git a/external/eigen/Eigen/src/Core/GenericPacketMath.h b/external/eigen/Eigen/src/Core/GenericPacketMath.h index 53800a00..cf677a19 100644 --- a/external/eigen/Eigen/src/Core/GenericPacketMath.h +++ b/external/eigen/Eigen/src/Core/GenericPacketMath.h @@ -129,6 +129,22 @@ template struct packet_traits : default_packet_traits template struct packet_traits : packet_traits { }; +template struct unpacket_traits +{ + typedef T type; + typedef T half; + enum + { + size = 1, + alignment = 1, + vectorizable = false, + masked_load_available=false, + masked_store_available=false + }; +}; + +template struct unpacket_traits : unpacket_traits { }; + template struct type_casting_traits { enum { VectorizedCast = 0, @@ -154,6 +170,18 @@ struct eigen_packet_wrapper T m_val; }; + +/** \internal A convenience utility for determining if the type is a scalar. + * This is used to enable some generic packet implementations. + */ +template +struct is_scalar { + typedef typename unpacket_traits::type Scalar; + enum { + value = internal::is_same::value + }; +}; + /** \internal \returns static_cast(a) (coeff-wise) */ template EIGEN_DEVICE_FUNC inline TgtPacket @@ -215,13 +243,59 @@ pmul(const bool& a, const bool& b) { return a && b; } template EIGEN_DEVICE_FUNC inline Packet pdiv(const Packet& a, const Packet& b) { return a/b; } -/** \internal \returns one bits */ +// In the generic case, memset to all one bits. +template +struct ptrue_impl { + static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/){ + Packet b; + memset(static_cast(&b), 0xff, sizeof(Packet)); + return b; + } +}; + +// For non-trivial scalars, set to Scalar(1) (i.e. a non-zero value). +// Although this is technically not a valid bitmask, the scalar path for pselect +// uses a comparison to zero, so this should still work in most cases. We don't +// have another option, since the scalar type requires initialization. +template +struct ptrue_impl::value && NumTraits::RequireInitialization>::type > { + static EIGEN_DEVICE_FUNC inline T run(const T& /*a*/){ + return T(1); + } +}; + +/** \internal \returns one bits. */ template EIGEN_DEVICE_FUNC inline Packet -ptrue(const Packet& /*a*/) { Packet b; memset((void*)&b, 0xff, sizeof(b)); return b;} +ptrue(const Packet& a) { + return ptrue_impl::run(a); +} -/** \internal \returns zero bits */ +// In the general case, memset to zero. +template +struct pzero_impl { + static EIGEN_DEVICE_FUNC inline Packet run(const Packet& /*a*/) { + Packet b; + memset(static_cast(&b), 0x00, sizeof(Packet)); + return b; + } +}; + +// For scalars, explicitly set to Scalar(0), since the underlying representation +// for zero may not consist of all-zero bits. +template +struct pzero_impl::value>::type> { + static EIGEN_DEVICE_FUNC inline T run(const T& /*a*/) { + return T(0); + } +}; + +/** \internal \returns packet of zeros */ template EIGEN_DEVICE_FUNC inline Packet -pzero(const Packet& /*a*/) { Packet b; memset((void*)&b, 0, sizeof(b)); return b;} +pzero(const Packet& a) { + return pzero_impl::run(a); +} /** \internal \returns a <= b as a bit mask */ template EIGEN_DEVICE_FUNC inline Packet @@ -238,33 +312,6 @@ pcmp_eq(const Packet& a, const Packet& b) { return a==b ? ptrue(a) : pzero(a); } /** \internal \returns a < b or a==NaN or b==NaN as a bit mask */ template EIGEN_DEVICE_FUNC inline Packet pcmp_lt_or_nan(const Packet& a, const Packet& b) { return a>=b ? pzero(a) : ptrue(a); } -template<> EIGEN_DEVICE_FUNC inline float pzero(const float& a) { - EIGEN_UNUSED_VARIABLE(a) - return 0.f; -} - -template<> EIGEN_DEVICE_FUNC inline double pzero(const double& a) { - EIGEN_UNUSED_VARIABLE(a) - return 0.; -} - -template -EIGEN_DEVICE_FUNC inline std::complex ptrue(const std::complex& /*a*/) { - RealScalar b = ptrue(RealScalar(0)); - return std::complex(b, b); -} - -template -EIGEN_DEVICE_FUNC inline Packet bitwise_helper(const Packet& a, const Packet& b, Op op) { - const unsigned char* a_ptr = reinterpret_cast(&a); - const unsigned char* b_ptr = reinterpret_cast(&b); - Packet c; - unsigned char* c_ptr = reinterpret_cast(&c); - for (size_t i = 0; i < sizeof(Packet); ++i) { - *c_ptr++ = op(*a_ptr++, *b_ptr++); - } - return c; -} template struct bit_and { @@ -287,42 +334,123 @@ struct bit_xor { } }; +template +struct bit_not { + EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE T operator()(const T& a) const { + return ~a; + } +}; + +// Use operators &, |, ^, ~. +template +struct operator_bitwise_helper { + EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) { return bit_and()(a, b); } + EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) { return bit_or()(a, b); } + EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) { return bit_xor()(a, b); } + EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) { return bit_not()(a); } +}; + +// Apply binary operations byte-by-byte +template +struct bytewise_bitwise_helper { + EIGEN_DEVICE_FUNC static inline T bitwise_and(const T& a, const T& b) { + return binary(a, b, bit_and()); + } + EIGEN_DEVICE_FUNC static inline T bitwise_or(const T& a, const T& b) { + return binary(a, b, bit_or()); + } + EIGEN_DEVICE_FUNC static inline T bitwise_xor(const T& a, const T& b) { + return binary(a, b, bit_xor()); + } + EIGEN_DEVICE_FUNC static inline T bitwise_not(const T& a) { + return unary(a,bit_not()); + } + + private: + template + EIGEN_DEVICE_FUNC static inline T unary(const T& a, Op op) { + const unsigned char* a_ptr = reinterpret_cast(&a); + T c; + unsigned char* c_ptr = reinterpret_cast(&c); + for (size_t i = 0; i < sizeof(T); ++i) { + *c_ptr++ = op(*a_ptr++); + } + return c; + } + + template + EIGEN_DEVICE_FUNC static inline T binary(const T& a, const T& b, Op op) { + const unsigned char* a_ptr = reinterpret_cast(&a); + const unsigned char* b_ptr = reinterpret_cast(&b); + T c; + unsigned char* c_ptr = reinterpret_cast(&c); + for (size_t i = 0; i < sizeof(T); ++i) { + *c_ptr++ = op(*a_ptr++, *b_ptr++); + } + return c; + } +}; + +// In the general case, use byte-by-byte manipulation. +template +struct bitwise_helper : public bytewise_bitwise_helper {}; + +// For integers or non-trivial scalars, use binary operators. +template +struct bitwise_helper::value && (NumTraits::IsInteger || NumTraits::RequireInitialization)>::type + > : public operator_bitwise_helper {}; + /** \internal \returns the bitwise and of \a a and \a b */ template EIGEN_DEVICE_FUNC inline Packet pand(const Packet& a, const Packet& b) { - return bitwise_helper(a, b, bit_and()); + return bitwise_helper::bitwise_and(a, b); } /** \internal \returns the bitwise or of \a a and \a b */ template EIGEN_DEVICE_FUNC inline Packet por(const Packet& a, const Packet& b) { - return bitwise_helper(a ,b, bit_or()); + return bitwise_helper::bitwise_or(a, b); } /** \internal \returns the bitwise xor of \a a and \a b */ template EIGEN_DEVICE_FUNC inline Packet pxor(const Packet& a, const Packet& b) { - return bitwise_helper(a ,b, bit_xor()); + return bitwise_helper::bitwise_xor(a, b); +} + +/** \internal \returns the bitwise not of \a a */ +template EIGEN_DEVICE_FUNC inline Packet +pnot(const Packet& a) { + return bitwise_helper::bitwise_not(a); } /** \internal \returns the bitwise and of \a a and not \a b */ template EIGEN_DEVICE_FUNC inline Packet -pandnot(const Packet& a, const Packet& b) { return pand(a, pxor(ptrue(b), b)); } +pandnot(const Packet& a, const Packet& b) { return pand(a, pnot(b)); } + +// In the general case, use bitwise select. +template +struct pselect_impl { + static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) { + return por(pand(a,mask),pandnot(b,mask)); + } +}; + +// For scalars, use ternary select. +template +struct pselect_impl::value>::type > { + static EIGEN_DEVICE_FUNC inline Packet run(const Packet& mask, const Packet& a, const Packet& b) { + return numext::equal_strict(mask, Packet(0)) ? b : a; + } +}; /** \internal \returns \a or \b for each field in packet according to \mask */ template EIGEN_DEVICE_FUNC inline Packet pselect(const Packet& mask, const Packet& a, const Packet& b) { - return por(pand(a,mask),pandnot(b,mask)); -} - -template<> EIGEN_DEVICE_FUNC inline float pselect( - const float& cond, const float& a, const float&b) { - return numext::equal_strict(cond,0.f) ? b : a; -} - -template<> EIGEN_DEVICE_FUNC inline double pselect( - const double& cond, const double& a, const double& b) { - return numext::equal_strict(cond,0.) ? b : a; + return pselect_impl::run(mask, a, b); } template<> EIGEN_DEVICE_FUNC inline bool pselect( diff --git a/external/eigen/Eigen/src/Core/Map.h b/external/eigen/Eigen/src/Core/Map.h index 93d2ae90..218cc157 100644 --- a/external/eigen/Eigen/src/Core/Map.h +++ b/external/eigen/Eigen/src/Core/Map.h @@ -47,7 +47,7 @@ struct traits > * \brief A matrix or vector expression mapping an existing array of data. * * \tparam PlainObjectType the equivalent matrix type of the mapped data - * \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, , \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned. + * \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned. * The default is \c #Unaligned. * \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout * of an ordinary, contiguous array. This can be overridden by specifying strides. diff --git a/external/eigen/Eigen/src/Core/MathFunctions.h b/external/eigen/Eigen/src/Core/MathFunctions.h index d7ac4d64..61b78f4f 100644 --- a/external/eigen/Eigen/src/Core/MathFunctions.h +++ b/external/eigen/Eigen/src/Core/MathFunctions.h @@ -572,7 +572,9 @@ struct rint_retval * Implementation of arg * ****************************************************************************/ -#if EIGEN_HAS_CXX11_MATH +// Visual Studio 2017 has a bug where arg(float) returns 0 for negative inputs. +// This seems to be fixed in VS 2019. +#if EIGEN_HAS_CXX11_MATH && (!EIGEN_COMP_MSVC || EIGEN_COMP_MSVC >= 1920) // std::arg is only defined for types of std::complex, or integer types or float/double/long double template::IsComplex || is_integral::value diff --git a/external/eigen/Eigen/src/Core/Solve.h b/external/eigen/Eigen/src/Core/Solve.h index af30fcec..23d5cb70 100644 --- a/external/eigen/Eigen/src/Core/Solve.h +++ b/external/eigen/Eigen/src/Core/Solve.h @@ -77,7 +77,7 @@ class Solve : public SolveImpl::type m_rhs; + const RhsType &m_rhs; }; diff --git a/external/eigen/Eigen/src/Core/arch/AVX/Complex.h b/external/eigen/Eigen/src/Core/arch/AVX/Complex.h index 0491be99..ab7bd6c6 100644 --- a/external/eigen/Eigen/src/Core/arch/AVX/Complex.h +++ b/external/eigen/Eigen/src/Core/arch/AVX/Complex.h @@ -167,12 +167,15 @@ template<> EIGEN_STRONG_INLINE std::complex predux_mul(const P Packet2cf(_mm256_extractf128_ps(a.v, 1)))); } - EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cf,Packet8f) template<> EIGEN_STRONG_INLINE Packet4cf pdiv(const Packet4cf& a, const Packet4cf& b) { - return pdiv_complex(a, b); + Packet4cf num = pmul(a, pconj(b)); + __m256 tmp = _mm256_mul_ps(b.v, b.v); + __m256 tmp2 = _mm256_shuffle_ps(tmp,tmp,0xB1); + __m256 denom = _mm256_add_ps(tmp, tmp2); + return Packet4cf(_mm256_div_ps(num.v, denom)); } template<> EIGEN_STRONG_INLINE Packet4cf pcplxflip(const Packet4cf& x) @@ -318,7 +321,10 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cd,Packet4d) template<> EIGEN_STRONG_INLINE Packet2cd pdiv(const Packet2cd& a, const Packet2cd& b) { - return pdiv_complex(a, b); + Packet2cd num = pmul(a, pconj(b)); + __m256d tmp = _mm256_mul_pd(b.v, b.v); + __m256d denom = _mm256_hadd_pd(tmp, tmp); + return Packet2cd(_mm256_div_pd(num.v, denom)); } template<> EIGEN_STRONG_INLINE Packet2cd pcplxflip(const Packet2cd& x) diff --git a/external/eigen/Eigen/src/Core/arch/AVX/PacketMath.h b/external/eigen/Eigen/src/Core/arch/AVX/PacketMath.h index dd3f243d..7fc32fd7 100644 --- a/external/eigen/Eigen/src/Core/arch/AVX/PacketMath.h +++ b/external/eigen/Eigen/src/Core/arch/AVX/PacketMath.h @@ -1274,12 +1274,7 @@ EIGEN_STRONG_INLINE Packet8f Bf16ToF32(const Packet8bf& a) { EIGEN_STRONG_INLINE Packet8bf F32ToBf16(const Packet8f& a) { Packet8bf r; - // Flush input denormals value to zero with hardware capability. - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); - __m256 flush = _mm256_and_ps(a, a); - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_OFF); - - __m256i input = _mm256_castps_si256(flush); + __m256i input = _mm256_castps_si256(a); #ifdef EIGEN_VECTORIZE_AVX2 // uint32_t lsb = (input >> 16); @@ -1293,7 +1288,7 @@ EIGEN_STRONG_INLINE Packet8bf F32ToBf16(const Packet8f& a) { // input = input >> 16; t = _mm256_srli_epi32(t, 16); // Check NaN before converting back to bf16 - __m256 mask = _mm256_cmp_ps(flush, flush, _CMP_ORD_Q); + __m256 mask = _mm256_cmp_ps(a, a, _CMP_ORD_Q); __m256i nan = _mm256_set1_epi32(0x7fc0); t = _mm256_blendv_epi8(nan, t, _mm256_castps_si256(mask)); // output = numext::bit_cast(input); @@ -1316,7 +1311,7 @@ EIGEN_STRONG_INLINE Packet8bf F32ToBf16(const Packet8f& a) { lo = _mm_srli_epi32(lo, 16); hi = _mm_srli_epi32(hi, 16); // Check NaN before converting back to bf16 - __m256 mask = _mm256_cmp_ps(flush, flush, _CMP_ORD_Q); + __m256 mask = _mm256_cmp_ps(a, a, _CMP_ORD_Q); __m128i nan = _mm_set1_epi32(0x7fc0); lo = _mm_blendv_epi8(nan, lo, _mm_castps_si128(_mm256_castps256_ps128(mask))); hi = _mm_blendv_epi8(nan, hi, _mm_castps_si128(_mm256_extractf128_ps(mask, 1))); diff --git a/external/eigen/Eigen/src/Core/arch/AVX512/Complex.h b/external/eigen/Eigen/src/Core/arch/AVX512/Complex.h index c11b8d2f..49c72b3f 100644 --- a/external/eigen/Eigen/src/Core/arch/AVX512/Complex.h +++ b/external/eigen/Eigen/src/Core/arch/AVX512/Complex.h @@ -157,7 +157,11 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet8cf,Packet16f) template<> EIGEN_STRONG_INLINE Packet8cf pdiv(const Packet8cf& a, const Packet8cf& b) { - return pdiv_complex(a, b); + Packet8cf num = pmul(a, pconj(b)); + __m512 tmp = _mm512_mul_ps(b.v, b.v); + __m512 tmp2 = _mm512_shuffle_ps(tmp,tmp,0xB1); + __m512 denom = _mm512_add_ps(tmp, tmp2); + return Packet8cf(_mm512_div_ps(num.v, denom)); } template<> EIGEN_STRONG_INLINE Packet8cf pcplxflip(const Packet8cf& x) @@ -305,11 +309,47 @@ template<> EIGEN_STRONG_INLINE std::complex predux_mul(const Packet2cd(_mm512_extractf64x4_pd(a.v,1)))); } +template<> struct conj_helper +{ + EIGEN_STRONG_INLINE Packet4cd pmadd(const Packet4cd& x, const Packet4cd& y, const Packet4cd& c) const + { return padd(pmul(x,y),c); } + + EIGEN_STRONG_INLINE Packet4cd pmul(const Packet4cd& a, const Packet4cd& b) const + { + return internal::pmul(a, pconj(b)); + } +}; + +template<> struct conj_helper +{ + EIGEN_STRONG_INLINE Packet4cd pmadd(const Packet4cd& x, const Packet4cd& y, const Packet4cd& c) const + { return padd(pmul(x,y),c); } + + EIGEN_STRONG_INLINE Packet4cd pmul(const Packet4cd& a, const Packet4cd& b) const + { + return internal::pmul(pconj(a), b); + } +}; + +template<> struct conj_helper +{ + EIGEN_STRONG_INLINE Packet4cd pmadd(const Packet4cd& x, const Packet4cd& y, const Packet4cd& c) const + { return padd(pmul(x,y),c); } + + EIGEN_STRONG_INLINE Packet4cd pmul(const Packet4cd& a, const Packet4cd& b) const + { + return pconj(internal::pmul(a, b)); + } +}; + EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cd,Packet8d) template<> EIGEN_STRONG_INLINE Packet4cd pdiv(const Packet4cd& a, const Packet4cd& b) { - return pdiv_complex(a, b); + Packet4cd num = pmul(a, pconj(b)); + __m512d tmp = _mm512_mul_pd(b.v, b.v); + __m512d denom = padd(_mm512_permute_pd(tmp,0x55), tmp); + return Packet4cd(_mm512_div_pd(num.v, denom)); } template<> EIGEN_STRONG_INLINE Packet4cd pcplxflip(const Packet4cd& x) diff --git a/external/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h b/external/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h index 59bbef0d..34d49ab6 100644 --- a/external/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h +++ b/external/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h @@ -1945,23 +1945,15 @@ EIGEN_STRONG_INLINE Packet16f Bf16ToF32(const Packet16bf& a) { EIGEN_STRONG_INLINE Packet16bf F32ToBf16(const Packet16f& a) { Packet16bf r; - // Flush input denormals value to zero with hardware capability. - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); -#if defined(EIGEN_VECTORIZE_AVX512DQ) - __m512 flush = _mm512_and_ps(a, a); -#else - __m512 flush = _mm512_max_ps(a, a); -#endif // EIGEN_VECTORIZE_AVX512DQ - _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_OFF); - #if defined(EIGEN_VECTORIZE_AVX512BF16) && EIGEN_GNUC_AT_LEAST(10, 1) // Since GCC 10.1 supports avx512bf16 and C style explicit cast // (C++ static_cast is not supported yet), do converion via intrinsic // and register path for performance. - r = (__m256i)(_mm512_cvtneps_pbh(flush)); + r = (__m256i)(_mm512_cvtneps_pbh(a)); + #else __m512i t; - __m512i input = _mm512_castps_si512(flush); + __m512i input = _mm512_castps_si512(a); __m512i nan = _mm512_set1_epi32(0x7fc0); // uint32_t lsb = (input >> 16) & 1; @@ -1974,9 +1966,9 @@ EIGEN_STRONG_INLINE Packet16bf F32ToBf16(const Packet16f& a) { t = _mm512_srli_epi32(t, 16); // Check NaN before converting back to bf16 - __mmask16 mask = _mm512_cmp_ps_mask(flush, flush, _CMP_ORD_Q); - t = _mm512_mask_blend_epi32(mask, nan, t); + __mmask16 mask = _mm512_cmp_ps_mask(a, a, _CMP_ORD_Q); + t = _mm512_mask_blend_epi32(mask, nan, t); // output.value = static_cast(input); r = _mm512_cvtepi32_epi16(t); #endif // EIGEN_VECTORIZE_AVX512BF16 diff --git a/external/eigen/Eigen/src/Core/arch/AltiVec/Complex.h b/external/eigen/Eigen/src/Core/arch/AltiVec/Complex.h index 058f8dd1..f424f11c 100644 --- a/external/eigen/Eigen/src/Core/arch/AltiVec/Complex.h +++ b/external/eigen/Eigen/src/Core/arch/AltiVec/Complex.h @@ -74,7 +74,7 @@ struct Packet2cf return Packet2cf(*this) -= b; } EIGEN_STRONG_INLINE Packet2cf operator-(void) const { - return Packet2cf(vec_neg(v)); + return Packet2cf(-v); } Packet4f v; @@ -210,7 +210,10 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { - return pdiv_complex(a, b); + // TODO optimize it for AltiVec + Packet2cf res = pmul(a, pconj(b)); + Packet4f s = pmul(b.v, b.v); + return Packet2cf(pdiv(res.v, padd(s, vec_perm(s, s, p16uc_COMPLEX32_REV)))); } template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip(const Packet2cf& x) @@ -291,7 +294,7 @@ struct Packet1cd return Packet1cd(*this) -= b; } EIGEN_STRONG_INLINE Packet1cd operator-(void) const { - return Packet1cd(vec_neg(v)); + return Packet1cd(-v); } Packet2d v; @@ -372,7 +375,10 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { - return pdiv_complex(a, b); + // TODO optimize it for AltiVec + Packet1cd res = pmul(a,pconj(b)); + Packet2d s = pmul(b.v, b.v); + return Packet1cd(pdiv(res.v, padd(s, vec_perm(s, s, p16uc_REVERSE64)))); } EIGEN_STRONG_INLINE Packet1cd pcplxflip/**/(const Packet1cd& x) diff --git a/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h b/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h index 454b36cd..3f79b97d 100644 --- a/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +++ b/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProduct.h @@ -1113,7 +1113,7 @@ EIGEN_ALWAYS_INLINE void pgerc(PacketBlock* accReal, PacketBlock EIGEN_ALWAYS_INLINE Packet ploadLhs(const Scalar* lhs) { - return *reinterpret_cast(const_cast(lhs)); + return ploadu(lhs); } // Zero the accumulator on PacketBlock. @@ -1570,7 +1570,7 @@ EIGEN_STRONG_INLINE void gemm_unrolled_iteration( const Packet& pAlpha) { const Scalar* rhs_ptr = rhs_base; - const Scalar* lhs_ptr0, * lhs_ptr1, * lhs_ptr2, * lhs_ptr3, * lhs_ptr4, * lhs_ptr5, * lhs_ptr6, * lhs_ptr7; + 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; PacketBlock accZero0, accZero1, accZero2, accZero3, accZero4, accZero5, accZero6, accZero7; PacketBlock acc; @@ -1607,7 +1607,7 @@ EIGEN_STRONG_INLINE void gemm_unrolled_col_iteration( const Packet& pAlpha) { const Scalar* rhs_ptr = rhs_base; - const Scalar* lhs_ptr0, * lhs_ptr1, * lhs_ptr2, * lhs_ptr3, * lhs_ptr4, * lhs_ptr5, * lhs_ptr6, *lhs_ptr7; + 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; PacketBlock accZero0, accZero1, accZero2, accZero3, accZero4, accZero5, accZero6, accZero7; PacketBlock acc; @@ -2180,9 +2180,9 @@ EIGEN_STRONG_INLINE void gemm_complex_unrolled_iteration( } else { EIGEN_UNUSED_VARIABLE(rhs_ptr_imag); } - const Scalar* lhs_ptr_real0, * lhs_ptr_imag0, * lhs_ptr_real1, * lhs_ptr_imag1; - const Scalar* lhs_ptr_real2, * lhs_ptr_imag2, * lhs_ptr_real3, * lhs_ptr_imag3; - const Scalar* lhs_ptr_real4, * lhs_ptr_imag4; + const Scalar* lhs_ptr_real0 = NULL, * lhs_ptr_imag0 = NULL, * lhs_ptr_real1 = NULL, * lhs_ptr_imag1 = NULL; + const Scalar* lhs_ptr_real2 = NULL, * lhs_ptr_imag2 = NULL, * lhs_ptr_real3 = NULL, * lhs_ptr_imag3 = NULL; + const Scalar* lhs_ptr_real4 = NULL, * lhs_ptr_imag4 = NULL; PacketBlock accReal0, accImag0, accReal1, accImag1; PacketBlock accReal2, accImag2, accReal3, accImag3; PacketBlock accReal4, accImag4; @@ -2234,9 +2234,9 @@ EIGEN_STRONG_INLINE void gemm_complex_unrolled_col_iteration( } else { EIGEN_UNUSED_VARIABLE(rhs_ptr_imag); } - const Scalar* lhs_ptr_real0, * lhs_ptr_imag0, * lhs_ptr_real1, * lhs_ptr_imag1; - const Scalar* lhs_ptr_real2, * lhs_ptr_imag2, * lhs_ptr_real3, * lhs_ptr_imag3; - const Scalar* lhs_ptr_real4, * lhs_ptr_imag4; + const Scalar* lhs_ptr_real0 = NULL, * lhs_ptr_imag0 = NULL, * lhs_ptr_real1 = NULL, * lhs_ptr_imag1 = NULL; + const Scalar* lhs_ptr_real2 = NULL, * lhs_ptr_imag2 = NULL, * lhs_ptr_real3 = NULL, * lhs_ptr_imag3 = NULL; + const Scalar* lhs_ptr_real4 = NULL, * lhs_ptr_imag4 = NULL; PacketBlock accReal0, accImag0, accReal1, accImag1; PacketBlock accReal2, accImag2, accReal3, accImag3; PacketBlock accReal4, accImag4; diff --git a/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h b/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h index 41b27bf3..33d54349 100644 --- a/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +++ b/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h @@ -214,7 +214,7 @@ EIGEN_ALWAYS_INLINE void bcouple_common(PacketBlock EIGEN_ALWAYS_INLINE Packet ploadRhs(const Scalar* rhs) { - return *reinterpret_cast(const_cast(rhs)); + return ploadu(rhs); } } // end namespace internal diff --git a/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h b/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h index 13d9517e..6540c6fa 100644 --- a/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +++ b/external/eigen/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h @@ -256,7 +256,7 @@ EIGEN_STRONG_INLINE void gemm_unrolled_MMA_iteration( const Packet& pAlpha) { const Scalar* rhs_ptr = rhs_base; - const Scalar* lhs_ptr0, * lhs_ptr1, * lhs_ptr2, * lhs_ptr3, * lhs_ptr4, * lhs_ptr5, * lhs_ptr6, * lhs_ptr7; + 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; __vector_quad accZero0, accZero1, accZero2, accZero3, accZero4, accZero5, accZero6, accZero7; MICRO_MMA_SRC_PTR @@ -510,9 +510,9 @@ EIGEN_STRONG_INLINE void gemm_complex_unrolled_MMA_iteration( } else { EIGEN_UNUSED_VARIABLE(rhs_ptr_imag); } - const Scalar* lhs_ptr_real0, * lhs_ptr_imag0, * lhs_ptr_real1, * lhs_ptr_imag1; - const Scalar* lhs_ptr_real2, * lhs_ptr_imag2, * lhs_ptr_real3, * lhs_ptr_imag3; - const Scalar* lhs_ptr_real4, * lhs_ptr_imag4; + const Scalar* lhs_ptr_real0 = NULL, * lhs_ptr_imag0 = NULL, * lhs_ptr_real1 = NULL, * lhs_ptr_imag1 = NULL; + const Scalar* lhs_ptr_real2 = NULL, * lhs_ptr_imag2 = NULL, * lhs_ptr_real3 = NULL, * lhs_ptr_imag3 = NULL; + const Scalar* lhs_ptr_real4 = NULL, * lhs_ptr_imag4 = NULL; __vector_quad accReal0, accImag0, accReal1, accImag1, accReal2, accImag2, accReal3, accImag3, accReal4, accImag4; MICRO_COMPLEX_MMA_SRC_PTR diff --git a/external/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h b/external/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h index 8c42f495..2a440545 100755 --- a/external/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ b/external/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h @@ -433,7 +433,7 @@ EIGEN_STRONG_INLINE Packet pload_common(const __UNPACK_TYPE__(Packet)* from) EIGEN_UNUSED_VARIABLE(from); EIGEN_DEBUG_ALIGNED_LOAD #ifdef __VSX__ - return vec_xl(0, from); + return vec_xl(0, const_cast<__UNPACK_TYPE__(Packet)*>(from)); #else return vec_ld(0, from); #endif @@ -867,17 +867,26 @@ template<> EIGEN_STRONG_INLINE Packet16uc pmax(const Packet16uc& a, template<> EIGEN_STRONG_INLINE Packet4f pcmp_le(const Packet4f& a, const Packet4f& b) { return reinterpret_cast(vec_cmple(a,b)); } template<> EIGEN_STRONG_INLINE Packet4f pcmp_lt(const Packet4f& a, const Packet4f& b) { return reinterpret_cast(vec_cmplt(a,b)); } template<> EIGEN_STRONG_INLINE Packet4f pcmp_eq(const Packet4f& a, const Packet4f& b) { return reinterpret_cast(vec_cmpeq(a,b)); } -template<> EIGEN_STRONG_INLINE Packet16c pcmp_eq(const Packet16c& a, const Packet16c& b) { return reinterpret_cast(vec_cmpeq(a,b)); } -template<> EIGEN_STRONG_INLINE Packet16uc pcmp_eq(const Packet16uc& a, const Packet16uc& b) { return reinterpret_cast(vec_cmpeq(a,b)); } - -template<> EIGEN_STRONG_INLINE Packet8s pcmp_eq(const Packet8s& a, const Packet8s& b) { return reinterpret_cast(vec_cmpeq(a,b)); } -template<> EIGEN_STRONG_INLINE Packet8us pcmp_eq(const Packet8us& a, const Packet8us& b) { return reinterpret_cast(vec_cmpeq(a,b)); } - template<> EIGEN_STRONG_INLINE Packet4f pcmp_lt_or_nan(const Packet4f& a, const Packet4f& b) { Packet4f c = reinterpret_cast(vec_cmpge(a,b)); return vec_nor(c,c); } + +template<> EIGEN_STRONG_INLINE Packet4i pcmp_le(const Packet4i& a, const Packet4i& b) { return reinterpret_cast(vec_cmple(a,b)); } +template<> EIGEN_STRONG_INLINE Packet4i pcmp_lt(const Packet4i& a, const Packet4i& b) { return reinterpret_cast(vec_cmplt(a,b)); } template<> EIGEN_STRONG_INLINE Packet4i pcmp_eq(const Packet4i& a, const Packet4i& b) { return reinterpret_cast(vec_cmpeq(a,b)); } +template<> EIGEN_STRONG_INLINE Packet8s pcmp_le(const Packet8s& a, const Packet8s& b) { return reinterpret_cast(vec_cmple(a,b)); } +template<> EIGEN_STRONG_INLINE Packet8s pcmp_lt(const Packet8s& a, const Packet8s& b) { return reinterpret_cast(vec_cmplt(a,b)); } +template<> EIGEN_STRONG_INLINE Packet8s pcmp_eq(const Packet8s& a, const Packet8s& b) { return reinterpret_cast(vec_cmpeq(a,b)); } +template<> EIGEN_STRONG_INLINE Packet8us pcmp_le(const Packet8us& a, const Packet8us& b) { return reinterpret_cast(vec_cmple(a,b)); } +template<> EIGEN_STRONG_INLINE Packet8us pcmp_lt(const Packet8us& a, const Packet8us& b) { return reinterpret_cast(vec_cmplt(a,b)); } +template<> EIGEN_STRONG_INLINE Packet8us pcmp_eq(const Packet8us& a, const Packet8us& b) { return reinterpret_cast(vec_cmpeq(a,b)); } +template<> EIGEN_STRONG_INLINE Packet16c pcmp_le(const Packet16c& a, const Packet16c& b) { return reinterpret_cast(vec_cmple(a,b)); } +template<> EIGEN_STRONG_INLINE Packet16c pcmp_lt(const Packet16c& a, const Packet16c& b) { return reinterpret_cast(vec_cmplt(a,b)); } +template<> EIGEN_STRONG_INLINE Packet16c pcmp_eq(const Packet16c& a, const Packet16c& b) { return reinterpret_cast(vec_cmpeq(a,b)); } +template<> EIGEN_STRONG_INLINE Packet16uc pcmp_le(const Packet16uc& a, const Packet16uc& b) { return reinterpret_cast(vec_cmple(a,b)); } +template<> EIGEN_STRONG_INLINE Packet16uc pcmp_lt(const Packet16uc& a, const Packet16uc& b) { return reinterpret_cast(vec_cmplt(a,b)); } +template<> EIGEN_STRONG_INLINE Packet16uc pcmp_eq(const Packet16uc& a, const Packet16uc& b) { return reinterpret_cast(vec_cmpeq(a,b)); } template<> EIGEN_STRONG_INLINE Packet4f pand(const Packet4f& a, const Packet4f& b) { return vec_and(a, b); } template<> EIGEN_STRONG_INLINE Packet4i pand(const Packet4i& a, const Packet4i& b) { return vec_and(a, b); } @@ -902,8 +911,8 @@ template<> EIGEN_STRONG_INLINE Packet8bf pxor(const Packet8bf& a, con return pxor(a, b); } -template<> EIGEN_STRONG_INLINE Packet4f pandnot(const Packet4f& a, const Packet4f& b) { return vec_and(a, vec_nor(b, b)); } -template<> EIGEN_STRONG_INLINE Packet4i pandnot(const Packet4i& a, const Packet4i& b) { return vec_and(a, vec_nor(b, b)); } +template<> EIGEN_STRONG_INLINE Packet4f pandnot(const Packet4f& a, const Packet4f& b) { return vec_andc(a, b); } +template<> EIGEN_STRONG_INLINE Packet4i pandnot(const Packet4i& a, const Packet4i& b) { return vec_andc(a, b); } template<> EIGEN_STRONG_INLINE Packet4f pselect(const Packet4f& mask, const Packet4f& a, const Packet4f& b) { return vec_sel(b, a, reinterpret_cast(mask)); @@ -952,7 +961,7 @@ template EIGEN_STRONG_INLINE Packet ploadu_common(const __UNPAC return (Packet) vec_perm(MSQ, LSQ, mask); // align the data #else EIGEN_DEBUG_UNALIGNED_LOAD - return vec_xl(0, from); + return vec_xl(0, const_cast<__UNPACK_TYPE__(Packet)*>(from)); #endif } @@ -1260,15 +1269,15 @@ EIGEN_STRONG_INLINE Packet8bf F32ToBf16(Packet4f p4f){ Packet4bi is_max_exp = vec_cmpeq(exp, p4ui_max_exp); Packet4bi is_zero_exp = vec_cmpeq(exp, reinterpret_cast(p4i_ZERO)); - Packet4bi is_mant_not_zero = vec_cmpne(mantissa, reinterpret_cast(p4i_ZERO)); - Packet4ui nan_selector = pand( + Packet4bi is_mant_zero = vec_cmpeq(mantissa, reinterpret_cast(p4i_ZERO)); + Packet4ui nan_selector = pandnot( reinterpret_cast(is_max_exp), - reinterpret_cast(is_mant_not_zero) + reinterpret_cast(is_mant_zero) ); - Packet4ui subnormal_selector = pand( + Packet4ui subnormal_selector = pandnot( reinterpret_cast(is_zero_exp), - reinterpret_cast(is_mant_not_zero) + reinterpret_cast(is_mant_zero) ); const _EIGEN_DECLARE_CONST_FAST_Packet4ui(nan, 0x7FC00000); @@ -2453,7 +2462,7 @@ template<> EIGEN_STRONG_INLINE Packet2d print(const Packet2d& a) template<> EIGEN_STRONG_INLINE Packet2d ploadu(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD - return vec_xl(0, from); + return vec_xl(0, const_cast(from)); } template<> EIGEN_STRONG_INLINE Packet2d ploaddup(const double* from) diff --git a/external/eigen/Eigen/src/Core/arch/Default/BFloat16.h b/external/eigen/Eigen/src/Core/arch/Default/BFloat16.h index aac60f15..1c28f4f9 100644 --- a/external/eigen/Eigen/src/Core/arch/Default/BFloat16.h +++ b/external/eigen/Eigen/src/Core/arch/Default/BFloat16.h @@ -250,10 +250,6 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __bfloat16_raw truncate_to_bfloat16(const if (Eigen::numext::isnan EIGEN_NOT_A_MACRO(v)) { output.value = std::signbit(v) ? 0xFFC0: 0x7FC0; return output; - } else if (std::fabs(v) < std::numeric_limits::min EIGEN_NOT_A_MACRO()) { - // Flush denormal to +/- 0. - output.value = std::signbit(v) ? 0x8000 : 0; - return output; } const uint16_t* p = reinterpret_cast(&v); #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ @@ -288,9 +284,6 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __bfloat16_raw float_to_bfloat16_rtne::min EIGEN_NOT_A_MACRO()) { - // Flush denormal to +/- 0.0 - output.value = std::signbit(ff) ? 0x8000 : 0; } else { // Fast rounding algorithm that rounds a half value to nearest even. This // reduces expected error when we convert a large number of floats. Here diff --git a/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h b/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h index 596d8a52..c9fbaf68 100644 --- a/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +++ b/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h @@ -757,26 +757,6 @@ Packet pcos_float(const Packet& x) return psincos_float(x); } -template -EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -EIGEN_UNUSED Packet pdiv_complex(const Packet& x, const Packet& y) { - typedef typename unpacket_traits::as_real RealPacket; - // In the following we annotate the code for the case where the inputs - // are a pair length-2 SIMD vectors representing a single pair of complex - // numbers x = a + i*b, y = c + i*d. - const RealPacket y_abs = pabs(y.v); // |c|, |d| - const RealPacket y_abs_flip = pcplxflip(Packet(y_abs)).v; // |d|, |c| - const RealPacket y_max = pmax(y_abs, y_abs_flip); // max(|c|, |d|), max(|c|, |d|) - const RealPacket y_scaled = pdiv(y.v, y_max); // c / max(|c|, |d|), d / max(|c|, |d|) - // Compute scaled denominator. - const RealPacket y_scaled_sq = pmul(y_scaled, y_scaled); // c'**2, d'**2 - const RealPacket denom = padd(y_scaled_sq, pcplxflip(Packet(y_scaled_sq)).v); - Packet result_scaled = pmul(x, pconj(Packet(y_scaled))); // a * c' + b * d', -a * d + b * c - // Divide elementwise by denom. - result_scaled = Packet(pdiv(result_scaled.v, denom)); - // Rescale result - return Packet(pdiv(result_scaled.v, y_max)); -} template EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS diff --git a/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h b/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h index 730cc739..177a04e9 100644 --- a/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +++ b/external/eigen/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h @@ -101,12 +101,6 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet psqrt_complex(const Packet& a); -/** \internal \returns x / y for complex types */ -template -EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -EIGEN_UNUSED -Packet pdiv_complex(const Packet& x, const Packet& y); - template struct ppolevl; diff --git a/external/eigen/Eigen/src/Core/arch/MSA/Complex.h b/external/eigen/Eigen/src/Core/arch/MSA/Complex.h index 76e9f7ca..53dacfa4 100644 --- a/external/eigen/Eigen/src/Core/arch/MSA/Complex.h +++ b/external/eigen/Eigen/src/Core/arch/MSA/Complex.h @@ -75,13 +75,16 @@ struct Packet2cf { EIGEN_STRONG_INLINE Packet2cf operator-(const Packet2cf& b) const { return Packet2cf(*this) -= b; } - EIGEN_STRONG_INLINE Packet2cf operator/(const Packet2cf& b) const { - return pdiv_complex(Packet2cf(*this), b); - } EIGEN_STRONG_INLINE Packet2cf& operator/=(const Packet2cf& b) { - *this = Packet2cf(*this) / b; + *this *= b.conjugate(); + Packet4f s = pmul(b.v, b.v); + s = padd(s, (Packet4f)__builtin_msa_shf_w((v4i32)s, EIGEN_MSA_SHF_I8(1, 0, 3, 2))); + v = pdiv(v, s); return *this; } + EIGEN_STRONG_INLINE Packet2cf operator/(const Packet2cf& b) const { + return Packet2cf(*this) /= b; + } EIGEN_STRONG_INLINE Packet2cf operator-(void) const { return Packet2cf(pnegate(v)); } diff --git a/external/eigen/Eigen/src/Core/arch/NEON/Complex.h b/external/eigen/Eigen/src/Core/arch/NEON/Complex.h index 0f74fe8d..f40af7f8 100644 --- a/external/eigen/Eigen/src/Core/arch/NEON/Complex.h +++ b/external/eigen/Eigen/src/Core/arch/NEON/Complex.h @@ -347,11 +347,27 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) template<> EIGEN_STRONG_INLINE Packet1cf pdiv(const Packet1cf& a, const Packet1cf& b) { - return pdiv_complex(a, b); + // TODO optimize it for NEON + Packet1cf res = pmul(a, pconj(b)); + Packet2f s, rev_s; + + // this computes the norm + s = vmul_f32(b.v, b.v); + rev_s = vrev64_f32(s); + + return Packet1cf(pdiv(res.v, vadd_f32(s, rev_s))); } template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { - return pdiv_complex(a, b); + // TODO optimize it for NEON + Packet2cf res = pmul(a,pconj(b)); + Packet4f s, rev_s; + + // this computes the norm + s = vmulq_f32(b.v, b.v); + rev_s = vrev64q_f32(s); + + return Packet2cf(pdiv(res.v, vaddq_f32(s, rev_s))); } EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock& /*kernel*/) {} @@ -537,7 +553,12 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { - return pdiv_complex(a, b); + // TODO optimize it for NEON + Packet1cd res = pmul(a,pconj(b)); + Packet2d s = pmul(b.v, b.v); + Packet2d rev_s = preverse(s); + + return Packet1cd(pdiv(res.v, padd(s,rev_s))); } EIGEN_STRONG_INLINE Packet1cd pcplxflip/**/(const Packet1cd& x) diff --git a/external/eigen/Eigen/src/Core/arch/SSE/Complex.h b/external/eigen/Eigen/src/Core/arch/SSE/Complex.h index 08abd845..8fe22da4 100644 --- a/external/eigen/Eigen/src/Core/arch/SSE/Complex.h +++ b/external/eigen/Eigen/src/Core/arch/SSE/Complex.h @@ -174,9 +174,14 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { - return pdiv_complex(a, b); + // TODO optimize it for SSE3 and 4 + Packet2cf res = pmul(a, pconj(b)); + __m128 s = _mm_mul_ps(b.v,b.v); + return Packet2cf(_mm_div_ps(res.v,_mm_add_ps(s,vec4f_swizzle1(s, 1, 0, 3, 2)))); } + + //---------- double ---------- struct Packet1cd { @@ -294,7 +299,10 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { - return pdiv_complex(a, b); + // TODO optimize it for SSE3 and 4 + Packet1cd res = pmul(a,pconj(b)); + __m128d s = _mm_mul_pd(b.v,b.v); + return Packet1cd(_mm_div_pd(res.v, _mm_add_pd(s,_mm_shuffle_pd(s, s, 0x1)))); } EIGEN_STRONG_INLINE Packet1cd pcplxflip/* */(const Packet1cd& x) diff --git a/external/eigen/Eigen/src/Core/arch/ZVector/Complex.h b/external/eigen/Eigen/src/Core/arch/ZVector/Complex.h index a81ec249..0b9b33d9 100644 --- a/external/eigen/Eigen/src/Core/arch/ZVector/Complex.h +++ b/external/eigen/Eigen/src/Core/arch/ZVector/Complex.h @@ -169,7 +169,10 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { - return pdiv_complex(a, b); + // TODO optimize it for AltiVec + Packet1cd res = pmul(a,pconj(b)); + Packet2d s = vec_madd(b.v, b.v, p2d_ZERO_); + return Packet1cd(pdiv(res.v, s + vec_perm(s, s, p16uc_REVERSE64))); } EIGEN_STRONG_INLINE Packet1cd pcplxflip/**/(const Packet1cd& x) @@ -305,7 +308,11 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { - return pdiv_complex(a, b); + // TODO optimize it for AltiVec + Packet2cf res; + res.cd[0] = pdiv(a.cd[0], b.cd[0]); + res.cd[1] = pdiv(a.cd[1], b.cd[1]); + return res; } EIGEN_STRONG_INLINE Packet2cf pcplxflip/**/(const Packet2cf& x) @@ -387,7 +394,10 @@ EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { - return pdiv_complex(a, b); + // TODO optimize it for AltiVec + Packet2cf res = pmul(a, pconj(b)); + Packet4f s = pmul(b.v, b.v); + return Packet2cf(pdiv(res.v, padd(s, vec_perm(s, s, p16uc_COMPLEX32_REV)))); } template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip(const Packet2cf& x) diff --git a/external/eigen/Eigen/src/Core/functors/StlFunctors.h b/external/eigen/Eigen/src/Core/functors/StlFunctors.h index d2e7b5b0..4570c9b6 100644 --- a/external/eigen/Eigen/src/Core/functors/StlFunctors.h +++ b/external/eigen/Eigen/src/Core/functors/StlFunctors.h @@ -12,6 +12,28 @@ namespace Eigen { +// Portable replacements for certain functors. +namespace numext { + +template +struct equal_to { + typedef bool result_type; + EIGEN_DEVICE_FUNC bool operator()(const T& lhs, const T& rhs) const { + return lhs == rhs; + } +}; + +template +struct not_equal_to { + typedef bool result_type; + EIGEN_DEVICE_FUNC bool operator()(const T& lhs, const T& rhs) const { + return lhs != rhs; + } +}; + +} + + namespace internal { // default functor traits for STL functors: @@ -68,10 +90,18 @@ template struct functor_traits > { enum { Cost = 1, PacketAccess = false }; }; +template +struct functor_traits > + : functor_traits > {}; + template struct functor_traits > { enum { Cost = 1, PacketAccess = false }; }; +template +struct functor_traits > + : functor_traits > {}; + #if (EIGEN_COMP_CXXVER < 11) // std::binder* are deprecated since c++11 and will be removed in c++17 template diff --git a/external/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/external/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h index 1116321a..f35b760c 100644 --- a/external/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ b/external/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h @@ -44,7 +44,7 @@ inline std::ptrdiff_t manage_caching_sizes_helper(std::ptrdiff_t a, std::ptrdiff #endif // defined(EIGEN_DEFAULT_L2_CACHE_SIZE) #if defined(EIGEN_DEFAULT_L3_CACHE_SIZE) -#define EIGEN_SET_DEFAULT_L3_CACHE_SIZE(val) EIGEN_SET_DEFAULT_L3_CACHE_SIZE +#define EIGEN_SET_DEFAULT_L3_CACHE_SIZE(val) EIGEN_DEFAULT_L3_CACHE_SIZE #else #define EIGEN_SET_DEFAULT_L3_CACHE_SIZE(val) val #endif // defined(EIGEN_DEFAULT_L3_CACHE_SIZE) diff --git a/external/eigen/Eigen/src/Core/util/Constants.h b/external/eigen/Eigen/src/Core/util/Constants.h index f7f907ab..35dcaa7b 100644 --- a/external/eigen/Eigen/src/Core/util/Constants.h +++ b/external/eigen/Eigen/src/Core/util/Constants.h @@ -157,7 +157,7 @@ const unsigned int DirectAccessBit = 0x40; /** \deprecated \ingroup flags * * means the first coefficient packet is guaranteed to be aligned. - * An expression cannot has the AlignedBit without the PacketAccessBit flag. + * An expression cannot have the AlignedBit without the PacketAccessBit flag. * In other words, this means we are allow to perform an aligned packet access to the first element regardless * of the expression kind: * \code diff --git a/external/eigen/Eigen/src/Core/util/DisableStupidWarnings.h b/external/eigen/Eigen/src/Core/util/DisableStupidWarnings.h index b85aeae3..fe0cfec0 100755 --- a/external/eigen/Eigen/src/Core/util/DisableStupidWarnings.h +++ b/external/eigen/Eigen/src/Core/util/DisableStupidWarnings.h @@ -45,10 +45,7 @@ #pragma clang diagnostic ignored "-Wabsolute-value" #endif #if __clang_major__ >= 10 - // https://stackoverflow.com/questions/40761120/unknown-warning-group-wmaybe-unintialized-mac-os-sierra - #if !defined(__has_warning) || __has_warning("-Wimplicit-int-float-conversion") #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" - #endif #endif #if ( defined(__ALTIVEC__) || defined(__VSX__) ) && __cplusplus < 201103L // warning: generic selections are a C11-specific feature diff --git a/external/eigen/Eigen/src/Core/util/Macros.h b/external/eigen/Eigen/src/Core/util/Macros.h index fca94a98..986c3d44 100644 --- a/external/eigen/Eigen/src/Core/util/Macros.h +++ b/external/eigen/Eigen/src/Core/util/Macros.h @@ -16,8 +16,8 @@ //------------------------------------------------------------------------------------------ #define EIGEN_WORLD_VERSION 3 -#define EIGEN_MAJOR_VERSION 3 -#define EIGEN_MINOR_VERSION 90 +#define EIGEN_MAJOR_VERSION 4 +#define EIGEN_MINOR_VERSION 0 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ @@ -1185,8 +1185,12 @@ namespace Eigen { #define EIGEN_USING_STD(FUNC) using std::FUNC; #endif -#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || EIGEN_COMP_NVCC) - // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324) +#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || (EIGEN_COMP_MSVC == 1900 && EIGEN_COMP_NVCC)) + // For older MSVC versions, as well as 1900 && CUDA 8, using the base operator is necessary, + // otherwise we get duplicate definition errors + // For later MSVC versions, we require explicit operator= definition, otherwise we get + // use of implicitly deleted operator errors. + // (cf Bugs 920, 1000, 1324, 2291) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ using Base::operator =; #elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653) diff --git a/external/eigen/Eigen/src/Core/util/Meta.h b/external/eigen/Eigen/src/Core/util/Meta.h index 2429ddad..81ae2a32 100755 --- a/external/eigen/Eigen/src/Core/util/Meta.h +++ b/external/eigen/Eigen/src/Core/util/Meta.h @@ -715,20 +715,25 @@ class meta_sqrt { public: enum { ret = (SupX*SupX <= Y) ? /** \internal Computes the least common multiple of two positive integer A and B - * at compile-time. It implements a naive algorithm testing all multiples of A. - * It thus works better if A>=B. + * at compile-time. */ -template +template=B)> struct meta_least_common_multiple { enum { ret = meta_least_common_multiple::ret }; }; +template +struct meta_least_common_multiple +{ + enum { ret = meta_least_common_multiple::ret }; +}; template -struct meta_least_common_multiple +struct meta_least_common_multiple { enum { ret = A*K }; }; + /** \internal determines whether the product of two numeric types is allowed and what the return type is */ template struct scalar_product_traits { diff --git a/external/eigen/Eigen/src/Core/util/XprHelper.h b/external/eigen/Eigen/src/Core/util/XprHelper.h index f2323174..71c32b8a 100644 --- a/external/eigen/Eigen/src/Core/util/XprHelper.h +++ b/external/eigen/Eigen/src/Core/util/XprHelper.h @@ -184,19 +184,7 @@ template struct functor_traits template struct packet_traits; -template struct unpacket_traits -{ - typedef T type; - typedef T half; - enum - { - size = 1, - alignment = 1, - vectorizable = false, - masked_load_available=false, - masked_store_available=false - }; -}; +template struct unpacket_traits; template::size)==0 || is_same::half>::value> diff --git a/external/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/external/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index 59e59644..14692365 100644 --- a/external/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/external/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -125,6 +125,7 @@ template class SelfAdjointEigenSolver : m_eivec(), m_eivalues(), m_subdiag(), + m_hcoeffs(), m_info(InvalidInput), m_isInitialized(false), m_eigenvectorsOk(false) @@ -147,6 +148,7 @@ template class SelfAdjointEigenSolver : m_eivec(size, size), m_eivalues(size), m_subdiag(size > 1 ? size - 1 : 1), + m_hcoeffs(size > 1 ? size - 1 : 1), m_isInitialized(false), m_eigenvectorsOk(false) {} @@ -172,6 +174,7 @@ template class SelfAdjointEigenSolver : m_eivec(matrix.rows(), matrix.cols()), m_eivalues(matrix.cols()), m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1), + m_hcoeffs(matrix.cols() > 1 ? matrix.cols() - 1 : 1), m_isInitialized(false), m_eigenvectorsOk(false) { @@ -378,6 +381,7 @@ template class SelfAdjointEigenSolver EigenvectorsType m_eivec; RealVectorType m_eivalues; typename TridiagonalizationType::SubDiagonalType m_subdiag; + typename TridiagonalizationType::CoeffVectorType m_hcoeffs; ComputationInfo m_info; bool m_isInitialized; bool m_eigenvectorsOk; @@ -450,7 +454,8 @@ ::compute(const EigenBase& a_matrix, int options) if(scale==RealScalar(0)) scale = RealScalar(1); mat.template triangularView() /= scale; m_subdiag.resize(n-1); - internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors); + m_hcoeffs.resize(n-1); + internal::tridiagonalization_inplace(mat, diag, m_subdiag, m_hcoeffs, computeEigenvectors); m_info = internal::computeFromTridiagonal_impl(diag, m_subdiag, m_maxIterations, computeEigenvectors, m_eivec); diff --git a/external/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h b/external/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h index 6c8084f7..674c92a3 100644 --- a/external/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h +++ b/external/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h @@ -425,12 +425,13 @@ struct tridiagonalization_inplace_selector; * * \sa class Tridiagonalization */ -template +template EIGEN_DEVICE_FUNC -void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) +void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, + CoeffVectorType& hcoeffs, bool extractQ) { eigen_assert(mat.cols()==mat.rows() && diag.size()==mat.rows() && subdiag.size()==mat.rows()-1); - tridiagonalization_inplace_selector::run(mat, diag, subdiag, extractQ); + tridiagonalization_inplace_selector::run(mat, diag, subdiag, hcoeffs, extractQ); } /** \internal @@ -443,10 +444,9 @@ struct tridiagonalization_inplace_selector typedef typename Tridiagonalization::HouseholderSequenceType HouseholderSequenceType; template static EIGEN_DEVICE_FUNC - void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) + void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, CoeffVectorType& hCoeffs, bool extractQ) { - CoeffVectorType hCoeffs(mat.cols()-1); - tridiagonalization_inplace(mat,hCoeffs); + tridiagonalization_inplace(mat, hCoeffs); diag = mat.diagonal().real(); subdiag = mat.template diagonal<-1>().real(); if(extractQ) @@ -466,8 +466,8 @@ struct tridiagonalization_inplace_selector typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; - template - static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ) + template + static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, CoeffVectorType&, bool extractQ) { using std::sqrt; const RealScalar tol = (std::numeric_limits::min)(); @@ -511,9 +511,9 @@ struct tridiagonalization_inplace_selector { typedef typename MatrixType::Scalar Scalar; - template + template static EIGEN_DEVICE_FUNC - void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, bool extractQ) + void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, CoeffVectorType&, bool extractQ) { diag(0,0) = numext::real(mat(0,0)); if(extractQ) diff --git a/external/eigen/Eigen/src/LU/InverseImpl.h b/external/eigen/Eigen/src/LU/InverseImpl.h index 27e26394..a40cefa9 100644 --- a/external/eigen/Eigen/src/LU/InverseImpl.h +++ b/external/eigen/Eigen/src/LU/InverseImpl.h @@ -144,13 +144,18 @@ inline void compute_inverse_size3_helper( const Matrix& cofactors_col0, ResultType& result) { - result.row(0) = cofactors_col0 * invdet; - result.coeffRef(1,0) = cofactor_3x3(matrix) * invdet; - result.coeffRef(1,1) = cofactor_3x3(matrix) * invdet; + // Compute cofactors in a way that avoids aliasing issues. + typedef typename ResultType::Scalar Scalar; + const Scalar c01 = cofactor_3x3(matrix) * invdet; + const Scalar c11 = cofactor_3x3(matrix) * invdet; + const Scalar c02 = cofactor_3x3(matrix) * invdet; result.coeffRef(1,2) = cofactor_3x3(matrix) * invdet; - result.coeffRef(2,0) = cofactor_3x3(matrix) * invdet; result.coeffRef(2,1) = cofactor_3x3(matrix) * invdet; result.coeffRef(2,2) = cofactor_3x3(matrix) * invdet; + result.coeffRef(1,0) = c01; + result.coeffRef(1,1) = c11; + result.coeffRef(2,0) = c02; + result.row(0) = cofactors_col0 * invdet; } template @@ -166,12 +171,7 @@ struct compute_inverse cofactors_col0.coeffRef(2) = cofactor_3x3(matrix); const Scalar det = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); const Scalar invdet = Scalar(1) / det; - if(extract_data(matrix) != extract_data(result)) { - compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result); - } else { - MatrixType matrix_t = matrix; - compute_inverse_size3_helper(matrix_t, invdet, cofactors_col0, result); - } + compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result); } }; @@ -187,22 +187,16 @@ struct compute_inverse_and_det_with_check bool& invertible ) { - using std::abs; typedef typename ResultType::Scalar Scalar; Matrix cofactors_col0; cofactors_col0.coeffRef(0) = cofactor_3x3(matrix); cofactors_col0.coeffRef(1) = cofactor_3x3(matrix); cofactors_col0.coeffRef(2) = cofactor_3x3(matrix); determinant = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); - invertible = abs(determinant) > absDeterminantThreshold; + invertible = Eigen::numext::abs(determinant) > absDeterminantThreshold; if(!invertible) return; const Scalar invdet = Scalar(1) / determinant; - if(extract_data(matrix) != extract_data(inverse)) { - compute_inverse_size3_helper(matrix, invdet, cofactors_col0, inverse); - } else { - MatrixType matrix_t = matrix; - compute_inverse_size3_helper(matrix_t, invdet, cofactors_col0, inverse); - } + compute_inverse_size3_helper(matrix, invdet, cofactors_col0, inverse); } }; diff --git a/external/eigen/Eigen/src/SVD/JacobiSVD.h b/external/eigen/Eigen/src/SVD/JacobiSVD.h index 8551a06c..9d95acdf 100644 --- a/external/eigen/Eigen/src/SVD/JacobiSVD.h +++ b/external/eigen/Eigen/src/SVD/JacobiSVD.h @@ -112,12 +112,12 @@ class qr_preconditioner_impl - TransposeTypeWithSameStorageOrder; + + typedef typename internal::make_proper_matrix_type< + Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime + >::type TransposeTypeWithSameStorageOrder; void allocate(const JacobiSVD& svd) { @@ -202,13 +202,12 @@ class qr_preconditioner_impl - TransposeTypeWithSameStorageOrder; + typedef typename internal::make_proper_matrix_type< + Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime + >::type TransposeTypeWithSameStorageOrder; void allocate(const JacobiSVD& svd) { @@ -303,8 +302,9 @@ class qr_preconditioner_impl - TransposeTypeWithSameStorageOrder; + typedef typename internal::make_proper_matrix_type< + Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime + >::type TransposeTypeWithSameStorageOrder; void allocate(const JacobiSVD& svd) { diff --git a/external/eigen/Eigen/src/SparseCore/SparseMatrix.h b/external/eigen/Eigen/src/SparseCore/SparseMatrix.h index 1db906d5..616b4a0c 100644 --- a/external/eigen/Eigen/src/SparseCore/SparseMatrix.h +++ b/external/eigen/Eigen/src/SparseCore/SparseMatrix.h @@ -253,10 +253,9 @@ class SparseMatrix inline void setZero() { m_data.clear(); - std::fill_n(m_outerIndex, m_outerSize + 1, StorageIndex(0)); - if(m_innerNonZeros) { - std::fill_n(m_innerNonZeros, m_outerSize, StorageIndex(0)); - } + memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(StorageIndex)); + if(m_innerNonZeros) + memset(m_innerNonZeros, 0, (m_outerSize)*sizeof(StorageIndex)); } /** Preallocates \a reserveSize non zeros. @@ -642,7 +641,7 @@ class SparseMatrix std::free(m_innerNonZeros); m_innerNonZeros = 0; } - std::fill_n(m_outerIndex, m_outerSize + 1, StorageIndex(0)); + memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(StorageIndex)); } /** \internal @@ -1261,7 +1260,7 @@ typename SparseMatrix<_Scalar,_Options,_StorageIndex>::Scalar& SparseMatrix<_Sca m_innerNonZeros = static_cast(std::malloc(m_outerSize * sizeof(StorageIndex))); if(!m_innerNonZeros) internal::throw_std_bad_alloc(); - std::fill(m_innerNonZeros, m_innerNonZeros + m_outerSize, StorageIndex(0)); + memset(m_innerNonZeros, 0, (m_outerSize)*sizeof(StorageIndex)); // pack all inner-vectors to the end of the pre-allocated space // and allocate the entire free-space to the first inner-vector diff --git a/external/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/external/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h index b7ea22a9..13c55f4b 100644 --- a/external/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/external/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -497,6 +497,45 @@ ceil() const return CeilReturnType(derived()); } +template struct ShiftRightXpr { + typedef CwiseUnaryOp, const Derived> Type; +}; + +/** \returns an expression of \c *this with the \a Scalar type arithmetically + * shifted right by \a N bit positions. + * + * The template parameter \a N specifies the number of bit positions to shift. + * + * \sa shiftLeft() + */ +template +EIGEN_DEVICE_FUNC +typename ShiftRightXpr::Type +shiftRight() const +{ + return typename ShiftRightXpr::Type(derived()); +} + + +template struct ShiftLeftXpr { + typedef CwiseUnaryOp, const Derived> Type; +}; + +/** \returns an expression of \c *this with the \a Scalar type logically + * shifted left by \a N bit positions. + * + * The template parameter \a N specifies the number of bit positions to shift. + * + * \sa shiftRight() + */ +template +EIGEN_DEVICE_FUNC +typename ShiftLeftXpr::Type +shiftLeft() const +{ + return typename ShiftLeftXpr::Type(derived()); +} + /** \returns an expression of the coefficient-wise isnan of *this. * * Example: \include Cwise_isNaN.cpp diff --git a/external/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h b/external/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h index 42ff901c..5418dc41 100644 --- a/external/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h +++ b/external/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h @@ -64,49 +64,6 @@ cast() const return typename CastXpr::Type(derived()); } -template struct ShiftRightXpr { - typedef CwiseUnaryOp, const Derived> Type; -}; - -/// \returns an expression of \c *this with the \a Scalar type arithmetically -/// shifted right by \a N bit positions. -/// -/// The template parameter \a N specifies the number of bit positions to shift. -/// -EIGEN_DOC_UNARY_ADDONS(cast,conversion function) -/// -/// \sa class CwiseUnaryOp -/// -template -EIGEN_DEVICE_FUNC -typename ShiftRightXpr::Type -shift_right() const -{ - return typename ShiftRightXpr::Type(derived()); -} - - -template struct ShiftLeftXpr { - typedef CwiseUnaryOp, const Derived> Type; -}; - -/// \returns an expression of \c *this with the \a Scalar type logically -/// shifted left by \a N bit positions. -/// -/// The template parameter \a N specifies the number of bit positions to shift. -/// -EIGEN_DOC_UNARY_ADDONS(cast,conversion function) -/// -/// \sa class CwiseUnaryOp -/// -template -EIGEN_DEVICE_FUNC -typename ShiftLeftXpr::Type -shift_left() const -{ - return typename ShiftLeftXpr::Type(derived()); -} - /// \returns an expression of the complex conjugate of \c *this. /// EIGEN_DOC_UNARY_ADDONS(conjugate,complex conjugate) diff --git a/external/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/external/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h index f1084abe..a0feef87 100644 --- a/external/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h +++ b/external/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h @@ -39,10 +39,10 @@ cwiseProduct(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const */ template EIGEN_DEVICE_FUNC -inline const CwiseBinaryOp, const Derived, const OtherDerived> +inline const CwiseBinaryOp, const Derived, const OtherDerived> cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const { - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); + return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); } /** \returns an expression of the coefficient-wise != operator of *this and \a other @@ -59,10 +59,10 @@ cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const */ template EIGEN_DEVICE_FUNC -inline const CwiseBinaryOp, const Derived, const OtherDerived> +inline const CwiseBinaryOp, const Derived, const OtherDerived> cwiseNotEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const { - return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); + return CwiseBinaryOp, const Derived, const OtherDerived>(derived(), other.derived()); } /** \returns an expression of the coefficient-wise min of *this and \a other diff --git a/external/eigen/bench/tensors/tensor_benchmarks.h b/external/eigen/bench/tensors/tensor_benchmarks.h index 0e8339e1..0825e156 100644 --- a/external/eigen/bench/tensors/tensor_benchmarks.h +++ b/external/eigen/bench/tensors/tensor_benchmarks.h @@ -564,9 +564,9 @@ for (int iter = 0; iter < 10; ++iter) { // Initialize the content of the memory pools to prevent asan from // complaining. - device_.fill(a_, a_ + m_ * k_, T(12)); - device_.fill(b_, b_ + k_ * n_, T(23)); - device_.fill(c_, c_ + m_ * n_, T(31)); + device_.memset(a_, 12, m_ * k_ * sizeof(T)); + device_.memset(b_, 23, k_ * n_ * sizeof(T)); + device_.memset(c_, 31, m_ * n_ * sizeof(T)); } diff --git a/external/eigen/bench/tensors/tensor_contract_sycl_bench.cc b/external/eigen/bench/tensors/tensor_contract_sycl_bench.cc index c2d098ec..8f2defe4 100644 --- a/external/eigen/bench/tensors/tensor_contract_sycl_bench.cc +++ b/external/eigen/bench/tensors/tensor_contract_sycl_bench.cc @@ -56,9 +56,9 @@ void contraction(const Device& device_, TensorIndex num_iters, TensorIndex m_, T // Initialize the content of the memory pools to prevent asan from // complaining. - device_.fill(a_, m_ * k_, T(12)); - device_.fill(b_, k_ * n_, T(23)); - device_.fill(c_, m_ * n_, T(31)); + device_.memset(a_, 12, m_ * k_ * sizeof(T)); + device_.memset(b_, 23, k_ * n_ * sizeof(T)); + device_.memset(c_, 31, m_ * n_ * sizeof(T)); Eigen::array sizeA; sizeA[0] = m_; diff --git a/external/eigen/blas/CMakeLists.txt b/external/eigen/blas/CMakeLists.txt index 545bc989..f3a94ec4 100644 --- a/external/eigen/blas/CMakeLists.txt +++ b/external/eigen/blas/CMakeLists.txt @@ -26,20 +26,27 @@ else() set(EigenBlas_SRCS ${EigenBlas_SRCS} f2c/complexdots.c) endif() +set(EIGEN_BLAS_TARGETS "") + add_library(eigen_blas_static ${EigenBlas_SRCS}) -add_library(eigen_blas SHARED ${EigenBlas_SRCS}) +list(APPEND EIGEN_BLAS_TARGETS eigen_blas_static) -if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) - target_link_libraries(eigen_blas_static ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) - target_link_libraries(eigen_blas ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) +if (EIGEN_BUILD_SHARED_LIBS) + add_library(eigen_blas SHARED ${EigenBlas_SRCS}) + list(APPEND EIGEN_BLAS_TARGETS eigen_blas) endif() -add_dependencies(blas eigen_blas eigen_blas_static) +foreach(target IN LISTS EIGEN_BLAS_TARGETS) + if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) + target_link_libraries(${target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) + endif() -install(TARGETS eigen_blas eigen_blas_static - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) + add_dependencies(blas ${target}) + install(TARGETS ${target} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) +endforeach() if(EIGEN_Fortran_COMPILER_WORKS) diff --git a/external/eigen/cmake/FindBLAS.cmake b/external/eigen/cmake/FindBLAS.cmake index 7d1f81b0..1bb8f196 100644 --- a/external/eigen/cmake/FindBLAS.cmake +++ b/external/eigen/cmake/FindBLAS.cmake @@ -147,6 +147,7 @@ mark_as_advanced(BLAS_VERBOSE) include(CheckFunctionExists) include(CheckFortranFunctionExists) +include(CMakeFindDependencyMacro) set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) @@ -509,9 +510,9 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED) - find_package(Threads) + find_dependency(Threads) else() - find_package(Threads REQUIRED) + find_dependency(Threads REQUIRED) endif() set(BLAS_SEARCH_LIBS "") diff --git a/external/eigen/cmake/FindBLASEXT.cmake b/external/eigen/cmake/FindBLASEXT.cmake index 0fe7fb84..69a94189 100644 --- a/external/eigen/cmake/FindBLASEXT.cmake +++ b/external/eigen/cmake/FindBLASEXT.cmake @@ -41,18 +41,19 @@ # License text for the above reference.) # macro to factorize this call +include(CMakeFindDependencyMacro) macro(find_package_blas) if(BLASEXT_FIND_REQUIRED) if(BLASEXT_FIND_QUIETLY) - find_package(BLAS REQUIRED QUIET) + find_dependency(BLAS REQUIRED QUIET) else() - find_package(BLAS REQUIRED) + find_dependency(BLAS REQUIRED) endif() else() if(BLASEXT_FIND_QUIETLY) - find_package(BLAS QUIET) + find_dependency(BLAS QUIET) else() - find_package(BLAS) + find_dependency(BLAS) endif() endif() endmacro() @@ -316,7 +317,7 @@ if(BLA_VENDOR MATCHES "Intel*") "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_SEQ_LIBRARIES BLAS_LIBRARY_DIRS BLAS_INCLUDE_DIRS) @@ -324,14 +325,14 @@ if(BLA_VENDOR MATCHES "Intel*") if(NOT BLASEXT_FIND_QUIETLY) message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_PAR_LIBRARIES) endif() else() if(NOT BLASEXT_FIND_QUIETLY) message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_SEQ_LIBRARIES BLAS_LIBRARY_DIRS BLAS_INCLUDE_DIRS) @@ -343,14 +344,14 @@ elseif(BLA_VENDOR MATCHES "ACML*") "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_SEQ_LIBRARIES BLAS_LIBRARY_DIRS) if(BLAS_PAR_LIBRARIES) if(NOT BLASEXT_FIND_QUIETLY) message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_PAR_LIBRARIES) endif() elseif(BLA_VENDOR MATCHES "IBMESSL*") @@ -360,21 +361,24 @@ elseif(BLA_VENDOR MATCHES "IBMESSL*") "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_SEQ_LIBRARIES BLAS_LIBRARY_DIRS) if(BLAS_PAR_LIBRARIES) if(NOT BLASEXT_FIND_QUIETLY) message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_PAR_LIBRARIES) endif() else() if(NOT BLASEXT_FIND_QUIETLY) message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG + find_package_handle_standard_args(BLASEXT DEFAULT_MSG BLAS_SEQ_LIBRARIES BLAS_LIBRARY_DIRS) endif() + +# Callers expect BLAS_FOUND to be set as well. +set(BLAS_FOUND BLASEXT_FOUND) diff --git a/external/eigen/cmake/FindComputeCpp.cmake b/external/eigen/cmake/FindComputeCpp.cmake index 3cca5150..1c271f0f 100644 --- a/external/eigen/cmake/FindComputeCpp.cmake +++ b/external/eigen/cmake/FindComputeCpp.cmake @@ -41,7 +41,8 @@ set(COMPUTECPP_BITCODE "spir64" CACHE STRING "Bitcode type to use as SYCL target in compute++") mark_as_advanced(COMPUTECPP_BITCODE) -find_package(OpenCL REQUIRED) +include(CMakeFindDependencyMacro) +find_dependency(OpenCL REQUIRED) # Find ComputeCpp package diff --git a/external/eigen/cmake/FindFFTW.cmake b/external/eigen/cmake/FindFFTW.cmake index fad476d0..ed55c5fa 100644 --- a/external/eigen/cmake/FindFFTW.cmake +++ b/external/eigen/cmake/FindFFTW.cmake @@ -22,7 +22,8 @@ if( NOT FFTW_ROOT AND ENV{FFTWDIR} ) endif() # Check if we can use PkgConfig -find_package(PkgConfig) +include(CMakeFindDependencyMacro) +find_dependency(PkgConfig) #Determine from PKG if( PKG_CONFIG_FOUND AND NOT FFTW_ROOT ) diff --git a/external/eigen/cmake/FindHWLOC.cmake b/external/eigen/cmake/FindHWLOC.cmake index 48329151..522f5215 100644 --- a/external/eigen/cmake/FindHWLOC.cmake +++ b/external/eigen/cmake/FindHWLOC.cmake @@ -65,8 +65,9 @@ endif() # Optionally use pkg-config to detect include/library dirs (if pkg-config is available) # ------------------------------------------------------------------------------------- -include(FindPkgConfig) -find_package(PkgConfig QUIET) +include(CMakeFindDependencyMacro) +# include(FindPkgConfig) +find_dependency(PkgConfig QUIET) if( PKG_CONFIG_EXECUTABLE AND NOT HWLOC_GIVEN_BY_USER ) pkg_search_module(HWLOC hwloc) diff --git a/external/eigen/cmake/FindLAPACK.cmake b/external/eigen/cmake/FindLAPACK.cmake index 284a4529..3fd73880 100644 --- a/external/eigen/cmake/FindLAPACK.cmake +++ b/external/eigen/cmake/FindLAPACK.cmake @@ -26,6 +26,7 @@ include(CheckFunctionExists) +include(CMakeFindDependencyMacro) # This macro checks for the existence of the combination of fortran libraries # given by _list. If the combination is found, this macro checks (using the @@ -88,7 +89,7 @@ macro(check_lapack_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _b set(${LIBRARIES} ${_libraries_found}) # Some C++ linkers require the f2c library to link with Fortran libraries. # I do not know which ones, thus I just add the f2c library if it is available. - find_package( F2C QUIET ) + find_dependency( F2C QUIET ) if ( F2C_FOUND ) set(${DEFINITIONS} ${${DEFINITIONS}} ${F2C_DEFINITIONS}) set(${LIBRARIES} ${${LIBRARIES}} ${F2C_LIBRARIES}) @@ -135,9 +136,9 @@ endmacro() # LAPACK requires BLAS if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_package(BLAS) + find_dependency(BLAS) else() - find_package(BLAS REQUIRED) + find_dependency(BLAS REQUIRED) endif() if (NOT BLAS_FOUND) diff --git a/external/eigen/cmake/FindMPREAL.cmake b/external/eigen/cmake/FindMPREAL.cmake new file mode 100644 index 00000000..947a1ce8 --- /dev/null +++ b/external/eigen/cmake/FindMPREAL.cmake @@ -0,0 +1,103 @@ +# Try to find the MPFR C++ (MPREAL) library +# See http://www.holoborodko.com/pavel/mpreal/ +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(MPREAL 1.8.6) +# to require version 1.8.6 or newer of MPREAL C++. +# +# Once done this will define +# +# MPREAL_FOUND - system has MPREAL lib with correct version +# MPREAL_INCLUDES - MPREAL required include directories +# MPREAL_LIBRARIES - MPREAL required libraries +# MPREAL_VERSION - MPREAL version + +# Copyright (c) 2020 The Eigen Authors. +# Redistribution and use is allowed according to the terms of the BSD license. + +include(CMakeFindDependencyMacro) +find_dependency(MPFR) +find_dependency(GMP) + +# Set MPREAL_INCLUDES +find_path(MPREAL_INCLUDES + NAMES + mpreal.h + PATHS + $ENV{GMPDIR} + ${INCLUDE_INSTALL_DIR} +) + +# Set MPREAL_FIND_VERSION to 1.0.0 if no minimum version is specified + +if(NOT MPREAL_FIND_VERSION) + if(NOT MPREAL_FIND_VERSION_MAJOR) + set(MPREAL_FIND_VERSION_MAJOR 1) + endif() + if(NOT MPREAL_FIND_VERSION_MINOR) + set(MPREAL_FIND_VERSION_MINOR 0) + endif() + if(NOT MPREAL_FIND_VERSION_PATCH) + set(MPREAL_FIND_VERSION_PATCH 0) + endif() + + set(MPREAL_FIND_VERSION "${MPREAL_FIND_VERSION_MAJOR}.${MPREAL_FIND_VERSION_MINOR}.${MPREAL_FIND_VERSION_PATCH}") +endif() + +# Check bugs +# - https://github.com/advanpix/mpreal/issues/7 +# - https://github.com/advanpix/mpreal/issues/9 +set(MPREAL_TEST_PROGRAM " +#include +#include +int main(int argc, char** argv) { + const mpfr::mpreal one = 1.0; + const mpfr::mpreal zero = 0.0; + using namespace std; + const mpfr::mpreal smaller = min(one, zero); + return 0; +}") + +if(MPREAL_INCLUDES) + + # Set MPREAL_VERSION + + file(READ "${MPREAL_INCLUDES}/mpreal.h" _mpreal_version_header) + + string(REGEX MATCH "define[ \t]+MPREAL_VERSION_MAJOR[ \t]+([0-9]+)" _mpreal_major_version_match "${_mpreal_version_header}") + set(MPREAL_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+MPREAL_VERSION_MINOR[ \t]+([0-9]+)" _mpreal_minor_version_match "${_mpreal_version_header}") + set(MPREAL_MINOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+MPREAL_VERSION_PATCHLEVEL[ \t]+([0-9]+)" _mpreal_patchlevel_version_match "${_mpreal_version_header}") + set(MPREAL_PATCHLEVEL_VERSION "${CMAKE_MATCH_1}") + + set(MPREAL_VERSION ${MPREAL_MAJOR_VERSION}.${MPREAL_MINOR_VERSION}.${MPREAL_PATCHLEVEL_VERSION}) + + # Check whether found version exceeds minimum version + + if(${MPREAL_VERSION} VERSION_LESS ${MPREAL_FIND_VERSION}) + set(MPREAL_VERSION_OK FALSE) + message(STATUS "MPREAL version ${MPREAL_VERSION} found in ${MPREAL_INCLUDES}, " + "but at least version ${MPREAL_FIND_VERSION} is required") + else() + set(MPREAL_VERSION_OK TRUE) + + list(APPEND MPREAL_INCLUDES "${MPFR_INCLUDES}" "${GMP_INCLUDES}") + list(REMOVE_DUPLICATES MPREAL_INCLUDES) + + list(APPEND MPREAL_LIBRARIES "${MPFR_LIBRARIES}" "${GMP_LIBRARIES}") + list(REMOVE_DUPLICATES MPREAL_LIBRARIES) + + # Make sure it compiles with the current compiler. + unset(MPREAL_WORKS CACHE) + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_INCLUDES "${MPREAL_INCLUDES}") + set(CMAKE_REQUIRED_LIBRARIES "${MPREAL_LIBRARIES}") + check_cxx_source_compiles("${MPREAL_TEST_PROGRAM}" MPREAL_WORKS) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MPREAL DEFAULT_MSG + MPREAL_INCLUDES MPREAL_VERSION_OK MPREAL_WORKS) +mark_as_advanced(MPREAL_INCLUDES) diff --git a/external/eigen/cmake/FindPTSCOTCH.cmake b/external/eigen/cmake/FindPTSCOTCH.cmake index 51eecf1a..6ccc743e 100644 --- a/external/eigen/cmake/FindPTSCOTCH.cmake +++ b/external/eigen/cmake/FindPTSCOTCH.cmake @@ -79,20 +79,21 @@ if( PTSCOTCH_FIND_COMPONENTS ) endif() # PTSCOTCH depends on Threads, try to find it +include(CMakeFindDependencyMacro) if (NOT THREADS_FOUND) if (PTSCOTCH_FIND_REQUIRED) - find_package(Threads REQUIRED) + find_dependency(Threads REQUIRED) else() - find_package(Threads) + find_dependency(Threads) endif() endif() # PTSCOTCH depends on MPI, try to find it if (NOT MPI_FOUND) if (PTSCOTCH_FIND_REQUIRED) - find_package(MPI REQUIRED) + find_dependency(MPI REQUIRED) else() - find_package(MPI) + find_dependency(MPI) endif() endif() @@ -148,18 +149,18 @@ else() foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find}) set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND") find_path(PTSCOTCH_${ptscotch_hdr}_DIRS - NAMES ${ptscotch_hdr} - HINTS ${PTSCOTCH_DIR} - PATH_SUFFIXES "include" "include/scotch") + NAMES ${ptscotch_hdr} + HINTS ${PTSCOTCH_DIR} + PATH_SUFFIXES "include" "include/scotch") mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS) endforeach() else() foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find}) set(PTSCOTCH_${ptscotch_hdr}_DIRS "PTSCOTCH_${ptscotch_hdr}_DIRS-NOTFOUND") find_path(PTSCOTCH_${ptscotch_hdr}_DIRS - NAMES ${ptscotch_hdr} - HINTS ${_inc_env} - PATH_SUFFIXES "scotch") + NAMES ${ptscotch_hdr} + HINTS ${_inc_env} + PATH_SUFFIXES "scotch") mark_as_advanced(PTSCOTCH_${ptscotch_hdr}_DIRS) endforeach() endif() @@ -171,7 +172,6 @@ foreach(ptscotch_hdr ${PTSCOTCH_hdrs_to_find}) if (PTSCOTCH_${ptscotch_hdr}_DIRS) list(APPEND PTSCOTCH_INCLUDE_DIRS "${PTSCOTCH_${ptscotch_hdr}_DIRS}") else () - set(PTSCOTCH_INCLUDE_DIRS "PTSCOTCH_INCLUDE_DIRS-NOTFOUND") if (NOT PTSCOTCH_FIND_QUIETLY) message(STATUS "Looking for ptscotch -- ${ptscotch_hdr} not found") endif() @@ -229,16 +229,16 @@ else() foreach(ptscotch_lib ${PTSCOTCH_libs_to_find}) set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND") find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY - NAMES ${ptscotch_lib} - HINTS ${PTSCOTCH_DIR} - PATH_SUFFIXES lib lib32 lib64) + NAMES ${ptscotch_lib} + HINTS ${PTSCOTCH_DIR} + PATH_SUFFIXES lib lib32 lib64) endforeach() else() foreach(ptscotch_lib ${PTSCOTCH_libs_to_find}) set(PTSCOTCH_${ptscotch_lib}_LIBRARY "PTSCOTCH_${ptscotch_lib}_LIBRARY-NOTFOUND") find_library(PTSCOTCH_${ptscotch_lib}_LIBRARY - NAMES ${ptscotch_lib} - HINTS ${_lib_env}) + NAMES ${ptscotch_lib} + HINTS ${_lib_env}) endforeach() endif() endif() @@ -255,7 +255,6 @@ foreach(ptscotch_lib ${PTSCOTCH_libs_to_find}) list(APPEND PTSCOTCH_LIBRARIES "${PTSCOTCH_${ptscotch_lib}_LIBRARY}") list(APPEND PTSCOTCH_LIBRARY_DIRS "${${ptscotch_lib}_lib_path}") else () - list(APPEND PTSCOTCH_LIBRARIES "${PTSCOTCH_${ptscotch_lib}_LIBRARY}") if (NOT PTSCOTCH_FIND_QUIETLY) message(STATUS "Looking for ptscotch -- lib ${ptscotch_lib} not found") endif() diff --git a/external/eigen/cmake/FindPastix.cmake b/external/eigen/cmake/FindPastix.cmake index 3b47d5ce..db1427b0 100644 --- a/external/eigen/cmake/FindPastix.cmake +++ b/external/eigen/cmake/FindPastix.cmake @@ -118,7 +118,7 @@ if( PASTIX_FIND_COMPONENTS ) if (${component} STREQUAL "SCOTCH") set(PASTIX_LOOK_FOR_SCOTCH ON) endif() - if (${component} STREQUAL "SCOTCH") + if (${component} STREQUAL "PTSCOTCH") set(PASTIX_LOOK_FOR_PTSCOTCH ON) endif() if (${component} STREQUAL "METIS") @@ -133,14 +133,14 @@ endif() # Required dependencies # --------------------- - +include(CMakeFindDependencyMacro) if (NOT PASTIX_FIND_QUIETLY) message(STATUS "Looking for PASTIX - Try to detect pthread") endif() if (PASTIX_FIND_REQUIRED) - find_package(Threads REQUIRED QUIET) + find_dependency(Threads REQUIRED QUIET) else() - find_package(Threads QUIET) + find_dependency(Threads QUIET) endif() set(PASTIX_EXTRA_LIBRARIES "") if( THREADS_FOUND ) @@ -198,9 +198,9 @@ if (NOT PASTIX_FIND_QUIETLY) message(STATUS "Looking for PASTIX - Try to detect HWLOC") endif() if (PASTIX_FIND_REQUIRED) - find_package(HWLOC REQUIRED QUIET) + find_dependency(HWLOC REQUIRED QUIET) else() - find_package(HWLOC QUIET) + find_dependency(HWLOC QUIET) endif() # PASTIX depends on BLAS @@ -209,9 +209,9 @@ if (NOT PASTIX_FIND_QUIETLY) message(STATUS "Looking for PASTIX - Try to detect BLAS") endif() if (PASTIX_FIND_REQUIRED) - find_package(BLASEXT REQUIRED QUIET) + find_dependency(BLASEXT REQUIRED QUIET) else() - find_package(BLASEXT QUIET) + find_dependency(BLASEXT QUIET) endif() # Optional dependencies @@ -230,9 +230,9 @@ if (NOT MPI_FOUND AND PASTIX_LOOK_FOR_MPI) set(MPI_C_COMPILER mpicc) endif() if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_MPI) - find_package(MPI REQUIRED QUIET) + find_dependency(MPI REQUIRED QUIET) else() - find_package(MPI QUIET) + find_dependency(MPI QUIET) endif() if (MPI_FOUND) mark_as_advanced(MPI_LIBRARY) @@ -272,10 +272,10 @@ if( NOT STARPU_FOUND AND PASTIX_LOOK_FOR_STARPU) endif() # set the list of optional dependencies we may discover if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_STARPU) - find_package(STARPU ${PASTIX_STARPU_VERSION} REQUIRED + find_dependency(STARPU ${PASTIX_STARPU_VERSION} REQUIRED COMPONENTS ${STARPU_COMPONENT_LIST}) else() - find_package(STARPU ${PASTIX_STARPU_VERSION} + find_dependency(STARPU ${PASTIX_STARPU_VERSION} COMPONENTS ${STARPU_COMPONENT_LIST}) endif() @@ -288,9 +288,9 @@ if (NOT SCOTCH_FOUND AND PASTIX_LOOK_FOR_SCOTCH) message(STATUS "Looking for PASTIX - Try to detect SCOTCH") endif() if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_SCOTCH) - find_package(SCOTCH REQUIRED QUIET) + find_dependency(SCOTCH REQUIRED QUIET) else() - find_package(SCOTCH QUIET) + find_dependency(SCOTCH QUIET) endif() endif() @@ -301,9 +301,9 @@ if (NOT PTSCOTCH_FOUND AND PASTIX_LOOK_FOR_PTSCOTCH) message(STATUS "Looking for PASTIX - Try to detect PTSCOTCH") endif() if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_PTSCOTCH) - find_package(PTSCOTCH REQUIRED QUIET) + find_dependency(PTSCOTCH REQUIRED QUIET) else() - find_package(PTSCOTCH QUIET) + find_dependency(PTSCOTCH QUIET) endif() endif() @@ -314,9 +314,9 @@ if (NOT METIS_FOUND AND PASTIX_LOOK_FOR_METIS) message(STATUS "Looking for PASTIX - Try to detect METIS") endif() if (PASTIX_FIND_REQUIRED AND PASTIX_FIND_REQUIRED_METIS) - find_package(METIS REQUIRED QUIET) + find_dependency(METIS REQUIRED QUIET) else() - find_package(METIS QUIET) + find_dependency(METIS QUIET) endif() endif() diff --git a/external/eigen/cmake/FindScotch.cmake b/external/eigen/cmake/FindScotch.cmake index af00eb0f..11b971a9 100644 --- a/external/eigen/cmake/FindScotch.cmake +++ b/external/eigen/cmake/FindScotch.cmake @@ -71,11 +71,12 @@ if( SCOTCH_FIND_COMPONENTS ) endif() # SCOTCH may depend on Threads, try to find it +include(CMakeFindDependencyMacro) if (NOT THREADS_FOUND) if (SCOTCH_FIND_REQUIRED) - find_package(Threads REQUIRED) + find_dependency(Threads REQUIRED) else() - find_package(Threads) + find_dependency(Threads) endif() endif() diff --git a/external/eigen/cmake/FindTriSYCL.cmake b/external/eigen/cmake/FindTriSYCL.cmake index 41bc2fa8..81042390 100644 --- a/external/eigen/cmake/FindTriSYCL.cmake +++ b/external/eigen/cmake/FindTriSYCL.cmake @@ -57,18 +57,19 @@ mark_as_advanced(TRISYCL_DEBUG_STRUCTORS) mark_as_advanced(TRISYCL_TRACE_KERNEL) #triSYCL definitions -set(CL_SYCL_LANGUAGE_VERSION 220 CACHE VERSION +set(CL_SYCL_LANGUAGE_VERSION 220 CACHE STRING "Host language version to be used by trisYCL (default is: 220)") -set(TRISYCL_CL_LANGUAGE_VERSION 220 CACHE VERSION +set(TRISYCL_CL_LANGUAGE_VERSION 220 CACHE STRING "Device language version to be used by trisYCL (default is: 220)") -#set(TRISYCL_COMPILE_OPTIONS "-std=c++1z -Wall -Wextra") -set(CMAKE_CXX_STANDARD 14) +# triSYCL now requires c++17 +set(CMAKE_CXX_STANDARD 17) set(CXX_STANDARD_REQUIRED ON) # Find OpenCL package +include(CMakeFindDependencyMacro) if(TRISYCL_OPENCL) - find_package(OpenCL REQUIRED) + find_dependency(OpenCL REQUIRED) if(UNIX) set(BOOST_COMPUTE_INCPATH /usr/include/compute CACHE PATH "Path to Boost.Compute headers (default is: /usr/include/compute)") @@ -77,11 +78,11 @@ endif() # Find OpenMP package if(TRISYCL_OPENMP) - find_package(OpenMP REQUIRED) + find_dependency(OpenMP REQUIRED) endif() # Find Boost -find_package(Boost 1.58 REQUIRED COMPONENTS chrono log) +find_dependency(Boost 1.58 REQUIRED COMPONENTS chrono log) # If debug or trace we need boost log if(TRISYCL_DEBUG OR TRISYCL_DEBUG_STRUCTORS OR TRISYCL_TRACE_KERNEL) @@ -90,9 +91,23 @@ else() set(LOG_NEEDED OFF) endif() -find_package(Threads REQUIRED) +find_dependency(Threads REQUIRED) # Find triSYCL directory +if (TRISYCL_INCLUDES AND TRISYCL_LIBRARIES) + set(TRISYCL_FIND_QUIETLY TRUE) +endif () + +find_path(TRISYCL_INCLUDE_DIR + NAMES sycl.hpp + PATHS $ENV{TRISYCLDIR} $ENV{TRISYCLDIR}/include ${INCLUDE_INSTALL_DIR} + PATH_SUFFIXES triSYCL +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(TriSYCL DEFAULT_MSG + TRISYCL_INCLUDE_DIR) + if(NOT TRISYCL_INCLUDE_DIR) message(FATAL_ERROR "triSYCL include directory - Not found! (please set TRISYCL_INCLUDE_DIR") @@ -100,36 +115,42 @@ else() message(STATUS "triSYCL include directory - Found ${TRISYCL_INCLUDE_DIR}") endif() +include(CMakeParseArguments) ####################### # add_sycl_to_target ####################### -# -# Sets the proper flags and includes for the target compilation. -# -# targetName : Name of the target to add a SYCL to. -# sourceFile : Source file to be compiled for SYCL. -# binaryDir : Intermediate directory to output the integration header. -# -function(add_sycl_to_target targetName sourceFile binaryDir) +function(add_sycl_to_target) + set(options) + set(one_value_args + TARGET + ) + set(multi_value_args + SOURCES + ) + cmake_parse_arguments(ADD_SYCL_ARGS + "${options}" + "${one_value_args}" + "${multi_value_args}" + ${ARGN} + ) # Add include directories to the "#include <>" paths - target_include_directories (${targetName} PUBLIC + target_include_directories (${ADD_SYCL_ARGS_TARGET} PUBLIC ${TRISYCL_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} $<$:${OpenCL_INCLUDE_DIRS}> $<$:${BOOST_COMPUTE_INCPATH}>) - # Link dependencies - target_link_libraries(${targetName} PUBLIC + target_link_libraries(${ADD_SYCL_ARGS_TARGET} $<$:${OpenCL_LIBRARIES}> Threads::Threads $<$:Boost::log> Boost::chrono) - # Compile definitions - target_compile_definitions(${targetName} PUBLIC + target_compile_definitions(${ADD_SYCL_ARGS_TARGET} PUBLIC + EIGEN_SYCL_TRISYCL $<$:TRISYCL_NO_ASYNC> $<$:TRISYCL_OPENCL> $<$:TRISYCL_DEBUG> @@ -138,13 +159,13 @@ function(add_sycl_to_target targetName sourceFile binaryDir) $<$:BOOST_LOG_DYN_LINK>) # C++ and OpenMP requirements - target_compile_options(${targetName} PUBLIC + target_compile_options(${ADD_SYCL_ARGS_TARGET} PUBLIC ${TRISYCL_COMPILE_OPTIONS} $<$:${OpenMP_CXX_FLAGS}>) if(${TRISYCL_OPENMP} AND (NOT WIN32)) # Does not support generator expressions - set_target_properties(${targetName} + set_target_properties(${ADD_SYCL_ARGS_TARGET} PROPERTIES LINK_FLAGS ${OpenMP_CXX_FLAGS}) endif() diff --git a/external/eigen/doc/LeastSquares.dox b/external/eigen/doc/LeastSquares.dox index 24dfe4b4..ddbf38de 100644 --- a/external/eigen/doc/LeastSquares.dox +++ b/external/eigen/doc/LeastSquares.dox @@ -30,14 +30,17 @@ computing least squares solutions: This is example from the page \link TutorialLinearAlgebra Linear algebra and decompositions \endlink. +If you just need to solve the least squares problem, but are not interested in the SVD per se, a +faster alternative method is CompleteOrthogonalDecomposition. \section LeastSquaresQR Using the QR decomposition The solve() method in QR decomposition classes also computes the least squares solution. There are -three QR decomposition classes: HouseholderQR (no pivoting, so fast but unstable), -ColPivHouseholderQR (column pivoting, thus a bit slower but more accurate) and FullPivHouseholderQR -(full pivoting, so slowest and most stable). Here is an example with column pivoting: +three QR decomposition classes: HouseholderQR (no pivoting, fast but unstable if your matrix is +not rull rank), ColPivHouseholderQR (column pivoting, thus a bit slower but more stable) and +FullPivHouseholderQR (full pivoting, so slowest and slightly more stable than ColPivHouseholderQR). +Here is an example with column pivoting: @@ -61,9 +64,11 @@ Finding the least squares solution of \a Ax = \a b is equivalent to solving the
Example:Output:
-If the matrix \a A is ill-conditioned, then this is not a good method, because the condition number +This method is usually the fastest, especially when \a A is "tall and skinny". However, if the +matrix \a A is even mildly ill-conditioned, this is not a good method, because the condition number of ATA is the square of the condition number of \a A. This means that you -lose twice as many digits using normal equation than if you use the other methods. +lose roughly twice as many digits of accuracy using the normal equation, compared to the more stable +methods mentioned above. */ diff --git a/external/eigen/doc/TopicLinearAlgebraDecompositions.dox b/external/eigen/doc/TopicLinearAlgebraDecompositions.dox index 0965da87..402b3769 100644 --- a/external/eigen/doc/TopicLinearAlgebraDecompositions.dox +++ b/external/eigen/doc/TopicLinearAlgebraDecompositions.dox @@ -72,7 +72,7 @@ To get an overview of the true relative speed of the different decompositions, c Orthogonalization Yes Excellent - Soon: blocking + - @@ -88,6 +88,18 @@ To get an overview of the true relative speed of the different decompositions, c + CompleteOrthogonalDecomposition + - + Fast + Good + Yes + Orthogonalization + Yes + Excellent + - + + + LLT Positive definite Very fast @@ -99,7 +111,7 @@ To get an overview of the true relative speed of the different decompositions, c Blocking - + LDLT Positive or negative semidefinite1 Very fast diff --git a/external/eigen/doc/TutorialBlockOperations.dox b/external/eigen/doc/TutorialBlockOperations.dox index a2d8c97c..df277482 100644 --- a/external/eigen/doc/TutorialBlockOperations.dox +++ b/external/eigen/doc/TutorialBlockOperations.dox @@ -167,6 +167,20 @@ matrix.rightCols(q);\endcode \code matrix.rightCols();\endcode +%Block containing the q columns starting from i + \link DenseBase::middleCols() * \endlink + \code +matrix.middleCols(i,q);\endcode + \code +matrix.middleCols(i);\endcode + +%Block containing the q rows starting from i + \link DenseBase::middleRows() * \endlink + \code +matrix.middleRows(i,q);\endcode + \code +matrix.middleRows(i);\endcode + Here is a simple example illustrating the use of the operations presented above: diff --git a/external/eigen/doc/TutorialLinearAlgebra.dox b/external/eigen/doc/TutorialLinearAlgebra.dox index a7272414..8042fcad 100644 --- a/external/eigen/doc/TutorialLinearAlgebra.dox +++ b/external/eigen/doc/TutorialLinearAlgebra.dox @@ -14,7 +14,7 @@ QR, %SVD, eigendecompositions... After reading this page, don't miss our \f[ Ax \: = \: b \f] Where \a A and \a b are matrices (\a b could be a vector, as a special case). You want to find a solution \a x. -\b The \b solution: You can choose between various decompositions, depending on what your matrix \a A looks like, +\b The \b solution: You can choose between various decompositions, depending on the properties of your matrix \a A, and depending on whether you favor speed or accuracy. However, let's start with an example that works in all cases, and is a good compromise: @@ -34,7 +34,7 @@ Vector3f x = dec.solve(b); Here, ColPivHouseholderQR is a QR decomposition with column pivoting. It's a good compromise for this tutorial, as it works for all matrices while being quite fast. Here is a table of some other decompositions that you can choose from, -depending on your matrix and the trade-off you want to make: +depending on your matrix, the problem you are trying to solve, and the trade-off you want to make:
@@ -128,11 +128,13 @@ depending on your matrix and the trade-off you want to make:
To get an overview of the true relative speed of the different decompositions, check this \link DenseDecompositionBenchmark benchmark \endlink. -All of these decompositions offer a solve() method that works as in the above example. +All of these decompositions offer a solve() method that works as in the above example. -For example, if your matrix is positive definite, the above table says that a very good -choice is then the LLT or LDLT decomposition. Here's an example, also demonstrating that using a general -matrix (not a vector) as right hand side is possible. +If you know more about the properties of your matrix, you can use the above table to select the best method. +For example, a good choice for solving linear systems with a non-symmetric matrix of full rank is PartialPivLU. +If you know that your matrix is also symmetric and positive definite, the above table says that +a very good choice is the LLT or LDLT decomposition. Here's an example, also demonstrating that using a general +matrix (not a vector) as right hand side is possible: @@ -146,7 +148,34 @@ For a \ref TopicLinearAlgebraDecompositions "much more complete table" comparing supports many other decompositions), see our special page on \ref TopicLinearAlgebraDecompositions "this topic". -\section TutorialLinAlgSolutionExists Checking if a solution really exists + +\section TutorialLinAlgLeastsquares Least squares solving + +The most general and accurate method to solve under- or over-determined linear systems +in the least squares sense, is the SVD decomposition. Eigen provides two implementations. +The recommended one is the BDCSVD class, which scales well for large problems +and automatically falls back to the JacobiSVD class for smaller problems. +For both classes, their solve() method solved the linear system in the least-squares +sense. + +Here is an example: +
Example:Output:
+ + + + + +
Example:Output:
\include TutorialLinAlgSVDSolve.cpp \verbinclude TutorialLinAlgSVDSolve.out
+ +An alternative to the SVD, which is usually faster and about as accurate, is CompleteOrthogonalDecomposition. + +Again, if you know more about the problem, the table above contains methods that are potentially faster. +If your matrix is full rank, HouseHolderQR is the method of choice. If your matrix is full rank and well conditioned, +using the Cholesky decomposition (LLT) on the matrix of the normal equations can be faster still. +Our page on \link LeastSquares least squares solving \endlink has more details. + + +\section TutorialLinAlgSolutionExists Checking if a matrix is singular Only you know what error margin you want to allow for a solution to be considered valid. So Eigen lets you do this computation for yourself, if you want to, as in this example: @@ -179,11 +208,11 @@ very rare. The call to info() is to check for this possibility. \section TutorialLinAlgInverse Computing inverse and determinant First of all, make sure that you really want this. While inverse and determinant are fundamental mathematical concepts, -in \em numerical linear algebra they are not as popular as in pure mathematics. Inverse computations are often +in \em numerical linear algebra they are not as useful as in pure mathematics. Inverse computations are often advantageously replaced by solve() operations, and the determinant is often \em not a good way of checking if a matrix is invertible. -However, for \em very \em small matrices, the above is not true, and inverse and determinant can be very useful. +However, for \em very \em small matrices, the above may not be true, and inverse and determinant can be very useful. While certain decompositions, such as PartialPivLU and FullPivLU, offer inverse() and determinant() methods, you can also call inverse() and determinant() directly on a matrix. If your matrix is of a very small fixed size (at most 4x4) this @@ -198,28 +227,6 @@ Here is an example: -\section TutorialLinAlgLeastsquares Least squares solving - -The most accurate method to do least squares solving is with a SVD decomposition. -Eigen provides two implementations. -The recommended one is the BDCSVD class, which scale well for large problems -and automatically fall-back to the JacobiSVD class for smaller problems. -For both classes, their solve() method is doing least-squares solving. - -Here is an example: - - - - - - -
Example:Output:
\include TutorialLinAlgSVDSolve.cpp \verbinclude TutorialLinAlgSVDSolve.out
- -Another methods, potentially faster but less reliable, are to use a Cholesky decomposition of the -normal matrix or a QR decomposition. Our page on \link LeastSquares least squares solving \endlink -has more details. - - \section TutorialLinAlgSeparateComputation Separating the computation from the construction In the above examples, the decomposition was computed at the same time that the decomposition object was constructed. diff --git a/external/eigen/doc/TutorialSparse.dox b/external/eigen/doc/TutorialSparse.dox index 350ea113..c69171ec 100644 --- a/external/eigen/doc/TutorialSparse.dox +++ b/external/eigen/doc/TutorialSparse.dox @@ -60,7 +60,7 @@ On the other hand, inserting elements with increasing inner indices in a given i The case where no empty space is available is a special case, and is referred as the \em compressed mode. It corresponds to the widely used Compressed Column (or Row) Storage schemes (CCS or CRS). Any SparseMatrix can be turned to this form by calling the SparseMatrix::makeCompressed() function. -In this case, one can remark that the \c InnerNNZs array is redundant with \c OuterStarts because we the equality: \c InnerNNZs[j] = \c OuterStarts[j+1]-\c OuterStarts[j]. +In this case, one can remark that the \c InnerNNZs array is redundant with \c OuterStarts because we have the equality: \c InnerNNZs[j] = \c OuterStarts[j+1]-\c OuterStarts[j]. Therefore, in practice a call to SparseMatrix::makeCompressed() frees this buffer. It is worth noting that most of our wrappers to external libraries requires compressed matrices as inputs. diff --git a/external/eigen/doc/snippets/Tridiagonalization_decomposeInPlace.cpp b/external/eigen/doc/snippets/Tridiagonalization_decomposeInPlace.cpp index 93dcfca1..3cdce679 100644 --- a/external/eigen/doc/snippets/Tridiagonalization_decomposeInPlace.cpp +++ b/external/eigen/doc/snippets/Tridiagonalization_decomposeInPlace.cpp @@ -4,7 +4,8 @@ cout << "Here is a random symmetric 5x5 matrix:" << endl << A << endl << endl; VectorXd diag(5); VectorXd subdiag(4); -internal::tridiagonalization_inplace(A, diag, subdiag, true); +VectorXd hcoeffs(4); // Scratch space for householder reflector. +internal::tridiagonalization_inplace(A, diag, subdiag, hcoeffs, true); cout << "The orthogonal matrix Q is:" << endl << A << endl; cout << "The diagonal of the tridiagonal matrix T is:" << endl << diag << endl; cout << "The subdiagonal of the tridiagonal matrix T is:" << endl << subdiag << endl; diff --git a/external/eigen/lapack/CMakeLists.txt b/external/eigen/lapack/CMakeLists.txt index 9eec8107..e48497fd 100644 --- a/external/eigen/lapack/CMakeLists.txt +++ b/external/eigen/lapack/CMakeLists.txt @@ -88,25 +88,29 @@ endif() endif() -add_library(eigen_lapack_static ${EigenLapack_SRCS} ${ReferenceLapack_SRCS}) -add_library(eigen_lapack SHARED ${EigenLapack_SRCS}) +set(EIGEN_LAPACK_TARGETS "") -target_link_libraries(eigen_lapack eigen_blas) +add_library(eigen_lapack_static ${EigenLapack_SRCS} ${ReferenceLapack_SRCS}) +list(APPEND EIGEN_LAPACK_TARGETS eigen_lapack_static) -if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) - target_link_libraries(eigen_lapack_static ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) - target_link_libraries(eigen_lapack ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) +if (EIGEN_BUILD_SHARED_LIBS) + add_library(eigen_lapack SHARED ${EigenLapack_SRCS}) + list(APPEND EIGEN_LAPACK_TARGETS eigen_lapack) + target_link_libraries(eigen_lapack eigen_blas) endif() -add_dependencies(lapack eigen_lapack eigen_lapack_static) +foreach(target IN LISTS EIGEN_LAPACK_TARGETS) + if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO) + target_link_libraries(${target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}) + endif() + add_dependencies(lapack ${target}) + install(TARGETS ${target} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) +endforeach() -install(TARGETS eigen_lapack eigen_lapack_static - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - - get_filename_component(eigen_full_path_to_testing_lapack "./testing/" ABSOLUTE) if(EXISTS ${eigen_full_path_to_testing_lapack}) diff --git a/external/eigen/test/AnnoyingScalar.h b/external/eigen/test/AnnoyingScalar.h index 0f8e70d3..7ace083c 100644 --- a/external/eigen/test/AnnoyingScalar.h +++ b/external/eigen/test/AnnoyingScalar.h @@ -126,7 +126,7 @@ template<> struct NumTraits : NumTraits { enum { - RequireInitialization = true + RequireInitialization = 1, }; typedef AnnoyingScalar Real; typedef AnnoyingScalar Nested; @@ -145,10 +145,6 @@ bool (isfinite)(const AnnoyingScalar& x) { } namespace internal { - template<> EIGEN_STRONG_INLINE AnnoyingScalar pcmp_eq(const AnnoyingScalar& a, const AnnoyingScalar& b) - { return AnnoyingScalar(pcmp_eq(*a.v, *b.v)); } - template<> EIGEN_STRONG_INLINE AnnoyingScalar pselect(const AnnoyingScalar& mask, const AnnoyingScalar& a, const AnnoyingScalar& b) - { return numext::equal_strict(*mask.v, 0.f) ? b : a; } template<> EIGEN_STRONG_INLINE double cast(const AnnoyingScalar& x) { return double(*x.v); } template<> EIGEN_STRONG_INLINE float cast(const AnnoyingScalar& x) { return *x.v; } } diff --git a/external/eigen/test/CMakeLists.txt b/external/eigen/test/CMakeLists.txt index 56664e78..5136f82a 100644 --- a/external/eigen/test/CMakeLists.txt +++ b/external/eigen/test/CMakeLists.txt @@ -164,7 +164,6 @@ ei_add_test(nullary) ei_add_test(mixingtypes) ei_add_test(io) ei_add_test(packetmath "-DEIGEN_FAST_MATH=1") -ei_add_test(unalignedassert) ei_add_test(vectorization_logic) ei_add_test(basicstuff) ei_add_test(constructor) diff --git a/external/eigen/test/OffByOneScalar.h b/external/eigen/test/OffByOneScalar.h deleted file mode 100644 index c0371a6c..00000000 --- a/external/eigen/test/OffByOneScalar.h +++ /dev/null @@ -1,28 +0,0 @@ - -// A Scalar with internal representation T+1 so that zero is internally -// represented by T(1). This is used to test memory fill. -// -template -class OffByOneScalar { - public: - OffByOneScalar() : val_(1) {} - OffByOneScalar(const OffByOneScalar& other) { - *this = other; - } - OffByOneScalar& operator=(const OffByOneScalar& other) { - val_ = other.val_; - return *this; - } - - OffByOneScalar(T val) : val_(val + 1) {} - OffByOneScalar& operator=(T val) { - val_ = val + 1; - } - - operator T() const { - return val_ - 1; - } - - private: - T val_; -}; diff --git a/external/eigen/test/array_cwise.cpp b/external/eigen/test/array_cwise.cpp index 1bc8e19f..0cc438b3 100644 --- a/external/eigen/test/array_cwise.cpp +++ b/external/eigen/test/array_cwise.cpp @@ -626,6 +626,41 @@ template void min_max(const ArrayType& m) } } +template +struct shift_left { + template + Scalar operator()(const Scalar& v) const { + return v << N; + } +}; + +template +struct arithmetic_shift_right { + template + Scalar operator()(const Scalar& v) const { + return v >> N; + } +}; + +template void array_integer(const ArrayType& m) +{ + Index rows = m.rows(); + Index cols = m.cols(); + + ArrayType m1 = ArrayType::Random(rows, cols), + m2(rows, cols); + + m2 = m1.template shiftLeft<2>(); + VERIFY( (m2 == m1.unaryExpr(shift_left<2>())).all() ); + m2 = m1.template shiftLeft<9>(); + VERIFY( (m2 == m1.unaryExpr(shift_left<9>())).all() ); + + m2 = m1.template shiftRight<2>(); + VERIFY( (m2 == m1.unaryExpr(arithmetic_shift_right<2>())).all() ); + m2 = m1.template shiftRight<9>(); + VERIFY( (m2 == m1.unaryExpr(arithmetic_shift_right<9>())).all() ); +} + EIGEN_DECLARE_TEST(array_cwise) { for(int i = 0; i < g_repeat; i++) { @@ -636,6 +671,8 @@ EIGEN_DECLARE_TEST(array_cwise) CALL_SUBTEST_5( array(ArrayXXf(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); CALL_SUBTEST_6( array(ArrayXXi(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); CALL_SUBTEST_6( array(Array(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); + CALL_SUBTEST_6( array_integer(ArrayXXi(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); + CALL_SUBTEST_6( array_integer(Array(internal::random(1,EIGEN_TEST_MAX_SIZE), internal::random(1,EIGEN_TEST_MAX_SIZE))) ); } for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_1( comparisons(Array()) ); diff --git a/external/eigen/test/bfloat16_float.cpp b/external/eigen/test/bfloat16_float.cpp index 1df22f73..c3de0b19 100644 --- a/external/eigen/test/bfloat16_float.cpp +++ b/external/eigen/test/bfloat16_float.cpp @@ -32,18 +32,6 @@ float BinaryToFloat(uint32_t sign, uint32_t exponent, uint32_t high_mantissa, return dest; } -void test_truncate(float input, float expected_truncation, float expected_rounding){ - bfloat16 truncated = Eigen::bfloat16_impl::truncate_to_bfloat16(input); - bfloat16 rounded = Eigen::bfloat16_impl::float_to_bfloat16_rtne(input); - if ((numext::isnan)(input)){ - VERIFY((numext::isnan)(static_cast(truncated)) || (numext::isinf)(static_cast(truncated))); - VERIFY((numext::isnan)(static_cast(rounded)) || (numext::isinf)(static_cast(rounded))); - return; - } - VERIFY_IS_EQUAL(expected_truncation, static_cast(truncated)); - VERIFY_IS_EQUAL(expected_rounding, static_cast(rounded)); -} - template void test_roundtrip() { // Representable T round trip via bfloat16 @@ -122,31 +110,6 @@ void test_conversion() VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(0.0f), 0x0000); VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(-0.0f), 0x8000); - // Flush denormals to zero - for (float denorm = -std::numeric_limits::denorm_min(); - denorm < std::numeric_limits::denorm_min(); - denorm = nextafterf(denorm, 1.0f)) { - bfloat16 bf_trunc = Eigen::bfloat16_impl::truncate_to_bfloat16(denorm); - VERIFY_IS_EQUAL(static_cast(bf_trunc), 0.0f); - - // Implicit conversion of denormls to bool is correct - VERIFY_IS_EQUAL(static_cast(bfloat16(denorm)), false); - VERIFY_IS_EQUAL(bfloat16(denorm), false); - - if (std::signbit(denorm)) { - VERIFY_BFLOAT16_BITS_EQUAL(bf_trunc, 0x8000); - } else { - VERIFY_BFLOAT16_BITS_EQUAL(bf_trunc, 0x0000); - } - bfloat16 bf_round = Eigen::bfloat16_impl::float_to_bfloat16_rtne(denorm); - VERIFY_IS_EQUAL(static_cast(bf_round), 0.0f); - if (std::signbit(denorm)) { - VERIFY_BFLOAT16_BITS_EQUAL(bf_round, 0x8000); - } else { - VERIFY_BFLOAT16_BITS_EQUAL(bf_round, 0x0000); - } - } - // Default is zero VERIFY_IS_EQUAL(static_cast(bfloat16()), 0.0f); @@ -156,52 +119,6 @@ void test_conversion() test_roundtrip >(); test_roundtrip >(); - // Truncate test - test_truncate( - BinaryToFloat(0, 0x80, 0x48, 0xf5c3), - BinaryToFloat(0, 0x80, 0x48, 0x0000), - BinaryToFloat(0, 0x80, 0x49, 0x0000)); - test_truncate( - BinaryToFloat(1, 0x80, 0x48, 0xf5c3), - BinaryToFloat(1, 0x80, 0x48, 0x0000), - BinaryToFloat(1, 0x80, 0x49, 0x0000)); - test_truncate( - BinaryToFloat(0, 0x80, 0x48, 0x8000), - BinaryToFloat(0, 0x80, 0x48, 0x0000), - BinaryToFloat(0, 0x80, 0x48, 0x0000)); - test_truncate( - BinaryToFloat(0, 0xff, 0x00, 0x0001), - BinaryToFloat(0, 0xff, 0x40, 0x0000), - BinaryToFloat(0, 0xff, 0x40, 0x0000)); - test_truncate( - BinaryToFloat(0, 0xff, 0x7f, 0xffff), - BinaryToFloat(0, 0xff, 0x40, 0x0000), - BinaryToFloat(0, 0xff, 0x40, 0x0000)); - test_truncate( - BinaryToFloat(1, 0x80, 0x48, 0xc000), - BinaryToFloat(1, 0x80, 0x48, 0x0000), - BinaryToFloat(1, 0x80, 0x49, 0x0000)); - test_truncate( - BinaryToFloat(0, 0x80, 0x48, 0x0000), - BinaryToFloat(0, 0x80, 0x48, 0x0000), - BinaryToFloat(0, 0x80, 0x48, 0x0000)); - test_truncate( - BinaryToFloat(0, 0x80, 0x48, 0x4000), - BinaryToFloat(0, 0x80, 0x48, 0x0000), - BinaryToFloat(0, 0x80, 0x48, 0x0000)); - test_truncate( - BinaryToFloat(0, 0x80, 0x48, 0x8000), - BinaryToFloat(0, 0x80, 0x48, 0x0000), - BinaryToFloat(0, 0x80, 0x48, 0x0000)); - test_truncate( - BinaryToFloat(0, 0x00, 0x48, 0x8000), - BinaryToFloat(0, 0x00, 0x00, 0x0000), - BinaryToFloat(0, 0x00, 0x00, 0x0000)); - test_truncate( - BinaryToFloat(0, 0x00, 0x7f, 0xc000), - BinaryToFloat(0, 0x00, 0x00, 0x0000), - BinaryToFloat(0, 0x00, 0x00, 0x0000)); - // Conversion Array a; for (int i = 0; i < 100; i++) a(i) = i + 1.25; @@ -250,12 +167,6 @@ void test_conversion() VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(BinaryToFloat(0x0, 0xff, 0x40, 0x0)), 0x7fc0); VERIFY_BFLOAT16_BITS_EQUAL(bfloat16(BinaryToFloat(0x1, 0xff, 0x40, 0x0)), 0xffc0); - VERIFY_BFLOAT16_BITS_EQUAL(Eigen::bfloat16_impl::truncate_to_bfloat16( - BinaryToFloat(0x0, 0xff, 0x40, 0x0)), - 0x7fc0); - VERIFY_BFLOAT16_BITS_EQUAL(Eigen::bfloat16_impl::truncate_to_bfloat16( - BinaryToFloat(0x1, 0xff, 0x40, 0x0)), - 0xffc0); } void test_numtraits() diff --git a/external/eigen/test/conservative_resize.cpp b/external/eigen/test/conservative_resize.cpp index d709e334..d48eb126 100644 --- a/external/eigen/test/conservative_resize.cpp +++ b/external/eigen/test/conservative_resize.cpp @@ -115,9 +115,11 @@ template void noncopyable() { typedef Eigen::Matrix VectorType; typedef Eigen::Matrix MatrixType; - + { +#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW AnnoyingScalar::dont_throw = true; +#endif int n = 50; VectorType v0(n), v1(n); MatrixType m0(n,n), m1(n,n), m2(n,n); @@ -156,7 +158,9 @@ EIGEN_DECLARE_TEST(conservative_resize) CALL_SUBTEST_4((run_vector_tests >())); CALL_SUBTEST_5((run_vector_tests >())); +#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW AnnoyingScalar::dont_throw = true; +#endif CALL_SUBTEST_6(( run_vector_tests() )); CALL_SUBTEST_6(( noncopyable<0>() )); } diff --git a/external/eigen/test/geo_hyperplane.cpp b/external/eigen/test/geo_hyperplane.cpp index 2c89ecd2..44b2f2ae 100644 --- a/external/eigen/test/geo_hyperplane.cpp +++ b/external/eigen/test/geo_hyperplane.cpp @@ -172,11 +172,6 @@ template void hyperplane_alignment() VERIFY_IS_APPROX(p1->coeffs(), p2->coeffs()); VERIFY_IS_APPROX(p1->coeffs(), p3->coeffs()); - - #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES > 0 - if(internal::packet_traits::Vectorizable && internal::packet_traits::size<=4) - VERIFY_RAISES_ASSERT((::new(reinterpret_cast(array3u)) Plane3a)); - #endif } diff --git a/external/eigen/test/geo_parametrizedline.cpp b/external/eigen/test/geo_parametrizedline.cpp index 7135c8fa..e4b194ab 100644 --- a/external/eigen/test/geo_parametrizedline.cpp +++ b/external/eigen/test/geo_parametrizedline.cpp @@ -110,11 +110,6 @@ template void parametrizedline_alignment() VERIFY_IS_APPROX(p1->origin(), p3->origin()); VERIFY_IS_APPROX(p1->direction(), p2->direction()); VERIFY_IS_APPROX(p1->direction(), p3->direction()); - - #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES>0 - if(internal::packet_traits::Vectorizable && internal::packet_traits::size<=4) - VERIFY_RAISES_ASSERT((::new(reinterpret_cast(array3u)) Line4a)); - #endif } EIGEN_DECLARE_TEST(geo_parametrizedline) diff --git a/external/eigen/test/geo_quaternion.cpp b/external/eigen/test/geo_quaternion.cpp index c4a3162b..c561fc89 100644 --- a/external/eigen/test/geo_quaternion.cpp +++ b/external/eigen/test/geo_quaternion.cpp @@ -218,10 +218,6 @@ template void mapQuaternion(void){ VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs()); VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs()); VERIFY_IS_APPROX(q4.coeffs(), q3.coeffs()); - #ifdef EIGEN_VECTORIZE - if(internal::packet_traits::Vectorizable) - VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned))); - #endif VERIFY_IS_APPROX(mq1 * (mq1.inverse() * v1), v1); VERIFY_IS_APPROX(mq1 * (mq1.conjugate() * v1), v1); @@ -281,10 +277,6 @@ template void quaternionAlignment(void){ VERIFY_IS_APPROX(q1->coeffs(), q2->coeffs()); VERIFY_IS_APPROX(q1->coeffs(), q3->coeffs()); - #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES>0 - if(internal::packet_traits::Vectorizable && internal::packet_traits::size<=4) - VERIFY_RAISES_ASSERT((::new(reinterpret_cast(arrayunaligned)) QuaternionA)); - #endif } template void check_const_correctness(const PlainObjectType&) diff --git a/external/eigen/test/geo_transformations.cpp b/external/eigen/test/geo_transformations.cpp index d433561c..72c6edac 100644 --- a/external/eigen/test/geo_transformations.cpp +++ b/external/eigen/test/geo_transformations.cpp @@ -582,11 +582,6 @@ template void transform_alignment() VERIFY_IS_APPROX(p1->matrix(), p3->matrix()); VERIFY_IS_APPROX( (*p1) * (*p1), (*p2)*(*p3)); - - #if defined(EIGEN_VECTORIZE) && EIGEN_MAX_STATIC_ALIGN_BYTES>0 - if(internal::packet_traits::Vectorizable) - VERIFY_RAISES_ASSERT((::new(reinterpret_cast(array3u)) Projective3a)); - #endif } template void transform_products() diff --git a/external/eigen/test/gpu_basic.cu b/external/eigen/test/gpu_basic.cu index bf8dcacd..4298da3b 100644 --- a/external/eigen/test/gpu_basic.cu +++ b/external/eigen/test/gpu_basic.cu @@ -197,18 +197,17 @@ struct complex_operators { res.segment(block_idx, size) = x1; res.segment(block_idx, size).array() /= x2.array(); block_idx += size; - // Equality comparisons currently not functional on device - // (std::equal_to is host-only). - // const T true_vector = T::Constant(true_value); - // const T false_vector = T::Constant(false_value); - // res.segment(block_idx, size) = (x1 == x2 ? true_vector : false_vector); - // block_idx += size; + const T true_vector = T::Constant(true_value); + const T false_vector = T::Constant(false_value); + res.segment(block_idx, size) = (x1 == x2 ? true_vector : false_vector); + block_idx += size; + // Mixing types in equality comparison does not work. // res.segment(block_idx, size) = (x1 == x2.real() ? true_vector : false_vector); // block_idx += size; // res.segment(block_idx, size) = (x1.real() == x2 ? true_vector : false_vector); // block_idx += size; - // res.segment(block_idx, size) = (x1 != x2 ? true_vector : false_vector); - // block_idx += size; + res.segment(block_idx, size) = (x1 != x2 ? true_vector : false_vector); + block_idx += size; // res.segment(block_idx, size) = (x1 != x2.real() ? true_vector : false_vector); // block_idx += size; // res.segment(block_idx, size) = (x1.real() != x2 ? true_vector : false_vector); diff --git a/external/eigen/test/jacobisvd.cpp b/external/eigen/test/jacobisvd.cpp index 89484d97..5b15c5a2 100644 --- a/external/eigen/test/jacobisvd.cpp +++ b/external/eigen/test/jacobisvd.cpp @@ -36,6 +36,9 @@ void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true) template void jacobisvd_verify_assert(const MatrixType& m) { svd_verify_assert >(m); + svd_verify_assert >(m, true); + svd_verify_assert >(m); + svd_verify_assert >(m); Index rows = m.rows(); Index cols = m.cols(); diff --git a/external/eigen/test/main.h b/external/eigen/test/main.h index 786673de..07f3794a 100644 --- a/external/eigen/test/main.h +++ b/external/eigen/test/main.h @@ -641,21 +641,14 @@ bool test_is_equal(const T& actual, const U& expected, bool expect_equal) return false; } +/** Creates a random Partial Isometry matrix of given rank. + * + * A partial isometry is a matrix all of whose singular values are either 0 or 1. + * This is very useful to test rank-revealing algorithms. + */ // Forward declaration to avoid ICC warning template void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m); -/** - * Creates a random partial isometry matrix of given rank. - * - * A partial isometry is a matrix all of whose singular values are either 0 or 1. - * This is very useful to test rank-revealing algorithms. - * - * @tparam MatrixType type of random partial isometry matrix - * @param desired_rank rank requested for the random partial isometry matrix - * @param rows row dimension of requested random partial isometry matrix - * @param cols column dimension of requested random partial isometry matrix - * @param m random partial isometry matrix - */ template void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, MatrixType& m) { @@ -696,13 +689,6 @@ void createRandomPIMatrixOfRank(Index desired_rank, Index rows, Index cols, Matr // Forward declaration to avoid ICC warning template void randomPermutationVector(PermutationVectorType& v, Index size); -/** - * Generate random permutation vector. - * - * @tparam PermutationVectorType type of vector used to store permutation - * @param v permutation vector - * @param size length of permutation vector - */ template void randomPermutationVector(PermutationVectorType& v, Index size) { @@ -719,37 +705,16 @@ void randomPermutationVector(PermutationVectorType& v, Index size) } } -/** - * Check if number is "not a number" (NaN). - * - * @tparam T input type - * @param x input value - * @return true, if input value is "not a number" (NaN) - */ template bool isNotNaN(const T& x) { return x==x; } -/** - * Check if number is plus infinity. - * - * @tparam T input type - * @param x input value - * @return true, if input value is plus infinity - */ template bool isPlusInf(const T& x) { return x > NumTraits::highest(); } -/** - * Check if number is minus infinity. - * - * @tparam T input type - * @param x input value - * @return true, if input value is minus infinity - */ template bool isMinusInf(const T& x) { return x < NumTraits::lowest(); @@ -778,11 +743,6 @@ template<> std::string type_name >() { return "comple using namespace Eigen; -/** - * Set number of repetitions for unit test from input string. - * - * @param str input string - */ inline void set_repeat_from_string(const char *str) { errno = 0; @@ -795,11 +755,6 @@ inline void set_repeat_from_string(const char *str) g_has_set_repeat = true; } -/** - * Set seed for randomized unit tests from input string. - * - * @param str input string - */ inline void set_seed_from_string(const char *str) { errno = 0; diff --git a/external/eigen/test/solverbase.h b/external/eigen/test/solverbase.h index ba76ba4e..13c09593 100644 --- a/external/eigen/test/solverbase.h +++ b/external/eigen/test/solverbase.h @@ -31,10 +31,6 @@ void check_solverbase(const MatrixType& matrix, const SolverType& solver, Index solver_solution2 = RhsType::Random(rows,cols2); solver_solution2 = solver.adjoint().solve(m2); VERIFY_IS_APPROX(m2, matrix.adjoint()*solver_solution2); - // test with temporary expression as rhs - m2 = DstType::Random(cols,cols2); - solver_solution = solver.solve(matrix*m2); - VERIFY_IS_APPROX(matrix*m2, matrix*solver_solution); } #endif // TEST_SOLVERBASE_H diff --git a/external/eigen/test/sparse_block.cpp b/external/eigen/test/sparse_block.cpp index f9668102..b4905b05 100644 --- a/external/eigen/test/sparse_block.cpp +++ b/external/eigen/test/sparse_block.cpp @@ -315,8 +315,9 @@ EIGEN_DECLARE_TEST(sparse_block) CALL_SUBTEST_4(( sparse_block(SparseMatrix(short(r), short(c))) )); CALL_SUBTEST_4(( sparse_block(SparseMatrix(short(r), short(c))) )); - +#ifndef EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW AnnoyingScalar::dont_throw = true; +#endif CALL_SUBTEST_5(( sparse_block(SparseMatrix(r,c)) )); } } diff --git a/external/eigen/test/svd_common.h b/external/eigen/test/svd_common.h index bd62edcc..eae4c0bf 100644 --- a/external/eigen/test/svd_common.h +++ b/external/eigen/test/svd_common.h @@ -462,7 +462,7 @@ void svd_preallocate() } template -void svd_verify_assert(const MatrixType& m) +void svd_verify_assert(const MatrixType& m, bool fullOnly = false) { typedef typename MatrixType::Scalar Scalar; Index rows = m.rows(); @@ -489,8 +489,17 @@ void svd_verify_assert(const MatrixType& m) VERIFY_RAISES_ASSERT(svd.matrixV()) svd.singularValues(); VERIFY_RAISES_ASSERT(svd.solve(rhs)) - - if (ColsAtCompileTime == Dynamic) + + svd.compute(a, ComputeFullU); + svd.matrixU(); + VERIFY_RAISES_ASSERT(svd.matrixV()) + VERIFY_RAISES_ASSERT(svd.solve(rhs)) + svd.compute(a, ComputeFullV); + svd.matrixV(); + VERIFY_RAISES_ASSERT(svd.matrixU()) + VERIFY_RAISES_ASSERT(svd.solve(rhs)) + + if (!fullOnly && ColsAtCompileTime == Dynamic) { svd.compute(a, ComputeThinU); svd.matrixU(); diff --git a/external/eigen/test/unalignedassert.cpp b/external/eigen/test/unalignedassert.cpp deleted file mode 100644 index 120cc42b..00000000 --- a/external/eigen/test/unalignedassert.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Benoit Jacob -// Copyright (C) 2015 Gael Guennebaud -// -// 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/. - -#if defined(EIGEN_TEST_PART_1) - // default -#elif defined(EIGEN_TEST_PART_2) - #define EIGEN_MAX_STATIC_ALIGN_BYTES 16 - #define EIGEN_MAX_ALIGN_BYTES 16 -#elif defined(EIGEN_TEST_PART_3) - #define EIGEN_MAX_STATIC_ALIGN_BYTES 32 - #define EIGEN_MAX_ALIGN_BYTES 32 -#elif defined(EIGEN_TEST_PART_4) - #define EIGEN_MAX_STATIC_ALIGN_BYTES 64 - #define EIGEN_MAX_ALIGN_BYTES 64 -#endif - -#include "main.h" - -typedef Matrix Vector6f; -typedef Matrix Vector8f; -typedef Matrix Vector12f; - -typedef Matrix Vector5d; -typedef Matrix Vector6d; -typedef Matrix Vector7d; -typedef Matrix Vector8d; -typedef Matrix Vector9d; -typedef Matrix Vector10d; -typedef Matrix Vector12d; - -struct TestNew1 -{ - MatrixXd m; // good: m will allocate its own array, taking care of alignment. - TestNew1() : m(20,20) {} -}; - -struct TestNew2 -{ - Matrix3d m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned, - // 8-byte alignment is good enough here, which we'll get automatically -}; - -struct TestNew3 -{ - Vector2f m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned -}; - -struct TestNew4 -{ - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - Vector2d m; - float f; // make the struct have sizeof%16!=0 to make it a little more tricky when we allow an array of 2 such objects -}; - -struct TestNew5 -{ - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - float f; // try the f at first -- the EIGEN_ALIGN_MAX attribute of m should make that still work - Matrix4f m; -}; - -struct TestNew6 -{ - Matrix m; // good: no alignment requested - float f; -}; - -template struct Depends -{ - EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(Align) - Vector2d m; - float f; -}; - -template -void check_unalignedassert_good() -{ - T *x, *y; - x = new T; - delete x; - y = new T[2]; - delete[] y; -} - -#if EIGEN_MAX_STATIC_ALIGN_BYTES>0 -template -void construct_at_boundary(int boundary) -{ - char buf[sizeof(T)+256]; - size_t _buf = reinterpret_cast(buf); - _buf += (EIGEN_MAX_ALIGN_BYTES - (_buf % EIGEN_MAX_ALIGN_BYTES)); // make 16/32/...-byte aligned - _buf += boundary; // make exact boundary-aligned - T *x = ::new(reinterpret_cast(_buf)) T; - x[0].setZero(); // just in order to silence warnings - x->~T(); -} -#endif - -void unalignedassert() -{ -#if EIGEN_MAX_STATIC_ALIGN_BYTES>0 - construct_at_boundary(4); - construct_at_boundary(4); - construct_at_boundary(16); - construct_at_boundary(4); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - construct_at_boundary(16); - construct_at_boundary(16); - construct_at_boundary(4); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - - construct_at_boundary(16); - construct_at_boundary(4); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - construct_at_boundary(4); - construct_at_boundary(16); - construct_at_boundary(4); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - construct_at_boundary(4); - construct_at_boundary(16); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - construct_at_boundary(4); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - - construct_at_boundary(16); - construct_at_boundary(4); - construct_at_boundary(EIGEN_MAX_ALIGN_BYTES); - construct_at_boundary(16); -#endif - - check_unalignedassert_good(); - check_unalignedassert_good(); - check_unalignedassert_good(); - - check_unalignedassert_good(); - check_unalignedassert_good(); - check_unalignedassert_good(); - check_unalignedassert_good >(); - -#if EIGEN_MAX_STATIC_ALIGN_BYTES>0 - if(EIGEN_MAX_ALIGN_BYTES>=16) - { - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - // Complexes are disabled because the compiler might aggressively vectorize - // the initialization of complex coeffs to 0 before we can check for alignedness - //VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - VERIFY_RAISES_ASSERT(construct_at_boundary(8)); - } - for(int b=8; b(b)); - if(b<64) VERIFY_RAISES_ASSERT(construct_at_boundary(b)); - if(b<32) VERIFY_RAISES_ASSERT(construct_at_boundary(b)); - if(b<32) VERIFY_RAISES_ASSERT(construct_at_boundary(b)); - if(b<128) VERIFY_RAISES_ASSERT(construct_at_boundary(b)); - //if(b<32) VERIFY_RAISES_ASSERT(construct_at_boundary(b)); - } -#endif -} - -EIGEN_DECLARE_TEST(unalignedassert) -{ - CALL_SUBTEST(unalignedassert()); -} diff --git a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md index d4d3d598..2f65b1b0 100644 --- a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md +++ b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md @@ -1466,9 +1466,9 @@ the input tensor. Eigen::Tensor a(4, 3); a.setValues({{0, 100, 200}, {300, 400, 500}, {600, 700, 800}, {900, 1000, 1100}}); - Eigen::array offsets = {1, 0}; - Eigen::array extents = {2, 2}; - Eigen::Tensor slice = a.slice(offsets, extents); + Eigen::array offsets = {1, 0}; + Eigen::array extents = {2, 2}; + Eigen::Tensor slice = a.slice(offsets, extents); cout << "a" << endl << a << endl; => a diff --git a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h index cdd8840f..8b35f798 100644 --- a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h +++ b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h @@ -762,7 +762,7 @@ struct TensorContractionEvaluatorBase : internal::no_assignment_operator const Index resIncr(1); // zero out the result buffer (which must be of size at least rows * sizeof(Scalar) - m_device.fill(buffer, buffer + rows, Scalar(0)); + m_device.memset(buffer, 0, rows * sizeof(Scalar)); internal::general_matrix_vector_product::run( rows, cols, lhs, rhs, @@ -869,7 +869,7 @@ struct TensorContractionEvaluatorBase : internal::no_assignment_operator // If a contraction kernel does not support beta, explicitly initialize // output buffer with zeroes. if (!TensorContractionKernel::HasBeta) { - this->m_device.fill(buffer, buffer + m * n, Scalar(0)); + this->m_device.memset(buffer, 0, m * n * sizeof(Scalar)); } for(Index i2=0; i2m_j_size; - // zero out the result buffer (which must be of size at least m * n * sizeof(Scalar)) - this->m_device.fill(buffer, buffer + m * n, Scalar(0)); + // zero out the result buffer (which must be of size at least m * n * sizeof(Scalar) + this->m_device.memset(buffer, 0, m * n * sizeof(Scalar)); typedef internal::TensorContractionInputMapper - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void fill(T* begin, T* end, const T& value) const { -#ifdef EIGEN_GPU_COMPILE_PHASE - // std::fill is not a device function, so resort to simple loop. - for (T* it = begin; it != end; ++it) { - *it = value; - } -#else - std::fill(begin, end, value); -#endif - } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Type get(Type data) const { return data; diff --git a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h index 8ee4478c..ec2e3cb1 100644 --- a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h +++ b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h @@ -281,49 +281,10 @@ struct GpuDevice { EIGEN_UNUSED_VARIABLE(err) gpu_assert(err == gpuSuccess); #else - EIGEN_UNUSED_VARIABLE(buffer) - EIGEN_UNUSED_VARIABLE(c) - EIGEN_UNUSED_VARIABLE(n) eigen_assert(false && "The default device should be used instead to generate kernel code"); #endif } - template - EIGEN_STRONG_INLINE void fill(T* begin, T* end, const T& value) const { -#ifndef EIGEN_GPU_COMPILE_PHASE - const size_t count = end - begin; - // Split value into bytes and run memset with stride. - const int value_size = sizeof(value); - char* buffer = (char*)begin; - char* value_bytes = (char*)(&value); - gpuError_t err; - EIGEN_UNUSED_VARIABLE(err) - - // If all value bytes are equal, then a single memset can be much faster. - bool use_single_memset = true; - for (int i=1; istream()); - gpu_assert(err == gpuSuccess); - } else { - for (int b=0; bstream()); - gpu_assert(err == gpuSuccess); - } - } -#else - EIGEN_UNUSED_VARIABLE(begin) - EIGEN_UNUSED_VARIABLE(end) - EIGEN_UNUSED_VARIABLE(value) - eigen_assert(false && "The default device should be used instead to generate kernel code"); -#endif - } - EIGEN_STRONG_INLINE size_t numThreads() const { // FIXME return 32; diff --git a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h index 844c0939..df591c21 100644 --- a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h +++ b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h @@ -327,27 +327,13 @@ class QueueInterface { if (n == 0) { return; } + n /= sizeof(buffer_scalar_t); auto f = [&](cl::sycl::handler &cgh) { - // Get a typed range accesser to ensure we fill each byte, in case - // `buffer_scalar_t` is not (u)int8_t. - auto dst_acc = get_typed_range_accessor(cgh, data, n); - cgh.fill(dst_acc, static_cast(c)); - }; - cl::sycl::event e; - EIGEN_SYCL_TRY_CATCH(e = m_queue.submit(f)); - async_synchronize(e); - } - - template - EIGEN_STRONG_INLINE void fill(T* begin, T* end, const T& value) const { - static const auto write_mode = cl::sycl::access::mode::discard_write; - if (begin == end) { - return; - } - const ptrdiff_t count = end - begin; - auto f = [&](cl::sycl::handler &cgh) { - auto dst_acc = get_typed_range_accessor(cgh, begin, count); - cgh.fill(dst_acc, value); + auto dst_acc = get_range_accessor(cgh, data, n); + // The cast to uint8_t is here to match the behaviour of the standard + // memset. The cast to buffer_scalar_t is needed to match the type of the + // accessor (in case buffer_scalar_t is not uint8_t) + cgh.fill(dst_acc, static_cast(static_cast(c))); }; cl::sycl::event e; EIGEN_SYCL_TRY_CATCH(e = m_queue.submit(f)); @@ -373,8 +359,6 @@ class QueueInterface { auto original_buffer = pMapper.get_buffer(ptr); const ptrdiff_t offset = pMapper.get_offset(ptr); - eigen_assert(offset % sizeof(T) == 0 && "The offset must be a multiple of sizeof(T)"); - eigen_assert(original_buffer.get_size() % sizeof(T) == 0 && "The buffer size must be a multiple of sizeof(T)"); const ptrdiff_t typed_offset = offset / sizeof(T); eigen_assert(typed_offset >= 0); const auto typed_size = original_buffer.get_size() / sizeof(T); @@ -411,40 +395,6 @@ class QueueInterface { cgh, cl::sycl::range<1>(n_bytes), cl::sycl::id<1>(offset)); } - /// Get a range accessor to the virtual pointer's device memory with a - /// specified type and count. - template - EIGEN_STRONG_INLINE cl::sycl::accessor< - T, 1, AcMd, cl::sycl::access::target::global_buffer> - get_typed_range_accessor(cl::sycl::handler &cgh, const void *ptr, - const Index count) const { - static const auto global_access = cl::sycl::access::target::global_buffer; - eigen_assert(count >= 0); - std::lock_guard lock(pmapper_mutex_); - auto buffer = pMapper.get_buffer(ptr); - const ptrdiff_t offset = pMapper.get_offset(ptr); - eigen_assert(offset >= 0); - - // Technically we should create a subbuffer for the desired range, - // then reinterpret that. However, I was not able to get changes to reflect - // in the original buffer (only the subbuffer and reinterpretted buffer). - // This current implementation now has the restriction that the buffer - // offset and original buffer size must be a multiple of sizeof(T). - // Note that get_range_accessor(void*) currently has the same restriction. - // - // auto subbuffer = cl::sycl::buffer(buffer, - // cl::sycl::id<1>(offset), cl::sycl::range<1>(n_bytes)); - eigen_assert(offset % sizeof(T) == 0 && "The offset must be a multiple of sizeof(T)"); - eigen_assert(buffer.get_size() % sizeof(T) == 0 && "The buffer size must be a multiple of sizeof(T)"); - const ptrdiff_t typed_offset = offset / sizeof(T); - const size_t typed_size = buffer.get_size() / sizeof(T); - auto reint = buffer.template reinterpret< - typename Eigen::internal::remove_const::type>( - cl::sycl::range<1>(typed_size)); - return reint.template get_access( - cgh, cl::sycl::range<1>(count), cl::sycl::id<1>(typed_offset)); - } - /// Creation of sycl accessor for a buffer. This function first tries to find /// the buffer in the buffer_map. If found it gets the accessor from it, if /// not, the function then adds an entry by creating a sycl buffer for that @@ -1001,11 +951,6 @@ struct SyclDevice : public SyclDeviceBase { EIGEN_STRONG_INLINE void memset(void *data, int c, size_t n) const { queue_stream()->memset(data, c, n); } - /// the fill function - template - EIGEN_STRONG_INLINE void fill(T* begin, T* end, const T& value) const { - queue_stream()->fill(begin, end, value); - } /// returning the sycl queue EIGEN_STRONG_INLINE cl::sycl::queue &sycl_queue() const { return queue_stream()->sycl_queue(); diff --git a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h index 18cc79a0..e524b535 100644 --- a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h +++ b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h @@ -122,11 +122,6 @@ struct ThreadPoolDevice { ::memset(buffer, c, n); } - template - EIGEN_STRONG_INLINE void fill(T* begin, T* end, const T& value) const { - std::fill(begin, end, value); - } - EIGEN_STRONG_INLINE int numThreads() const { return num_threads_; } diff --git a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaDefines.h b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaDefines.h index 82ca999b..cb53ce29 100644 --- a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaDefines.h +++ b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaDefines.h @@ -41,7 +41,6 @@ #define gpuMalloc hipMalloc #define gpuFree hipFree #define gpuMemsetAsync hipMemsetAsync -#define gpuMemset2DAsync hipMemset2DAsync #define gpuMemcpyAsync hipMemcpyAsync #define gpuMemcpyDeviceToDevice hipMemcpyDeviceToDevice #define gpuMemcpyDeviceToHost hipMemcpyDeviceToHost @@ -72,7 +71,6 @@ #define gpuMalloc cudaMalloc #define gpuFree cudaFree #define gpuMemsetAsync cudaMemsetAsync -#define gpuMemset2DAsync cudaMemset2DAsync #define gpuMemcpyAsync cudaMemcpyAsync #define gpuMemcpyDeviceToDevice cudaMemcpyDeviceToDevice #define gpuMemcpyDeviceToHost cudaMemcpyDeviceToHost diff --git a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaUndefines.h b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaUndefines.h index e4d4bd5e..1d142f2e 100644 --- a/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaUndefines.h +++ b/external/eigen/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaUndefines.h @@ -26,7 +26,6 @@ #undef gpuMalloc #undef gpuFree #undef gpuMemsetAsync -#undef gpuMemset2DAsync #undef gpuMemcpyAsync #undef gpuMemcpyDeviceToDevice #undef gpuMemcpyDeviceToHost diff --git a/external/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/external/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h index 0ef159e3..0f166e35 100755 --- a/external/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +++ b/external/eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h @@ -26,11 +26,11 @@ void make_coherent(const A& a, const B&b) make_coherent_impl::run(a.const_cast_derived(), b.const_cast_derived()); } -template struct auto_diff_special_op; +template struct auto_diff_special_op; } // end namespace internal -template class AutoDiffScalar; +template class AutoDiffScalar; template inline AutoDiffScalar MakeAutoDiffScalar(const typename NewDerType::Scalar& value, const NewDerType &der) { @@ -38,16 +38,16 @@ inline AutoDiffScalar MakeAutoDiffScalar(const typename NewDerType:: } /** \class AutoDiffScalar - * \brief A scalar type replacement with automatic differentation capability + * \brief A scalar type replacement with automatic differentiation capability * - * \param _DerType the vector type used to store/represent the derivatives. The base scalar type + * \param DerivativeType the vector type used to store/represent the derivatives. The base scalar type * as well as the number of derivatives to compute are determined from this type. * Typical choices include, e.g., \c Vector4f for 4 derivatives, or \c VectorXf * if the number of derivatives is not known at compile time, and/or, the number * of derivatives is large. - * Note that _DerType can also be a reference (e.g., \c VectorXf&) to wrap a + * Note that DerivativeType can also be a reference (e.g., \c VectorXf&) to wrap a * existing vector into an AutoDiffScalar. - * Finally, _DerType can also be any Eigen compatible expression. + * Finally, DerivativeType can also be any Eigen compatible expression. * * This class represents a scalar value while tracking its respective derivatives using Eigen's expression * template mechanism. @@ -63,17 +63,17 @@ inline AutoDiffScalar MakeAutoDiffScalar(const typename NewDerType:: * */ -template +template class AutoDiffScalar : public internal::auto_diff_special_op - <_DerType, !internal::is_same::type>::Scalar, - typename NumTraits::type>::Scalar>::Real>::value> + ::type>::Scalar, + typename NumTraits::type>::Scalar>::Real>::value> { public: typedef internal::auto_diff_special_op - <_DerType, !internal::is_same::type>::Scalar, - typename NumTraits::type>::Scalar>::Real>::value> Base; - typedef typename internal::remove_all<_DerType>::type DerType; + ::type>::Scalar, + typename NumTraits::type>::Scalar>::Real>::value> Base; + typedef typename internal::remove_all::type DerType; typedef typename internal::traits::Scalar Scalar; typedef typename NumTraits::Real Real; @@ -382,16 +382,16 @@ class AutoDiffScalar namespace internal { -template -struct auto_diff_special_op<_DerType, true> -// : auto_diff_scalar_op<_DerType, typename NumTraits::Real, +template +struct auto_diff_special_op +// : auto_diff_scalar_op::Real, // is_same::Real>::value> { - typedef typename remove_all<_DerType>::type DerType; + typedef typename remove_all::type DerType; typedef typename traits::Scalar Scalar; typedef typename NumTraits::Real Real; -// typedef auto_diff_scalar_op<_DerType, typename NumTraits::Real, +// typedef auto_diff_scalar_op::Real, // is_same::Real>::value> Base; // using Base::operator+; @@ -401,8 +401,8 @@ struct auto_diff_special_op<_DerType, true> // using Base::operator*; // using Base::operator*=; - const AutoDiffScalar<_DerType>& derived() const { return *static_cast*>(this); } - AutoDiffScalar<_DerType>& derived() { return *static_cast*>(this); } + const AutoDiffScalar& derived() const { return *static_cast*>(this); } + AutoDiffScalar& derived() { return *static_cast*>(this); } inline const AutoDiffScalar operator+(const Real& other) const @@ -410,12 +410,12 @@ struct auto_diff_special_op<_DerType, true> return AutoDiffScalar(derived().value() + other, derived().derivatives()); } - friend inline const AutoDiffScalar operator+(const Real& a, const AutoDiffScalar<_DerType>& b) + friend inline const AutoDiffScalar operator+(const Real& a, const AutoDiffScalar& b) { return AutoDiffScalar(a + b.value(), b.derivatives()); } - inline AutoDiffScalar<_DerType>& operator+=(const Real& other) + inline AutoDiffScalar& operator+=(const Real& other) { derived().value() += other; return derived(); @@ -431,22 +431,22 @@ struct auto_diff_special_op<_DerType, true> } friend inline const AutoDiffScalar >, DerType>::Type > - operator*(const Real& other, const AutoDiffScalar<_DerType>& a) + operator*(const Real& other, const AutoDiffScalar& a) { return AutoDiffScalar >, DerType>::Type >( a.value() * other, a.derivatives() * other); } - inline AutoDiffScalar<_DerType>& operator*=(const Scalar& other) + inline AutoDiffScalar& operator*=(const Scalar& other) { *this = *this * other; return derived(); } }; -template -struct auto_diff_special_op<_DerType, false> +template +struct auto_diff_special_op { void operator*() const; void operator-() const; diff --git a/external/eigen/unsupported/Eigen/src/Skyline/SkylineMatrix.h b/external/eigen/unsupported/Eigen/src/Skyline/SkylineMatrix.h index 664a97f6..7c7eace7 100644 --- a/external/eigen/unsupported/Eigen/src/Skyline/SkylineMatrix.h +++ b/external/eigen/unsupported/Eigen/src/Skyline/SkylineMatrix.h @@ -375,8 +375,8 @@ class SkylineMatrix /** Removes all non zeros */ inline void setZero() { m_data.clear(); - std::fill_n(m_colStartIndex, m_outerSize + 1, Index(0)); - std::fill_n(m_rowStartIndex, m_outerSize + 1, Index(0)); + memset(m_colStartIndex, 0, (m_outerSize + 1) * sizeof (Index)); + memset(m_rowStartIndex, 0, (m_outerSize + 1) * sizeof (Index)); } /** \returns the number of non zero coefficients */ @@ -435,7 +435,7 @@ class SkylineMatrix } //zeros new data - std::fill_n(this->_upperPtr() + start, bandIncrement - 1, Scalar(0)); + memset(this->_upperPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar)); return m_data.upper(m_colStartIndex[inner]); } else { @@ -466,7 +466,7 @@ class SkylineMatrix } //zeros new data - std::fill_n(this->_lowerPtr() + start, bandIncrement - 1, Scalar(0)); + memset(this->_lowerPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar)); return m_data.lower(m_rowStartIndex[outer]); } else { return m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer))); @@ -493,7 +493,7 @@ class SkylineMatrix for (Index innerIdx = inner + 1; innerIdx < outerSize() + 1; innerIdx++) { m_rowStartIndex[innerIdx] += bandIncrement; } - std::fill_n(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, bandIncrement - 1, Scalar(0)); + memset(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar)); return m_data.upper(m_rowStartIndex[inner] + m_data.upperProfile(inner)); } else { return m_data.upper(m_rowStartIndex[inner] + (outer - inner)); @@ -520,7 +520,7 @@ class SkylineMatrix for (Index innerIdx = outer + 1; innerIdx < outerSize() + 1; innerIdx++) { m_colStartIndex[innerIdx] += bandIncrement; } - std::fill_n(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, bandIncrement - 1, Scalar(0)); + memset(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar)); return m_data.lower(m_colStartIndex[outer] + m_data.lowerProfile(outer)); } else { return m_data.lower(m_colStartIndex[outer] + (inner - outer)); @@ -619,8 +619,8 @@ class SkylineMatrix m_data.clear(); m_outerSize = diagSize; - std::fill_n(m_colStartIndex, cols + 1, Index(0)); - std::fill_n(m_rowStartIndex, rows + 1, Index(0)); + memset(m_colStartIndex, 0, (cols + 1) * sizeof (Index)); + memset(m_rowStartIndex, 0, (rows + 1) * sizeof (Index)); } void resizeNonZeros(Index size) { diff --git a/external/eigen/unsupported/Eigen/src/Skyline/SkylineStorage.h b/external/eigen/unsupported/Eigen/src/Skyline/SkylineStorage.h index 9c55f299..cc7514f1 100644 --- a/external/eigen/unsupported/Eigen/src/Skyline/SkylineStorage.h +++ b/external/eigen/unsupported/Eigen/src/Skyline/SkylineStorage.h @@ -187,11 +187,11 @@ class SkylineStorage { } inline void reset() { - std::fill_n(m_diag, m_diagSize, Scalar(0)); - std::fill_n(m_upper, m_upperSize, Scalar(0)); - std::fill_n(m_lower, m_lowerSize, Scalar(0)); - std::fill_n(m_upperProfile, m_diagSize, Index(0)); - std::fill_n(m_lowerProfile, m_diagSize, Index(0)); + memset(m_diag, 0, m_diagSize * sizeof (Scalar)); + memset(m_upper, 0, m_upperSize * sizeof (Scalar)); + memset(m_lower, 0, m_lowerSize * sizeof (Scalar)); + memset(m_upperProfile, 0, m_diagSize * sizeof (Index)); + memset(m_lowerProfile, 0, m_diagSize * sizeof (Index)); } void prune(Scalar reference, RealScalar epsilon = dummy_precision()) { diff --git a/external/eigen/unsupported/doc/examples/SYCL/CMakeLists.txt b/external/eigen/unsupported/doc/examples/SYCL/CMakeLists.txt index bef4f192..1d0f721d 100644 --- a/external/eigen/unsupported/doc/examples/SYCL/CMakeLists.txt +++ b/external/eigen/unsupported/doc/examples/SYCL/CMakeLists.txt @@ -3,8 +3,7 @@ FILE(GLOB examples_SRCS "*.cpp") set(EIGEN_SYCL ON) list(APPEND CMAKE_EXE_LINKER_FLAGS -pthread) if(EIGEN_SYCL_TRISYCL) - set(CMAKE_CXX_STANDARD 14) - set(STD_CXX_FLAG "-std=c++1z") + set(CMAKE_CXX_STANDARD 17) else(EIGEN_SYCL_TRISYCL) if(MSVC) # Set the host and device compilers C++ standard to C++14. On Windows setting this to C++11 diff --git a/external/eigen/unsupported/test/CMakeLists.txt b/external/eigen/unsupported/test/CMakeLists.txt index 18191936..d30fa62b 100644 --- a/external/eigen/unsupported/test/CMakeLists.txt +++ b/external/eigen/unsupported/test/CMakeLists.txt @@ -55,13 +55,11 @@ ei_add_test(FFT) ei_add_test(EulerAngles) -find_package(MPFR 2.3.0) -find_package(GMP) -if(MPFR_FOUND AND EIGEN_COMPILER_SUPPORT_CPP11) - include_directories(${MPFR_INCLUDES} ./mpreal) +find_package(MPREAL) +if(MPREAL_FOUND AND EIGEN_COMPILER_SUPPORT_CPP11) ei_add_property(EIGEN_TESTED_BACKENDS "MPFR C++, ") - set(EIGEN_MPFR_TEST_LIBRARIES ${MPFR_LIBRARIES} ${GMP_LIBRARIES}) - ei_add_test(mpreal_support "-std=c++11" "${EIGEN_MPFR_TEST_LIBRARIES}" ) + include_directories(${MPREAL_INCLUDES}) + ei_add_test(mpreal_support "-std=c++11" "${MPREAL_LIBRARIES}" ) else() ei_add_property(EIGEN_MISSING_BACKENDS "MPFR C++, ") endif() @@ -165,8 +163,8 @@ if(EIGEN_TEST_CXX11) endif() if(EIGEN_SYCL_TRISYCL) - set(CMAKE_CXX_STANDARD 14) - set(STD_CXX_FLAG "-std=c++1z") + # triSYCL now requires c++17. + set(CMAKE_CXX_STANDARD 17) else() if(MSVC) # Set the host and device compilers C++ standard to C++14. On Windows setting this to C++11 diff --git a/external/eigen/unsupported/test/cxx11_tensor_assign.cpp b/external/eigen/unsupported/test/cxx11_tensor_assign.cpp index 8e3ca0fc..ce9d2436 100644 --- a/external/eigen/unsupported/test/cxx11_tensor_assign.cpp +++ b/external/eigen/unsupported/test/cxx11_tensor_assign.cpp @@ -25,8 +25,10 @@ static void test_1d() vec1(4) = 23; vec2(4) = 4; vec1(5) = 42; vec2(5) = 5; - int col_major[6] = {0}; - int row_major[6] = {0}; + int col_major[6]; + int row_major[6]; + memset(col_major, 0, 6*sizeof(int)); + memset(row_major, 0, 6*sizeof(int)); TensorMap > vec3(col_major, 6); TensorMap > vec4(row_major, 6); @@ -86,8 +88,10 @@ static void test_2d() mat2(1,1) = 4; mat2(1,2) = 5; - int col_major[6] = {0}; - int row_major[6] = {0}; + int col_major[6]; + int row_major[6]; + memset(col_major, 0, 6*sizeof(int)); + memset(row_major, 0, 6*sizeof(int)); TensorMap > mat3(row_major, 2, 3); TensorMap > mat4(col_major, 2, 3); @@ -144,8 +148,10 @@ static void test_3d() } } - int col_major[2*3*7] = {0}; - int row_major[2*3*7] = {0}; + int col_major[2*3*7]; + int row_major[2*3*7]; + memset(col_major, 0, 2*3*7*sizeof(int)); + memset(row_major, 0, 2*3*7*sizeof(int)); TensorMap > mat3(col_major, 2, 3, 7); TensorMap > mat4(row_major, 2, 3, 7); diff --git a/external/eigen/unsupported/test/cxx11_tensor_device.cu b/external/eigen/unsupported/test/cxx11_tensor_device.cu index 58cfc01b..c9f78d2d 100644 --- a/external/eigen/unsupported/test/cxx11_tensor_device.cu +++ b/external/eigen/unsupported/test/cxx11_tensor_device.cu @@ -14,7 +14,6 @@ #define EIGEN_USE_GPU #include "main.h" -#include "OffByOneScalar.h" #include #include @@ -176,44 +175,6 @@ void test_3d_convolution(Context* context) context->out().slice(indices, sizes).device(context->device()) = context->in1().convolve(context->kernel3d(), dims); } -// Helper method to synchronize device. -template -void synchronize(Device& device) { /*nothing*/ } -template<> -void synchronize(Eigen::GpuDevice& device) { - device.synchronize(); -} - -template -void test_device_memory(const TensorDevice& device) { - int count = 100; - Eigen::array tensorRange = {{count}}; - Eigen::Tensor host(tensorRange); - Eigen::Tensor expected(tensorRange); - DataType* device_data = static_cast(device.allocate(count * sizeof(DataType))); - - // memset - const char byte_value = static_cast(0xAB); - device.memset(device_data, byte_value, count * sizeof(DataType)); - device.memcpyDeviceToHost(host.data(), device_data, count * sizeof(DataType)); - synchronize(device); - memset(expected.data(), byte_value, count * sizeof(DataType)); - for (size_t i=0; i in1(40,50,70); @@ -305,9 +266,6 @@ void test_cpu() { } } } - - test_device_memory(context.device()); - test_device_memory>(context.device()); } void test_gpu() { @@ -428,8 +386,6 @@ void test_gpu() { #endif - test_device_memory(context.device()); - test_device_memory>(context.device()); } diff --git a/external/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp b/external/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp index d7ff38d3..5095cb07 100644 --- a/external/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp +++ b/external/eigen/unsupported/test/cxx11_tensor_device_sycl.cpp @@ -18,36 +18,26 @@ #define EIGEN_USE_SYCL #include "main.h" -#include "OffByOneScalar.h" #include #include #include template void test_device_memory(const Eigen::SyclDevice &sycl_device) { + std::cout << "Running on : " + << sycl_device.sycl_queue().get_device(). template get_info() + < tensorRange = {{sizeDim1}}; Tensor in(tensorRange); Tensor in1(tensorRange); - DataType* gpu_in_data = static_cast(sycl_device.allocate(in.size()*sizeof(DataType))); - - // memset memset(in1.data(), 1, in1.size() * sizeof(DataType)); + DataType* gpu_in_data = static_cast(sycl_device.allocate(in.size()*sizeof(DataType))); sycl_device.memset(gpu_in_data, 1, in.size()*sizeof(DataType)); sycl_device.memcpyDeviceToHost(in.data(), gpu_in_data, in.size()*sizeof(DataType)); for (IndexType i=0; i -void test_device_attach_buffer(const Eigen::SyclDevice &sycl_device) { - IndexType sizeDim1 = 100; - - array tensorRange = {{sizeDim1}}; - Tensor in(tensorRange); - - cl::sycl::buffer buffer(cl::sycl::range<1>(sizeDim1 * sizeof(DataType))); - DataType* gpu_in_data = static_cast(sycl_device.attach_buffer(buffer)); - - // fill - DataType value = DataType(7); - std::fill_n(in.data(), in.size(), value); - sycl_device.fill(gpu_in_data, gpu_in_data + in.size(), value); - - // Check that buffer is filled with the correct value. - auto reint = buffer.reinterpret(cl::sycl::range<1>(sizeDim1)); - auto access = reint.template get_access(); - for (IndexType i=0; i void sycl_device_test_per_device(const cl::sycl::device& d){ std::cout << "Running on " << d.template get_info() << std::endl; QueueInterface queueInterface(d); @@ -103,12 +68,10 @@ template void sycl_device_test_per_device(const cl::sycl::dev //test_device_exceptions(sycl_device); /// this test throw an exception. enable it if you want to see the exception //test_device_exceptions(sycl_device); - test_device_attach_buffer(sycl_device); } EIGEN_DECLARE_TEST(cxx11_tensor_device_sycl) { for (const auto& device :Eigen::get_sycl_supported_devices()) { CALL_SUBTEST(sycl_device_test_per_device(device)); - CALL_SUBTEST(sycl_device_test_per_device>(device)); } } diff --git a/external/eigen/unsupported/test/mpreal/mpreal.h b/external/eigen/unsupported/test/mpreal/mpreal.h deleted file mode 100644 index 5cfd66a1..00000000 --- a/external/eigen/unsupported/test/mpreal/mpreal.h +++ /dev/null @@ -1,3184 +0,0 @@ -/* - MPFR C++: Multi-precision floating point number class for C++. - Based on MPFR library: http://mpfr.org - - Project homepage: http://www.holoborodko.com/pavel/mpfr - Contact e-mail: pavel@holoborodko.com - - Copyright (c) 2008-2016 Pavel Holoborodko - - Contributors: - Dmitriy Gubanov, Konstantin Holoborodko, Brian Gladman, - Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, Heinz van Saanen, - Pere Constans, Peter van Hoof, Gael Guennebaud, Tsai Chia Cheng, - Alexei Zubanov, Jauhien Piatlicki, Victor Berger, John Westwood, - Petr Aleksandrov, Orion Poplawski, Charles Karney, Arash Partow, - Rodney James, Jorge Leitao, Jerome Benoit. - - Licensing: - (A) MPFR C++ is under GNU General Public License ("GPL"). - - (B) Non-free licenses may also be purchased from the author, for users who - do not want their programs protected by the GPL. - - The non-free licenses are for users that wish to use MPFR C++ in - their products but are unwilling to release their software - under the GPL (which would require them to release source code - and allow free redistribution). - - Such users can purchase an unlimited-use license from the author. - Contact us for more details. - - GNU General Public License ("GPL") copyright permissions statement: - ************************************************************************** - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef __MPREAL_H__ -#define __MPREAL_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Options -#define MPREAL_HAVE_MSVC_DEBUGVIEW // Enable Debugger Visualizer for "Debug" builds in MSVC. -#define MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS // Enable extended std::numeric_limits specialization. - // Meaning that "digits", "round_style" and similar members are defined as functions, not constants. - // See std::numeric_limits at the end of the file for more information. - -// Library version -#define MPREAL_VERSION_MAJOR 3 -#define MPREAL_VERSION_MINOR 6 -#define MPREAL_VERSION_PATCHLEVEL 5 -#define MPREAL_VERSION_STRING "3.6.5" - -// Detect compiler using signatures from http://predef.sourceforge.net/ -#if defined(__GNUC__) && defined(__INTEL_COMPILER) - #define IsInf(x) isinf EIGEN_NOT_A_MACRO (x) // Intel ICC compiler on Linux - -#elif defined(_MSC_VER) // Microsoft Visual C++ - #define IsInf(x) (!_finite(x)) - -#else - #define IsInf(x) std::isinf EIGEN_NOT_A_MACRO (x) // GNU C/C++ (and/or other compilers), just hope for C99 conformance -#endif - -// A Clang feature extension to determine compiler features. -#ifndef __has_feature - #define __has_feature(x) 0 -#endif - -// Detect support for r-value references (move semantic). -// Move semantic should be enabled with great care in multi-threading environments, -// especially if MPFR uses custom memory allocators. -// Everything should be thread-safe and support passing ownership over thread boundary. -#if (__has_feature(cxx_rvalue_references) || \ - defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) && !defined(MPREAL_DISABLE_MOVE_SEMANTIC)) - - #define MPREAL_HAVE_MOVE_SUPPORT - - // Use fields in mpfr_t structure to check if it was initialized / set dummy initialization - #define mpfr_is_initialized(x) (0 != (x)->_mpfr_d) - #define mpfr_set_uninitialized(x) ((x)->_mpfr_d = 0 ) -#endif - -// Detect support for explicit converters. -#if (__has_feature(cxx_explicit_conversions) || \ - (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC_MINOR__ >= 5) || __cplusplus >= 201103L || \ - (defined(_MSC_VER) && _MSC_VER >= 1800) || \ - (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300)) - - #define MPREAL_HAVE_EXPLICIT_CONVERTERS -#endif - -#define MPFR_USE_INTMAX_T // Enable 64-bit integer types - should be defined before mpfr.h - -#if defined(MPREAL_HAVE_MSVC_DEBUGVIEW) && defined(_MSC_VER) && defined(_DEBUG) - #define MPREAL_MSVC_DEBUGVIEW_CODE DebugView = toString(); - #define MPREAL_MSVC_DEBUGVIEW_DATA std::string DebugView; -#else - #define MPREAL_MSVC_DEBUGVIEW_CODE - #define MPREAL_MSVC_DEBUGVIEW_DATA -#endif - -#include - -#if (MPFR_VERSION < MPFR_VERSION_NUM(3,0,0)) - #include // Needed for random() -#endif - -// Less important options -#define MPREAL_DOUBLE_BITS_OVERFLOW -1 // Triggers overflow exception during conversion to double if mpreal - // cannot fit in MPREAL_DOUBLE_BITS_OVERFLOW bits - // = -1 disables overflow checks (default) - -// Fast replacement for mpfr_set_zero(x, +1): -// (a) uses low-level data members, might not be forward compatible -// (b) sign is not set, add (x)->_mpfr_sign = 1; -#define mpfr_set_zero_fast(x) ((x)->_mpfr_exp = __MPFR_EXP_ZERO) - -#if defined(__GNUC__) - #define MPREAL_PERMISSIVE_EXPR __extension__ -#else - #define MPREAL_PERMISSIVE_EXPR -#endif - -namespace mpfr { - -class mpreal { -private: - mpfr_t mp; - -public: - - // Get default rounding mode & precision - inline static mp_rnd_t get_default_rnd() { return (mp_rnd_t)(mpfr_get_default_rounding_mode()); } - inline static mp_prec_t get_default_prec() { return (mpfr_get_default_prec)(); } - - // Constructors && type conversions - mpreal(); - mpreal(const mpreal& u); - mpreal(const mpf_t u); - mpreal(const mpz_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const mpq_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const double u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const long double u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const unsigned long long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const long long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const unsigned long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const unsigned int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); - - // Construct mpreal from mpfr_t structure. - // shared = true allows to avoid deep copy, so that mpreal and 'u' share the same data & pointers. - mpreal(const mpfr_t u, bool shared = false); - - mpreal(const char* s, mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd()); - mpreal(const std::string& s, mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd()); - - ~mpreal(); - -#ifdef MPREAL_HAVE_MOVE_SUPPORT - mpreal& operator=(mpreal&& v); - mpreal(mpreal&& u); -#endif - - // Operations - // = - // +, -, *, /, ++, --, <<, >> - // *=, +=, -=, /=, - // <, >, ==, <=, >= - - // = - mpreal& operator=(const mpreal& v); - mpreal& operator=(const mpf_t v); - mpreal& operator=(const mpz_t v); - mpreal& operator=(const mpq_t v); - mpreal& operator=(const long double v); - mpreal& operator=(const double v); - mpreal& operator=(const unsigned long int v); - mpreal& operator=(const unsigned long long int v); - mpreal& operator=(const long long int v); - mpreal& operator=(const unsigned int v); - mpreal& operator=(const long int v); - mpreal& operator=(const int v); - mpreal& operator=(const char* s); - mpreal& operator=(const std::string& s); - template mpreal& operator= (const std::complex& z); - - // + - mpreal& operator+=(const mpreal& v); - mpreal& operator+=(const mpf_t v); - mpreal& operator+=(const mpz_t v); - mpreal& operator+=(const mpq_t v); - mpreal& operator+=(const long double u); - mpreal& operator+=(const double u); - mpreal& operator+=(const unsigned long int u); - mpreal& operator+=(const unsigned int u); - mpreal& operator+=(const long int u); - mpreal& operator+=(const int u); - - mpreal& operator+=(const long long int u); - mpreal& operator+=(const unsigned long long int u); - mpreal& operator-=(const long long int u); - mpreal& operator-=(const unsigned long long int u); - mpreal& operator*=(const long long int u); - mpreal& operator*=(const unsigned long long int u); - mpreal& operator/=(const long long int u); - mpreal& operator/=(const unsigned long long int u); - - const mpreal operator+() const; - mpreal& operator++ (); - const mpreal operator++ (int); - - // - - mpreal& operator-=(const mpreal& v); - mpreal& operator-=(const mpz_t v); - mpreal& operator-=(const mpq_t v); - mpreal& operator-=(const long double u); - mpreal& operator-=(const double u); - mpreal& operator-=(const unsigned long int u); - mpreal& operator-=(const unsigned int u); - mpreal& operator-=(const long int u); - mpreal& operator-=(const int u); - const mpreal operator-() const; - friend const mpreal operator-(const unsigned long int b, const mpreal& a); - friend const mpreal operator-(const unsigned int b, const mpreal& a); - friend const mpreal operator-(const long int b, const mpreal& a); - friend const mpreal operator-(const int b, const mpreal& a); - friend const mpreal operator-(const double b, const mpreal& a); - mpreal& operator-- (); - const mpreal operator-- (int); - - // * - mpreal& operator*=(const mpreal& v); - mpreal& operator*=(const mpz_t v); - mpreal& operator*=(const mpq_t v); - mpreal& operator*=(const long double v); - mpreal& operator*=(const double v); - mpreal& operator*=(const unsigned long int v); - mpreal& operator*=(const unsigned int v); - mpreal& operator*=(const long int v); - mpreal& operator*=(const int v); - - // / - mpreal& operator/=(const mpreal& v); - mpreal& operator/=(const mpz_t v); - mpreal& operator/=(const mpq_t v); - mpreal& operator/=(const long double v); - mpreal& operator/=(const double v); - mpreal& operator/=(const unsigned long int v); - mpreal& operator/=(const unsigned int v); - mpreal& operator/=(const long int v); - mpreal& operator/=(const int v); - friend const mpreal operator/(const unsigned long int b, const mpreal& a); - friend const mpreal operator/(const unsigned int b, const mpreal& a); - friend const mpreal operator/(const long int b, const mpreal& a); - friend const mpreal operator/(const int b, const mpreal& a); - friend const mpreal operator/(const double b, const mpreal& a); - - //<<= Fast Multiplication by 2^u - mpreal& operator<<=(const unsigned long int u); - mpreal& operator<<=(const unsigned int u); - mpreal& operator<<=(const long int u); - mpreal& operator<<=(const int u); - - //>>= Fast Division by 2^u - mpreal& operator>>=(const unsigned long int u); - mpreal& operator>>=(const unsigned int u); - mpreal& operator>>=(const long int u); - mpreal& operator>>=(const int u); - - // Type Conversion operators - bool toBool ( ) const; - long toLong (mp_rnd_t mode = GMP_RNDZ) const; - unsigned long toULong (mp_rnd_t mode = GMP_RNDZ) const; - long long toLLong (mp_rnd_t mode = GMP_RNDZ) const; - unsigned long long toULLong (mp_rnd_t mode = GMP_RNDZ) const; - float toFloat (mp_rnd_t mode = GMP_RNDN) const; - double toDouble (mp_rnd_t mode = GMP_RNDN) const; - long double toLDouble (mp_rnd_t mode = GMP_RNDN) const; - -#if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS) - explicit operator bool () const { return toBool(); } - explicit operator int () const { return int(toLong()); } - explicit operator long () const { return toLong(); } - explicit operator long long () const { return toLLong(); } - explicit operator unsigned () const { return unsigned(toULong()); } - explicit operator unsigned long () const { return toULong(); } - explicit operator unsigned long long () const { return toULLong(); } - explicit operator float () const { return toFloat(); } - explicit operator double () const { return toDouble(); } - explicit operator long double () const { return toLDouble(); } -#endif - - // Get raw pointers so that mpreal can be directly used in raw mpfr_* functions - ::mpfr_ptr mpfr_ptr(); - ::mpfr_srcptr mpfr_ptr() const; - ::mpfr_srcptr mpfr_srcptr() const; - - // Convert mpreal to string with n significant digits in base b - // n = -1 -> convert with the maximum available digits - std::string toString(int n = -1, int b = 10, mp_rnd_t mode = mpreal::get_default_rnd()) const; - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - std::string toString(const std::string& format) const; -#endif - - std::ostream& output(std::ostream& os) const; - - // Math Functions - friend const mpreal sqr (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode); - friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); - friend const mpreal pow (const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode); - friend const mpreal pow (const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode); - friend const mpreal pow (const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode); - friend const mpreal pow (const mpreal& a, const long int b, mp_rnd_t rnd_mode); - friend const mpreal pow (const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode); - friend const mpreal pow (const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode); - friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode); - - friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode); - friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); - friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode); - friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); - friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode); - friend int cmpabs(const mpreal& a,const mpreal& b); - - friend const mpreal log (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal logb (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal exp (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal log1p(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal expm1(const mpreal& v, mp_rnd_t rnd_mode); - - friend const mpreal nextpow2(const mpreal& v, mp_rnd_t rnd_mode); - - friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode); - friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode); - - friend const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode); - friend const mpreal acot (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal asec (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal acsc (const mpreal& v, mp_rnd_t rnd_mode); - - friend const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode); - - friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); - - friend const mpreal fac_ui (unsigned long int v, mp_prec_t prec, mp_rnd_t rnd_mode); - friend const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode); - - friend const mpreal gamma (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal tgamma (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal lgamma (const mpreal& v, int *signp, mp_rnd_t rnd_mode); - friend const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode); - friend const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode); - friend const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode); - friend const mpreal sum (const mpreal tab[], const unsigned long int n, int& status, mp_rnd_t rnd_mode); - friend int sgn (const mpreal& v); - -// MPFR 2.4.0 Specifics -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - friend int sinh_cosh (mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal li2 (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); - friend const mpreal rec_sqrt (const mpreal& v, mp_rnd_t rnd_mode); - - // MATLAB's semantic equivalents - friend const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Remainder after division - friend const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Modulus after division -#endif - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) - friend const mpreal digamma (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal ai (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode); // use gmp_randinit_default() to init state, gmp_randclear() to clear -#endif - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,1,0)) - friend const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode); // use gmp_randinit_default() to init state, gmp_randclear() to clear - friend const mpreal grandom (unsigned int seed); -#endif - - // Uniformly distributed random number generation in [0,1] using - // Mersenne-Twister algorithm by default. - // Use parameter to setup seed, e.g.: random((unsigned)time(NULL)) - // Check urandom() for more precise control. - friend const mpreal random(unsigned int seed); - - // Splits mpreal value into fractional and integer parts. - // Returns fractional part and stores integer part in n. - friend const mpreal modf(const mpreal& v, mpreal& n); - - // Constants - // don't forget to call mpfr_free_cache() for every thread where you are using const-functions - friend const mpreal const_log2 (mp_prec_t prec, mp_rnd_t rnd_mode); - friend const mpreal const_pi (mp_prec_t prec, mp_rnd_t rnd_mode); - friend const mpreal const_euler (mp_prec_t prec, mp_rnd_t rnd_mode); - friend const mpreal const_catalan (mp_prec_t prec, mp_rnd_t rnd_mode); - - // returns +inf iff sign>=0 otherwise -inf - friend const mpreal const_infinity(int sign, mp_prec_t prec); - - // Output/ Input - friend std::ostream& operator<<(std::ostream& os, const mpreal& v); - friend std::istream& operator>>(std::istream& is, mpreal& v); - - // Integer Related Functions - friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal ceil (const mpreal& v); - friend const mpreal floor(const mpreal& v); - friend const mpreal round(const mpreal& v); - friend const mpreal trunc(const mpreal& v); - friend const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal rint_floor (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal rint_round (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal rint_trunc (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode); - friend const mpreal remainder ( const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); - friend const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); - - // Miscellaneous Functions - friend const mpreal nexttoward (const mpreal& x, const mpreal& y); - friend const mpreal nextabove (const mpreal& x); - friend const mpreal nextbelow (const mpreal& x); - - // use gmp_randinit_default() to init state, gmp_randclear() to clear - friend const mpreal urandomb (gmp_randstate_t& state); - -// MPFR < 2.4.2 Specifics -#if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2)) - friend const mpreal random2 (mp_size_t size, mp_exp_t exp); -#endif - - // Instance Checkers - friend bool isnan EIGEN_NOT_A_MACRO (const mpreal& v); - friend bool (isinf) (const mpreal& v); - friend bool (isfinite) (const mpreal& v); - - friend bool isnum (const mpreal& v); - friend bool iszero (const mpreal& v); - friend bool isint (const mpreal& v); - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) - friend bool isregular(const mpreal& v); -#endif - - // Set/Get instance properties - inline mp_prec_t get_prec() const; - inline void set_prec(mp_prec_t prec, mp_rnd_t rnd_mode = get_default_rnd()); // Change precision with rounding mode - - // Aliases for get_prec(), set_prec() - needed for compatibility with std::complex interface - inline mpreal& setPrecision(int Precision, mp_rnd_t RoundingMode = get_default_rnd()); - inline int getPrecision() const; - - // Set mpreal to +/- inf, NaN, +/-0 - mpreal& setInf (int Sign = +1); - mpreal& setNan (); - mpreal& setZero (int Sign = +1); - mpreal& setSign (int Sign, mp_rnd_t RoundingMode = get_default_rnd()); - - //Exponent - mp_exp_t get_exp() const; - int set_exp(mp_exp_t e); - int check_range (int t, mp_rnd_t rnd_mode = get_default_rnd()); - int subnormalize (int t, mp_rnd_t rnd_mode = get_default_rnd()); - - // Inexact conversion from float - inline bool fits_in_bits(double x, int n); - - // Set/Get global properties - static void set_default_prec(mp_prec_t prec); - static void set_default_rnd(mp_rnd_t rnd_mode); - - static mp_exp_t get_emin (void); - static mp_exp_t get_emax (void); - static mp_exp_t get_emin_min (void); - static mp_exp_t get_emin_max (void); - static mp_exp_t get_emax_min (void); - static mp_exp_t get_emax_max (void); - static int set_emin (mp_exp_t exp); - static int set_emax (mp_exp_t exp); - - // Efficient swapping of two mpreal values - needed for std algorithms - friend void swap(mpreal& x, mpreal& y); - - friend const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); - friend const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); - -private: - // Human friendly Debug Preview in Visual Studio. - // Put one of these lines: - // - // mpfr::mpreal= ; Show value only - // mpfr::mpreal=, bits ; Show value & precision - // - // at the beginning of - // [Visual Studio Installation Folder]\Common7\Packages\Debugger\autoexp.dat - MPREAL_MSVC_DEBUGVIEW_DATA - - // "Smart" resources deallocation. Checks if instance initialized before deletion. - void clear(::mpfr_ptr); -}; - -////////////////////////////////////////////////////////////////////////// -// Exceptions -class conversion_overflow : public std::exception { -public: - std::string why() { return "inexact conversion from floating point"; } -}; - -////////////////////////////////////////////////////////////////////////// -// Constructors & converters -// Default constructor: creates mp number and initializes it to 0. -inline mpreal::mpreal() -{ - mpfr_init2(mpfr_ptr(), mpreal::get_default_prec()); - mpfr_set_zero_fast(mpfr_ptr()); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const mpreal& u) -{ - mpfr_init2(mpfr_ptr(),mpfr_get_prec(u.mpfr_srcptr())); - mpfr_set (mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -#ifdef MPREAL_HAVE_MOVE_SUPPORT -inline mpreal::mpreal(mpreal&& other) -{ - mpfr_set_uninitialized(mpfr_ptr()); // make sure "other" holds null-pointer (in uninitialized state) - mpfr_swap(mpfr_ptr(), other.mpfr_ptr()); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal& mpreal::operator=(mpreal&& other) -{ - if (this != &other) - { - mpfr_swap(mpfr_ptr(), other.mpfr_ptr()); // destructor for "other" will be called just afterwards - MPREAL_MSVC_DEBUGVIEW_CODE; - } - return *this; -} -#endif - -inline mpreal::mpreal(const mpfr_t u, bool shared) -{ - if(shared) - { - std::memcpy(mpfr_ptr(), u, sizeof(mpfr_t)); - } - else - { - mpfr_init2(mpfr_ptr(), mpfr_get_prec(u)); - mpfr_set (mpfr_ptr(), u, mpreal::get_default_rnd()); - } - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const mpf_t u) -{ - mpfr_init2(mpfr_ptr(),(mp_prec_t) mpf_get_prec(u)); // (gmp: mp_bitcnt_t) unsigned long -> long (mpfr: mp_prec_t) - mpfr_set_f(mpfr_ptr(),u,mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2(mpfr_ptr(), prec); - mpfr_set_z(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2(mpfr_ptr(), prec); - mpfr_set_q(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2(mpfr_ptr(), prec); - -#if (MPREAL_DOUBLE_BITS_OVERFLOW > -1) - if(fits_in_bits(u, MPREAL_DOUBLE_BITS_OVERFLOW)) - { - mpfr_set_d(mpfr_ptr(), u, mode); - }else - throw conversion_overflow(); -#else - mpfr_set_d(mpfr_ptr(), u, mode); -#endif - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_ld(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const unsigned long long int u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_uj(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const long long int u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_sj(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_ui(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_ui(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_si(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_si(mpfr_ptr(), u, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_str(mpfr_ptr(), s, base, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mpreal::mpreal(const std::string& s, mp_prec_t prec, int base, mp_rnd_t mode) -{ - mpfr_init2 (mpfr_ptr(), prec); - mpfr_set_str(mpfr_ptr(), s.c_str(), base, mode); - - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline void mpreal::clear(::mpfr_ptr x) -{ -#ifdef MPREAL_HAVE_MOVE_SUPPORT - if(mpfr_is_initialized(x)) -#endif - mpfr_clear(x); -} - -inline mpreal::~mpreal() -{ - clear(mpfr_ptr()); -} - -// internal namespace needed for template magic -namespace internal{ - - // Use SFINAE to restrict arithmetic operations instantiation only for numeric types - // This is needed for smooth integration with libraries based on expression templates, like Eigen. - // TODO: Do the same for boolean operators. - template struct result_type {}; - - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; - template <> struct result_type {typedef mpreal type;}; -} - -// + Addition -template -inline const typename internal::result_type::type - operator+(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) += rhs; } - -template -inline const typename internal::result_type::type - operator+(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) += lhs; } - -// - Subtraction -template -inline const typename internal::result_type::type - operator-(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) -= rhs; } - -template -inline const typename internal::result_type::type - operator-(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) -= rhs; } - -// * Multiplication -template -inline const typename internal::result_type::type - operator*(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) *= rhs; } - -template -inline const typename internal::result_type::type - operator*(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) *= lhs; } - -// / Division -template -inline const typename internal::result_type::type - operator/(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) /= rhs; } - -template -inline const typename internal::result_type::type - operator/(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) /= rhs; } - -////////////////////////////////////////////////////////////////////////// -// sqrt -const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal sqrt(const long int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -// abs -inline const mpreal abs(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()); - -////////////////////////////////////////////////////////////////////////// -// pow -const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); -inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); - -////////////////////////////////////////////////////////////////////////// -// Estimate machine epsilon for the given precision -// Returns smallest eps such that 1.0 + eps != 1.0 -inline mpreal machine_epsilon(mp_prec_t prec = mpreal::get_default_prec()); - -// Returns smallest eps such that x + eps != x (relative machine epsilon) -inline mpreal machine_epsilon(const mpreal& x); - -// Gives max & min values for the required precision, -// minval is 'safe' meaning 1 / minval does not overflow -// maxval is 'safe' meaning 1 / maxval does not underflow -inline mpreal minval(mp_prec_t prec = mpreal::get_default_prec()); -inline mpreal maxval(mp_prec_t prec = mpreal::get_default_prec()); - -// 'Dirty' equality check 1: |a-b| < min{|a|,|b|} * eps -inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps); - -// 'Dirty' equality check 2: |a-b| < min{|a|,|b|} * eps( min{|a|,|b|} ) -inline bool isEqualFuzzy(const mpreal& a, const mpreal& b); - -// 'Bitwise' equality check -// maxUlps - a and b can be apart by maxUlps binary numbers. -inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps); - -////////////////////////////////////////////////////////////////////////// -// Convert precision in 'bits' to decimal digits and vice versa. -// bits = ceil(digits*log[2](10)) -// digits = floor(bits*log[10](2)) - -inline mp_prec_t digits2bits(int d); -inline int bits2digits(mp_prec_t b); - -////////////////////////////////////////////////////////////////////////// -// min, max -const mpreal (max)(const mpreal& x, const mpreal& y); -const mpreal (min)(const mpreal& x, const mpreal& y); - -////////////////////////////////////////////////////////////////////////// -// Implementation -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -// Operators - Assignment -inline mpreal& mpreal::operator=(const mpreal& v) -{ - if (this != &v) - { - mp_prec_t tp = mpfr_get_prec( mpfr_srcptr()); - mp_prec_t vp = mpfr_get_prec(v.mpfr_srcptr()); - - if(tp != vp){ - clear(mpfr_ptr()); - mpfr_init2(mpfr_ptr(), vp); - } - - mpfr_set(mpfr_ptr(), v.mpfr_srcptr(), mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - } - return *this; -} - -inline mpreal& mpreal::operator=(const mpf_t v) -{ - mpfr_set_f(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const mpz_t v) -{ - mpfr_set_z(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const mpq_t v) -{ - mpfr_set_q(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const long double v) -{ - mpfr_set_ld(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const double v) -{ -#if (MPREAL_DOUBLE_BITS_OVERFLOW > -1) - if(fits_in_bits(v, MPREAL_DOUBLE_BITS_OVERFLOW)) - { - mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd()); - }else - throw conversion_overflow(); -#else - mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd()); -#endif - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const unsigned long int v) -{ - mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const unsigned int v) -{ - mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const unsigned long long int v) -{ - mpfr_set_uj(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const long long int v) -{ - mpfr_set_sj(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const long int v) -{ - mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const int v) -{ - mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd()); - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator=(const char* s) -{ - // Use other converters for more precise control on base & precision & rounding: - // - // mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode) - // mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode) - // - // Here we assume base = 10 and we use precision of target variable. - - mpfr_t t; - - mpfr_init2(t, mpfr_get_prec(mpfr_srcptr())); - - if(0 == mpfr_set_str(t, s, 10, mpreal::get_default_rnd())) - { - mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - } - - clear(t); - return *this; -} - -inline mpreal& mpreal::operator=(const std::string& s) -{ - // Use other converters for more precise control on base & precision & rounding: - // - // mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode) - // mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode) - // - // Here we assume base = 10 and we use precision of target variable. - - mpfr_t t; - - mpfr_init2(t, mpfr_get_prec(mpfr_srcptr())); - - if(0 == mpfr_set_str(t, s.c_str(), 10, mpreal::get_default_rnd())) - { - mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - } - - clear(t); - return *this; -} - -template -inline mpreal& mpreal::operator= (const std::complex& z) -{ - return *this = z.real(); -} - -////////////////////////////////////////////////////////////////////////// -// + Addition -inline mpreal& mpreal::operator+=(const mpreal& v) -{ - mpfr_add(mpfr_ptr(), mpfr_srcptr(), v.mpfr_srcptr(), mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const mpf_t u) -{ - *this += mpreal(u); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const mpz_t u) -{ - mpfr_add_z(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const mpq_t u) -{ - mpfr_add_q(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+= (const long double u) -{ - *this += mpreal(u); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+= (const double u) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_add_d(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); -#else - *this += mpreal(u); -#endif - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const unsigned long int u) -{ - mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const unsigned int u) -{ - mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const long int u) -{ - mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const int u) -{ - mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator+=(const long long int u) { *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } -inline mpreal& mpreal::operator+=(const unsigned long long int u){ *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } -inline mpreal& mpreal::operator-=(const long long int u) { *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } -inline mpreal& mpreal::operator-=(const unsigned long long int u){ *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } -inline mpreal& mpreal::operator*=(const long long int u) { *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } -inline mpreal& mpreal::operator*=(const unsigned long long int u){ *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } -inline mpreal& mpreal::operator/=(const long long int u) { *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } -inline mpreal& mpreal::operator/=(const unsigned long long int u){ *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } - -inline const mpreal mpreal::operator+()const { return mpreal(*this); } - -inline const mpreal operator+(const mpreal& a, const mpreal& b) -{ - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); - mpfr_add(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; -} - -inline mpreal& mpreal::operator++() -{ - return *this += 1; -} - -inline const mpreal mpreal::operator++ (int) -{ - mpreal x(*this); - *this += 1; - return x; -} - -inline mpreal& mpreal::operator--() -{ - return *this -= 1; -} - -inline const mpreal mpreal::operator-- (int) -{ - mpreal x(*this); - *this -= 1; - return x; -} - -////////////////////////////////////////////////////////////////////////// -// - Subtraction -inline mpreal& mpreal::operator-=(const mpreal& v) -{ - mpfr_sub(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const mpz_t v) -{ - mpfr_sub_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const mpq_t v) -{ - mpfr_sub_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const long double v) -{ - *this -= mpreal(v); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const double v) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_sub_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); -#else - *this -= mpreal(v); -#endif - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const unsigned long int v) -{ - mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const unsigned int v) -{ - mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const long int v) -{ - mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator-=(const int v) -{ - mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline const mpreal mpreal::operator-()const -{ - mpreal u(*this); - mpfr_neg(u.mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd()); - return u; -} - -inline const mpreal operator-(const mpreal& a, const mpreal& b) -{ - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); - mpfr_sub(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; -} - -inline const mpreal operator-(const double b, const mpreal& a) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_d_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -#else - mpreal x(b, mpfr_get_prec(a.mpfr_ptr())); - x -= a; - return x; -#endif -} - -inline const mpreal operator-(const unsigned long int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -inline const mpreal operator-(const unsigned int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -inline const mpreal operator-(const long int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -inline const mpreal operator-(const int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -////////////////////////////////////////////////////////////////////////// -// * Multiplication -inline mpreal& mpreal::operator*= (const mpreal& v) -{ - mpfr_mul(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const mpz_t v) -{ - mpfr_mul_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const mpq_t v) -{ - mpfr_mul_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const long double v) -{ - *this *= mpreal(v); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const double v) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_mul_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); -#else - *this *= mpreal(v); -#endif - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const unsigned long int v) -{ - mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const unsigned int v) -{ - mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const long int v) -{ - mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator*=(const int v) -{ - mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline const mpreal operator*(const mpreal& a, const mpreal& b) -{ - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); - mpfr_mul(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; -} - -////////////////////////////////////////////////////////////////////////// -// / Division -inline mpreal& mpreal::operator/=(const mpreal& v) -{ - mpfr_div(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const mpz_t v) -{ - mpfr_div_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const mpq_t v) -{ - mpfr_div_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const long double v) -{ - *this /= mpreal(v); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const double v) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpfr_div_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); -#else - *this /= mpreal(v); -#endif - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const unsigned long int v) -{ - mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const unsigned int v) -{ - mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const long int v) -{ - mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator/=(const int v) -{ - mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline const mpreal operator/(const mpreal& a, const mpreal& b) -{ - mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_srcptr()), mpfr_get_prec(b.mpfr_srcptr()))); - mpfr_div(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); - return c; -} - -inline const mpreal operator/(const unsigned long int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); - mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -inline const mpreal operator/(const unsigned int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); - mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -inline const mpreal operator/(const long int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); - mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -inline const mpreal operator/(const int b, const mpreal& a) -{ - mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); - mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -} - -inline const mpreal operator/(const double b, const mpreal& a) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); - mpfr_d_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); - return x; -#else - mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); - x /= a; - return x; -#endif -} - -////////////////////////////////////////////////////////////////////////// -// Shifts operators - Multiplication/Division by power of 2 -inline mpreal& mpreal::operator<<=(const unsigned long int u) -{ - mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator<<=(const unsigned int u) -{ - mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator<<=(const long int u) -{ - mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator<<=(const int u) -{ - mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator>>=(const unsigned long int u) -{ - mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator>>=(const unsigned int u) -{ - mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator>>=(const long int u) -{ - mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::operator>>=(const int u) -{ - mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),static_cast(u),mpreal::get_default_rnd()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline const mpreal operator<<(const mpreal& v, const unsigned long int k) -{ - return mul_2ui(v,k); -} - -inline const mpreal operator<<(const mpreal& v, const unsigned int k) -{ - return mul_2ui(v,static_cast(k)); -} - -inline const mpreal operator<<(const mpreal& v, const long int k) -{ - return mul_2si(v,k); -} - -inline const mpreal operator<<(const mpreal& v, const int k) -{ - return mul_2si(v,static_cast(k)); -} - -inline const mpreal operator>>(const mpreal& v, const unsigned long int k) -{ - return div_2ui(v,k); -} - -inline const mpreal operator>>(const mpreal& v, const long int k) -{ - return div_2si(v,k); -} - -inline const mpreal operator>>(const mpreal& v, const unsigned int k) -{ - return div_2ui(v,static_cast(k)); -} - -inline const mpreal operator>>(const mpreal& v, const int k) -{ - return div_2si(v,static_cast(k)); -} - -// mul_2ui -inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode) -{ - mpreal x(v); - mpfr_mul_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); - return x; -} - -// mul_2si -inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode) -{ - mpreal x(v); - mpfr_mul_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); - return x; -} - -inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode) -{ - mpreal x(v); - mpfr_div_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); - return x; -} - -inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode) -{ - mpreal x(v); - mpfr_div_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); - return x; -} - -////////////////////////////////////////////////////////////////////////// -//Relational operators - -// WARNING: -// -// Please note that following checks for double-NaN are guaranteed to work only in IEEE math mode: -// -// isnan(b) = (b != b) -// isnan(b) = !(b == b) (we use in code below) -// -// Be cautions if you use compiler options which break strict IEEE compliance (e.g. -ffast-math in GCC). -// Use std::isnan instead (C++11). - -inline bool operator > (const mpreal& a, const mpreal& b ){ return (mpfr_greater_p(a.mpfr_srcptr(),b.mpfr_srcptr()) != 0 ); } -inline bool operator > (const mpreal& a, const unsigned long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) > 0 ); } -inline bool operator > (const mpreal& a, const unsigned int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) > 0 ); } -inline bool operator > (const mpreal& a, const long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) > 0 ); } -inline bool operator > (const mpreal& a, const int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) > 0 ); } -inline bool operator > (const mpreal& a, const long double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_ld(a.mpfr_srcptr(),b) > 0 ); } -inline bool operator > (const mpreal& a, const double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_d (a.mpfr_srcptr(),b) > 0 ); } - -inline bool operator >= (const mpreal& a, const mpreal& b ){ return (mpfr_greaterequal_p(a.mpfr_srcptr(),b.mpfr_srcptr()) != 0 ); } -inline bool operator >= (const mpreal& a, const unsigned long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) >= 0 ); } -inline bool operator >= (const mpreal& a, const unsigned int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) >= 0 ); } -inline bool operator >= (const mpreal& a, const long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) >= 0 ); } -inline bool operator >= (const mpreal& a, const int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) >= 0 ); } -inline bool operator >= (const mpreal& a, const long double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_ld(a.mpfr_srcptr(),b) >= 0 ); } -inline bool operator >= (const mpreal& a, const double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_d (a.mpfr_srcptr(),b) >= 0 ); } - -inline bool operator < (const mpreal& a, const mpreal& b ){ return (mpfr_less_p(a.mpfr_srcptr(),b.mpfr_srcptr()) != 0 ); } -inline bool operator < (const mpreal& a, const unsigned long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) < 0 ); } -inline bool operator < (const mpreal& a, const unsigned int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) < 0 ); } -inline bool operator < (const mpreal& a, const long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) < 0 ); } -inline bool operator < (const mpreal& a, const int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) < 0 ); } -inline bool operator < (const mpreal& a, const long double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_ld(a.mpfr_srcptr(),b) < 0 ); } -inline bool operator < (const mpreal& a, const double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_d (a.mpfr_srcptr(),b) < 0 ); } - -inline bool operator <= (const mpreal& a, const mpreal& b ){ return (mpfr_lessequal_p(a.mpfr_srcptr(),b.mpfr_srcptr()) != 0 ); } -inline bool operator <= (const mpreal& a, const unsigned long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) <= 0 ); } -inline bool operator <= (const mpreal& a, const unsigned int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) <= 0 ); } -inline bool operator <= (const mpreal& a, const long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) <= 0 ); } -inline bool operator <= (const mpreal& a, const int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) <= 0 ); } -inline bool operator <= (const mpreal& a, const long double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_ld(a.mpfr_srcptr(),b) <= 0 ); } -inline bool operator <= (const mpreal& a, const double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_d (a.mpfr_srcptr(),b) <= 0 ); } - -inline bool operator == (const mpreal& a, const mpreal& b ){ return (mpfr_equal_p(a.mpfr_srcptr(),b.mpfr_srcptr()) != 0 ); } -inline bool operator == (const mpreal& a, const unsigned long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 ); } -inline bool operator == (const mpreal& a, const unsigned int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 ); } -inline bool operator == (const mpreal& a, const long int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 ); } -inline bool operator == (const mpreal& a, const int b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 ); } -inline bool operator == (const mpreal& a, const long double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_ld(a.mpfr_srcptr(),b) == 0 ); } -inline bool operator == (const mpreal& a, const double b ){ return !isnan EIGEN_NOT_A_MACRO (a) && (b == b) && (mpfr_cmp_d (a.mpfr_srcptr(),b) == 0 ); } - -inline bool operator != (const mpreal& a, const mpreal& b ){ return !(a == b); } -inline bool operator != (const mpreal& a, const unsigned long int b ){ return !(a == b); } -inline bool operator != (const mpreal& a, const unsigned int b ){ return !(a == b); } -inline bool operator != (const mpreal& a, const long int b ){ return !(a == b); } -inline bool operator != (const mpreal& a, const int b ){ return !(a == b); } -inline bool operator != (const mpreal& a, const long double b ){ return !(a == b); } -inline bool operator != (const mpreal& a, const double b ){ return !(a == b); } - -inline bool isnan EIGEN_NOT_A_MACRO (const mpreal& op){ return (mpfr_nan_p (op.mpfr_srcptr()) != 0 ); } -inline bool (isinf) (const mpreal& op){ return (mpfr_inf_p (op.mpfr_srcptr()) != 0 ); } -inline bool (isfinite) (const mpreal& op){ return (mpfr_number_p (op.mpfr_srcptr()) != 0 ); } -inline bool iszero (const mpreal& op){ return (mpfr_zero_p (op.mpfr_srcptr()) != 0 ); } -inline bool isint (const mpreal& op){ return (mpfr_integer_p(op.mpfr_srcptr()) != 0 ); } - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) -inline bool isregular(const mpreal& op){ return (mpfr_regular_p(op.mpfr_srcptr()));} -#endif - -////////////////////////////////////////////////////////////////////////// -// Type Converters -inline bool mpreal::toBool ( ) const { return mpfr_zero_p (mpfr_srcptr()) == 0; } -inline long mpreal::toLong (mp_rnd_t mode) const { return mpfr_get_si (mpfr_srcptr(), mode); } -inline unsigned long mpreal::toULong (mp_rnd_t mode) const { return mpfr_get_ui (mpfr_srcptr(), mode); } -inline float mpreal::toFloat (mp_rnd_t mode) const { return mpfr_get_flt(mpfr_srcptr(), mode); } -inline double mpreal::toDouble (mp_rnd_t mode) const { return mpfr_get_d (mpfr_srcptr(), mode); } -inline long double mpreal::toLDouble(mp_rnd_t mode) const { return mpfr_get_ld (mpfr_srcptr(), mode); } -inline long long mpreal::toLLong (mp_rnd_t mode) const { return mpfr_get_sj (mpfr_srcptr(), mode); } -inline unsigned long long mpreal::toULLong (mp_rnd_t mode) const { return mpfr_get_uj (mpfr_srcptr(), mode); } - -inline ::mpfr_ptr mpreal::mpfr_ptr() { return mp; } -inline ::mpfr_srcptr mpreal::mpfr_ptr() const { return mp; } -inline ::mpfr_srcptr mpreal::mpfr_srcptr() const { return mp; } - -template -inline std::string toString(T t, std::ios_base & (*f)(std::ios_base&)) -{ - std::ostringstream oss; - oss << f << t; - return oss.str(); -} - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - -inline std::string mpreal::toString(const std::string& format) const -{ - char *s = NULL; - std::string out; - - if( !format.empty() ) - { - if(!(mpfr_asprintf(&s, format.c_str(), mpfr_srcptr()) < 0)) - { - out = std::string(s); - - mpfr_free_str(s); - } - } - - return out; -} - -#endif - -inline std::string mpreal::toString(int n, int b, mp_rnd_t mode) const -{ - // TODO: Add extended format specification (f, e, rounding mode) as it done in output operator - (void)b; - (void)mode; - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - - std::ostringstream format; - - int digits = (n >= 0) ? n : 2 + bits2digits(mpfr_get_prec(mpfr_srcptr())); - - format << "%." << digits << "RNg"; - - return toString(format.str()); - -#else - - char *s, *ns = NULL; - size_t slen, nslen; - mp_exp_t exp; - std::string out; - - if(mpfr_inf_p(mp)) - { - if(mpfr_sgn(mp)>0) return "+Inf"; - else return "-Inf"; - } - - if(mpfr_zero_p(mp)) return "0"; - if(mpfr_nan_p(mp)) return "NaN"; - - s = mpfr_get_str(NULL, &exp, b, 0, mp, mode); - ns = mpfr_get_str(NULL, &exp, b, (std::max)(0,n), mp, mode); - - if(s!=NULL && ns!=NULL) - { - slen = strlen(s); - nslen = strlen(ns); - if(nslen<=slen) - { - mpfr_free_str(s); - s = ns; - slen = nslen; - } - else { - mpfr_free_str(ns); - } - - // Make human eye-friendly formatting if possible - if (exp>0 && static_cast(exp)s+exp) ptr--; - - if(ptr==s+exp) out = std::string(s,exp+1); - else out = std::string(s,exp+1)+'.'+std::string(s+exp+1,ptr-(s+exp+1)+1); - - //out = string(s,exp+1)+'.'+string(s+exp+1); - } - else - { - // Remove zeros starting from right end - char* ptr = s+slen-1; - while (*ptr=='0' && ptr>s+exp-1) ptr--; - - if(ptr==s+exp-1) out = std::string(s,exp); - else out = std::string(s,exp)+'.'+std::string(s+exp,ptr-(s+exp)+1); - - //out = string(s,exp)+'.'+string(s+exp); - } - - }else{ // exp<0 || exp>slen - if(s[0]=='-') - { - // Remove zeros starting from right end - char* ptr = s+slen-1; - while (*ptr=='0' && ptr>s+1) ptr--; - - if(ptr==s+1) out = std::string(s,2); - else out = std::string(s,2)+'.'+std::string(s+2,ptr-(s+2)+1); - - //out = string(s,2)+'.'+string(s+2); - } - else - { - // Remove zeros starting from right end - char* ptr = s+slen-1; - while (*ptr=='0' && ptr>s) ptr--; - - if(ptr==s) out = std::string(s,1); - else out = std::string(s,1)+'.'+std::string(s+1,ptr-(s+1)+1); - - //out = string(s,1)+'.'+string(s+1); - } - - // Make final string - if(--exp) - { - if(exp>0) out += "e+"+mpfr::toString(exp,std::dec); - else out += "e"+mpfr::toString(exp,std::dec); - } - } - - mpfr_free_str(s); - return out; - }else{ - return "conversion error!"; - } -#endif -} - - -////////////////////////////////////////////////////////////////////////// -// I/O -inline std::ostream& mpreal::output(std::ostream& os) const -{ - std::ostringstream format; - const std::ios::fmtflags flags = os.flags(); - - format << ((flags & std::ios::showpos) ? "%+" : "%"); - if (os.precision() >= 0) - format << '.' << os.precision() << "R*" - << ((flags & std::ios::floatfield) == std::ios::fixed ? 'f' : - (flags & std::ios::floatfield) == std::ios::scientific ? 'e' : - 'g'); - else - format << "R*e"; - - char *s = NULL; - if(!(mpfr_asprintf(&s, format.str().c_str(), - mpfr::mpreal::get_default_rnd(), - mpfr_srcptr()) - < 0)) - { - os << std::string(s); - mpfr_free_str(s); - } - return os; -} - -inline std::ostream& operator<<(std::ostream& os, const mpreal& v) -{ - return v.output(os); -} - -inline std::istream& operator>>(std::istream &is, mpreal& v) -{ - // TODO: use cout::hexfloat and other flags to setup base - std::string tmp; - is >> tmp; - mpfr_set_str(v.mpfr_ptr(), tmp.c_str(), 10, mpreal::get_default_rnd()); - return is; -} - -////////////////////////////////////////////////////////////////////////// -// Bits - decimal digits relation -// bits = ceil(digits*log[2](10)) -// digits = floor(bits*log[10](2)) - -inline mp_prec_t digits2bits(int d) -{ - const double LOG2_10 = 3.3219280948873624; - - return mp_prec_t(std::ceil( d * LOG2_10 )); -} - -inline int bits2digits(mp_prec_t b) -{ - const double LOG10_2 = 0.30102999566398119; - - return int(std::floor( b * LOG10_2 )); -} - -////////////////////////////////////////////////////////////////////////// -// Set/Get number properties -inline mpreal& mpreal::setSign(int sign, mp_rnd_t RoundingMode) -{ - mpfr_setsign(mpfr_ptr(), mpfr_srcptr(), sign < 0, RoundingMode); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline int mpreal::getPrecision() const -{ - return int(mpfr_get_prec(mpfr_srcptr())); -} - -inline mpreal& mpreal::setPrecision(int Precision, mp_rnd_t RoundingMode) -{ - mpfr_prec_round(mpfr_ptr(), Precision, RoundingMode); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::setInf(int sign) -{ - mpfr_set_inf(mpfr_ptr(), sign); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::setNan() -{ - mpfr_set_nan(mpfr_ptr()); - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mpreal& mpreal::setZero(int sign) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) - mpfr_set_zero(mpfr_ptr(), sign); -#else - mpfr_set_si(mpfr_ptr(), 0, (mpfr_get_default_rounding_mode)()); - setSign(sign); -#endif - - MPREAL_MSVC_DEBUGVIEW_CODE; - return *this; -} - -inline mp_prec_t mpreal::get_prec() const -{ - return mpfr_get_prec(mpfr_srcptr()); -} - -inline void mpreal::set_prec(mp_prec_t prec, mp_rnd_t rnd_mode) -{ - mpfr_prec_round(mpfr_ptr(),prec,rnd_mode); - MPREAL_MSVC_DEBUGVIEW_CODE; -} - -inline mp_exp_t mpreal::get_exp () const -{ - return mpfr_get_exp(mpfr_srcptr()); -} - -inline int mpreal::set_exp (mp_exp_t e) -{ - int x = mpfr_set_exp(mpfr_ptr(), e); - MPREAL_MSVC_DEBUGVIEW_CODE; - return x; -} - -inline const mpreal frexp(const mpreal& x, mp_exp_t* exp, mp_rnd_t mode = mpreal::get_default_rnd()) -{ - mpreal y(x); -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,1,0)) - mpfr_frexp(exp,y.mpfr_ptr(),x.mpfr_srcptr(),mode); -#else - *exp = mpfr_get_exp(y.mpfr_srcptr()); - mpfr_set_exp(y.mpfr_ptr(),0); -#endif - return y; -} - -inline const mpreal ldexp(const mpreal& v, mp_exp_t exp) -{ - mpreal x(v); - - // rounding is not important since we are just increasing the exponent (= exact operation) - mpfr_mul_2si(x.mpfr_ptr(), x.mpfr_srcptr(), exp, mpreal::get_default_rnd()); - return x; -} - -inline const mpreal scalbn(const mpreal& v, mp_exp_t exp) -{ - return ldexp(v, exp); -} - -inline mpreal machine_epsilon(mp_prec_t prec) -{ - /* the smallest eps such that 1 + eps != 1 */ - return machine_epsilon(mpreal(1, prec)); -} - -inline mpreal machine_epsilon(const mpreal& x) -{ - /* the smallest eps such that x + eps != x */ - if( x < 0) - { - return nextabove(-x) + x; - }else{ - return nextabove( x) - x; - } -} - -// minval is 'safe' meaning 1 / minval does not overflow -inline mpreal minval(mp_prec_t prec) -{ - /* min = 1/2 * 2^emin = 2^(emin - 1) */ - return mpreal(1, prec) << mpreal::get_emin()-1; -} - -// maxval is 'safe' meaning 1 / maxval does not underflow -inline mpreal maxval(mp_prec_t prec) -{ - /* max = (1 - eps) * 2^emax, eps is machine epsilon */ - return (mpreal(1, prec) - machine_epsilon(prec)) << mpreal::get_emax(); -} - -inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps) -{ - return abs(a - b) <= machine_epsilon((max)(abs(a), abs(b))) * maxUlps; -} - -inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps) -{ - return abs(a - b) <= eps; -} - -inline bool isEqualFuzzy(const mpreal& a, const mpreal& b) -{ - return isEqualFuzzy(a, b, machine_epsilon((max)(1, (min)(abs(a), abs(b))))); -} - -////////////////////////////////////////////////////////////////////////// -// C++11 sign functions. -inline mpreal copysign(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal rop(0, mpfr_get_prec(x.mpfr_ptr())); - mpfr_setsign(rop.mpfr_ptr(), x.mpfr_srcptr(), mpfr_signbit(y.mpfr_srcptr()), rnd_mode); - return rop; -} - -inline bool signbit(const mpreal& x) -{ - return mpfr_signbit(x.mpfr_srcptr()); -} - -inline mpreal& setsignbit(mpreal& x, bool minus, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpfr_setsign(x.mpfr_ptr(), x.mpfr_srcptr(), minus, rnd_mode); - return x; -} - -inline const mpreal modf(const mpreal& v, mpreal& n) -{ - mpreal f(v); - - // rounding is not important since we are using the same number - mpfr_frac (f.mpfr_ptr(),f.mpfr_srcptr(),mpreal::get_default_rnd()); - mpfr_trunc(n.mpfr_ptr(),v.mpfr_srcptr()); - return f; -} - -inline int mpreal::check_range (int t, mp_rnd_t rnd_mode) -{ - return mpfr_check_range(mpfr_ptr(),t,rnd_mode); -} - -inline int mpreal::subnormalize (int t,mp_rnd_t rnd_mode) -{ - int r = mpfr_subnormalize(mpfr_ptr(),t,rnd_mode); - MPREAL_MSVC_DEBUGVIEW_CODE; - return r; -} - -inline mp_exp_t mpreal::get_emin (void) -{ - return mpfr_get_emin(); -} - -inline int mpreal::set_emin (mp_exp_t exp) -{ - return mpfr_set_emin(exp); -} - -inline mp_exp_t mpreal::get_emax (void) -{ - return mpfr_get_emax(); -} - -inline int mpreal::set_emax (mp_exp_t exp) -{ - return mpfr_set_emax(exp); -} - -inline mp_exp_t mpreal::get_emin_min (void) -{ - return mpfr_get_emin_min(); -} - -inline mp_exp_t mpreal::get_emin_max (void) -{ - return mpfr_get_emin_max(); -} - -inline mp_exp_t mpreal::get_emax_min (void) -{ - return mpfr_get_emax_min(); -} - -inline mp_exp_t mpreal::get_emax_max (void) -{ - return mpfr_get_emax_max(); -} - -////////////////////////////////////////////////////////////////////////// -// Mathematical Functions -////////////////////////////////////////////////////////////////////////// -#define MPREAL_UNARY_MATH_FUNCTION_BODY(f) \ - mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); \ - mpfr_##f(y.mpfr_ptr(), x.mpfr_srcptr(), r); \ - return y; - -inline const mpreal sqr (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) -{ MPREAL_UNARY_MATH_FUNCTION_BODY(sqr ); } - -inline const mpreal sqrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) -{ MPREAL_UNARY_MATH_FUNCTION_BODY(sqrt); } - -inline const mpreal sqrt(const unsigned long int x, mp_rnd_t r) -{ - mpreal y; - mpfr_sqrt_ui(y.mpfr_ptr(), x, r); - return y; -} - -inline const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode) -{ - return sqrt(static_cast(v),rnd_mode); -} - -inline const mpreal sqrt(const long int v, mp_rnd_t rnd_mode) -{ - if (v>=0) return sqrt(static_cast(v),rnd_mode); - else return mpreal().setNan(); // NaN -} - -inline const mpreal sqrt(const int v, mp_rnd_t rnd_mode) -{ - if (v>=0) return sqrt(static_cast(v),rnd_mode); - else return mpreal().setNan(); // NaN -} - -inline const mpreal root(const mpreal& x, unsigned long int k, mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); - #if (MPFR_VERSION >= MPFR_VERSION_NUM(4,0,0)) - mpfr_rootn_ui(y.mpfr_ptr(), x.mpfr_srcptr(), k, r); - #else - mpfr_root(y.mpfr_ptr(), x.mpfr_srcptr(), k, r); - #endif - return y; -} - -inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal y(0, mpfr_get_prec(a.mpfr_srcptr())); - mpfr_dim(y.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), r); - return y; -} - -inline int cmpabs(const mpreal& a,const mpreal& b) -{ - return mpfr_cmpabs(a.mpfr_ptr(), b.mpfr_srcptr()); -} - -inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - return mpfr_sin_cos(s.mpfr_ptr(), c.mpfr_ptr(), v.mpfr_srcptr(), rnd_mode); -} - -inline const mpreal sqrt (const long double v, mp_rnd_t rnd_mode) { return sqrt(mpreal(v),rnd_mode); } -inline const mpreal sqrt (const double v, mp_rnd_t rnd_mode) { return sqrt(mpreal(v),rnd_mode); } - -inline const mpreal cbrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cbrt ); } -inline const mpreal fabs (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } -inline const mpreal abs (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } -inline const mpreal log (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log ); } -inline const mpreal log2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log2 ); } -inline const mpreal log10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log10); } -inline const mpreal exp (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp ); } -inline const mpreal exp2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp2 ); } -inline const mpreal exp10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp10); } -inline const mpreal cos (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cos ); } -inline const mpreal sin (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sin ); } -inline const mpreal tan (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(tan ); } -inline const mpreal sec (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sec ); } -inline const mpreal csc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(csc ); } -inline const mpreal cot (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cot ); } -inline const mpreal acos (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(acos ); } -inline const mpreal asin (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(asin ); } -inline const mpreal atan (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(atan ); } - -inline const mpreal logb (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { return log2 (abs(x),r); } - -inline const mpreal acot (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return atan (1/v, r); } -inline const mpreal asec (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return acos (1/v, r); } -inline const mpreal acsc (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return asin (1/v, r); } -inline const mpreal acoth (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return atanh(1/v, r); } -inline const mpreal asech (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return acosh(1/v, r); } -inline const mpreal acsch (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return asinh(1/v, r); } - -inline const mpreal cosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cosh ); } -inline const mpreal sinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sinh ); } -inline const mpreal tanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(tanh ); } -inline const mpreal sech (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sech ); } -inline const mpreal csch (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(csch ); } -inline const mpreal coth (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(coth ); } -inline const mpreal acosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(acosh); } -inline const mpreal asinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(asinh); } -inline const mpreal atanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(atanh); } - -inline const mpreal log1p (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log1p ); } -inline const mpreal expm1 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(expm1 ); } -inline const mpreal eint (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(eint ); } -inline const mpreal gamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(gamma ); } -inline const mpreal tgamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(gamma ); } -inline const mpreal lngamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(lngamma); } -inline const mpreal zeta (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(zeta ); } -inline const mpreal erf (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(erf ); } -inline const mpreal erfc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(erfc ); } -inline const mpreal besselj0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(j0 ); } -inline const mpreal besselj1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(j1 ); } -inline const mpreal bessely0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(y0 ); } -inline const mpreal bessely1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(y1 ); } - -inline const mpreal nextpow2(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal y(0, x.getPrecision()); - - if(!iszero(x)) - y = ceil(log2(abs(x,r),r)); - - return y; -} - -inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); - mpfr_atan2(a.mpfr_ptr(), y.mpfr_srcptr(), x.mpfr_srcptr(), rnd_mode); - return a; -} - -inline const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); - mpfr_hypot(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); - return a; -} - -inline const mpreal hypot(const mpreal& a, const mpreal& b, const mpreal& c) -{ - if(isnan EIGEN_NOT_A_MACRO (a) || isnan EIGEN_NOT_A_MACRO (b) || isnan EIGEN_NOT_A_MACRO(c)) return mpreal().setNan(); - else - { - mpreal absa = abs(a), absb = abs(b), absc = abs(c); - mpreal w = (std::max)(absa, (std::max)(absb, absc)); - mpreal r; - - if (!iszero(w)) - { - mpreal iw = 1/w; - r = w * sqrt(sqr(absa*iw) + sqr(absb*iw) + sqr(absc*iw)); - } - - return r; - } -} - -inline const mpreal hypot(const mpreal& a, const mpreal& b, const mpreal& c, const mpreal& d) -{ - if(isnan EIGEN_NOT_A_MACRO (a) || isnan EIGEN_NOT_A_MACRO (b) || isnan EIGEN_NOT_A_MACRO (c) || isnan EIGEN_NOT_A_MACRO (d)) return mpreal().setNan(); - else - { - mpreal absa = abs(a), absb = abs(b), absc = abs(c), absd = abs(d); - mpreal w = (std::max)(absa, (std::max)(absb, (std::max)(absc, absd))); - mpreal r; - - if (!iszero(w)) - { - mpreal iw = 1/w; - r = w * sqrt(sqr(absa*iw) + sqr(absb*iw) + sqr(absc*iw) + sqr(absd*iw)); - } - - return r; - } -} - -inline const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); - mpfr_remainder(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); - return a; -} - -inline const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); - mpfr_remquo(a.mpfr_ptr(),q, x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); - return a; -} - -inline const mpreal fac_ui (unsigned long int v, mp_prec_t prec = mpreal::get_default_prec(), - mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(0, prec); - mpfr_fac_ui(x.mpfr_ptr(),v,rnd_mode); - return x; -} - - -inline const mpreal lgamma (const mpreal& v, int *signp = 0, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(v); - int tsignp; - - if(signp) mpfr_lgamma(x.mpfr_ptr(), signp,v.mpfr_srcptr(),rnd_mode); - else mpfr_lgamma(x.mpfr_ptr(),&tsignp,v.mpfr_srcptr(),rnd_mode); - - return x; -} - - -inline const mpreal besseljn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal y(0, x.getPrecision()); - mpfr_jn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r); - return y; -} - -inline const mpreal besselyn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal y(0, x.getPrecision()); - mpfr_yn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r); - return y; -} - -inline const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a; - mp_prec_t p1, p2, p3; - - p1 = v1.get_prec(); - p2 = v2.get_prec(); - p3 = v3.get_prec(); - - a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1)); - - mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode); - return a; -} - -inline const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a; - mp_prec_t p1, p2, p3; - - p1 = v1.get_prec(); - p2 = v2.get_prec(); - p3 = v3.get_prec(); - - a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1)); - - mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode); - return a; -} - -inline const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a; - mp_prec_t p1, p2; - - p1 = v1.get_prec(); - p2 = v2.get_prec(); - - a.set_prec(p1>p2?p1:p2); - - mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode); - - return a; -} - -inline const mpreal sum (const mpreal tab[], const unsigned long int n, int& status, mp_rnd_t mode = mpreal::get_default_rnd()) -{ - mpfr_srcptr *p = new mpfr_srcptr[n]; - - for (unsigned long int i = 0; i < n; i++) - p[i] = tab[i].mpfr_srcptr(); - - mpreal x; - status = mpfr_sum(x.mpfr_ptr(), (mpfr_ptr*)p, n, mode); - - delete [] p; - return x; -} - -////////////////////////////////////////////////////////////////////////// -// MPFR 2.4.0 Specifics -#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) - -inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - return mpfr_sinh_cosh(s.mp,c.mp,v.mp,rnd_mode); -} - -inline const mpreal li2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) -{ - MPREAL_UNARY_MATH_FUNCTION_BODY(li2); -} - -inline const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - /* R = rem(X,Y) if Y != 0, returns X - n * Y where n = trunc(X/Y). */ - return fmod(x, y, rnd_mode); -} - -inline const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - (void)rnd_mode; - - /* - - m = mod(x,y) if y != 0, returns x - n*y where n = floor(x/y) - - The following are true by convention: - - mod(x,0) is x - - mod(x,x) is 0 - - mod(x,y) for x != y and y != 0 has the same sign as y. - - */ - - if(iszero(y)) return x; - if(x == y) return 0; - - mpreal m = x - floor(x / y) * y; - - return copysign(abs(m),y); // make sure result has the same sign as Y -} - -inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal a; - mp_prec_t yp, xp; - - yp = y.get_prec(); - xp = x.get_prec(); - - a.set_prec(yp>xp?yp:xp); - - mpfr_fmod(a.mp, x.mp, y.mp, rnd_mode); - - return a; -} - -inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(v); - mpfr_rec_sqrt(x.mp,v.mp,rnd_mode); - return x; -} -#endif // MPFR 2.4.0 Specifics - -////////////////////////////////////////////////////////////////////////// -// MPFR 3.0.0 Specifics -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) -inline const mpreal digamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(digamma); } -inline const mpreal ai (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(ai); } -#endif // MPFR 3.0.0 Specifics - -////////////////////////////////////////////////////////////////////////// -// Constants -inline const mpreal const_log2 (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal x(0, p); - mpfr_const_log2(x.mpfr_ptr(), r); - return x; -} - -inline const mpreal const_pi (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal x(0, p); - mpfr_const_pi(x.mpfr_ptr(), r); - return x; -} - -inline const mpreal const_euler (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal x(0, p); - mpfr_const_euler(x.mpfr_ptr(), r); - return x; -} - -inline const mpreal const_catalan (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) -{ - mpreal x(0, p); - mpfr_const_catalan(x.mpfr_ptr(), r); - return x; -} - -inline const mpreal const_infinity (int sign = 1, mp_prec_t p = mpreal::get_default_prec()) -{ - mpreal x(0, p); - mpfr_set_inf(x.mpfr_ptr(), sign); - return x; -} - -////////////////////////////////////////////////////////////////////////// -// Integer Related Functions -inline const mpreal ceil(const mpreal& v) -{ - mpreal x(v); - mpfr_ceil(x.mp,v.mp); - return x; -} - -inline const mpreal floor(const mpreal& v) -{ - mpreal x(v); - mpfr_floor(x.mp,v.mp); - return x; -} - -inline const mpreal round(const mpreal& v) -{ - mpreal x(v); - mpfr_round(x.mp,v.mp); - return x; -} - -inline const mpreal trunc(const mpreal& v) -{ - mpreal x(v); - mpfr_trunc(x.mp,v.mp); - return x; -} - -inline const mpreal rint (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint ); } -inline const mpreal rint_ceil (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_ceil ); } -inline const mpreal rint_floor (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_floor); } -inline const mpreal rint_round (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_round); } -inline const mpreal rint_trunc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_trunc); } -inline const mpreal frac (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(frac ); } - -////////////////////////////////////////////////////////////////////////// -// Miscellaneous Functions -inline int sgn(const mpreal& op) -{ - // Please note, this is classic signum function which ignores sign of zero. - // Use signbit if you need sign of zero. - return mpfr_sgn(op.mpfr_srcptr()); -} - -////////////////////////////////////////////////////////////////////////// -// Miscellaneous Functions -inline void swap (mpreal& a, mpreal& b) { mpfr_swap(a.mpfr_ptr(),b.mpfr_ptr()); } -inline const mpreal (max)(const mpreal& x, const mpreal& y){ return (x>y?x:y); } -inline const mpreal (min)(const mpreal& x, const mpreal& y){ return (x= MPFR_VERSION_NUM(3,0,0)) -inline const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x; - mpfr_urandom(x.mpfr_ptr(), state, rnd_mode); - return x; -} -#endif - -#if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2)) -inline const mpreal random2 (mp_size_t size, mp_exp_t exp) -{ - mpreal x; - mpfr_random2(x.mpfr_ptr(),size,exp); - return x; -} -#endif - -// Uniformly distributed random number generation -// a = random(seed); <- initialization & first random number generation -// a = random(); <- next random numbers generation -// seed != 0 -inline const mpreal random(unsigned int seed = 0) -{ -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) - static gmp_randstate_t state; - static bool initialize = true; - - if(initialize) - { - gmp_randinit_default(state); - gmp_randseed_ui(state,0); - initialize = false; - } - - if(seed != 0) gmp_randseed_ui(state,seed); - - return mpfr::urandom(state); -#else - if(seed != 0) std::srand(seed); - return mpfr::mpreal(std::rand()/(double)RAND_MAX); -#endif - -} - -#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,1,0) && MPFR_VERSION < MPFR_VERSION_NUM(4,0,0)) - -// TODO: -// Use mpfr_nrandom since mpfr_grandom is deprecated -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 1478) -#endif -inline const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x; - mpfr_grandom(x.mpfr_ptr(), NULL, state, rnd_mode); - return x; -} -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - -inline const mpreal grandom(unsigned int seed = 0) -{ - static gmp_randstate_t state; - static bool initialize = true; - - if(initialize) - { - gmp_randinit_default(state); - gmp_randseed_ui(state,0); - initialize = false; - } - - if(seed != 0) gmp_randseed_ui(state,seed); - - return mpfr::grandom(state); -} -#endif - -////////////////////////////////////////////////////////////////////////// -// Set/Get global properties -inline void mpreal::set_default_prec(mp_prec_t prec) -{ - mpfr_set_default_prec(prec); -} - -inline void mpreal::set_default_rnd(mp_rnd_t rnd_mode) -{ - mpfr_set_default_rounding_mode(rnd_mode); -} - -inline bool mpreal::fits_in_bits(double x, int n) -{ - int i; - double t; - return IsInf(x) || (std::modf ( std::ldexp ( std::frexp ( x, &i ), n ), &t ) == 0.0); -} - -inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(a); - mpfr_pow(x.mp,x.mp,b.mp,rnd_mode); - return x; -} - -inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(a); - mpfr_pow_z(x.mp,x.mp,b,rnd_mode); - return x; -} - -inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(a); - mpfr_pow_ui(x.mp,x.mp,b,rnd_mode); - return x; -} - -inline const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode) -{ - return pow(a,static_cast(b),rnd_mode); -} - -inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(a); - mpfr_pow_si(x.mp,x.mp,b,rnd_mode); - return x; -} - -inline const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode) -{ - return pow(a,static_cast(b),rnd_mode); -} - -inline const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode) -{ - return pow(a,mpreal(b),rnd_mode); -} - -inline const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode) -{ - return pow(a,mpreal(b),rnd_mode); -} - -inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) -{ - mpreal x(a); - mpfr_ui_pow(x.mp,a,b.mp,rnd_mode); - return x; -} - -inline const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode) -{ - return pow(static_cast(a),b,rnd_mode); -} - -inline const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode) -{ - if (a>=0) return pow(static_cast(a),b,rnd_mode); - else return pow(mpreal(a),b,rnd_mode); -} - -inline const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode) -{ - if (a>=0) return pow(static_cast(a),b,rnd_mode); - else return pow(mpreal(a),b,rnd_mode); -} - -inline const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),b,rnd_mode); -} - -inline const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),b,rnd_mode); -} - -// pow unsigned long int -inline const mpreal pow(const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode) -{ - mpreal x(a); - mpfr_ui_pow_ui(x.mp,a,b,rnd_mode); - return x; -} - -inline const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode) -{ - return pow(a,static_cast(b),rnd_mode); //mpfr_ui_pow_ui -} - -inline const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode) -{ - if(b>0) return pow(a,static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow -} - -inline const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode) -{ - if(b>0) return pow(a,static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow -} - -inline const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode) -{ - return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow -} - -inline const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode) -{ - return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow -} - -// pow unsigned int -inline const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode) -{ - return pow(static_cast(a),b,rnd_mode); //mpfr_ui_pow_ui -} - -inline const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode) -{ - return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui -} - -inline const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode) -{ - if(b>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow -} - -inline const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode) -{ - if(b>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow -} - -inline const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode) -{ - return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow -} - -inline const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode) -{ - return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow -} - -// pow long int -inline const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode) -{ - if (a>0) return pow(static_cast(a),b,rnd_mode); //mpfr_ui_pow_ui - else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui -} - -inline const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode) -{ - if (a>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(mpreal(a),static_cast(b),rnd_mode); //mpfr_pow_ui -} - -inline const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode) -{ - if (a>0) - { - if(b>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - }else{ - return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si - } -} - -inline const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode) -{ - if (a>0) - { - if(b>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - }else{ - return pow(mpreal(a),static_cast(b),rnd_mode); // mpfr_pow_si - } -} - -inline const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode) -{ - if (a>=0) return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow -} - -inline const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode) -{ - if (a>=0) return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow -} - -// pow int -inline const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode) -{ - if (a>0) return pow(static_cast(a),b,rnd_mode); //mpfr_ui_pow_ui - else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui -} - -inline const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode) -{ - if (a>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(mpreal(a),static_cast(b),rnd_mode); //mpfr_pow_ui -} - -inline const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode) -{ - if (a>0) - { - if(b>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - }else{ - return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si - } -} - -inline const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode) -{ - if (a>0) - { - if(b>0) return pow(static_cast(a),static_cast(b),rnd_mode); //mpfr_ui_pow_ui - else return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - }else{ - return pow(mpreal(a),static_cast(b),rnd_mode); // mpfr_pow_si - } -} - -inline const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode) -{ - if (a>=0) return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow -} - -inline const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode) -{ - if (a>=0) return pow(static_cast(a),mpreal(b),rnd_mode); //mpfr_ui_pow - else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow -} - -// pow long double -inline const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),mpreal(b),rnd_mode); -} - -inline const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui -} - -inline const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),static_cast(b),rnd_mode); //mpfr_pow_ui -} - -inline const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si -} - -inline const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),static_cast(b),rnd_mode); // mpfr_pow_si -} - -inline const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),mpreal(b),rnd_mode); -} - -inline const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),b,rnd_mode); // mpfr_pow_ui -} - -inline const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),static_cast(b),rnd_mode); // mpfr_pow_ui -} - -inline const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si -} - -inline const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode) -{ - return pow(mpreal(a),static_cast(b),rnd_mode); // mpfr_pow_si -} -} // End of mpfr namespace - -// Explicit specialization of std::swap for mpreal numbers -// Thus standard algorithms will use efficient version of swap (due to Koenig lookup) -// Non-throwing swap C++ idiom: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap -namespace std -{ - // we are allowed to extend namespace std with specializations only - template <> - inline void swap(mpfr::mpreal& x, mpfr::mpreal& y) - { - return mpfr::swap(x, y); - } - - template<> - class numeric_limits - { - public: - static const bool is_specialized = true; - static const bool is_signed = true; - static const bool is_integer = false; - static const bool is_exact = false; - static const int radix = 2; - - static const bool has_infinity = true; - static const bool has_quiet_NaN = true; - static const bool has_signaling_NaN = true; - - static const bool is_iec559 = true; // = IEEE 754 - static const bool is_bounded = true; - static const bool is_modulo = false; - static const bool traps = true; - static const bool tinyness_before = true; - - static const float_denorm_style has_denorm = denorm_absent; - - inline static mpfr::mpreal (min) (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::minval(precision); } - inline static mpfr::mpreal (max) (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::maxval(precision); } - inline static mpfr::mpreal lowest (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return -mpfr::maxval(precision); } - - // Returns smallest eps such that 1 + eps != 1 (classic machine epsilon) - inline static mpfr::mpreal epsilon(mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::machine_epsilon(precision); } - - // Returns smallest eps such that x + eps != x (relative machine epsilon) - inline static mpfr::mpreal epsilon(const mpfr::mpreal& x) { return mpfr::machine_epsilon(x); } - - inline static mpfr::mpreal round_error(mp_prec_t precision = mpfr::mpreal::get_default_prec()) - { - mp_rnd_t r = mpfr::mpreal::get_default_rnd(); - - if(r == GMP_RNDN) return mpfr::mpreal(0.5, precision); - else return mpfr::mpreal(1.0, precision); - } - - inline static const mpfr::mpreal infinity() { return mpfr::const_infinity(); } - inline static const mpfr::mpreal quiet_NaN() { return mpfr::mpreal().setNan(); } - inline static const mpfr::mpreal signaling_NaN() { return mpfr::mpreal().setNan(); } - inline static const mpfr::mpreal denorm_min() { return (min)(); } - - // Please note, exponent range is not fixed in MPFR - static const int min_exponent = MPFR_EMIN_DEFAULT; - static const int max_exponent = MPFR_EMAX_DEFAULT; - MPREAL_PERMISSIVE_EXPR static const int min_exponent10 = (int) (MPFR_EMIN_DEFAULT * 0.3010299956639811); - MPREAL_PERMISSIVE_EXPR static const int max_exponent10 = (int) (MPFR_EMAX_DEFAULT * 0.3010299956639811); - -#ifdef MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS - - // Following members should be constant according to standard, but they can be variable in MPFR - // So we define them as functions here. - // - // This is preferable way for std::numeric_limits specialization. - // But it is incompatible with standard std::numeric_limits and might not work with other libraries, e.g. boost. - // See below for compatible implementation. - inline static float_round_style round_style() - { - mp_rnd_t r = mpfr::mpreal::get_default_rnd(); - - switch (r) - { - case GMP_RNDN: return round_to_nearest; - case GMP_RNDZ: return round_toward_zero; - case GMP_RNDU: return round_toward_infinity; - case GMP_RNDD: return round_toward_neg_infinity; - default: return round_indeterminate; - } - } - - inline static int digits() { return int(mpfr::mpreal::get_default_prec()); } - inline static int digits(const mpfr::mpreal& x) { return x.getPrecision(); } - - inline static int digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec()) - { - return mpfr::bits2digits(precision); - } - - inline static int digits10(const mpfr::mpreal& x) - { - return mpfr::bits2digits(x.getPrecision()); - } - - inline static int max_digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec()) - { - return digits10(precision); - } -#else - // Digits and round_style are NOT constants when it comes to mpreal. - // If possible, please use functions digits() and round_style() defined above. - // - // These (default) values are preserved for compatibility with existing libraries, e.g. boost. - // Change them accordingly to your application. - // - // For example, if you use 256 bits of precision uniformly in your program, then: - // digits = 256 - // digits10 = 77 - // max_digits10 = 78 - // - // Approximate formula for decimal digits is: digits10 = floor(log10(2) * digits). See bits2digits() for more details. - - static const std::float_round_style round_style = round_to_nearest; - static const int digits = 53; - static const int digits10 = 15; - static const int max_digits10 = 16; -#endif - }; - -} - -#endif /* __MPREAL_H__ */ diff --git a/external/eigen/unsupported/test/mpreal_support.cpp b/external/eigen/unsupported/test/mpreal_support.cpp index 4a25e993..10beb071 100644 --- a/external/eigen/unsupported/test/mpreal_support.cpp +++ b/external/eigen/unsupported/test/mpreal_support.cpp @@ -1,3 +1,4 @@ +#include // Must be included before main.h. #include "main.h" #include #include diff --git a/external/eigen/unsupported/test/sparse_extra.cpp b/external/eigen/unsupported/test/sparse_extra.cpp index cdfd10ca..602c2cb8 100644 --- a/external/eigen/unsupported/test/sparse_extra.cpp +++ b/external/eigen/unsupported/test/sparse_extra.cpp @@ -31,6 +31,22 @@ static long g_dense_op_sparse_count = 0; #include "sparse_basic.cpp" #endif +#if EIGEN_HAS_CXX11 + +#ifdef min +#undef min +#endif + +#ifdef max +#undef max +#endif + +#include +#define EIGEN_UNORDERED_MAP_SUPPORT + +#endif + + #include template @@ -146,6 +162,7 @@ template void sparse_extra(const SparseMatrixType& re } + template void check_marketio() {