implement horners rule
This commit is contained in:
parent
8c72530390
commit
c59b28926f
@ -154,6 +154,23 @@ static f64 sin_using_taylor(f64 input, f64 *coeffs, size_t coeffs_len)
|
|||||||
return result;
|
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)
|
static void tester_record_result(struct tester *tester, f64 input, f64 my_output, f64 reference_output)
|
||||||
{
|
{
|
||||||
f64 error = reference_output - my_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);
|
create_taylor_series_coeffs(coeffs, coeffs_len);
|
||||||
|
|
||||||
struct tester tester = { };
|
struct tester tester = { };
|
||||||
|
struct tester tester_horner = { };
|
||||||
|
|
||||||
for (int j = 0; j < samples; j++) {
|
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, 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);
|
char name[64] = { 0 };
|
||||||
tester_show_result(&tester, name);
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
uint64_t samples = 10000;
|
uint64_t samples = 100000;
|
||||||
struct math_spec specs[] = {
|
struct math_spec specs[] = {
|
||||||
{
|
{
|
||||||
.name = "sin",
|
.name = "sin",
|
||||||
@ -267,8 +297,8 @@ int main()
|
|||||||
tester_show_result(&tester, spec.name);
|
tester_show_result(&tester, spec.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 taylor_coeffs[41];
|
f64 taylor_coeffs[10];
|
||||||
for (int i = 3; i < ARRAY_LEN(taylor_coeffs); i++) {
|
for (int i = 1; i < ARRAY_LEN(taylor_coeffs); i++) {
|
||||||
test_taylor_series(samples, taylor_coeffs, i);
|
test_taylor_series(samples, taylor_coeffs, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user