acosh.js (2846B)
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 following copyright, license, and long comment were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/e_acosh.c?view=markup}. The implementation follows the original, but has been modified for JavaScript. 22 * 23 * ```text 24 * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. 25 * 26 * Developed at SunPro, a Sun Microsystems, Inc. business. 27 * Permission to use, copy, modify, and distribute this 28 * software is freely granted, provided that this notice 29 * is preserved. 30 * ``` 31 */ 32 33 'use strict'; 34 35 // MODULES // 36 37 var isnan = require( './../../../../base/assert/is-nan' ); 38 var log1p = require( './../../../../base/special/log1p' ); 39 var sqrt = require( './../../../../base/special/sqrt' ); 40 var LN2 = require( '@stdlib/constants/float64/ln-two' ); 41 var ln = require( './../../../../base/special/ln' ); 42 43 44 // VARIABLES // 45 46 var HUGE = 1 << 28; // 2**28 47 48 49 // MAIN // 50 51 /** 52 * Computes the hyperbolic arccosine of a number. 53 * 54 * ## Method 55 * 56 * Based on 57 * 58 * ```tex 59 * \operatorname{acosh}(x) = \log \left[ x + \sqrt{ x^2 - 1 } \right] 60 * ``` 61 * 62 * we have 63 * 64 * ```tex 65 * \operatorname{acosh}(x) = \begin{cases} 66 * \log(x) + \tfrac{\ln}{2} & \text{ if x is large } \\ 67 * \log \left( 2x-\tfrac{1}{\sqrt{x^2-1}+x} \right) & \text{ if } x > 2 \\ 68 * \operatorname{log1p}\left( x - 1 + \sqrt{ 2 \cdot (x-1) + (x-1)^2 } \right) & \text{ otherwise } 69 * \end{cases} 70 * ``` 71 * 72 * ## Special Cases 73 * 74 * ```tex 75 * \begin{align*} 76 * \operatorname{acosh}(x) &= \mathrm{NaN}\ \text{ if } x < 1 \\ 77 * \end{align*} 78 * ``` 79 * 80 * @param {number} x - input value 81 * @returns {number} hyperbolic arccosine (in radians) 82 * 83 * @example 84 * var v = acosh( 1.0 ); 85 * // returns 0.0 86 * 87 * @example 88 * var v = acosh( 2.0 ); 89 * // returns ~1.317 90 * 91 * @example 92 * var v = acosh( NaN ); 93 * // returns NaN 94 */ 95 function acosh( x ) { 96 var t; 97 if ( isnan( x ) ) { 98 return NaN; 99 } 100 if ( x < 1.0 ) { 101 return NaN; 102 } 103 if ( x === 1.0 ) { 104 return 0.0; 105 } 106 if ( x >= HUGE ) { 107 return ln( x ) + LN2; 108 } 109 if ( x > 2.0 ) { 110 return ln( (2.0*x) - ( 1.0 / ( x + sqrt( (x*x) - 1.0 ) ) ) ); 111 } 112 // Case: 2 >= x > 1 113 t = x - 1.0; 114 return log1p( t + sqrt( (2.0*t) + (t*t) ) ); 115 } 116 117 118 // EXPORTS // 119 120 module.exports = acosh;