From d47291cc65e28ea42397a943e30ee37a9f0afb7e Mon Sep 17 00:00:00 2001 From: Alexander Voigt Date: Thu, 7 Mar 2024 14:26:11 +0100 Subject: [PATCH] Feature: test symmetries of Clausen functions (#42) --- test/test.hpp | 5 +++++ test/test_Cl.cpp | 9 +++++++++ test/test_Cl2.cpp | 25 +++++++++++++++++++++++++ test/test_Cl3.cpp | 25 +++++++++++++++++++++++++ test/test_Cl4.cpp | 25 +++++++++++++++++++++++++ test/test_Cl5.cpp | 25 +++++++++++++++++++++++++ test/test_Cl6.cpp | 25 +++++++++++++++++++++++++ test/test_Sl.cpp | 15 ++++++++++++--- 8 files changed, 151 insertions(+), 3 deletions(-) diff --git a/test/test.hpp b/test/test.hpp index 551c273..e388e1b 100644 --- a/test/test.hpp +++ b/test/test.hpp @@ -9,6 +9,11 @@ #endif +#ifndef M_PIL +#define M_PIL 3.14159265358979323846264338327950288L +#endif + + #define CHECK_CLOSE(a,b,eps) \ do { \ if (std::isinf(a) && std::isinf(b)) { \ diff --git a/test/test_Cl.cpp b/test/test_Cl.cpp index dcfed74..c797a05 100644 --- a/test/test_Cl.cpp +++ b/test/test_Cl.cpp @@ -137,6 +137,15 @@ TEST_CASE("test_fixed_values") INFO("n = " << n << ", x = " << x); CHECK_CLOSE(polylogarithm::Cl(n, x), cl_expected, 1e-13); CHECK_CLOSE(Cl_via_Li(n, x), cl_expected, 1e-9); + + // test symmetries + if (std::abs(std::fmod(x, 2*M_PI)) > 0.1 && std::abs(x - 2*M_PI) > 0.1) { + const int sgn = n % 2 == 0 ? -1 : 1; + CHECK_CLOSE(polylogarithm::Cl(n, x + 2*M_PI), cl_expected, 1e-10); + CHECK_CLOSE(polylogarithm::Cl(n, x - 2*M_PI), cl_expected, 1e-10); + CHECK_CLOSE(polylogarithm::Cl(n, -x ), sgn*cl_expected, 1e-10); + CHECK_CLOSE(polylogarithm::Cl(n, -x ), sgn*cl_expected, 1e-10); + } } } } diff --git a/test/test_Cl2.cpp b/test/test_Cl2.cpp index 64513e1..d65d88a 100644 --- a/test/test_Cl2.cpp +++ b/test/test_Cl2.cpp @@ -264,5 +264,30 @@ TEST_CASE("test_real_fixed_values") CHECK_CLOSE(cl128_koelbig, cl128_expected, 50*eps128); } CHECK_CLOSE(cl128_li2 , cl128_expected, 10*eps128); + + // test symmetries + if (std::abs(std::fmod(x64, 2*M_PI)) > 0.1 && std::abs(x64 - 2*M_PI) > 0.1) { + CHECK_CLOSE( polylogarithm::Cl2(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl2(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl2(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl2(-x64 ), -cl64_expected , 10*eps64); + + CHECK_CLOSE( cl2(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl2(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl2(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( cl2(-x64 ), -cl64_expected , 10*eps64); + +#ifdef ENABLE_FORTRAN + CHECK_CLOSE( poly_Cl2_fortran(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl2_fortran(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl2_fortran(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl2_fortran(-x64 ), -cl64_expected , 10*eps64); +#endif + + CHECK_CLOSE(polylogarithm::Cl2(x128 + 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl2(x128 - 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl2(-x128 ), -cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl2(-x128 ), -cl128_expected, 10*eps128); + } } } diff --git a/test/test_Cl3.cpp b/test/test_Cl3.cpp index 82fe90d..a234d61 100644 --- a/test/test_Cl3.cpp +++ b/test/test_Cl3.cpp @@ -124,5 +124,30 @@ TEST_CASE("test_real_fixed_values") CHECK_CLOSE(cl128_poly , cl128_expected, 5*eps128); CHECK_CLOSE(cl128_poly_c, cl128_expected, 5*eps128); CHECK_CLOSE(cl128_li3 , cl128_expected, 2*eps128); + + // test symmetries + if (std::abs(std::fmod(x64, 2*M_PI)) > 0.1 && std::abs(x64 - 2*M_PI) > 0.1) { + CHECK_CLOSE( polylogarithm::Cl3(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl3(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl3(-x64 ), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl3(-x64 ), cl64_expected , 10*eps64); + + CHECK_CLOSE( cl3(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl3(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl3(-x64 ), cl64_expected , 10*eps64); + CHECK_CLOSE( cl3(-x64 ), cl64_expected , 10*eps64); + +#ifdef ENABLE_FORTRAN + CHECK_CLOSE( poly_Cl3_fortran(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl3_fortran(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl3_fortran(-x64 ), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl3_fortran(-x64 ), cl64_expected , 10*eps64); +#endif + + CHECK_CLOSE(polylogarithm::Cl3(x128 + 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl3(x128 - 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl3(-x128 ), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl3(-x128 ), cl128_expected, 10*eps128); + } } } diff --git a/test/test_Cl4.cpp b/test/test_Cl4.cpp index c043e6a..81690eb 100644 --- a/test/test_Cl4.cpp +++ b/test/test_Cl4.cpp @@ -167,5 +167,30 @@ TEST_CASE("test_real_fixed_values") CHECK_CLOSE(cl128_li4 , cl128_expected, 2*eps128); CHECK_CLOSE(cl128_poly , cl128_expected, 2*eps128); CHECK_CLOSE(cl128_poly_c, cl128_expected, 2*eps128); + + // test symmetries + if (std::abs(std::fmod(x64, 2*M_PI)) > 0.1 && std::abs(x64 - 2*M_PI) > 0.1) { + CHECK_CLOSE( polylogarithm::Cl4(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl4(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl4(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl4(-x64 ), -cl64_expected , 10*eps64); + + CHECK_CLOSE( cl4(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl4(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl4(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( cl4(-x64 ), -cl64_expected , 10*eps64); + +#ifdef ENABLE_FORTRAN + CHECK_CLOSE( poly_Cl4_fortran(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl4_fortran(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl4_fortran(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl4_fortran(-x64 ), -cl64_expected , 10*eps64); +#endif + + CHECK_CLOSE(polylogarithm::Cl4(x128 + 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl4(x128 - 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl4(-x128 ), -cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl4(-x128 ), -cl128_expected, 10*eps128); + } } } diff --git a/test/test_Cl5.cpp b/test/test_Cl5.cpp index 8039e3f..5feec5e 100644 --- a/test/test_Cl5.cpp +++ b/test/test_Cl5.cpp @@ -117,5 +117,30 @@ TEST_CASE("test_real_fixed_values") CHECK_CLOSE(cl128_li , cl128_expected, 4*eps128); CHECK_CLOSE(cl128_poly , cl128_expected, 7*eps128); CHECK_CLOSE(cl128_poly_c, cl128_expected, 7*eps128); + + // test symmetries + if (std::abs(std::fmod(x64, 2*M_PI)) > 0.1 && std::abs(x64 - 2*M_PI) > 0.1) { + CHECK_CLOSE( polylogarithm::Cl5(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl5(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl5(-x64 ), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl5(-x64 ), cl64_expected , 10*eps64); + + CHECK_CLOSE( cl5(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl5(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl5(-x64 ), cl64_expected , 10*eps64); + CHECK_CLOSE( cl5(-x64 ), cl64_expected , 10*eps64); + +#ifdef ENABLE_FORTRAN + CHECK_CLOSE( poly_Cl5_fortran(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl5_fortran(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl5_fortran(-x64 ), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl5_fortran(-x64 ), cl64_expected , 10*eps64); +#endif + + CHECK_CLOSE(polylogarithm::Cl5(x128 + 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl5(x128 - 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl5(-x128 ), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl5(-x128 ), cl128_expected, 10*eps128); + } } } diff --git a/test/test_Cl6.cpp b/test/test_Cl6.cpp index e00317e..6f55b94 100644 --- a/test/test_Cl6.cpp +++ b/test/test_Cl6.cpp @@ -166,5 +166,30 @@ TEST_CASE("test_real_fixed_values") CHECK_CLOSE(cl128_li , cl128_expected, 4*eps128); CHECK_CLOSE(cl128_poly , cl128_expected, 8*eps128); CHECK_CLOSE(cl128_poly_c, cl128_expected, 8*eps128); + + // test symmetries + if (std::abs(std::fmod(x64, 2*M_PI)) > 0.1 && std::abs(x64 - 2*M_PI) > 0.1) { + CHECK_CLOSE( polylogarithm::Cl6(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl6(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl6(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( polylogarithm::Cl6(-x64 ), -cl64_expected , 10*eps64); + + CHECK_CLOSE( cl6(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl6(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( cl6(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( cl6(-x64 ), -cl64_expected , 10*eps64); + +#ifdef ENABLE_FORTRAN + CHECK_CLOSE( poly_Cl6_fortran(x64 + 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl6_fortran(x64 - 2*M_PI), cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl6_fortran(-x64 ), -cl64_expected , 10*eps64); + CHECK_CLOSE( poly_Cl6_fortran(-x64 ), -cl64_expected , 10*eps64); +#endif + + CHECK_CLOSE(polylogarithm::Cl6(x128 + 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl6(x128 - 2*M_PIL), cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl6(-x128 ), -cl128_expected, 10*eps128); + CHECK_CLOSE(polylogarithm::Cl6(-x128 ), -cl128_expected, 10*eps128); + } } } diff --git a/test/test_Sl.cpp b/test/test_Sl.cpp index e1431d6..c877549 100644 --- a/test/test_Sl.cpp +++ b/test/test_Sl.cpp @@ -53,10 +53,19 @@ TEST_CASE("test_fixed_values") for (const auto& v: fixed_values) { const auto x = v.first; - const auto cl_expected = v.second; + const auto sl_expected = v.second; INFO("n = " << n << ", x = " << x); - CHECK_CLOSE(polylogarithm::Sl(n, x), cl_expected, 1e-13); - CHECK_CLOSE(Sl_via_Li(n, x), cl_expected, 1e-9); + CHECK_CLOSE(polylogarithm::Sl(n, x), sl_expected, 1e-13); + CHECK_CLOSE(Sl_via_Li(n, x), sl_expected, 1e-9); + + // test symmetries + if (std::abs(std::fmod(x, 2*M_PI)) > 0.1 && std::abs(x - 2*M_PI) > 0.1) { + const int sgn = n % 2 == 0 ? 1 : -1; + CHECK_CLOSE(polylogarithm::Sl(n, x + 2*M_PI), sl_expected, 1e-10); + CHECK_CLOSE(polylogarithm::Sl(n, x - 2*M_PI), sl_expected, 1e-10); + CHECK_CLOSE(polylogarithm::Sl(n, -x ), sgn*sl_expected, 1e-10); + CHECK_CLOSE(polylogarithm::Sl(n, -x ), sgn*sl_expected, 1e-10); + } } } }