glsl 1.30: Fix numerical instabilities in asinh
authorPaul Berry <stereotype441@gmail.com>
Mon, 26 Sep 2011 22:51:39 +0000 (15:51 -0700)
committerPaul Berry <stereotype441@gmail.com>
Wed, 28 Sep 2011 19:20:25 +0000 (12:20 -0700)
commit9c7552729971463af015a767e547c43f94fe1212
tree741ac76298fac2bf85ec826b66865b3ae3e644ab
parentb79782cbedf8b23ea392d9a597eb4831a605bbe0
glsl 1.30: Fix numerical instabilities in asinh

The formula we were previously using for asinh:

    asinh x = ln(x + sqrt(x * x + 1))

is numerically unstable: when x is a large negative value, the quantity

    x + sqrt(x * x + 1)

is a small positive value (on the order of 1/(2|x|)).  Since the
logarithm function is very sensitive in this range, any error in the
computation of the square root manifests as a large error in the
result.

This patch changes to the equivalent formula:

    asinh x = sign(x) * ln(abs(x) + sqrt(x * x + 1))

which is only slightly more expensive to compute, and is numerically
stable for all x.

Fixes piglit tests
spec/glsl-1.30/execution/built-in-functions/[fv]s-asinh-*.

Reviewed-by: Chad Versace <chad@chad-versace.us>
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/glsl/builtins/ir/asinh