From 7dca77192e3f79f23476c62961755628a8cac29f Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Sun, 11 Dec 2022 19:41:38 +0100 Subject: [PATCH] same multi-q test is used everywhere --- Tests/Unit/Numeric/FormFactorOtherTest.cpp | 33 +++++++++-------- Tests/Unit/Numeric/MultiQTest.cpp | 23 ------------ Tests/Unit/Numeric/MultiQTest.h | 42 ---------------------- 3 files changed, 19 insertions(+), 79 deletions(-) diff --git a/Tests/Unit/Numeric/FormFactorOtherTest.cpp b/Tests/Unit/Numeric/FormFactorOtherTest.cpp index 06afe4bc947..8e0e449afdc 100644 --- a/Tests/Unit/Numeric/FormFactorOtherTest.cpp +++ b/Tests/Unit/Numeric/FormFactorOtherTest.cpp @@ -1,30 +1,35 @@ -#include "Base/Const/Units.h" #include "Sample/HardParticle/HardParticles.h" #include "Sample/Scattering/Rotations.h" #include "Tests/Unit/Numeric/MultiQTest.h" -class FormFactorOtherTest : public MultiQTest {}; +class FormFactorOtherTest : public testing::Test {}; //*********** cylinders *************** TEST_F(FormFactorOtherTest, HorizontalCylinderAsCylinder) { const double R = .3, L = 3; - Cylinder p0(R, L); - HorizontalCylinder p1(R, L); - test_absEq_at_realQ([&](C3 q) { return p0.formfactor(q); }, - [&](C3 q) { return p1.formfactor(q.rotatedY(M_PI / 2)); }, 2e-15, 1e-99, - 100); + Cylinder f0(R, L); + HorizontalCylinder f1(R, L); + + int failures = formfactorTest::run_test3_for_many_q( + [&](C3 q) -> complex_t { return f0.formfactor(q); }, + [&](C3 q) -> complex_t { return f1.formfactor(q.rotatedY(M_PI / 2)); }, + 1e-99, 100, 2e-15, true); + EXPECT_EQ(failures, 0); } TEST_F(FormFactorOtherTest, HorizontalCylinderSlices) { const double R = .3, L = 3; - HorizontalCylinder p0(R, L); - HorizontalCylinder p1a(R, L, -R, -0.3 * R); - HorizontalCylinder p1b(R, L, -0.3 * R, +R); - test_complexEq_at_realQ( - [&](C3 q) { return p0.formfactor(q); }, - [&](C3 q) { return p1a.formfactor(q) + exp_I(q.z() * 0.7 * R) * p1b.formfactor(q); }, - 1.2e-3, 1e-99, 100); + HorizontalCylinder f0(R, L); + HorizontalCylinder f1a(R, L, -R, -0.3 * R); + HorizontalCylinder f1b(R, L, -0.3 * R, +R); + + int failures = formfactorTest::run_test3_for_many_q( + [&](C3 q) -> complex_t { return f0.formfactor(q); }, + [&](C3 q) -> complex_t { return f1a.formfactor(q) + + exp_I(q.z() * 0.7 * R) * f1b.formfactor(q); }, + 1e-99, 100, 1.2e-3, true); + EXPECT_EQ(failures, 0); } diff --git a/Tests/Unit/Numeric/MultiQTest.cpp b/Tests/Unit/Numeric/MultiQTest.cpp index c173cd7df57..e520ce78819 100644 --- a/Tests/Unit/Numeric/MultiQTest.cpp +++ b/Tests/Unit/Numeric/MultiQTest.cpp @@ -16,29 +16,6 @@ const auto qlist = testing::Combine( testing::Values(-1e-15, +1e-14, -1e-11, 1e-7, -1e-3, .1, 1, sqrt(2), sqrt(3)), testing::Values(0, -4e-16, +8e-16, -5e-11, 3e-7, -2e-3, .01, .1)); -void run_test_for_many_q(std::function<void(C3)> run_one_test, double qmag_min, double qmag_max, - bool real_only) -{ - ParamGenerator<std::tuple<C3, C3, double, double, double>> gen = qlist; - for (auto it : gen) { - const C3 q_maindir = std::get<0>(it); - const C3 q_sidedir = std::get<1>(it); - const double qrealmag = std::get<2>(it); - const double qsidemag = std::get<3>(it); - const double qimagrel = std::get<4>(it); - if (real_only && qimagrel) - continue; - const complex_t qmag(qrealmag, qrealmag * qimagrel); - if (std::abs(qmag) <= qmag_min || std::abs(qmag) >= qmag_max) - continue; - if (q_maindir == q_sidedir) - continue; - const C3 q = qmag * (q_maindir + qsidemag * q_sidedir).unit(); - - run_one_test(q); // callback passed as argument - } -} - int run_test3_for_many_q(std::function<complex_t(C3)> fff0, std::function<complex_t(C3)> fff1, double qmag_min, double qmag_max, double eps, bool real_only) { diff --git a/Tests/Unit/Numeric/MultiQTest.h b/Tests/Unit/Numeric/MultiQTest.h index a05fa74e668..0b1fb44af9d 100644 --- a/Tests/Unit/Numeric/MultiQTest.h +++ b/Tests/Unit/Numeric/MultiQTest.h @@ -10,10 +10,6 @@ namespace formfactorTest { -//! Runs callback function "run_one_test(q)" for a huge number of different vectors q. -void run_test_for_many_q(std::function<void(C3)> run_one_test, double qmag_min, double qmag_max, - bool real_only = false); - //! Runs tests of fff0(q) vs fff1(q) for a huge number of different vectors q. //! The callback functions fff0/1 may compute ff0(q) vs ff1(q), or ff(q) vs ff(q'). int run_test3_for_many_q(std::function<complex_t(C3)> fff0, std::function<complex_t(C3)> fff1, @@ -21,42 +17,4 @@ int run_test3_for_many_q(std::function<complex_t(C3)> fff0, std::function<comple } // namespace formfactorTest - -class MultiQTest : public testing::Test { -protected: - //! Tests whether form factors are almost equal for various real q - void test_complexEq_at_realQ(std::function<complex_t(const C3&)> f0, - std::function<complex_t(const C3&)> f1, double eps, double qmag1, - double qmag2) - { - formfactorTest::run_test_for_many_q([&](C3 q) { complexEq(q, f0(q), f1(q), eps); }, qmag1, - qmag2, true); - } - //! Tests whether absolute values of form factors are almost equal for various real q - void test_absEq_at_realQ(std::function<complex_t(const C3&)> f0, - std::function<complex_t(const C3&)> f1, double eps, double qmag1, - double qmag2) - { - formfactorTest::run_test_for_many_q([&](C3 q) { absEq(q, f0(q), f1(q), eps); }, qmag1, - qmag2, true); - } - -private: - //! Tests whether c0 and c1 are almost equal. - //! Parameter q is transmitted for use in error message only. - void complexEq(C3 q, complex_t c0, complex_t c1, double eps) - { - const double avge = (std::abs(c0) + std::abs(c1)) / 2; - const double precision = std::max(1e-16, eps * avge); - EXPECT_NEAR(real(c0), real(c1), precision) << "q=" << q << "\n"; - EXPECT_NEAR(imag(c0), imag(c1), precision) << "q=" << q << "\n"; - } - void absEq(C3 q, complex_t c0, complex_t c1, double eps) - { - const double avge = (std::abs(c0) + std::abs(c1)) / 2; - const double precision = std::max(1e-16, eps * avge); - EXPECT_NEAR(abs(c0), abs(c1), precision) << "q=" << q << "\n"; - } -}; - #endif // BORNAGAIN_TESTS_UNIT_NUMERIC_MULTIQTEST_H -- GitLab