From c59b28926f4562174eb2e39b87e018f0fe09b139 Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Mon, 16 Jun 2025 23:04:33 +0300 Subject: [PATCH] implement horners rule --- src/math_func_checker.c | 44 ++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/math_func_checker.c b/src/math_func_checker.c index 155dda6..7bbac04 100644 --- a/src/math_func_checker.c +++ b/src/math_func_checker.c @@ -154,6 +154,23 @@ static f64 sin_using_taylor(f64 input, f64 *coeffs, size_t coeffs_len) return result; } +static f64 sin_using_taylor_horner(f64 input, f64 *coeffs, size_t coeffs_len) +{ + f64 input_sqr = input * input; + + f64 result = coeffs[coeffs_len - 1]; + for (size_t j = 1; j < coeffs_len; j++) { + size_t i = coeffs_len - j - 1; + + result *= input_sqr; + result += coeffs[i]; + } + + result *= input; + + return result; +} + static void tester_record_result(struct tester *tester, f64 input, f64 my_output, f64 reference_output) { f64 error = reference_output - my_output; @@ -182,19 +199,32 @@ static void test_taylor_series(u64 samples, f64 *coeffs, size_t coeffs_len) create_taylor_series_coeffs(coeffs, coeffs_len); struct tester tester = { }; + struct tester tester_horner = { }; + for (int j = 0; j < samples; j++) { - f64 input = lerp((f64)j / samples, -M_PI, M_PI); + f64 input = lerp((f64)j / samples, 0, M_PI/2); tester_record_result(&tester, input, sin_using_taylor(input, coeffs, coeffs_len), sin(input)); + tester_record_result(&tester_horner, input, sin_using_taylor_horner(input, coeffs, coeffs_len), sin(input)); } - char name[64] = { 0 }; - snprintf(name, sizeof(name), "taylor %zu", coeffs_len); - tester_show_result(&tester, name); + { + char name[64] = { 0 }; + snprintf(name, sizeof(name), "taylor %zu", coeffs_len); + tester_show_result(&tester, name); + } + + { + char name[64] = { 0 }; + snprintf(name, sizeof(name), "taylor h %zu", coeffs_len); + tester_show_result(&tester_horner, name); + } + + printf(" diff %.16f\n", tester.max_error - tester_horner.max_error); } int main() { - uint64_t samples = 10000; + uint64_t samples = 100000; struct math_spec specs[] = { { .name = "sin", @@ -267,8 +297,8 @@ int main() tester_show_result(&tester, spec.name); } - f64 taylor_coeffs[41]; - for (int i = 3; i < ARRAY_LEN(taylor_coeffs); i++) { + f64 taylor_coeffs[10]; + for (int i = 1; i < ARRAY_LEN(taylor_coeffs); i++) { test_taylor_series(samples, taylor_coeffs, i); }