time-to-botec

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

asinh.js (3205B)


      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/s_asinh.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 isinfinite = require( './../../../../base/assert/is-infinite' );
     38 var isnan = require( './../../../../base/assert/is-nan' );
     39 var log1p = require( './../../../../base/special/log1p' );
     40 var sqrt = require( './../../../../base/special/sqrt' );
     41 var LN2 = require( '@stdlib/constants/float64/ln-two' );
     42 var ln = require( './../../../../base/special/ln' );
     43 
     44 
     45 // VARIABLES //
     46 
     47 var NEAR_ZERO = 1.0 / (1 << 28); // 2**-28
     48 var HUGE = 1 << 28; // 2**28
     49 
     50 
     51 // MAIN //
     52 
     53 /**
     54 * Computes the hyperbolic arcsine of a number.
     55 *
     56 * ## Method
     57 *
     58 * Based on
     59 *
     60 * ```tex
     61 * \operatorname{asinh}(x) = \operatorname{sgn}(x) \cdot \log \left( |x| + \sqrt{x^2 + 1} \right)
     62 * ```
     63 *
     64 * we have
     65 *
     66 * ```tex
     67 * \operatorname{asinh}(x) = \begin{cases}
     68 * x  & \text{ if }  1+x^2 =1, \\
     69 * \operatorname{sgn}(x) \cdot \left( \log(x) + \tfrac{\ln}{2} \right) & \text{ if large } |x| \\
     70 * \operatorname{sgn}(x) \cdot \log\left( 2 |x| + 1 / ( |x|+ \sqrt{x^2+1} ) \right) & \text{ if } |x| > 2 \\
     71 * \operatorname{sgn}(x) \cdot \operatorname{log1p}\left( |x| + \tfrac{x^2}{1 + \sqrt{1+x^2}} \right) & \text{otherwise}
     72 * \end{cases}
     73 * ```
     74 *
     75 * @param {number} x - input value
     76 * @returns {number} hyperbolic arcsine (in radians)
     77 *
     78 * @example
     79 * var v = asinh( 0.0 );
     80 * // returns 0.0
     81 *
     82 * @example
     83 * var v = asinh( 2.0 );
     84 * // returns ~1.444
     85 *
     86 * @example
     87 * var v = asinh( -2.0 );
     88 * // returns ~-1.444
     89 *
     90 * @example
     91 * var v = asinh( NaN );
     92 * // returns NaN
     93 */
     94 function asinh( x ) {
     95 	var sgn;
     96 	var xx;
     97 	var t;
     98 	if ( isnan( x ) || isinfinite( x ) ) {
     99 		return x;
    100 	}
    101 	if ( x < 0.0 ) {
    102 		x = -x;
    103 		sgn = true;
    104 	}
    105 	// Case: |x| < 2**-28
    106 	if ( x < NEAR_ZERO ) {
    107 		t = x;
    108 	}
    109 	// Case: |x| > 2**28
    110 	else if ( x > HUGE ) {
    111 		t = ln( x ) + LN2;
    112 	}
    113 	// Case: 2**28 > |x| > 2.0
    114 	else if ( x > 2.0 ) {
    115 		t = ln( (2.0*x) + ( 1.0 / (sqrt( (x*x) + 1.0 ) + x) ) );
    116 	}
    117 	// Case: 2.0 > |x| > 2**-28
    118 	else {
    119 		xx = x * x;
    120 		t = log1p( x + ( xx/(1.0 + sqrt(1.0 + xx)) ) );
    121 	}
    122 	return ( sgn ) ? -t : t;
    123 }
    124 
    125 
    126 // EXPORTS //
    127 
    128 module.exports = asinh;