inv-chisquare-cdf
Advanced tools
Comparing version 1.0.0 to 1.0.1
{ | ||
"name": "inv-chisquare-cdf", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Inverse chi-squared cumulative distribution function", | ||
@@ -9,4 +9,4 @@ "main": "src/index.js", | ||
"watch": "mocha -w src", | ||
"coverage": "./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- -R spec src", | ||
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js" | ||
"coverage": "nyc npm test", | ||
"coveralls": "nyc report --reporter=text-lcov | coveralls" | ||
}, | ||
@@ -34,10 +34,11 @@ "repository": { | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"coveralls": "^2.12.0", | ||
"eslint": "^3.18.0", | ||
"eslint-config-google": "^0.7.1", | ||
"eslint-plugin-mocha": "^4.9.0", | ||
"istanbul": "^0.4.5", | ||
"mocha": "^3.2.0" | ||
"chai": "^4.2.0", | ||
"coveralls": "^3.0.6", | ||
"eslint": "^6.2.2", | ||
"eslint-config-google": "^0.13.0", | ||
"eslint-plugin-mocha": "^6.1.0", | ||
"mocha": "^6.2.0", | ||
"mocha-lcov-reporter": "^1.3.0", | ||
"nyc": "^14.1.1" | ||
} | ||
} |
@@ -11,35 +11,35 @@ /* eslint-env mocha*/ | ||
describe('index', function() { | ||
describe('Every function on package should be avaliable', function() { | ||
it('invChiSquareCDF should exist', ()=>{ | ||
expect(invChiSquareCDF).to.exist; | ||
}); | ||
describe('Every function on package should be avaliable', function() { | ||
it('invChiSquareCDF should exist', ()=>{ | ||
expect(invChiSquareCDF).to.exist; | ||
}); | ||
it('invChiSquareCDF should be a function', ()=>{ | ||
expect(invChiSquareCDF).to.be.a('function'); | ||
}); | ||
it('invChiSquareCDF should be a function', ()=>{ | ||
expect(invChiSquareCDF).to.be.a('function'); | ||
}); | ||
it('invRegLowGamma should exist', ()=>{ | ||
expect(invRegLowGamma).to.exist; | ||
}); | ||
it('invRegLowGamma should exist', ()=>{ | ||
expect(invRegLowGamma).to.exist; | ||
}); | ||
it('invRegLowGamma should be a function', ()=>{ | ||
expect(invRegLowGamma).to.be.a('function'); | ||
}); | ||
it('invRegLowGamma should be a function', ()=>{ | ||
expect(invRegLowGamma).to.be.a('function'); | ||
}); | ||
it('logGamma should exist', ()=>{ | ||
expect(logGamma).to.exist; | ||
}); | ||
it('logGamma should exist', ()=>{ | ||
expect(logGamma).to.exist; | ||
}); | ||
it('logGamma should be a function', ()=>{ | ||
expect(logGamma).to.be.a('function'); | ||
}); | ||
it('logGamma should be a function', ()=>{ | ||
expect(logGamma).to.be.a('function'); | ||
}); | ||
it('regLowGamma should exist', ()=>{ | ||
expect(regLowGamma).to.exist; | ||
}); | ||
it('regLowGamma should exist', ()=>{ | ||
expect(regLowGamma).to.exist; | ||
}); | ||
it('regLowGamma should be a function', ()=>{ | ||
expect(regLowGamma).to.be.a('function'); | ||
}); | ||
}); | ||
it('regLowGamma should be a function', ()=>{ | ||
expect(regLowGamma).to.be.a('function'); | ||
}); | ||
}); | ||
}); |
const invRegLowGamma = require('./invRegLowGamma.js'); | ||
module.exports = function invChiSquareCDF(probability, degreeOfFreedom) { | ||
if(isNaN(probability)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "probability" is not an number.'); | ||
} else if(isNaN(degreeOfFreedom)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "degreeOfFreedom" is not an number.'); | ||
} else if (probability >= 1 || probability <= 0) { | ||
throw new Error('The number in param "probability" must lie in the interval [0 1].'); | ||
} else if (degreeOfFreedom <= 0) { | ||
throw new Error('The number in param "degreeOfFreedom" must be greater than 0.'); | ||
} | ||
if (isNaN(probability)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "probability" is not an number.'); | ||
} else if (isNaN(degreeOfFreedom)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "degreeOfFreedom" is not an number.'); | ||
} else if (probability >= 1 || probability <= 0) { | ||
throw new Error('The number in param "probability" must lie in the interval [0 1].'); | ||
} else if (degreeOfFreedom <= 0) { | ||
throw new Error('The number in param "degreeOfFreedom" must be greater than 0.'); | ||
} | ||
return 2 * invRegLowGamma(probability, 0.5 * degreeOfFreedom); | ||
return 2 * invRegLowGamma(probability, 0.5 * degreeOfFreedom); | ||
}; |
@@ -7,55 +7,55 @@ /* eslint-env mocha*/ | ||
describe('invChiSquareCDF', function() { | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(invChiSquareCDF).to.exist; | ||
}); | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(invChiSquareCDF).to.exist; | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(invChiSquareCDF).to.be.a('function'); | ||
}); | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(invChiSquareCDF).to.be.a('function'); | ||
}); | ||
}); | ||
describe('Returns the inverse chi-square cdf with "degreeOfFreedom" for the "probability".', function() { | ||
it('should return 0.10258658877510105 for probability=0.05 and degreeOfFreedom=2', ()=>{ | ||
expect(invChiSquareCDF(0.05, 2)).to.equal(0.10258658877510105); | ||
}); | ||
describe('Returns the inverse chi-square cdf with "degreeOfFreedom" for the "probability".', function() { | ||
it('should return 0.10258658877510105 for probability=0.05 and degreeOfFreedom=2', ()=>{ | ||
expect(invChiSquareCDF(0.05, 2)).to.equal(0.10258658877510105); | ||
}); | ||
it('should return 18.307038053275143 for probability=0.95 and degreeOfFreedom=10', ()=>{ | ||
expect(invChiSquareCDF(0.95, 10)).to.equal(18.307038053275143); | ||
}); | ||
}); | ||
it('should return 18.307038053275143 for probability=0.95 and degreeOfFreedom=10', ()=>{ | ||
expect(invChiSquareCDF(0.95, 10)).to.equal(18.307038053275143); | ||
}); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF('Not a number', 6)).to.throw('The value in param "probability" is not an number.'); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF('Not a number', 6)).to.throw('The value in param "probability" is not an number.'); | ||
}); | ||
it('should return a error for a NaN input in the parameter: degreeOfFreedom', ()=>{ | ||
expect(()=>invChiSquareCDF(6, 'Not a number')).to.throw('The value in param "degreeOfFreedom" is not an number.'); | ||
}); | ||
it('should return a error for a NaN input in the parameter: degreeOfFreedom', ()=>{ | ||
expect(()=>invChiSquareCDF(6, 'Not a number')).to.throw('The value in param "degreeOfFreedom" is not an number.'); | ||
}); | ||
it('should return a error for the number 0 in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(0, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for the number 0 in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(0, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for a negative number in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(-1, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for a negative number in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(-1, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for the number 1 in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(1, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for the number 1 in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(1, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for a number greater than 1 in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(666, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for a number greater than 1 in the parameter: probability', ()=>{ | ||
expect(()=>invChiSquareCDF(666, 2)).to.throw('The number in param "probability" must lie in the interval [0 1].'); | ||
}); | ||
it('should return a error for the number 0 in the parameter: degreeOfFreedom', ()=>{ | ||
expect(()=>invChiSquareCDF(0.05, 0)).to.throw('The number in param "degreeOfFreedom" must be greater than 0.'); | ||
}); | ||
it('should return a error for the number 0 in the parameter: degreeOfFreedom', ()=>{ | ||
expect(()=>invChiSquareCDF(0.05, 0)).to.throw('The number in param "degreeOfFreedom" must be greater than 0.'); | ||
}); | ||
it('should return a error for a negative number in the parameter: degreeOfFreedom', ()=>{ | ||
expect(()=>invChiSquareCDF(0.05, -2)).to.throw('The number in param "degreeOfFreedom" must be greater than 0.'); | ||
}); | ||
}); | ||
it('should return a error for a negative number in the parameter: degreeOfFreedom', ()=>{ | ||
expect(()=>invChiSquareCDF(0.05, -2)).to.throw('The number in param "degreeOfFreedom" must be greater than 0.'); | ||
}); | ||
}); | ||
}); |
@@ -5,60 +5,65 @@ const logGamma = require('./logGamma.js'); | ||
module.exports = function invRegLowGamma(p, a) { | ||
if(isNaN(p)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "p" is not an number.'); | ||
} else if(isNaN(a)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "a" is not an number.'); | ||
} else if (p >= 1) { | ||
return Math.max(100, a + 100 * Math.sqrt(a)); | ||
} else if (p <= 0) { | ||
return 0; | ||
} | ||
if (isNaN(p)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "p" is not an number.'); | ||
} else if (isNaN(a)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param "a" is not an number.'); | ||
} else if (p >= 1) { | ||
return Math.max(100, a + 100 * Math.sqrt(a)); | ||
} else if (p <= 0) { | ||
return 0; | ||
} | ||
let a1 = a - 1; | ||
let EPS = 1e-8; | ||
let gln = logGamma(a); | ||
let inverseRegLowGamma; | ||
let err; | ||
let t; | ||
let u; | ||
let pp; | ||
let lna1; | ||
let afac; | ||
const a1 = a - 1; | ||
const EPS = 1e-8; | ||
const gln = logGamma(a); | ||
let inverseRegLowGamma; | ||
let err; | ||
let t; | ||
let u; | ||
let pp; | ||
let lna1; | ||
let afac; | ||
if (a > 1) { | ||
lna1 = Math.log(a1); | ||
afac = Math.exp(a1 * (lna1 - 1) - gln); | ||
pp = (p < 0.5) ? p : 1 - p; | ||
t = Math.sqrt(-2 * Math.log(pp)); | ||
inverseRegLowGamma = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t; | ||
if (p < 0.5) | ||
inverseRegLowGamma = -inverseRegLowGamma; | ||
inverseRegLowGamma = Math.max(1e-3, | ||
a * Math.pow(1 - 1 / (9 * a) - inverseRegLowGamma / (3 * Math.sqrt(a)), 3)); | ||
if (a > 1) { | ||
lna1 = Math.log(a1); | ||
afac = Math.exp(a1 * (lna1 - 1) - gln); | ||
pp = (p < 0.5) ? p : 1 - p; | ||
t = Math.sqrt(-2 * Math.log(pp)); | ||
inverseRegLowGamma = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t; | ||
if (p < 0.5) { | ||
inverseRegLowGamma = -inverseRegLowGamma; | ||
} | ||
inverseRegLowGamma = Math.max(1e-3, a * Math.pow(1 - 1 / (9 * a) - inverseRegLowGamma / (3 * Math.sqrt(a)), 3)); | ||
} else { | ||
t = 1 - a * (0.253 + a * 0.12); | ||
if (p < t) { | ||
inverseRegLowGamma = Math.pow(p / t, 1 / a); | ||
} else { | ||
t = 1 - a * (0.253 + a * 0.12); | ||
if (p < t) | ||
inverseRegLowGamma = Math.pow(p / t, 1 / a); | ||
else | ||
inverseRegLowGamma = 1 - Math.log(1 - (p - t) / (1 - t)); | ||
inverseRegLowGamma = 1 - Math.log(1 - (p - t) / (1 - t)); | ||
} | ||
} | ||
for(let j = 0; j < 12; j++) { | ||
if (inverseRegLowGamma <= 0) | ||
return 0; | ||
err = regLowGamma(a, inverseRegLowGamma) - p; | ||
if (a > 1) | ||
t = afac * Math.exp(-(inverseRegLowGamma - a1) + a1 * (Math.log(inverseRegLowGamma) - lna1)); | ||
else | ||
t = Math.exp(-inverseRegLowGamma + a1 * Math.log(inverseRegLowGamma) - gln); | ||
u = err / t; | ||
inverseRegLowGamma -= (t = u / (1 - 0.5 * Math.min(1, u * ((a - 1) / inverseRegLowGamma - 1)))); | ||
if (inverseRegLowGamma <= 0) | ||
inverseRegLowGamma = 0.5 * (inverseRegLowGamma + t); | ||
if (Math.abs(t) < EPS * inverseRegLowGamma) | ||
break; | ||
for (let j = 0; j < 12; j++) { | ||
if (inverseRegLowGamma <= 0) { | ||
return 0; | ||
} | ||
err = regLowGamma(a, inverseRegLowGamma) - p; | ||
if (a > 1) { | ||
t = afac * Math.exp(-(inverseRegLowGamma - a1) + a1 * (Math.log(inverseRegLowGamma) - lna1)); | ||
} else { | ||
t = Math.exp(-inverseRegLowGamma + a1 * Math.log(inverseRegLowGamma) - gln); | ||
} | ||
u = err / t; | ||
inverseRegLowGamma -= (t = u / (1 - 0.5 * Math.min(1, u * ((a - 1) / inverseRegLowGamma - 1)))); | ||
if (inverseRegLowGamma <= 0) { | ||
inverseRegLowGamma = 0.5 * (inverseRegLowGamma + t); | ||
} | ||
if (Math.abs(t) < EPS * inverseRegLowGamma) { | ||
break; | ||
} | ||
} | ||
return inverseRegLowGamma; | ||
return inverseRegLowGamma; | ||
}; |
@@ -7,47 +7,47 @@ /* eslint-env mocha*/ | ||
describe('invRegLowGamma', function() { | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(invRegLowGamma).to.exist; | ||
}); | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(invRegLowGamma).to.exist; | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(invRegLowGamma).to.be.a('function'); | ||
}); | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(invRegLowGamma).to.be.a('function'); | ||
}); | ||
}); | ||
describe('Returns the inverse of the lower regularized incomplete Gamma function evaluated at (p,a)', function() { | ||
it('should return 228.60679774997897 for p=5 and a=5', ()=>{ | ||
expect(invRegLowGamma(5, 5)).to.equal(228.60679774997897); | ||
}); | ||
describe('Returns the inverse of the lower regularized incomplete Gamma function evaluated at (p,a)', function() { | ||
it('should return 228.60679774997897 for p=5 and a=5', ()=>{ | ||
expect(invRegLowGamma(5, 5)).to.equal(228.60679774997897); | ||
}); | ||
it('should return 6.475606702314761 for p=0.666 and a=5.75', ()=>{ | ||
expect(invRegLowGamma(0.666, 5.75)).to.equal(6.475606702314761); | ||
}); | ||
it('should return 5.420322349497806 for p=0.5 and a=5.75', ()=>{ | ||
expect(invRegLowGamma(.5, 5.75)).to.equal(5.420322349497806); | ||
}); | ||
it('should return 100 for p=5 and a=0', ()=>{ | ||
expect(invRegLowGamma(5, 0)).to.equal(100); | ||
}); | ||
it('should return 100 for p=5 and a=0', ()=>{ | ||
expect(invRegLowGamma(5, 0)).to.equal(100); | ||
}); | ||
it('should return 1.678346990016661 for p=0.5 and a=2', ()=>{ | ||
expect(invRegLowGamma(0.5, 2)).to.equal(1.678346990016661); | ||
}); | ||
it('should return 1.678346990016661 for p=0.5 and a=2', ()=>{ | ||
expect(invRegLowGamma(0.5, 2)).to.equal(1.678346990016661); | ||
}); | ||
it('should return 0.3759413598815398 for p=0.5 and a=0.666', ()=>{ | ||
expect(invRegLowGamma(0.5, 0.666)).to.equal(0.3759413598815398); | ||
}); | ||
it('should return 0.3759413598815398 for p=0.5 and a=0.666', ()=>{ | ||
expect(invRegLowGamma(0.5, 0.666)).to.equal(0.3759413598815398); | ||
}); | ||
it('should return 0 for p=-1(any negative number) and a=2', ()=>{ | ||
expect(invRegLowGamma(-1, 2)).to.equal(0); | ||
}); | ||
}); | ||
it('should return 0 for p=-1(any negative number) and a=2', ()=>{ | ||
expect(invRegLowGamma(-1, 2)).to.equal(0); | ||
}); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input in the parameter: p', ()=>{ | ||
expect(()=>invRegLowGamma('Not a number', 6)).to.throw('The value in param "p" is not an number.'); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input in the parameter: p', ()=>{ | ||
expect(()=>invRegLowGamma('Not a number', 6)).to.throw('The value in param "p" is not an number.'); | ||
}); | ||
it('should return a error for a NaN input in the parameter: a', ()=>{ | ||
expect(()=>invRegLowGamma(6, 'Not a number')).to.throw('The value in param "a" is not an number.'); | ||
}); | ||
}); | ||
it('should return a error for a NaN input in the parameter: a', ()=>{ | ||
expect(()=>invRegLowGamma(6, 'Not a number')).to.throw('The value in param "a" is not an number.'); | ||
}); | ||
}); | ||
}); |
module.exports = function logGamma(x) { | ||
if(x===1 || x===2) { | ||
return 0; | ||
} else if(x===0) { | ||
return Infinity; | ||
} else if(isNaN(x)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error(`The value is not a number.`); | ||
} else if(x<0) { | ||
throw new Error(`The value is a negative number.`); | ||
} | ||
if (x===1 || x===2) { | ||
return 0; | ||
} else if (x===0) { | ||
return Infinity; | ||
} else if (isNaN(x)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error(`The value is not a number.`); | ||
} else if (x<0) { | ||
throw new Error(`The value is a negative number.`); | ||
} | ||
// Lanczos approximation | ||
const cof = [ | ||
// Lanczos approximation | ||
const cof = [ | ||
76.18009172947146, | ||
@@ -21,16 +21,16 @@ -86.50532032941677, | ||
-0.5395239384953e-5, | ||
]; | ||
let ser = 1.000000000190015; | ||
]; | ||
let ser = 1.000000000190015; | ||
let xx; | ||
let y; | ||
let tmp; | ||
tmp = (y = xx = x) + 5.5; | ||
tmp -= (xx + 0.5) * Math.log(tmp); | ||
let xx; | ||
let y; | ||
let tmp; | ||
tmp = (y = xx = x) + 5.5; | ||
tmp -= (xx + 0.5) * Math.log(tmp); | ||
cof.map((approximation)=>{ | ||
ser += approximation / ++y; | ||
}); | ||
cof.map((approximation)=>{ | ||
ser += approximation / ++y; | ||
}); | ||
return Math.log(2.5066282746310005 * ser / xx) - tmp; | ||
return Math.log(2.5066282746310005 * ser / xx) - tmp; | ||
}; |
@@ -8,47 +8,47 @@ /* eslint no-undef: "error"*/ | ||
describe('logGamma', function() { | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(logGamma).to.exist; | ||
}); | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(logGamma).to.exist; | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(logGamma).to.be.a('function'); | ||
}); | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(logGamma).to.be.a('function'); | ||
}); | ||
}); | ||
describe('the function returns the logarithm of the gamma function', function() { | ||
it('should return 1.20097360234 for the input 3.5', ()=>{ | ||
expect(logGamma(3.5)).to.equal(1.2009736023470738); | ||
}); | ||
describe('the function returns the logarithm of the gamma function', function() { | ||
it('should return 1.20097360234 for the input 3.5', ()=>{ | ||
expect(logGamma(3.5)).to.equal(1.2009736023470738); | ||
}); | ||
it('should return 9.210282658633963 for the input 0.0001', ()=>{ | ||
expect(logGamma(0.0001)).to.equal(9.210282658633963); | ||
}); | ||
it('should return 9.210282658633963 for the input 0.0001', ()=>{ | ||
expect(logGamma(0.0001)).to.equal(9.210282658633963); | ||
}); | ||
it('should return 3.1780538303479453 for the input 5', ()=>{ | ||
expect(logGamma(5)).to.equal(3.1780538303479453); | ||
}); | ||
it('should return 3.1780538303479453 for the input 5', ()=>{ | ||
expect(logGamma(5)).to.equal(3.1780538303479453); | ||
}); | ||
it('should return 0 for the input 1', ()=>{ | ||
expect(logGamma(1)).to.equal(0); | ||
}); | ||
it('should return 0 for the input 1', ()=>{ | ||
expect(logGamma(1)).to.equal(0); | ||
}); | ||
it('should return 0 for the input 2', ()=>{ | ||
expect(logGamma(2)).to.equal(0); | ||
}); | ||
it('should return 0 for the input 2', ()=>{ | ||
expect(logGamma(2)).to.equal(0); | ||
}); | ||
it('should return +Infinity for the input 0', ()=>{ | ||
expect(logGamma(0)).to.equal(Infinity); | ||
}); | ||
}); | ||
it('should return +Infinity for the input 0', ()=>{ | ||
expect(logGamma(0)).to.equal(Infinity); | ||
}); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input', ()=>{ | ||
expect(()=>logGamma('Not a number')).to.throw('The value is not a number.'); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input', ()=>{ | ||
expect(()=>logGamma('Not a number')).to.throw('The value is not a number.'); | ||
}); | ||
it('should return a error for a negative number', ()=>{ | ||
expect(()=>logGamma(-666)).to.throw('The value is a negative number.'); | ||
}); | ||
}); | ||
it('should return a error for a negative number', ()=>{ | ||
expect(()=>logGamma(-666)).to.throw('The value is a negative number.'); | ||
}); | ||
}); | ||
}); |
const logGamma = require('./logGamma.js'); | ||
module.exports = function regLowGamma(a, x) { | ||
if(isNaN(a)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param a is not a number.'); | ||
} else if(isNaN(x)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param x is not a number.'); | ||
} else if(a <= 0) { | ||
throw new Error('The number in param a is equal or less tham 0.'); | ||
} else if(x<0) { | ||
throw new Error('The number in param x is a negative number.'); | ||
} | ||
if (isNaN(a)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param a is not a number.'); | ||
} else if (isNaN(x)) { | ||
// TODO fix: booleans and strings like '123' will not fall here. | ||
throw new Error('The value in param x is not a number.'); | ||
} else if (a <= 0) { | ||
throw new Error('The number in param a is equal or less tham 0.'); | ||
} else if (x<0) { | ||
throw new Error('The number in param x is a negative number.'); | ||
} | ||
const logGammaOfA = logGamma(a); | ||
let b = x + 1 - a; | ||
let c = 1 / 1.0e-30; | ||
let d = 1 / b; | ||
let h = d; | ||
let i = 1; | ||
const maxOfIterationsForA = -~(Math.log((a >= 1) ? a : 1 / a) * 8.5 + a * 0.4 + 17); | ||
const logGammaOfA = logGamma(a); | ||
let b = x + 1 - a; | ||
let c = 1 / 1.0e-30; | ||
let d = 1 / b; | ||
let h = d; | ||
let i = 1; | ||
const maxOfIterationsForA = -~(Math.log((a >= 1) ? a : 1 / a) * 8.5 + a * 0.4 + 17); | ||
if (x < a + 1) { | ||
let sum = 1 / a; | ||
let del = sum; | ||
for (let ap = a; i <= maxOfIterationsForA; i++) { | ||
sum += del *= x / ++ap; | ||
} | ||
return (sum * Math.exp(-x + a * Math.log(x) - (logGammaOfA))); | ||
if (x < a + 1) { | ||
let sum = 1 / a; | ||
let del = sum; | ||
for (let ap = a; i <= maxOfIterationsForA; i++) { | ||
sum += del *= x / ++ap; | ||
} | ||
return (sum * Math.exp(-x + a * Math.log(x) - (logGammaOfA))); | ||
} | ||
let an; | ||
for (; i <= maxOfIterationsForA; i++) { | ||
an = -i * (i - a); | ||
b += 2; | ||
d = an * d + b; | ||
c = b + an / c; | ||
d = 1 / d; | ||
h *= d * c; | ||
} | ||
let an; | ||
for (; i <= maxOfIterationsForA; i++) { | ||
an = -i * (i - a); | ||
b += 2; | ||
d = an * d + b; | ||
c = b + an / c; | ||
d = 1 / d; | ||
h *= d * c; | ||
} | ||
return (1 - h * Math.exp(-x + a * Math.log(x) - (logGammaOfA))); | ||
return (1 - h * Math.exp(-x + a * Math.log(x) - (logGammaOfA))); | ||
}; |
@@ -7,47 +7,47 @@ /* eslint-env mocha*/ | ||
describe('regLowGamma', function() { | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(regLowGamma).to.exist; | ||
}); | ||
describe('smoke tests', function() { | ||
it('should exist', ()=>{ | ||
expect(regLowGamma).to.exist; | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(regLowGamma).to.be.a('function'); | ||
}); | ||
}); | ||
it('should be a function', ()=>{ | ||
expect(regLowGamma).to.be.a('function'); | ||
}); | ||
}); | ||
describe('the function returns the lower regularized incomplete gamma function evaluated at (a,x)', function() { | ||
it('should return 0.5595067149347875 for a=5 and x=5', ()=>{ | ||
expect(regLowGamma(5, 5)).to.equal(0.5595067149347875); | ||
}); | ||
describe('the function returns the lower regularized incomplete gamma function evaluated at (a,x)', function() { | ||
it('should return 0.5595067149347875 for a=5 and x=5', ()=>{ | ||
expect(regLowGamma(5, 5)).to.equal(0.5595067149347875); | ||
}); | ||
it('should return 0.9987538088133204 for a=0.666 and x=5.75', ()=>{ | ||
expect(regLowGamma(0.666, 5.75)).to.equal(0.9987538088133204); | ||
}); | ||
it('should return 0.9987538088133204 for a=0.666 and x=5.75', ()=>{ | ||
expect(regLowGamma(0.666, 5.75)).to.equal(0.9987538088133204); | ||
}); | ||
it('should return 0 for a=5 and x=0', ()=>{ | ||
expect(regLowGamma(5, 0)).to.equal(0); | ||
}); | ||
}); | ||
it('should return 0 for a=5 and x=0', ()=>{ | ||
expect(regLowGamma(5, 0)).to.equal(0); | ||
}); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input in the parameter: a', ()=>{ | ||
expect(()=>regLowGamma('Not a number', 6)).to.throw('The value in param a is not a number.'); | ||
}); | ||
describe('error tests', function() { | ||
it('should return a error for a NaN input in the parameter: a', ()=>{ | ||
expect(()=>regLowGamma('Not a number', 6)).to.throw('The value in param a is not a number.'); | ||
}); | ||
it('should return a error for a NaN input in the parameter: x', ()=>{ | ||
expect(()=>regLowGamma(6, 'Not a number')).to.throw('The value in param x is not a number.'); | ||
}); | ||
it('should return a error for a NaN input in the parameter: x', ()=>{ | ||
expect(()=>regLowGamma(6, 'Not a number')).to.throw('The value in param x is not a number.'); | ||
}); | ||
it('should return a error for the input 0 in the parameter: a', ()=>{ | ||
expect(()=>regLowGamma(0, 2)).to.throw('The number in param a is equal or less tham 0.'); | ||
}); | ||
it('should return a error for the input 0 in the parameter: a', ()=>{ | ||
expect(()=>regLowGamma(0, 2)).to.throw('The number in param a is equal or less tham 0.'); | ||
}); | ||
it('should return a error for a negative number in the parameter: a', ()=>{ | ||
expect(()=>regLowGamma(-666, 2)).to.throw('The number in param a is equal or less tham 0.'); | ||
}); | ||
it('should return a error for a negative number in the parameter: a', ()=>{ | ||
expect(()=>regLowGamma(-666, 2)).to.throw('The number in param a is equal or less tham 0.'); | ||
}); | ||
it('should return a error for a negative number in the parameter: x', ()=>{ | ||
expect(()=>regLowGamma(2, -666)).to.throw('The number in param x is a negative number.'); | ||
}); | ||
}); | ||
it('should return a error for a negative number in the parameter: x', ()=>{ | ||
expect(()=>regLowGamma(2, -666)).to.throw('The number in param x is a negative number.'); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
376
17968
8
15