sinh.js (3331B)
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 PINF = require( '@stdlib/constants/float64/pinf' ); 38 var NINF = require( '@stdlib/constants/float64/ninf' ); 39 var abs = require( './../../../../base/special/abs' ); 40 var exp = require( './../../../../base/special/exp' ); 41 var LN2 = require( '@stdlib/constants/float64/ln-two' ); 42 var rateval = require( './rational_pq.js' ); 43 44 45 // VARIABLES // 46 47 // ln(2^1024) 48 var MAXLOG = 7.09782712893383996843e2; 49 50 // ln(2^-1022) 51 var MINLOG = -7.08396418532264106224e2; 52 53 var POS_OVERFLOW = MAXLOG + LN2; 54 var NEG_OVERFLOW = MINLOG - LN2; 55 56 var LARGE = MAXLOG - LN2; 57 58 59 // MAIN // 60 61 /** 62 * Computes the hyperbolic sine of a number. 63 * 64 * ## Method 65 * 66 * The range is partitioned into two segments. If \\( |x| \le 1 \\), we use a rational function of the form 67 * 68 * ```tex 69 * x + x^3 \frac{\mathrm{P}(x)}{\mathrm{Q}(x)} 70 * ``` 71 * 72 * Otherwise, the calculation is 73 * 74 * ```tex 75 * \operatorname{sinh}(x) = \frac{ e^x - e^{-x} }{2}. 76 * ``` 77 * 78 * ## Notes 79 * 80 * - Relative error: 81 * 82 * | arithmetic | domain | # trials | peak | rms | 83 * |:----------:|:--------:|:--------:|:-------:|:-------:| 84 * | DEC | +- 88 | 50000 | 4.0e-17 | 7.7e-18 | 85 * | IEEE | +-MAXLOG | 30000 | 2.6e-16 | 5.7e-17 | 86 * 87 * 88 * @param {number} x - input value (in radians) 89 * @returns {number} hyperbolic sine 90 * 91 * @example 92 * var v = sinh( 0.0 ); 93 * // returns 0.0 94 * 95 * @example 96 * var v = sinh( 2.0 ); 97 * // returns ~3.627 98 * 99 * @example 100 * var v = sinh( -2.0 ); 101 * // returns ~-3.627 102 * 103 * @example 104 * var v = sinh( NaN ); 105 * // returns NaN 106 */ 107 function sinh( x ) { 108 var a; 109 if ( x === 0.0 ) { 110 return x; // handles `+-0` 111 } 112 a = abs( x ); 113 if ( x > POS_OVERFLOW || x < NEG_OVERFLOW ) { 114 return ( x > 0.0 ) ? PINF : NINF; 115 } 116 if ( a > 1.0 ) { 117 if ( a >= LARGE ) { 118 a = exp( 0.5*a ); 119 a *= 0.5 * a; 120 if ( x < 0.0 ) { 121 a = -a; 122 } 123 return a; 124 } 125 a = exp( a ); 126 a = (0.5*a) - (0.5/a); 127 if ( x < 0.0 ) { 128 a = -a; 129 } 130 return a; 131 } 132 a *= a; 133 return x + ( x*a*rateval( a ) ); 134 } 135 136 137 // EXPORTS // 138 139 module.exports = sinh;