time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

tanh.js (2961B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 *
     18 *
     19 * ## Notice
     20 *
     21 * The original C code, long comment, copyright, license, and constants are from [Cephes]{@link http://www.netlib.org/cephes}. The implementation follows the original, but has been modified for JavaScript.
     22 *
     23 * ```text
     24 * Copyright 1984, 1995, 2000 by Stephen L. Moshier
     25 *
     26 * Some software in this archive may be from the book _Methods and Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster International, 1989) or from the Cephes Mathematical Library, a commercial product. In either event, it is copyrighted by the author. What you see here may be used freely but it comes with no support or guarantee.
     27 *
     28 * Stephen L. Moshier
     29 * moshier@na-net.ornl.gov
     30 * ```
     31 */
     32 
     33 'use strict';
     34 
     35 // MODULES //
     36 
     37 var abs = require( './../../../../base/special/abs' );
     38 var exp = require( './../../../../base/special/exp' );
     39 var ratval = require( './rational_pq.js' );
     40 
     41 
     42 // VARIABLES //
     43 
     44 // log(2**127)
     45 var MAXLOG = 8.8029691931113054295988e+01;
     46 
     47 
     48 // MAIN //
     49 
     50 /**
     51 * Computes the hyperbolic tangent of a number.
     52 *
     53 * ## Method
     54 *
     55 * For \\( |x| < 0.625 \\), we use a rational function of the form (Cody and Waite)
     56 *
     57 * ```tex
     58 * x + x^3 \frac{\mathrm{P}(x)}{\mathrm{Q}(x)}
     59 * ```
     60 *
     61 * Otherwise,
     62 *
     63 * ```tex
     64 * \begin{align*}
     65 * \operatorname{tanh}(x) &= \frac{\operatorname{sinh}(x)}{\operatorname{cosh(x)}} \\
     66 * &= 1 - \frac{2}{e^{2x} + 1}
     67 * \end{align*}
     68 * ```
     69 *
     70 * ## Notes
     71 *
     72 * -   Relative error:
     73 *
     74 *     | arithmetic | domain | # trials | peak    | rms     |
     75 *     |:----------:|:------:|:--------:|:-------:|:-------:|
     76 *     | DEC        | -2,2   | 50000    | 3.3e-17 | 6.4e-18 |
     77 *     | IEEE       | -2,2   | 30000    | 2.5e-16 | 5.8e-17 |
     78 *
     79 *
     80 * @param {number} x - input value (in radians)
     81 * @returns {number} hyperbolic tangent
     82 *
     83 * @example
     84 * var v = tanh( 0.0 );
     85 * // returns 0.0
     86 *
     87 * @example
     88 * var v = tanh( 2.0 );
     89 * // returns ~0.964
     90 *
     91 * @example
     92 * var v = tanh( -2.0 );
     93 * // returns ~-0.964
     94 *
     95 * @example
     96 * var v = tanh( NaN );
     97 * // returns NaN
     98 */
     99 function tanh( x ) {
    100 	var s;
    101 	var z;
    102 	z = abs( x );
    103 	if ( z > 0.5*MAXLOG ) {
    104 		return ( x < 0.0 ) ? -1.0 : 1.0;
    105 	}
    106 	if ( z >= 0.625 ) {
    107 		s = exp( 2.0 * z );
    108 		z = 1.0 - ( 2.0/(s+1.0) );
    109 		if ( x < 0.0 ) {
    110 			z = -z;
    111 		}
    112 	} else {
    113 		if ( x === 0.0 ) {
    114 			return x; // Handle `+-0`
    115 		}
    116 		s = x * x;
    117 		z = x + ( x*s*ratval( s ) );
    118 	}
    119 	return z;
    120 }
    121 
    122 
    123 // EXPORTS //
    124 
    125 module.exports = tanh;