time-to-botec

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

powm1.js (2922B)


      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 and copyright notice are from the [Boost library]{@link http://www.boost.org/doc/libs/1_60_0/boost/math/special_functions/powm1.hpp}. The implementation follows the original, but has been modified for JavaScript.
     22 *
     23 * ```text
     24 * (C) Copyright John Maddock 2006.
     25 *
     26 * Use, modification and distribution are subject to the
     27 * Boost Software License, Version 1.0. (See accompanying file
     28 * LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
     29 * ```
     30 */
     31 
     32 'use strict';
     33 
     34 // MODULES //
     35 
     36 var isnan = require( './../../../../base/assert/is-nan' );
     37 var abs = require( './../../../../base/special/abs' );
     38 var expm1 = require( './../../../../base/special/expm1' );
     39 var ln = require( './../../../../base/special/ln' );
     40 var pow = require( './../../../../base/special/pow' );
     41 var trunc = require( './../../../../base/special/trunc' );
     42 
     43 
     44 // MAIN //
     45 
     46 /**
     47 * Evaluates `bˣ - 1`.
     48 *
     49 * @param {number} b - base
     50 * @param {number} x - exponent
     51 * @returns {number} function value
     52 *
     53 * @example
     54 * var y = powm1( 2.0, 3.0 );
     55 * // returns 7.0
     56 *
     57 * @example
     58 * var y = powm1( 4.0, 0.5 );
     59 * // returns 1.0
     60 *
     61 * @example
     62 * var y = powm1( 0.0, 100.0 );
     63 * // returns -1.0
     64 *
     65 * @example
     66 * var y = powm1( 100.0, 0.0 );
     67 * // returns 0.0
     68 *
     69 * @example
     70 * var y = powm1( 0.0, 0.0 );
     71 * // returns 0.0
     72 *
     73 * @example
     74 * var y = powm1( 3.141592653589793, 5.0 );
     75 * // returns ~305.0197
     76 *
     77 * @example
     78 * var y = powm1( NaN, 3.0 );
     79 * // returns NaN
     80 *
     81 * @example
     82 * var y = powm1( 5.0, NaN );
     83 * // returns NaN
     84 */
     85 function powm1( b, x ) {
     86 	var y;
     87 	if (
     88 		isnan( b ) ||
     89 		isnan( x )
     90 	) {
     91 		return NaN;
     92 	}
     93 	if ( x === 0.0 ) {
     94 		// Any number raised to zero (including 0) is always 1 => b^0 - 1 = 0
     95 		return 0.0;
     96 	}
     97 	if ( b === 0.0 ) {
     98 		// Zero raised to any number (except 0) is always zero => 0^x - 1 = -1
     99 		return -1.0;
    100 	}
    101 	if ( b < 0.0 && x%2.0 === 0 ) {
    102 		// If `x` is even, recognize that `(-b)**x == (b)**x`...
    103 		b = -b;
    104 	}
    105 	if ( b > 0.0 ) {
    106 		if (
    107 			abs( x*(b-1.0) ) < 0.5 ||
    108 			abs( x ) < 0.2
    109 		) {
    110 			// No good/quick approximation for ln(b)*x, so we have to evaluate...
    111 			y = ln( b ) * x;
    112 			if ( y < 0.5 ) {
    113 				return expm1( y );
    114 			}
    115 		}
    116 	} else if ( trunc( x ) !== x ) {
    117 		// Exponentiation would yield a complex result...
    118 		return NaN;
    119 	}
    120 	return pow( b, x ) - 1.0;
    121 }
    122 
    123 
    124 // EXPORTS //
    125 
    126 module.exports = powm1;