All files higher_newton.js

98.36% Statements 120/122
90.9% Branches 20/22
100% Functions 1/1
98.36% Lines 120/122

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 1231x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 2028x 4798x 4798x 4798x 3333x 3333x 1x 1x 1x 3332x 4798x 1465x 1465x 4798x 2128x 2128x 2128x 4798x 2669x 2669x 2669x 2669x 4797x 4798x 4797x 4797x 4797x 4797x 4798x     4797x 4797x 4797x 4798x 1x 1x 1x 2028x 2028x 1x 1x 2028x 2028x 2028x 1x 1x 1x 1x 1x  
/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
 
'use strict';
 
// MODULES //
 
var logger = require( 'debug' );
var gammainc = require( '@stdlib/math/base/special/gammainc' );
var abs = require( '@stdlib/math/base/special/abs' );
var exp = require( '@stdlib/math/base/special/exp' );
var ln = require( '@stdlib/math/base/special/ln' );
var MAX_FLOAT32 = require( '@stdlib/constants/float32/max' );
 
 
// VARIABLES //
 
var debug = logger( 'gammaincinv:higher_newton' );
 
 
// MAIN //
 
/**
* Implementation of the high order Newton-like method.
*
* @private
* @param {number} x0 - initial value
* @param {number} a - scale parameter
* @param {number} m - indicator
* @param {Probability} p - probability value
* @param {Probability} q - probability value
* @param {number} lgama - logarithm of scale parameter
* @param {number} invfp - one over `fp`
* @param {boolean} pcase - boolean indicating whether p < 0.5
* @returns {number} function value of the inverse
*/
function higherNewton( x0, a, m, p, q, lgama, invfp, pcase ) {
	var dlnr;
	var xini;
	var ck0;
	var ck1;
	var ck2;
	var a2;
	var x2;
	var px;
	var qx;
	var xr;
	var t;
	var n;
	var r;
	var x;
 
	x = x0;
	t = 1;
	n = 1;
	a2 = a * a;
	xini = x0;
	do {
		x = x0;
		x2 = x * x;
		if ( m === 0 ) {
			dlnr = ( ( 1.0-a ) * ln( x ) ) + x + lgama;
			if ( dlnr > ln( MAX_FLOAT32 ) ) {
				debug( 'Warning: overflow problems in one or more steps of the computation. The initial approximation to the root is returned.' );
				return xini;
			}
			r = exp( dlnr );
		} else {
			r = -invfp * x;
		}
		if ( pcase ) {
			// Call: gammainc( x, s[, regularized = true ][, upper = false ] )
			px = gammainc( x, a, true, false );
			ck0 = -r * ( px - p );
		} else {
			// Call: gammainc( x, s[, regularized = true ][, upper = true ] )
			qx = gammainc( x, a, true, true );
			ck0 = r * ( qx - q );
		}
		r = ck0;
		if ( ( p > 1e-120 ) || ( n > 1 ) ) {
			ck1 = 0.5 * ( x - a + 1.0 ) / x;
			ck2 = ( (2*x2) - (4*x*a) + (4*x) + (2*a2) - (3*a) + 1 ) / x2;
			ck2 /= 6.0;
			x0 = x + ( r * ( 1.0 + ( r * ( ck1 + (r*ck2) ) ) ) );
		} else {
			x0 = x + r;
		}
		t = abs( ( x/x0 ) - 1.0 );
		n += 1;
		x = x0;
		if ( x < 0 ) {
			x = xini;
			n = 100;
		}
	} while ( ( ( t > 2e-14 ) && ( n < 35 ) ) );
	if ( ( t > 2e-14 ) || ( n > 99 ) ) {
		debug( 'Warning: the number of iterations in the Newton method reached the upper limit N=35. The last value obtained for the root is given as output.' );
	}
	xr = x || 0;
	return xr;
}
 
 
// EXPORTS //
 
module.exports = higherNewton;