diff --git a/include/math_approx/src/log_approx.hpp b/include/math_approx/src/log_approx.hpp index 4861a12..82bfd31 100644 --- a/include/math_approx/src/log_approx.hpp +++ b/include/math_approx/src/log_approx.hpp @@ -85,4 +85,16 @@ T log (T x) { return log>, order> (x); } + +template +T log2 (T x) +{ + return log>, order> (x); +} + +template +T log10 (T x) +{ + return log>, order> (x); +} } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fc1ab2e..622920c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -32,3 +32,4 @@ setup_catch_test(tanh_approx_test) setup_catch_test(sigmoid_approx_test) setup_catch_test(trig_approx_test) setup_catch_test(pow_approx_test) +setup_catch_test(log_approx_test) diff --git a/test/src/log_approx_test.cpp b/test/src/log_approx_test.cpp new file mode 100644 index 0000000..96a97b3 --- /dev/null +++ b/test/src/log_approx_test.cpp @@ -0,0 +1,115 @@ +#include "test_helpers.hpp" +#include "catch2/catch_template_test_macros.hpp" + +#include +#include + +#include + +template +void test_approx (const auto& all_floats, const auto& y_exact, auto&& f_approx, float err_bound) +{ + const auto y_approx = test_helpers::compute_all (all_floats, f_approx); + const auto error = test_helpers::compute_error (y_exact, y_approx); + const auto max_error = test_helpers::abs_max (error); + + std::cout << max_error << std::endl; + REQUIRE (std::abs (max_error) < err_bound); +} + + +TEMPLATE_TEST_CASE ("Log Approx Test", "", float, double) +{ + const auto all_floats = test_helpers::all_32_bit_floats (0.01f, 10.0f, 1.0e-3f); + const auto y_exact = test_helpers::compute_all (all_floats, [] (auto x) + { return std::log (x); }); + + SECTION ("6th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log<6> (x); }, + 4.5e-6f); + } + SECTION ("5th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log<5> (x); }, + 1.5e-5f); + } + SECTION ("4th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log<4> (x); }, + 8.5e-5f); + } + SECTION ("3th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log<3> (x); }, + 6.5e-4f); + } +} + +TEMPLATE_TEST_CASE ("Log2 Approx Test", "", float, double) +{ + const auto all_floats = test_helpers::all_32_bit_floats (0.01f, 10.0f, 1.0e-3f); + const auto y_exact = test_helpers::compute_all (all_floats, [] (auto x) + { return std::log2 (x); }); + + SECTION ("6th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log2<6> (x); }, + 6.0e-6f); + } + SECTION ("5th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log2<5> (x); }, + 2.0e-5f); + } + SECTION ("4th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log2<4> (x); }, + 1.5e-4f); + } + SECTION ("3th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log2<3> (x); }, + 9.0e-4f); + } +} + +TEMPLATE_TEST_CASE ("Log10 Approx Test", "", float, double) +{ + const auto all_floats = test_helpers::all_32_bit_floats (0.01f, 10.0f, 1.0e-3f); + const auto y_exact = test_helpers::compute_all (all_floats, [] (auto x) + { return std::log10 (x); }); + + SECTION ("6th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log10<6> (x); }, + 2.0e-6f); + } + SECTION ("5th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log10<5> (x); }, + 6.0e-6f); + } + SECTION ("4th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log10<4> (x); }, + 4.0e-5f); + } + SECTION ("3th-Order") + { + test_approx (all_floats, y_exact, [] (auto x) + { return math_approx::log10<3> (x); }, + 3.0e-4f); + } +}