mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Implement plog_complex
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
043442e21b
commit
7fd7a3f946
@@ -1340,6 +1340,8 @@ void packetmath_complex() {
|
||||
EIGEN_ALIGN_MAX Scalar data2[PacketSize * 4];
|
||||
EIGEN_ALIGN_MAX Scalar ref[PacketSize * 4];
|
||||
EIGEN_ALIGN_MAX Scalar pval[PacketSize * 4];
|
||||
EIGEN_ALIGN_MAX RealScalar realdata[PacketSize * 4];
|
||||
EIGEN_ALIGN_MAX RealScalar realref[PacketSize * 4];
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
data1[i] = internal::random<Scalar>() * Scalar(1e2);
|
||||
@@ -1401,6 +1403,47 @@ void packetmath_complex() {
|
||||
data1[3] = Scalar(-inf, nan);
|
||||
CHECK_CWISE1_N(numext::sqrt, internal::psqrt, 4);
|
||||
}
|
||||
if (PacketTraits::HasLog) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
data1[i] = Scalar(internal::random<RealScalar>(), internal::random<RealScalar>());
|
||||
}
|
||||
CHECK_CWISE1_N(std::log, internal::plog, size);
|
||||
|
||||
// Test misc. corner cases.
|
||||
const RealScalar zero = RealScalar(0);
|
||||
const RealScalar one = RealScalar(1);
|
||||
const RealScalar inf = std::numeric_limits<RealScalar>::infinity();
|
||||
const RealScalar nan = std::numeric_limits<RealScalar>::quiet_NaN();
|
||||
for (RealScalar x : {zero, one, inf}) {
|
||||
for (RealScalar y : {zero, one, inf}) {
|
||||
data1[0] = Scalar(x, y);
|
||||
data1[1] = Scalar(-x, y);
|
||||
data1[2] = Scalar(x, -y);
|
||||
data1[3] = Scalar(-x, -y);
|
||||
CHECK_CWISE1_IM1ULP_N(std::log, internal::plog, 4);
|
||||
}
|
||||
}
|
||||
// Set reference results to nan.
|
||||
// Some architectures don't handle IEEE edge cases correctly
|
||||
ref[0] = Scalar(nan, nan);
|
||||
ref[1] = Scalar(nan, nan);
|
||||
ref[2] = Scalar(nan, nan);
|
||||
ref[3] = Scalar(nan, nan);
|
||||
for (RealScalar x : {zero, one}) {
|
||||
data1[0] = Scalar(x, nan);
|
||||
data1[1] = Scalar(-x, nan);
|
||||
data1[2] = Scalar(nan, x);
|
||||
data1[3] = Scalar(nan, -x);
|
||||
for (int j = 0; j < size; j += PacketSize)
|
||||
internal::pstore(data2 + j, internal::plog(internal::pload<Packet>(data1 + j)));
|
||||
VERIFY(test::areApprox(ref, data2, 4));
|
||||
}
|
||||
data1[0] = Scalar(inf, nan);
|
||||
data1[1] = Scalar(-inf, nan);
|
||||
data1[2] = Scalar(nan, inf);
|
||||
data1[3] = Scalar(nan, -inf);
|
||||
CHECK_CWISE1_IM1ULP_N(std::log, internal::plog, 4);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Scalar, typename Packet>
|
||||
|
||||
@@ -124,6 +124,19 @@ bool areEqual(const Scalar* a, const Scalar* b, int size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
bool areApprox(const Scalar* a, const Scalar* b, int size, const typename NumTraits<Scalar>::Real& precision) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (numext::not_equal_strict(a[i], b[i]) && !internal::isApprox(a[i], b[i], precision) &&
|
||||
!((numext::isnan)(a[i]) && (numext::isnan)(b[i]))) {
|
||||
print_mismatch(a, b, size);
|
||||
std::cout << "Values differ in position " << i << ": " << a[i] << " vs " << b[i] << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CHECK_CWISE1(REFOP, POP) \
|
||||
{ \
|
||||
for (int i = 0; i < PacketSize; ++i) ref[i] = REFOP(data1[i]); \
|
||||
@@ -141,6 +154,29 @@ bool areEqual(const Scalar* a, const Scalar* b, int size) {
|
||||
VERIFY(test::areApprox(ref, data2, N) && #POP); \
|
||||
}
|
||||
|
||||
// Checks component-wise for input of complex type of size N. The real and
|
||||
// the imaginary part are compared separately, with 1ULP relaxed condition
|
||||
// for the imaginary part. All of data1 data2, ref, realdata1 and realref
|
||||
// should have size at least ceil(N/PacketSize)*PacketSize to avoid
|
||||
// memory access errors.
|
||||
#define CHECK_CWISE1_IM1ULP_N(REFOP, POP, N) \
|
||||
{ \
|
||||
RealScalar eps_1ulp = RealScalar(1e1) * std::numeric_limits<RealScalar>::epsilon(); \
|
||||
for (int j = 0; j < N; j += PacketSize) \
|
||||
internal::pstore(data2 + j, internal::plog(internal::pload<Packet>(data1 + j))); \
|
||||
for (int i = 0; i < N; ++i) { \
|
||||
ref[i] = REFOP(data1[i]); \
|
||||
realref[i] = ref[i].imag(); \
|
||||
realdata[i] = data2[i].imag(); \
|
||||
} \
|
||||
VERIFY(test::areApprox(realdata, realref, N, eps_1ulp)); \
|
||||
for (int i = 0; i < N; ++i) { \
|
||||
realdata[i] = data2[i].real(); \
|
||||
realref[i] = ref[i].real(); \
|
||||
} \
|
||||
VERIFY(test::areApprox(realdata, realref, N)); \
|
||||
}
|
||||
|
||||
template <bool Cond, typename Packet>
|
||||
struct packet_helper {
|
||||
template <typename T>
|
||||
|
||||
Reference in New Issue
Block a user