Last active
January 4, 2018 00:12
-
-
Save uucidl/d1a60cc0e4ce9d911c5f38dec8db6356 to your computer and use it in GitHub Desktop.
Approximations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Atan approximation | |
// https://www.dsprelated.com/showarticle/1052.php#tabs1-comments | |
#include <math.h> | |
#include <stdio.h> | |
double atan_approx(double z) | |
{ | |
double m = z<0? -1.0:1.0; | |
z *= m; | |
double y = 0.141499*z*z*z*z + | |
-0.343315*z*z*z + | |
-0.016224*z*z + | |
1.003839*z + | |
-0.000158; | |
return m*y; | |
} | |
double atan2_approx(double y, double x) | |
{ | |
double ay = fabs(y), ax = fabs(x); | |
int invert = ay > ax; | |
double z = invert ? ax/ay : ay/ax; // [0,1] | |
double th = atan_approx(z); // [0,π/4] | |
if(invert) th = M_PI_2 - th; // [0,π/2] | |
if(x < 0) th = M_PI - th; // [0,π] | |
th = copysign(th, y); // [-π,π] | |
return th; | |
} | |
int main(int argc, char **argv) | |
{ | |
float x0 = -1.0f; | |
float x1 = x0 + 2.f; | |
float xinc = (x1 - x0)/50.0f; | |
double err_max = 0.0; | |
double lsqerr = 0.0; | |
int lsqerr_n = 0; | |
printf("x\tatan\tatan_approx\terr\n"); | |
for (float x = x0; x <= x1; x += xinc) { | |
double y = atan(x); | |
double ay = atan_approx(x); | |
double err = fabs(ay - y); | |
err_max = err_max<err? err:err_max; | |
printf("%f\t%f\t%f\t%f\n", x, y, ay, err); | |
lsqerr += err*err; | |
++lsqerr_n; | |
} | |
printf("LSQERR: %ef\n", lsqerr/lsqerr_n); | |
printf("MAXERR: %f\n", err_max); | |
printf("PI_4: %f\n", M_PI/4.0); | |
return 0; | |
} | |
/* | |
x atan atan_approx err | |
-1.000000 -0.785398 -0.785641 0.000243 | |
-0.960000 -0.764993 -0.765014 0.000021 | |
-0.920000 -0.743756 -0.743675 0.000080 | |
-0.880000 -0.721655 -0.721553 0.000102 | |
-0.840000 -0.698660 -0.698583 0.000077 | |
-0.800000 -0.674741 -0.674711 0.000030 | |
-0.760000 -0.649870 -0.649889 0.000018 | |
-0.720000 -0.624023 -0.624080 0.000057 | |
-0.680000 -0.597177 -0.597256 0.000079 | |
-0.640000 -0.569313 -0.569395 0.000082 | |
-0.600000 -0.540419 -0.540487 0.000067 | |
-0.560000 -0.510488 -0.510528 0.000040 | |
-0.520000 -0.479519 -0.479524 0.000005 | |
-0.480000 -0.447520 -0.447490 0.000030 | |
-0.440000 -0.414507 -0.414449 0.000058 | |
-0.400000 -0.380506 -0.380432 0.000074 | |
-0.360000 -0.345555 -0.345480 0.000075 | |
-0.320000 -0.309703 -0.309643 0.000060 | |
-0.280000 -0.273009 -0.272978 0.000030 | |
-0.240000 -0.235545 -0.235552 0.000007 | |
-0.200000 -0.197395 -0.197441 0.000045 | |
-0.160000 -0.158655 -0.158727 0.000072 | |
-0.120000 -0.119429 -0.119505 0.000076 | |
-0.080000 -0.079830 -0.079875 0.000045 | |
-0.040000 -0.039979 -0.039948 0.000031 | |
0.000000 0.000000 -0.000158 0.000158 | |
0.040000 0.039979 0.039948 0.000031 | |
0.080000 0.079830 0.079875 0.000045 | |
0.120000 0.119429 0.119505 0.000076 | |
0.160000 0.158655 0.158728 0.000072 | |
0.200000 0.197396 0.197441 0.000045 | |
0.240000 0.235545 0.235552 0.000007 | |
0.280000 0.273009 0.272978 0.000030 | |
0.320000 0.309703 0.309643 0.000060 | |
0.360000 0.345556 0.345480 0.000075 | |
0.400000 0.380506 0.380432 0.000074 | |
0.440000 0.414507 0.414449 0.000058 | |
0.480000 0.447520 0.447490 0.000030 | |
0.520000 0.479519 0.479524 0.000005 | |
0.560000 0.510488 0.510528 0.000040 | |
0.600000 0.540420 0.540487 0.000068 | |
0.640000 0.569313 0.569395 0.000082 | |
0.680000 0.597177 0.597256 0.000079 | |
0.720000 0.624023 0.624080 0.000057 | |
0.760000 0.649871 0.649889 0.000018 | |
0.800000 0.674741 0.674711 0.000030 | |
0.840000 0.698660 0.698583 0.000077 | |
0.880000 0.721655 0.721553 0.000102 | |
0.920000 0.743756 0.743676 0.000080 | |
0.960000 0.764993 0.765014 0.000021 | |
LSQERR: 4.990835e-09f | |
MAXERR: 0.000243 | |
PI_4: 0.785398 | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Pseudo Sine function. | |
// | |
// Originally from Stefan Stenzel, CEO of Waldorf | |
// @url: https://namoseley.wordpress.com/2017/01/03/pseudo-sinusoidal-waveform-ii/ | |
// https://twitter.com/5tenzel/status/816225338330140673 | |
#include <math.h> | |
#include <stdio.h> | |
/* x in [-1,1] -> [-1,1] */ | |
float waldorf_cycle(float x) | |
{ | |
float abs_x = x < 0.f? -x:x; | |
return x*4.f*(1 - abs_x); | |
} | |
/* x in [-1,1] -> [-1,1] */ | |
float cycle(float x) | |
{ | |
return sin(x*3.14159265358979323846); | |
} | |
int main(int argc, char **argv) | |
{ | |
float x0 = -1.0f; | |
float x1 = x0 + 2.f; | |
float xinc = (x1 - x0)/50.0f; | |
float err_max = 0.0; | |
float lsqerr = 0.0; | |
int lsqerr_n = 0; | |
printf("x\tcycle\twaldorf_cycle\terr\n"); | |
for (float x = x0; x <= x1; x += xinc) { | |
float y = cycle(x); | |
float wy = waldorf_cycle(x); | |
float err = fabs(wy - y); | |
err_max = err_max<err? err:err_max; | |
printf("%f\t%f\t%f\t%f\n", x, wy, y, err); | |
lsqerr += err*err; | |
++lsqerr_n; | |
} | |
printf("LSQERR: %f\n", lsqerr/lsqerr_n); | |
printf("MAXERR: %f\n", err_max); | |
return 0; | |
} | |
/* | |
clang waldorf_sin.c -o waldorf_sin && ./waldorf_sin | |
x cycle waldorf_cycle err | |
-1.000000 -0.000000 -0.000000 0.000000 | |
-0.960000 -0.153600 -0.125333 0.028267 | |
-0.920000 -0.294400 -0.248690 0.045710 | |
-0.880000 -0.422400 -0.368125 0.054275 | |
-0.840000 -0.537600 -0.481754 0.055846 | |
-0.800000 -0.640000 -0.587786 0.052215 | |
-0.760000 -0.729600 -0.684547 0.045053 | |
-0.720000 -0.806400 -0.770514 0.035887 | |
-0.680000 -0.870400 -0.844328 0.026072 | |
-0.640000 -0.921600 -0.904827 0.016773 | |
-0.600000 -0.960000 -0.951057 0.008943 | |
-0.560000 -0.985600 -0.982287 0.003313 | |
-0.520000 -0.998400 -0.998027 0.000373 | |
-0.480000 -0.998400 -0.998027 0.000373 | |
-0.440000 -0.985600 -0.982287 0.003313 | |
-0.400000 -0.960000 -0.951056 0.008944 | |
-0.360000 -0.921600 -0.904827 0.016773 | |
-0.320000 -0.870400 -0.844328 0.026072 | |
-0.280000 -0.806400 -0.770513 0.035887 | |
-0.240000 -0.729600 -0.684547 0.045053 | |
-0.200000 -0.640000 -0.587785 0.052215 | |
-0.160000 -0.537600 -0.481753 0.055846 | |
-0.120000 -0.422399 -0.368124 0.054275 | |
-0.080000 -0.294399 -0.248689 0.045710 | |
-0.040000 -0.153599 -0.125333 0.028267 | |
0.000000 0.000001 0.000001 0.000000 | |
0.040000 0.153601 0.125334 0.028267 | |
0.080000 0.294401 0.248690 0.045710 | |
0.120000 0.422401 0.368125 0.054275 | |
0.160000 0.537600 0.481754 0.055846 | |
0.200000 0.640000 0.587786 0.052215 | |
0.240000 0.729600 0.684547 0.045053 | |
0.280000 0.806400 0.770514 0.035887 | |
0.320000 0.870400 0.844328 0.026072 | |
0.360000 0.921600 0.904827 0.016773 | |
0.400000 0.960000 0.951057 0.008943 | |
0.440000 0.985600 0.982287 0.003313 | |
0.480000 0.998400 0.998027 0.000373 | |
0.520000 0.998400 0.998027 0.000373 | |
0.560000 0.985600 0.982287 0.003313 | |
0.600000 0.960000 0.951056 0.008943 | |
0.640000 0.921600 0.904827 0.016773 | |
0.680000 0.870400 0.844328 0.026072 | |
0.720000 0.806400 0.770513 0.035887 | |
0.760000 0.729600 0.684547 0.045053 | |
0.800000 0.639999 0.587785 0.052215 | |
0.840000 0.537599 0.481753 0.055846 | |
0.880000 0.422399 0.368124 0.054275 | |
0.920000 0.294399 0.248689 0.045710 | |
0.960000 0.153599 0.125332 0.028267 | |
LSQERR: 0.001284 | |
MAXERR: 0.055846 | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment