julia icon indicating copy to clipboard operation
julia copied to clipboard

Faster and more accurate sinpi, cospi, sincospi for Float32, Float64

Open oscardssmith opened this issue 3 years ago • 8 comments

Instead of using sin_kernel and cos_kernel, use better kernels that need less precision.

I benchmark this as 14% faster for Float64, 7% faster for Float32.

Accuracy for Float64 is .64 ULPs compared to .75 for master.

Accuracy for Float32 is .5 ULP

oscardssmith avatar Jul 31 '21 06:07 oscardssmith

Thanks Oscar. For my own curiosity, how did you generate these polynomial coefficients? If it's not too much code, it would be cool to record that for future usage with other special functions, so that you're not the only person who knows how to do this.

Test failures look like cospi_kernel(::BigFloat) is trying to be called.

staticfloat avatar Aug 13 '21 20:08 staticfloat

The coefficient generation is slightly complex, but the TLDR is to use Remez to generate a minimax polynomial over the range of inputs, specialized to the even/oddness of the polynomial. I really need to put the general principals all into a blogpost at some point, but the TLDR for this is

using Remez
sinpi_coeffs = [(big(pi))^n/factorial(big(n)) for n in 1:2:40] #nonzero taylor coefficients in bigfloat
sinpi_kinda(x) = evalpoly(x, sinpi_coeffs)
bounds = (0, 0.25^2) #squared because we are getting coefficients for sqrt(sinpi(x))
n = 7 # degree 7 polynomial
exact_coeficients = ratfn_minimax(sinpi_kinda, bounds, n, 0)[1]
#now do lots of messing around with rounding to get things exact.

oscardssmith avatar Aug 13 '21 21:08 oscardssmith

This has been surprisingly tricky to get right. At the moment, the only failing tests is the behavior as to whether 0.0 or -0.0 is returned. To me, neither is clearly right. Is there a good reason why the specific signs need to be tested? If not, I will probably loosen the tests slightly to check for ==0 rather than ===0.0

oscardssmith avatar Sep 13 '21 20:09 oscardssmith

adding triage label to discus signs of zeros.

oscardssmith avatar Sep 14 '21 15:09 oscardssmith

removing triage tag after research suggests Base was correct.

oscardssmith avatar Sep 16 '21 04:09 oscardssmith

Is it worth trying to get this done? I suppose too late for 1.8 but maybe 1.9?

ViralBShah avatar Feb 20 '22 00:02 ViralBShah

yeah. it's still on my radar. I just haven't had the time recently.

oscardssmith avatar Feb 20 '22 00:02 oscardssmith

re: signed zeros, the IEEE754-2019 spec states

sinPi(+n) is +0 and sinPi(−n) is −0 for positive integers n cosPi(n + 1⁄2) is +0 for any integer n when n + 1⁄2 is representable

simonbyrne avatar Sep 13 '22 19:09 simonbyrne

I think this is finally ready to go. Anyone want to review?

oscardssmith avatar Nov 11 '22 14:11 oscardssmith