compute-gammainc v0.0.0
gammainc
Computes the regularized lower incomplete gamma function:
The function can also be used to evaluate the regularized upper incomplete gamma function, which is defined as follows:
The two functions have the relationship Q(x,a) = 1 - P(x,a).
In addition, this package can be used to evaluate the unregularized gamma functions. The range of above functions is [0,1], which is not the case fo the unregularized versions. The unregularized lower incomplete gamma function is defined as
and the upper unregularized incomplete gamma function is
The relationship between the two functions is γ(a,x) + Γ(a,x) = Γ(a).
Installation
$ npm install compute-gammaincFor use in the browser, use browserify.
Usage
var gammainc = require( 'compute-gammainc' );gammainc( x, a, opts )
Evaluates element-wise the regularized incomplete gamma function. x can be a number, array, typed array or matrix. a has to be either an array or matrix of equal dimensions as x or a single number. The function returns either an array with the same length as the x array, a matrix with the same dimensions as the x matrix or a single number. The domain of the function are the non-negative real numbers for x and the positve real numbers for a. If supplied a value outside the domain, the function returns NaN. For both the regularized and unregularized versions of the incomplete gamma function, in this implementation the first argument is x and the second argument is the scale factor a.
var matrix = require( 'dstructs-matrix' ),
data,
mat,
out,
i;
out = gammainc( 6, 2 );
// returns ~0.9826
out = gammainc( -7, 3 );
// returns NaN
data = [ 0.1, 0.2, 0.3 ];
out = gammainc( data, 1 );
// returns [ ~0.0952, ~0.18127, ~0.25918 ]
data = [ 1, 2, 3 ];
out = gammainc( 2, data );
// returns [ ~0.8647, ~0.5940, ~0.3233 ]
data = [ 1, 2, 3 ];
out = gammainc( data, [ 1, 2, 3 ] )
// returns [ ~0.6321, ~0.5940, ~0.5768 ]
data = new Float32Array( [0.1,0.2,0.3] );
out = gammainc( data, 1 );
// returns Float64Array( [~0.0952, ~0.18127, ~0.25918] )
data = new Int16Array( 6 );
for ( i = 0; i < 6; i++ ) {
data[ i ] = i;
}
mat = matrix( data, [3,2], 'int16' );
/*
[ 0 1
2 3
4 5 ]
*/
out = gammainc( mat, 4 );
/* returns approximately
[ 0 0.0190
0.1429 0.3528
0.5665 0.7350 ]
*/
out = gammainc( mat, mat );
/* returns approximately
. [ 0 0.6321
0.5940 0.5768
0.5665 0.5595 ]
*/The function accepts the following options:
__accessor__: accessor `function` for accessing `array` values.__dtype__: output [`typed array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays) or [`matrix`](https://github.com/dstructs/matrix) data type. Default: `float64`.- copy:
booleanindicating if thefunctionshould return a new data structure. Default:true. - path: deepget/deepset key path.
- sep: deepget/deepset key path separator. Default:
'.'. - tail:
stringindicating whether to evaluate the'lower'or'upper'incomplete gamma function. Default:'lower'. - regularized:
booleanindicating if thefunctionshould compute the regularized or unregularized incomplete gamma functions. Default:true.
By default, the function evaluates the lower regularized incomplete gamma function, P(x,a). To evaluate the upper function instead, i.e. Q(x,a), set the tail option to 'upper'.
var l, u, bool;
l = gammainc( 1, 2)
// returns ~0.2642
u = gammainc( 1, 2, {
'tail': 'upper'
});
// returns ~0.7358
bool = ( l + u === 1 )
// returns trueTo evaluate the unregularized incomplete gamma functions, set the regularized option to false.
var r, u;
r = gammainc( 7, 5 );
// returns 0.8270
u = gammainc( 7, 5, {
'regularized': false
});
// returns 19.8482For object arrays, provide an accessor function for accessing array values.
data = [
{'x':0.1},
{'x':0.2},
{'x':0.5},
{'x':1},
{'x':2},
{'x':3},
{'x':4},
{'x':5}
];
function getValue( d, i ) {
return d.x;
}
var out = gammainc( data, 2, {
'accessor': getValue
});
// returns [ ~0.0951, ~0.1812, ~0.3934, ~0.6321, ~0.8646, ~0.9502, ~0.9816, ~0.9932 ]When evaluating the incomplete gamma function for values between two object arrays, provide an accessor function which accepts 3 arguments.
var data = [
['beep', 0],
['boop', 1],
['bip', 2],
['bap', 3],
['baz', 4]
];
var arr = [
{'x': 0},
{'x': 1},
{'x': 2},
{'x': 3},
{'x': 4}
];
function getValue( d, i, j ) {
if ( j === 0 ) {
return d[ 1 ];
}
return d.x;
}
var out = gammainc( data, arr, {
'accessor': getValue
});
// returns [ 0, ~0.6321, ~0.5940, ~0.5768, ~0.5665 ]Note: j corresponds to the input array index, where j=0 is the index for the first input array and j=1 is the index for the second input array.
To deepset an object array, provide a key path and, optionally, a key path separator.
var data = [
{'x':[0,2]},
{'x':[1,3]},
{'x':[2,5]},
{'x':[3,7]},
{'x':[4,11]}
];
var out = gammainc( data, 7, 'x|1', '|' );
/*
[
{'x':[0,~0.0045]},
{'x':[1,~0.0335]},
{'x':[2,~0.2378]},
{'x':[3,~0.5503},
{'x':[4,~0.9214]}
]
*/
var bool = ( data === out );
// returns trueBy default, when provided a typed array or matrix, the output data structure is float64 in order to preserve precision. To specify a different data type, set the dtype option (see matrix for a list of acceptable data types).
var data, out;
data = new Int8Array( [ 4, 5, 6 ] );
out = gammainc( data, 5, {
'dtype': 'int32',
'regularized': false
});
// returns Int32Array( [8,13,17] )
// Works for plain arrays, as well...
out = gammainc( [ 4, 5, 6 ], 5, {
'dtype': 'uint8',
'regularized': false
});
// returns Uint8Array( [8,13,17] )By default, the function returns a new data structure. To mutate the input data structure, set the copy option to false.
var data,
bool,
mat,
out,
i;
data = [ 0.1, 0.2, 0.3 ];
out = gammainc( data, 1, {
'copy': false
});
// returns [ ~0.0952, ~0.18127, ~0.25918 ]
bool = ( data === out );
// returns true
data = new Int16Array( 6 );
for ( i = 0; i < 6; i++ ) {
data[ i ] = i;
}
mat = matrix( data, [3,2], 'int16' );
/*
[ 0 1
2 3
4 5 ]
*/
out = gammainc( mat, 4, {
'copy': false
});
/* returns approximately
[ 0 0.0190
0.1429 0.3528
0.5665 0.7350 ]
*/
bool = ( mat === out );
// returns trueNotes
If an element is not a numeric value, the returned value is
NaN.var data, out; out = gammainc( null, 1 ); // returns NaN out = gammainc( true, 1 ); // returns NaN out = gammainc( {'a':'b'}, 1 ); // returns NaN out = gammainc( [ true, null, [] ], 1 ); // returns [ NaN, NaN, NaN ] function getValue( d, i ) { return d.x; } data = [ {'x':true}, {'x':[]}, {'x':{}}, {'x':null} ]; out = gammainc( data, 1, { 'accessor': getValue }); // returns [ NaN, NaN, NaN, NaN ] out = gammainc( data, 1, { 'path': 'x' }); /* [ {'x':NaN}, {'x':NaN}, {'x':NaN, {'x':NaN} ] */Be careful when providing a data structure which contains non-numeric elements and specifying an
integeroutput data type, asNaNvalues are cast to0.var out = gammainc( [ true, null, [] ], 1, { 'dtype': 'int8' }); // returns Int8Array( [0,0,0] );When calling the function with a numeric value as the first argument and a
matrixorarrayas the second argument, only thedtypeoption is applicable.// Valid: var out = gammainc( 1, [ 1, 2, 3 ], { 'dtype': 'int8' }); // returns Int8Array( [0,0,0] ) // Not valid: var out = gammainc( 0.5, [ 1, 2, 3 ], { 'copy': false }); // throws an error
Implementation
All of the four functions (regularized and non-regularized, upper and lower) share a common implementation as they are all related to each other (see the Boost C++ library documentation for a good discussion of the functions and implementation strategies).
To evaluate the regularized lower incomplete gamma function, this package uses the following representation of the integral as a power series in its implementation:
This series is evaluated for all inputs x and s unless x > 1.1 and x > s, in which case the function is evaluated using the upper incomplete gamma function as P(x,s) = 1 - Q(x,s). To evaluate the upper incomplete gamma function, Gauss' continued fraction expansion is used:
To compute the continued fractions, the modified Lentz's method is implemented. For a discussion of this method, see section 5.2 of "Numerical Recipes in C (2nd Ed.): The Art of Scientific Computing".
References:
- Lentz, W. J. (1976). Generating bessel functions in mie scattering calculations using continued fractions. Applied Optics, 15(3), 668–671. doi:10.1364/AO.15.000668
- William H. Press, Saul A. Teukolsky, William T. Vetterling, and Brian P. Flannery. 1992. Numerical Recipes in C (2nd Ed.): The Art of Scientific Computing. Cambridge University Press, New York, NY, USA.
Examples
var matrix = require( 'dstructs-matrix' ),
gammainc = require( 'compute-gammainc' );
var data,
mat,
out,
tmp,
i;
// ----
// Plain arrays...
data = new Array( 100 );
for ( i = 0; i < data.length; i++ ) {
data[ i ] = Math.random();
}
out = gammainc( data, 1 );
// Object arrays (accessors)...
function getValue( d ) {
return d.x;
}
for ( i = 0; i < data.length; i++ ) {
data[ i ] = {
'x': data[ i ]
};
}
out = gammainc( data, 1, {
'accessor': getValue
});
// Deep set arrays...
for ( i = 0; i < data.length; i++ ) {
data[ i ] = {
'x': [ i, data[ i ].x ]
};
}
out = gammainc( data, 1, {
'path': 'x/1',
'sep': '/'
});
// Typed arrays...
data = new Float64Array( 100 );
for ( i = 0; i < data.length; i++ ) {
data[ i ] = Math.random();
}
tmp = gammainc( data, 1 );
out = '';
for ( i = 0; i < data.length; i++ ) {
out += tmp[ i ];
if ( i < data.length-1 ) {
out += ',';
}
}
// Matrices...
mat = matrix( data, [10,10], 'float64' );
out = gammainc( mat, 1 );
console.log( 'Matrix: %s\n', out.toString() );
// ----
// Matrices (custom output data type)...
out = gammainc( mat, 1, {
'dtype': 'float32'
});To run the example code from the top-level application directory,
$ node ./examples/index.jsTests
Unit
Unit tests use the Mocha test framework with Chai assertions. To run the tests, execute the following command in the top-level application directory:
$ make testAll new feature development should have corresponding unit tests to validate correct functionality.
Test Coverage
This repository uses Istanbul as its code coverage tool. To generate a test coverage report, execute the following command in the top-level application directory:
$ make test-covIstanbul creates a ./reports/coverage directory. To access an HTML version of the report,
$ make view-covLicense
Copyright
Copyright © 2015. The Compute.io Authors.
5 years ago