Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fast hyperbolic tangent approximation in Javascript

I'm doing some digital signal processing calculations in javascript, and I found that calculating the hyperbolic tangent (tanh) is a bit too expensive. This is how I currently approximate tanh:

function tanh (arg) {
    // sinh(number)/cosh(number)
    return (Math.exp(arg) - Math.exp(-arg)) / (Math.exp(arg) + Math.exp(-arg));
}

Anyone knows a faster way to calculate it?

like image 257
janesconference Avatar asked May 24 '11 23:05

janesconference


3 Answers

For an accurate answer using fewer Math.exp()s, you can use the relationship between tanh and the logistic function. Tanh(x) is exactly 2 * logistic(2 * x) - 1, and expanding out the logistic function, you get:

  function one_exp_tanh(x){
      return 2.0 / (1.0 + exp(-2.0 * x)) - 1.0;
  }

I don't know whether that is faster in javascript though.

like image 138
Douglas Bagnall Avatar answered Sep 21 '22 01:09

Douglas Bagnall


From here.

function rational_tanh(x)
{
    if( x < -3 )
        return -1;
    else if( x > 3 )
        return 1;
    else
        return x * ( 27 + x * x ) / ( 27 + 9 * x * x );
}

This is a rational function to approximate a tanh-like soft clipper. It is based on the pade-approximation of the tanh function with tweaked coefficients.

The function is in the range x=-3..3 and outputs the range y=-1..1. Beyond this range the output must be clamped to -1..1.

The first to derivatives of the function vanish at -3 and 3, so the transition to the hard clipped region is C2-continuous.

The Padé approximation is magnitudes better than the Taylor expansion. The clamping may also be an issue (depending on your range).

like image 14
David Titarenco Avatar answered Oct 27 '22 11:10

David Titarenco


You could do this and cut your performance time in half:

function tanh(arg) {
    var pos = Math.exp(arg);
    var neg = Math.exp(-arg);
    return (pos - neg) / (pos + neg);
}
like image 6
Andrew Hare Avatar answered Oct 27 '22 13:10

Andrew Hare