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;