logoalt Hacker News

Even faster asin() was staring right at me

82 pointsby def-pri-pubtoday at 12:30 PM40 commentsview on HN

Comments

sreantoday at 3:59 PM

A notable approximation of ~650 AD vintage, by Bhaskara is

   ArcCos(x)= Π √((1-x)/(4+x)).
The search for better and better approximations led Indian mathematicians to independently develop branches of differential and integral calculus.

This tradition came to its own as Madhava school of mathematics from Kerala. https://en.wikipedia.org/wiki/Kerala_school_of_astronomy_and...

Note the approximation is for 0 < x < 1. For the range [-1, 0] Bhaskara used symmetry.

If I remember correctly, Aryabhatta had derived a rational approximation about a hundred years before this.

EDIT https://doi.org/10.4169/math.mag.84.2.098

fhdkweigtoday at 1:43 PM

This is a followup of a different post from the same domain. 5 days ago, 134 comments https://news.ycombinator.com/item?id=47336111

show 1 reply
ashdnazgtoday at 4:14 PM

No idea if it's not already optimised, but x2 could also be x*x and not just abs_x * abs_x, shifting the dependencies earlier.

coldcity_againtoday at 5:24 PM

I've been thinking about this since [1] the other day, but I still love how rotation by small angles lets you drop trig entirely.

Let α represent a roll rotation, and β a pitch rotation.

Let R(α) be:

    ( cos α   sin α   0)
    (-sin α   cos α   0)
    (   0       0     1)
Let R(β) be:

    (1     0       0   )
    (0   cos β   -sin β)
    (0   sin β    cos β)
Combine them:

    R(β).R(α) = (    cos α           sin α          0   )
                ((-sin α*cos β)   (cos α*cos β)   -sin β)
                ((-sin α*sin β)   (cos α*sin β)    cos β)
But! For small α and β, just approximate:

    ( 1   α   0)
    (-α   1  -β)
    ( 0   β   1)
So now:

    x' = x + αy
    y' = y - αx - βz
    z' = z + βy
[1]https://news.ycombinator.com/item?id=47348192
show 1 reply
jonasenordintoday at 3:38 PM

I haven't kept up with C++ in a few years - what does constexpr do for local variables?

  constexpr double a0 = 1.5707288;
show 2 replies
jaentoday at 2:57 PM

Cool, although more ILP (instruction-level parallelism) might not necessarily be better on a modern GPU, which doesn't have much ILP, if any (instead it uses those resources to execute several threads in parallel).

That might explain why the original Cg (a GPU programming language) code did not use Estrin's, since at least the code in the post does add 1 extra op (squaring `abs_x`).

(AMD GPUs used to use VLIW (very long instruction word) which is "static" ILP).

jagged-chiseltoday at 4:20 PM

> It also gets in the way of elegance and truth.

That’s quite subjective. I happen to find trigonometry to be elegant and true.

I also agree that trigonometric functions lack efficiency in software.

show 1 reply
fatih-erikli-cgtoday at 1:35 PM

I think it is `atan` function. Sin is almost a lookup query.

show 1 reply
thomasahletoday at 1:49 PM

Did you try polynomial preprocessing methods, like Knuth's and Estrin's methods? https://en.wikipedia.org/wiki/Polynomial_evaluation#Evaluati... they let you compute polynomials with half the multiplications of Horner's method, and I used them in the past to improve the speed of the exponential function in Boost.

show 1 reply