Version 2 (modified by 11 years ago) (diff) | ,
---|
Trigonometric functions
Our research notes about implementation of fast trigonometric functions.
Minimax polynomial for sin(x)
Absolute error
Suppose we want to approximate sin(x) on [-π/2; π/2] with a polynomial P(x) such that the absolute error is never more than E:
![\[\big\vert\sin(x) - P(x)\big\vert \le E \qquad \forall x \in \bigg[-\frac{\pi}{2}, \frac{\pi}{2}\bigg]\]](https://lolengine.net/tracmath/fd15c2c1b3a4e903ffbb65c8788433d441531d4b.png)
We know sin(x) is an odd function, so instead we look for a polynomial Q(x) such that P(x) = xQ(x²):
![\[\big\vert\sin(x) - xQ(x^2)\big\vert \le E \qquad \forall x \in \bigg[-\frac{\pi}{2}, \frac{\pi}{2}\bigg]\]](https://lolengine.net/tracmath/c6599ce82285609bbf3ba11ab74a5cccf4d89b8b.png)
Substitute y for x² and reduce the range to positive values:
![\[\big\lvert\sin(\sqrt{y}) - \sqrt{y}Q(y)\big\rvert \le E \qquad \forall y \in \bigg[0, \frac{\pi^2}{4}\bigg]\]](https://lolengine.net/tracmath/b615c38c76c76a697a50e3799c751a5bed339414.png)
Divide through by √y:
![\[\bigg\lvert\frac{\sin(\sqrt{y})}{\sqrt{y}} - Q(y)\bigg\rvert \le \frac{E}{|\sqrt{y}|} \qquad \forall y \in \bigg[0, \frac{\pi^2}{4}\bigg]\]](https://lolengine.net/tracmath/259a33b58c56a5004c86f604a355121ddee1ac7d.png)
If we want to force the asymptotic behaviour in x=0, we substitute Q(y) with 1+yR(y):
![\[\bigg\lvert\frac{\sin(\sqrt{y})}{\sqrt{y}} - 1 - yR(y)\bigg\rvert \le \frac{E}{|\sqrt{y}|} \qquad \forall y \in \bigg[0, \frac{\pi^2}{4}\bigg]\]](https://lolengine.net/tracmath/038e1d7a9904b417346a161767da67ed92d75183.png)
Divide through by y:
![\[\bigg\lvert\frac{\sin(\sqrt{y})-\sqrt{y}}{y\sqrt{y}} - R(y)\bigg\rvert \le \frac{E}{|y\sqrt{y}|} \qquad \forall y \in \bigg[0, \frac{\pi^2}{4}\bigg]\]](https://lolengine.net/tracmath/b3a3709ecc282f53ecafca60ef039e1ad49aa6bc.png)
We then use the following code:
static real myfun(real const &x) { real y = sqrt(x); return (sin(y) - y) / (x * y); } static real myerr(real const &x) { real y = sqrt(x); return re(x * y); } RemezSolver<6> solver; solver.Run(real::R_1 >> 400, real::R_PI_2 * real::R_PI_2, myfun, myerr, 15);
These are the resulting R, Q and P:
