parent
fb98a3dffc
commit
747b3d2fa8
|
@ -371,3 +371,29 @@ float expf_taylor(float x)
|
|||
{
|
||||
return expf_taylor_impl(x, 4);
|
||||
}
|
||||
|
||||
float tanf_taylor(float x) {
|
||||
// This exists because the "normal" implementation, tanf, pulls in like 6kb of
|
||||
// code and loookup tables
|
||||
|
||||
// This is only specified from [0, pi/2 - 0.01)
|
||||
// Inside that range it has an error of less than 0.1%, and it gets worse as theta -> pi/2
|
||||
|
||||
// Precompute some exponents of x
|
||||
float x2 = x * x;
|
||||
float x3 = x2 * x;
|
||||
float x4 = x3 * x;
|
||||
float x5 = x4 * x;
|
||||
float x6 = x5 * x;
|
||||
// x7 not used
|
||||
float x8 = x6 * x2;
|
||||
|
||||
// 3-term Taylor Series for sin(theta)
|
||||
float sin_val = x - (x3 / 6) + (x5 / 120);
|
||||
|
||||
// 5-term Taylor Series for cos(theta)
|
||||
float cos_val = 1 - (x2 / 2) + (x4 / 24) - (x6 / 720) + (x8 / 40320);
|
||||
|
||||
// tan = sin / cos
|
||||
return sin_val / cos_val;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,10 @@ float limitRateOfChange(float newValue, float oldValue, float incrLimitPerSec, f
|
|||
// bogus results outside the range -2 < x < 0.
|
||||
float expf_taylor(float x);
|
||||
|
||||
// @brief Compute tan(theta) using a ratio of the Taylor series for sin and cos
|
||||
// Valid for the range [0, pi/2 - 0.01]
|
||||
float tanf_taylor(float theta);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "biquad.h"
|
||||
#include "error_handling.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "efilib.h"
|
||||
|
||||
Biquad::Biquad() {
|
||||
// Default to passthru
|
||||
|
@ -23,7 +23,7 @@ void Biquad::reset() {
|
|||
}
|
||||
|
||||
static float getK(float samplingFrequency, float cutoff) {
|
||||
return tanf(3.14159f * cutoff / samplingFrequency);
|
||||
return tanf_taylor(3.14159f * cutoff / samplingFrequency);
|
||||
}
|
||||
|
||||
static float getNorm(float K, float Q) {
|
||||
|
|
|
@ -36,3 +36,12 @@ TEST(EfiLibTest, clampf) {
|
|||
EXPECT_EQ(clampF(-10, 50, 10), 10);
|
||||
|
||||
}
|
||||
|
||||
TEST(EfiLibTest, tanf_taylor) {
|
||||
// Function is only specified from [0, pi/2) ish, so test that range
|
||||
for (float i = 0; i < 1.5; i += 0.1f)
|
||||
{
|
||||
// Compare to libc implementation
|
||||
EXPECT_NEAR(tanf_taylor(i), tanf(i), 0.05f) << "I = " << i;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue