The implementation of the __cos kernel in Musl is actually quite elegant. After reducing the input to the range [-pi/4, pi/4], it just applies the best degree-14 polynomial for approximating the cosine on this interval. It turns out that this suffices for having an error that is less than the machine precision. The coefficients of this polynomial can be computed with the Remez algorithm, but even truncating the Cheby…
Implementing Cosine in C from Scratch (2020)
101–110 of 139 posts
Re: Implementing Cosine in C from Scratch (2020)
#102* The range reduction is, well, probably worse than acos. Look for Payne–Hanek–Corbett. Not an issue for games, I assume.
* The LERP is nice and all, but Qt actually has an even better one: instead of doing a LERP, you use the local derivative also available from the lookup table. https://stackoverflow.com/a/52841086
Others have already mentioned the Remez and the Horner stuff. Won’t repeat here.
Re: Implementing Cosine in C from Scratch (2020)
#103Here's a solution which is vectorizable: http://gallium.inria.fr/blog/fast-vectorizable-math-approx/ I've also read that Chebyshev polynomials are far better for approximating functions than Taylor series (eg https://en.wikipedia.org/wiki/Approximation_theory )
This matters less once you put things through the horner scheme. And if you are not you are leaving performance on the table.
Re: Implementing Cosine in C from Scratch (2020)
#104Earlier quoted context omitted.
It does use Horner's rule, but splits the expression into two halves in order to exploit instruction-level parallelism.
Considering the form of both halves is the same, are compilers smart enough to vectorize this code?
Re: Implementing Cosine in C from Scratch (2020)
#105I did the same thing for sqrt() seven years ago. It benchmarked at about five times faster than math.h/libm, but the trade was a reduction in the maximum value of the result. My version would not produce accurate results for inputs greater than 2^16. It did work very well for generating real-time laser pointing X/Y coordinates for an Archimedean Spiral. https://en.wikipedia.org/wiki/Archimedean_spiral (This was on a…
I'm surprised this was faster than an initial guess (half the exponent and mantisa) followed by newton's method.
Even a 50% increase in speed was well worth my effort though.
* Replacement sqrtf() function. This function runs about 50% faster than
* the one in the TI math library. It provides identical accuracy, but
* it is limited to input values less than 2^14. This shouldn't be a problem
* because the passed argument will always be in the range of
* 0-(max spiral scan period). The spiral scan period is presently about
* 140 seconds.
Re: Implementing Cosine in C from Scratch (2020)
#106lookup tables and lerp are the most common solution I've seen (for a wide range of functions). You can also memorize with an LRU cache.
Yeah, lerping into a lookup table is common in audio and (old school) games. A common trick to make that faster is to not use doubles and radians to represent the phase. Instead, represent phase using an integer in some power-of-two range. That lets you truncate the phase to fit in a single period using a bit mask instead of the relatively slow modulo.
Re: Implementing Cosine in C from Scratch (2020)
#107>I couldn't find any notable projects on GitHub that use a table for trig functions, but I'm sure they exist. Doom?
Re: Implementing Cosine in C from Scratch (2020)
#108So 57 years ago, there weren’t any programming books. Well, there was one. McCracken and Dorn, Numerical Methods and Fortran Programming. A kindly childless couple, Ben and Bluma Goldin, who lived in the same apartment house in Brooklyn, bought me this book as a gift. An axiomatic lesson from the book was distrust of Taylor expansions, and the necessity of moving the expansion point of any function to a favorable loc…
Re: Implementing Cosine in C from Scratch (2020)
#109Earlier quoted context omitted.
> the FPU, which is basically legacy you'll pry my long doubles from my cold, dead hands!
You're selectively quoting me - I said it's 'legacy emulated'. It's emulated using very long-form microcode, so basically emulated in software. I didn't say it was simply 'legacy'.
Re: Implementing Cosine in C from Scratch (2020)
#110Mandatory Physics "troll" comment: For small angles, sin(x) ~= x and cos(x) ~= 1 -- the ["small angle approximation"]( https://en.wikipedia.org/wiki/Small-angle_approximation ) It's actually kind of ridiculous how many times it comes up and works well enough in undergraduate Mechanics.
This a perfectly nice Programming 101 example of a recursive function -- if an angle is too large, calculate its sine using the sine of the half-angle, otherwise return the angle (or, if you're fancy, some simple polynomial approximation of the sine). I'm sure everyone did this in school (we did, in fact).