File indexing completed on 2026-05-20 07:36:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Utilities/ArrayHelpers.hpp"
0013 #include "Acts/Utilities/MathHelpers.hpp"
0014 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0015
0016 #include <cmath>
0017
0018 namespace bdata = boost::unit_test::data;
0019
0020 const auto expDist = bdata::random(
0021 (bdata::engine = std::mt19937{}, bdata::seed = 0,
0022 bdata::distribution = std::uniform_real_distribution<double>(-4, 4)));
0023
0024 namespace ActsTetsts {
0025
0026 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0027
0028 BOOST_DATA_TEST_CASE(fastHypot, expDist ^ expDist ^ bdata::xrange(100), xExp,
0029 yExp, i) {
0030 static_cast<void>(i);
0031
0032 const double x = std::pow(10, xExp);
0033 const double y = std::pow(10, yExp);
0034
0035 const float fastFloat =
0036 Acts::fastHypot(static_cast<float>(x), static_cast<float>(y));
0037 const double fastDouble = Acts::fastHypot(x, y);
0038
0039 const float slowFloat =
0040 Acts::slowHypot(static_cast<float>(x), static_cast<float>(y));
0041 const double slowDouble = Acts::slowHypot(x, y);
0042
0043 CHECK_CLOSE_REL(slowFloat, fastFloat, 1e-6);
0044 CHECK_CLOSE_REL(slowDouble, fastDouble, 1e-6);
0045 }
0046
0047 BOOST_DATA_TEST_CASE(fastCathetus, expDist ^ expDist ^ bdata::xrange(100), xExp,
0048 yExp, i) {
0049 static_cast<void>(i);
0050
0051 const auto [y, x] = std::minmax({std::pow(10, xExp), std::pow(10, yExp)});
0052
0053 const float fastFloat =
0054 Acts::fastCathetus(static_cast<float>(x), static_cast<float>(y));
0055 const double fastDouble = Acts::fastCathetus(x, y);
0056
0057 const float slowFloat =
0058 Acts::slowCathetus(static_cast<float>(x), static_cast<float>(y));
0059 const double slowDouble = Acts::slowCathetus(x, y);
0060
0061 CHECK_CLOSE_REL(fastFloat, slowFloat, 1e-6);
0062 CHECK_CLOSE_REL(fastDouble, slowDouble, 1e-6);
0063 }
0064
0065 BOOST_AUTO_TEST_CASE(ProductTests) {
0066 static_assert(Acts::product(1u, 1u) == 1u);
0067 static_assert(Acts::product(2u, 2u) == 2u);
0068 static_assert(Acts::product(3u, 4u) == 12u);
0069 static_assert(Acts::product(1u, 5u) == 120u);
0070 static_assert(Acts::product(2u, 5u) == 120u);
0071 static_assert(Acts::product(3u, 5u) == 60u);
0072
0073 static_assert(Acts::product(5u, 4u) == 1u);
0074
0075 static_assert(Acts::product(0u, 0u) == 0u);
0076 static_assert(Acts::product(0u, 5u) == 0u);
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 const std::size_t zero{0};
0091 const std::size_t one{1};
0092 for (std::size_t k = 0; k <= 20; ++k) {
0093 BOOST_CHECK_EQUAL(Acts::product(zero, k), zero);
0094 BOOST_CHECK_EQUAL(Acts::product(one, k), Acts::factorial(k));
0095 BOOST_CHECK_EQUAL(Acts::product(k, k), k);
0096
0097 for (std::size_t j = 1; j < k; ++j) {
0098 BOOST_CHECK_EQUAL(Acts::product(j, k), j * Acts::product(j + one, k));
0099 BOOST_CHECK_EQUAL(Acts::product(one, k),
0100 Acts::product(one, j) * Acts::product(j + one, k));
0101 }
0102 }
0103 }
0104
0105 BOOST_AUTO_TEST_CASE(FactorialTests) {
0106 static_assert(Acts::factorial(0u) == 1u);
0107 static_assert(Acts::factorial(1u) == 1u);
0108 static_assert(Acts::factorial(2u) == 2u);
0109 static_assert(Acts::factorial(5u) == 5u * Acts::factorial(4u));
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 const std::size_t one{1};
0124 for (std::size_t k = 1; k <= 20; ++k) {
0125 BOOST_CHECK_EQUAL(Acts::factorial(k), k * Acts::factorial(k - one));
0126 for (std::size_t j = 1; j <= k; ++j) {
0127 BOOST_CHECK_EQUAL(Acts::product(j, k),
0128 Acts::factorial(k) / Acts::factorial(j - one));
0129 }
0130 }
0131 }
0132
0133 BOOST_AUTO_TEST_CASE(PowerTests) {
0134 for (unsigned p = 0; p <= 15; ++p) {
0135 BOOST_CHECK_EQUAL(std::pow(2., p), Acts::pow(2., p));
0136 BOOST_CHECK_EQUAL(std::pow(0.5, p), Acts::pow(0.5, p));
0137 for (std::size_t k = 1; k <= 15; ++k) {
0138 BOOST_CHECK_EQUAL(std::pow(k, p), Acts::pow(k, p));
0139 }
0140 }
0141 for (int p = 0; p <= 15; ++p) {
0142 BOOST_CHECK_EQUAL(std::pow(2., p), Acts::pow(2., p));
0143 BOOST_CHECK_EQUAL(std::pow(2., -p), Acts::pow(2., -p));
0144 BOOST_CHECK_EQUAL(std::pow(0.5, p), Acts::pow(0.5, p));
0145
0146 BOOST_CHECK_EQUAL(std::pow(0.5, -p), Acts::pow(0.5, -p));
0147 }
0148 }
0149
0150 BOOST_AUTO_TEST_CASE(SumOfIntegers) {
0151 std::array<unsigned, 100> numberSeq{Acts::filledArray<unsigned, 100>(1)};
0152 std::iota(numberSeq.begin(), numberSeq.end(), 1);
0153 for (unsigned i = 1; i <= numberSeq.size(); ++i) {
0154 const unsigned sum =
0155 std::accumulate(numberSeq.begin(), numberSeq.begin() + i, 0);
0156 BOOST_CHECK_EQUAL(sum, Acts::sumUpToN(i));
0157 }
0158 }
0159
0160 BOOST_AUTO_TEST_CASE(BinomialTests) {
0161 static_assert(Acts::binomial(0u, 0u) == 1u);
0162
0163 static_assert(Acts::binomial(5u, 0u) == 1u);
0164 static_assert(Acts::binomial(5u, 1u) == 5u);
0165 static_assert(Acts::binomial(5u, 2u) == 10u);
0166 static_assert(Acts::binomial(5u, 3u) == 10u);
0167 static_assert(Acts::binomial(5u, 4u) == 5u);
0168 static_assert(Acts::binomial(5u, 5u) == 1u);
0169
0170 static_assert(Acts::binomial(10u, 3u) == 120u);
0171 static_assert(Acts::binomial(10u, 7u) == 120u);
0172 static_assert(Acts::binomial(20ull, 10ull) == 184756ull);
0173
0174
0175
0176
0177 BOOST_CHECK_EQUAL(Acts::binomial(1u, 1u), 1u);
0178 for (unsigned n = 1; n <= 10; ++n) {
0179
0180 BOOST_CHECK_EQUAL(Acts::binomial(n, 0u), 1);
0181 BOOST_CHECK_EQUAL(Acts::binomial(n, n), 1);
0182
0183 for (unsigned k = 1; k <= n - 1u; ++k) {
0184
0185
0186
0187
0188 std::cout << "n: " << n << ", \tk: " << k
0189 << ", \tbinom(n, k): " << Acts::binomial(n, k)
0190 << ", \tbinom(n-1, k-1): " << Acts::binomial(n - 1, k - 1)
0191 << ", \tbinom(n-1, k): " << Acts::binomial(n - 1, k)
0192 << std::endl;
0193 BOOST_CHECK_EQUAL(Acts::binomial(n, k), Acts::binomial(n - 1, k - 1) +
0194 Acts::binomial(n - 1, k));
0195 BOOST_CHECK_EQUAL(Acts::binomial(n, k), Acts::binomial(n, n - k));
0196 }
0197 }
0198 }
0199
0200 BOOST_AUTO_TEST_CASE(CopySign) {
0201 BOOST_CHECK_EQUAL(Acts::copySign(5, -10), -5);
0202 BOOST_CHECK_EQUAL(Acts::copySign(5, 0), 5);
0203 BOOST_CHECK_EQUAL(Acts::copySign(5, 55), 5);
0204
0205 static_assert(Acts::copySign(5, -10) == -5);
0206 static_assert(Acts::copySign(5, 0) == 5);
0207 static_assert(Acts::copySign(5, 55) == 5);
0208
0209 BOOST_CHECK_EQUAL(Acts::copySign(5, -std::numeric_limits<double>::infinity()),
0210 -5);
0211 BOOST_CHECK_EQUAL(Acts::copySign(5, std::numeric_limits<double>::infinity()),
0212 5);
0213
0214 static_assert(Acts::copySign(5., -std::numeric_limits<double>::infinity()) ==
0215 -5.);
0216 static_assert(Acts::copySign(5., 0) == 5);
0217 static_assert(Acts::copySign(5., std::numeric_limits<double>::infinity()) ==
0218 5.);
0219
0220 BOOST_CHECK_EQUAL(Acts::copySign(5., -10.), -5.);
0221 BOOST_CHECK_EQUAL(Acts::copySign(5., 0.), 5.);
0222 BOOST_CHECK_EQUAL(Acts::copySign(5., 55.), 5.);
0223
0224 enum class CopyEnum : int { b = 1, a = -1, c = 0 };
0225 BOOST_CHECK_EQUAL(Acts::copySign(5, CopyEnum::a), -5);
0226 BOOST_CHECK_EQUAL(Acts::copySign(5, CopyEnum::b), 5);
0227 BOOST_CHECK_EQUAL(Acts::copySign(5, CopyEnum::c), 5);
0228
0229 const Acts::Vector3 v{Acts::Vector3::UnitZ()};
0230 CHECK_CLOSE_ABS(Acts::copySign(v, -1).dot(v), -1., 1.e-7);
0231 CHECK_CLOSE_ABS(Acts::copySign(v, 1).dot(v), 1., 1.e-7);
0232 }
0233
0234 BOOST_AUTO_TEST_SUITE_END()
0235
0236 }