1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
#include <numbers>
using std::numbers::pi;
#include "Base/Math/Functions.h"
#include "Tests/GTestWrapper/google_test.h"
#define EXPECT_CNEAR(a, b, epsi) \
EXPECT_NEAR((a).real(), (b).real(), epsi); \
EXPECT_NEAR((a).imag(), (b).imag(), epsi);
// Test accuracy of complex function sinc(z) near the removable singularity at z=0
TEST(SpecialFunctions, csinc)
{
const double eps = 4.7e-16; // more than twice the machine precision
for (int i = 0; i < 24; ++i) {
double ph = (2 * pi) * i / 24;
// std::cout << "---------------------------------------------------------------------\n";
// std::cout << "phase = " << ph << "\n";
EXPECT_EQ(Math::sinc(complex_t(0, 0)), complex_t(1., 0.));
complex_t z;
z = std::polar(1e-17, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(2e-17, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(5e-17, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(1e-16, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(2e-16, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(5e-16, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(1e-15, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(1e-13, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(1e-11, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(1e-9, ph);
EXPECT_CNEAR(Math::sinc(z), complex_t(1., 0.), eps);
z = std::polar(5e-8, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(2e-8, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(1e-8, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(5e-7, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(2e-7, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(1e-7, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(1e-6, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(1e-5, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6., eps);
z = std::polar(1e-4, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6. * (1. - z * z / 20.), eps);
z = std::polar(1e-3, ph);
EXPECT_CNEAR(Math::sinc(z), 1. - z * z / 6. * (1. - z * z / 20.), eps);
}
}
|