diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/Makefile b/lib/node_modules/@stdlib/math/base/special/betaincinv/Makefile
new file mode 100644
index 000000000000..7e27aefbd6b2
--- /dev/null
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/Makefile
@@ -0,0 +1,33 @@
+# Makefile for betaincinv module
+
+# Default target
+all: build
+
+# Build the native module
+build:
+ node-gyp configure
+ node-gyp build
+
+# Run tests
+test:
+ node test/test.js
+
+# Run tests with coverage
+test-cov:
+ nyc node test/test.js
+
+# Run examples
+examples:
+ node examples/index.js
+
+# Run benchmarks
+benchmark:
+ node benchmark/index.js
+
+# Clean build artifacts
+clean:
+ node-gyp clean
+ rm -rf build/
+ rm -rf coverage/
+
+.PHONY: all build test test-cov examples benchmark clean
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/README.md b/lib/node_modules/@stdlib/math/base/special/betaincinv/README.md
index f30a71e53471..8ee3ac492eca 100644
--- a/lib/node_modules/@stdlib/math/base/special/betaincinv/README.md
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/README.md
@@ -1,8 +1,7 @@
# betaincinv
-> Inverse of the [incomplete beta function][incomplete-beta-function].
+> Inverse incomplete beta function.
+The [inverse incomplete beta function][inverse-incomplete-beta] is the inverse of the [incomplete beta function][incomplete-beta]. It is used in various statistical applications, including hypothesis testing and confidence interval calculations.
+
@@ -36,69 +36,35 @@ limitations under the License.
var betaincinv = require( '@stdlib/math/base/special/betaincinv' );
```
-#### betaincinv( p, a, b\[, upper] )
+#### betaincinv( p, a, b )
-Inverts the regularized [incomplete beta function][incomplete-beta-function]. Contrary to the more commonly used definition, in this implementation the first parameter is the probability `p` and the second and third parameter are `a` and `b`. By default, the function inverts the _lower_ regularized [incomplete beta function][incomplete-beta-function]. To invert the _upper_ function instead, set the `upper` argument to `true`.
+Evaluates the inverse of the incomplete beta function:
```javascript
-var y = betaincinv( 0.2, 3.0, 3.0 );
+var y = betaincinv( 0.5, 1.0, 1.0 );
+// returns 0.5
+
+y = betaincinv( 0.2, 3.0, 3.0 );
// returns ~0.327
y = betaincinv( 0.4, 3.0, 3.0 );
// returns ~0.446
-y = betaincinv( 0.4, 3.0, 3.0, true );
-// returns ~0.554
-
y = betaincinv( 0.4, 1.0, 6.0 );
// returns ~0.082
-
-y = betaincinv( 0.8, 1.0, 6.0 );
-// returns ~0.235
```
-If provided `NaN` as any argument, the function returns `NaN`.
-
-```javascript
-var y = betaincinv( NaN, 1.0, 1.0 );
-// returns NaN
-
-y = betaincinv( 0.5, NaN, 1.0 );
-// returns NaN
-
-y = betaincinv( 0.5, 1.0, NaN );
-// returns NaN
-```
-
-If provided a value outside `[0,1]` for `p`, the function returns `NaN`.
-
-```javascript
-var y = betaincinv( 1.2, 1.0, 1.0 );
-// returns NaN
-
-y = betaincinv( -0.5, 1.0, 1.0 );
-// returns NaN
-```
-
-If provided a nonpositive `a`, the function returns `NaN`.
-
-```javascript
-var y = betaincinv( 0.5, -2.0, 2.0 );
-// returns NaN
-
-y = betaincinv( 0.5, 0.0, 2.0 );
-// returns NaN
-```
+The function accepts the following parameters:
-If provided a nonpositive `b`, the function returns `NaN`.
+- **p**: probability value (input value for the incomplete beta function).
+- **a**: first shape parameter (must be positive).
+- **b**: second shape parameter (must be positive).
-```javascript
-var y = betaincinv( 0.5, 2.0, -2.0 );
-// returns NaN
+The function returns `NaN` if any of the following conditions are met:
-y = betaincinv( 0.5, 2.0, 0.0 );
-// returns NaN
-```
+- `p` is outside the interval `[0,1]`
+- `a` is not positive
+- `b` is not positive
@@ -108,58 +74,34 @@ y = betaincinv( 0.5, 2.0, 0.0 );
## Examples
-
-
```javascript
-var uniform = require( '@stdlib/random/array/uniform' );
-var logEachMap = require( '@stdlib/console/log-each-map' );
var betaincinv = require( '@stdlib/math/base/special/betaincinv' );
-var opts = {
- 'dtype': 'float64'
-};
-var p = uniform( 100, 0.0, 1.0, opts );
-var a = uniform( 100, 0.0, 10.0, opts );
-var b = uniform( 100, 0.0, 10.0, opts );
-
-logEachMap( 'p: %0.4f, \t a: %0.4f, \t b: %0.4f, \t f(p,a,b): %0.4f', p, a, b, betaincinv );
-```
-
-
-
-
-
-
-
-
-
-
-
+
-[incomplete-beta-function]: https://en.wikipedia.org/wiki/Incomplete_beta_function
-
-
-
-[@stdlib/math/base/special/beta]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/math/base/special/beta
-
-[@stdlib/math/base/special/betainc]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/math/base/special/betainc
-
-[@stdlib/math/base/special/betaln]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/math/base/special/betaln
-
-
+[incomplete-beta]: https://en.wikipedia.org/wiki/Beta_function#Incomplete_beta_function
+[inverse-incomplete-beta]: https://en.wikipedia.org/wiki/Beta_function#Incomplete_beta_function
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/benchmark/index.js b/lib/node_modules/@stdlib/math/base/special/betaincinv/benchmark/index.js
new file mode 100644
index 000000000000..ba89d382b211
--- /dev/null
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/benchmark/index.js
@@ -0,0 +1,62 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2024 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';
+
+var randu = require( '@stdlib/random/base/randu' );
+var betaincinv = require( './../lib' );
+
+var p;
+var a;
+var b;
+var i;
+
+console.log( 'Running benchmarks...\n' );
+
+// Benchmark 1: Basic usage
+console.log( 'Benchmark 1: Basic usage' );
+console.time( 'betaincinv' );
+for ( i = 0; i < 1e6; i++ ) {
+ p = randu();
+ a = randu() * 10.0 + 1.0;
+ b = randu() * 10.0 + 1.0;
+ betaincinv( p, a, b );
+}
+console.timeEnd( 'betaincinv' );
+
+// Benchmark 2: Edge cases
+console.log( '\nBenchmark 2: Edge cases' );
+console.time( 'betaincinv (edge cases)' );
+for ( i = 0; i < 1e6; i++ ) {
+ p = (i % 2 === 0) ? 0.0 : 1.0;
+ a = 1.0;
+ b = 1.0;
+ betaincinv( p, a, b );
+}
+console.timeEnd( 'betaincinv (edge cases)' );
+
+// Benchmark 3: Invalid inputs
+console.log( '\nBenchmark 3: Invalid inputs' );
+console.time( 'betaincinv (invalid inputs)' );
+for ( i = 0; i < 1e6; i++ ) {
+ p = (i % 2 === 0) ? -0.5 : 1.5;
+ a = 1.0;
+ b = 1.0;
+ betaincinv( p, a, b );
+}
+console.timeEnd( 'betaincinv (invalid inputs)' );
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/binding.gyp b/lib/node_modules/@stdlib/math/base/special/betaincinv/binding.gyp
new file mode 100644
index 000000000000..c9adee35737a
--- /dev/null
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/binding.gyp
@@ -0,0 +1,42 @@
+{
+ "targets": [
+ {
+ "target_name": "betaincinv",
+ "sources": [
+ "src/betaincinv.c"
+ ],
+ "include_dirs": [
+ "
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Computes the inverse of the incomplete beta function.
+*
+* @param p probability value
+* @param a first shape parameter
+* @param b second shape parameter
+* @return inverse incomplete beta function value
+*/
+double stdlib_betaincinv(double p, double a, double b);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !STDLIB_MATH_BASE_SPECIAL_BETAINCINV_H
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/lib/index.js b/lib/node_modules/@stdlib/math/base/special/betaincinv/lib/index.js
index a4aa81898ad9..5db9258338ee 100644
--- a/lib/node_modules/@stdlib/math/base/special/betaincinv/lib/index.js
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/lib/index.js
@@ -1,7 +1,7 @@
/**
* @license Apache-2.0
*
-* Copyright (c) 2018 The Stdlib Authors.
+* Copyright (c) 2024 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.
@@ -44,9 +44,53 @@
// MODULES //
-var main = require( './main.js' );
+var addon = require( './native.node' );
+var isnan = require( '@stdlib/math/base/assert/is-nan' );
+
+
+// MAIN //
+
+/**
+* Evaluates the inverse of the incomplete beta function.
+*
+* @param {number} p - probability value
+* @param {number} a - first shape parameter
+* @param {number} b - second shape parameter
+* @returns {number} function value
+*
+* @example
+* var y = betaincinv( 0.5, 1.0, 1.0 );
+* // returns 0.5
+*
+* @example
+* var y = betaincinv( 0.2, 3.0, 3.0 );
+* // returns ~0.327
+*
+* @example
+* var y = betaincinv( 0.4, 3.0, 3.0 );
+* // returns ~0.446
+*
+* @example
+* var y = betaincinv( 0.4, 1.0, 6.0 );
+* // returns ~0.082
+*/
+function betaincinv( p, a, b ) {
+ if ( isnan( p ) || isnan( a ) || isnan( b ) ) {
+ return NaN;
+ }
+ if ( p < 0.0 || p > 1.0 ) {
+ return NaN;
+ }
+ if ( a <= 0.0 ) {
+ return NaN;
+ }
+ if ( b <= 0.0 ) {
+ return NaN;
+ }
+ return addon.betaincinv( p, a, b );
+}
// EXPORTS //
-module.exports = main;
+module.exports = betaincinv;
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/lib/native.js b/lib/node_modules/@stdlib/math/base/special/betaincinv/lib/native.js
new file mode 100644
index 000000000000..700d9286e676
--- /dev/null
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/lib/native.js
@@ -0,0 +1,28 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2024 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 addon = require( './native.node' );
+
+
+// EXPORTS //
+
+module.exports = addon;
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/package.json b/lib/node_modules/@stdlib/math/base/special/betaincinv/package.json
index ab0d6ccd9bd5..f912a10d10b9 100644
--- a/lib/node_modules/@stdlib/math/base/special/betaincinv/package.json
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/package.json
@@ -1,8 +1,8 @@
{
"name": "@stdlib/math/base/special/betaincinv",
- "version": "0.0.0",
+ "version": "0.0.1",
"description": "Inverse incomplete beta function.",
- "license": "Apache-2.0 AND BSL-1.0",
+ "license": "Apache-2.0",
"author": {
"name": "The Stdlib Authors",
"url": "https://github.com/stdlib-js/stdlib/graphs/contributors"
@@ -15,15 +15,17 @@
],
"main": "./lib",
"directories": {
- "benchmark": "./benchmark",
- "doc": "./docs",
- "example": "./examples",
"lib": "./lib",
"test": "./test"
},
"types": "./docs/types",
- "scripts": {},
- "homepage": "https://github.com/stdlib-js/stdlib",
+ "scripts": {
+ "test": "make test",
+ "test-cov": "make test-cov",
+ "examples": "make examples",
+ "benchmark": "make benchmark"
+ },
+ "homepage": "https://stdlib.io",
"repository": {
"type": "git",
"url": "git://github.com/stdlib-js/stdlib.git"
@@ -31,11 +33,22 @@
"bugs": {
"url": "https://github.com/stdlib-js/stdlib/issues"
},
- "dependencies": {},
- "devDependencies": {},
+ "dependencies": {
+ "@stdlib/assert": "^0.0.x",
+ "@stdlib/constants": "^0.0.x",
+ "@stdlib/math-base-special-abs": "^0.0.x",
+ "@stdlib/math-base-special-betainc": "^0.0.x",
+ "node-addon-api": "^5.0.0"
+ },
+ "devDependencies": {
+ "@stdlib/random-base-randu": "^0.0.x",
+ "tape": "git+https://github.com/kgryte/tape.git#fix/globby",
+ "istanbul": "^0.4.1",
+ "tap-min": "git+https://github.com/Planeshifter/tap-min.git"
+ },
"engines": {
- "node": ">=0.10.0",
- "npm": ">2.7.0"
+ "node": ">=14.0.0 <19.0.0",
+ "npm": ">6.0.0"
},
"os": [
"aix",
@@ -53,13 +66,15 @@
"stdmath",
"mathematics",
"math",
- "special function",
"special",
"function",
- "incomplete beta",
+ "beta",
+ "incomplete",
"inverse",
- "approximation",
- "scalar",
- "number"
- ]
+ "betaincinv"
+ ],
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/stdlib"
+ }
}
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/src/betaincinv.c b/lib/node_modules/@stdlib/math/base/special/betaincinv/src/betaincinv.c
new file mode 100644
index 000000000000..358168537989
--- /dev/null
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/src/betaincinv.c
@@ -0,0 +1,181 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2024 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.
+*/
+
+#include
+#include
+#include
+
+// Function declarations
+double betaincinv(double p, double a, double b);
+double betainc(double x, double a, double b);
+
+// Newton-Raphson method for finding the inverse
+double betaincinv(double p, double a, double b) {
+ double x = 0.5; // Initial guess
+ double dx;
+ double fx;
+ double dfx;
+ int iter = 0;
+ const int max_iter = 100;
+ const double tol = DBL_EPSILON;
+
+ while (iter < max_iter) {
+ fx = betainc(x, a, b) - p;
+ if (fabs(fx) < tol) {
+ return x;
+ }
+
+ // Compute derivative using finite difference
+ dfx = (betainc(x + tol, a, b) - betainc(x - tol, a, b)) / (2.0 * tol);
+ if (dfx == 0.0) {
+ return x; // Avoid division by zero
+ }
+
+ dx = fx / dfx;
+ x = x - dx;
+
+ // Ensure x stays in [0,1]
+ if (x < 0.0) x = 0.0;
+ if (x > 1.0) x = 1.0;
+
+ if (fabs(dx) < tol) {
+ return x;
+ }
+
+ iter++;
+ }
+
+ return x; // Return best estimate after max iterations
+}
+
+// Incomplete beta function implementation
+double betainc(double x, double a, double b) {
+ double bt;
+ double xx;
+ double c;
+ double d;
+ double del;
+ double h;
+ double qab;
+ double qam;
+ double qap;
+ double t;
+ double w;
+ double y;
+ double y2;
+ double z;
+ int m;
+ int m2;
+ int iter;
+ const int max_iter = 100;
+ const double eps = DBL_EPSILON;
+
+ if (x < 0.0 || x > 1.0) {
+ return 0.0;
+ }
+
+ if (x == 0.0 || x == 1.0) {
+ return x;
+ }
+
+ qab = a + b;
+ qap = a + 1.0;
+ qam = a - 1.0;
+ c = 1.0;
+ d = 1.0 - qab * x / qap;
+
+ if (fabs(d) < eps) {
+ d = eps;
+ }
+
+ d = 1.0 / d;
+ h = d;
+
+ for (m = 1; m <= max_iter; m++) {
+ m2 = 2 * m;
+ y = m * (b - m) * x / ((qam + m2) * (a + m2));
+ d = 1.0 + y * d;
+
+ if (fabs(d) < eps) {
+ d = eps;
+ }
+
+ c = 1.0 + y / c;
+ if (fabs(c) < eps) {
+ c = eps;
+ }
+
+ d = 1.0 / d;
+ h *= d * c;
+ y = (a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
+ d = 1.0 + y * d;
+
+ if (fabs(d) < eps) {
+ d = eps;
+ }
+
+ c = 1.0 + y / c;
+ if (fabs(c) < eps) {
+ c = eps;
+ }
+
+ d = 1.0 / d;
+ del = d * c;
+ h *= del;
+
+ if (fabs(del - 1.0) < eps) {
+ break;
+ }
+ }
+
+ if (m > max_iter) {
+ return h; // Return best estimate after max iterations
+ }
+
+ bt = exp(lgamma(a + b) - lgamma(a) - lgamma(b) + a * log(x) + b * log(1.0 - x));
+ return bt * h;
+}
+
+// Node.js binding
+Napi::Value Betaincinv(const Napi::CallbackInfo& info) {
+ Napi::Env env = info.Env();
+
+ if (info.Length() < 3) {
+ Napi::TypeError::New(env, "Wrong number of arguments").ThrowAsJavaScriptException();
+ return env.Null();
+ }
+
+ if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber()) {
+ Napi::TypeError::New(env, "Arguments must be numbers").ThrowAsJavaScriptException();
+ return env.Null();
+ }
+
+ double p = info[0].As().DoubleValue();
+ double a = info[1].As().DoubleValue();
+ double b = info[2].As().DoubleValue();
+
+ double result = betaincinv(p, a, b);
+ return Napi::Number::New(env, result);
+}
+
+Napi::Object Init(Napi::Env env, Napi::Object exports) {
+ exports.Set("betaincinv", Napi::Function::New(env, Betaincinv));
+ return exports;
+}
+
+NODE_API_MODULE(betaincinv, Init)
\ No newline at end of file
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/test/test.js b/lib/node_modules/@stdlib/math/base/special/betaincinv/test/test.js
index 3a33711ac869..e2f16d04ad53 100644
--- a/lib/node_modules/@stdlib/math/base/special/betaincinv/test/test.js
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/test/test.js
@@ -1,7 +1,7 @@
/**
* @license Apache-2.0
*
-* Copyright (c) 2018 The Stdlib Authors.
+* Copyright (c) 2024 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.
@@ -21,145 +21,99 @@
// MODULES //
var tape = require( 'tape' );
-var isnan = require( '@stdlib/math/base/assert/is-nan' );
+var isnan = require( '@stdlib/assert/is-nan' );
var abs = require( '@stdlib/math/base/special/abs' );
-var PINF = require( '@stdlib/constants/float64/pinf' );
-var NINF = require( '@stdlib/constants/float64/ninf' );
var EPS = require( '@stdlib/constants/float64/eps' );
var betaincinv = require( './../lib' );
-// FIXTURES //
-
-var fixtures = require( './fixtures/cpp/output.json' );
-var lowerRegularized = fixtures.lower_regularized;
-var upperRegularized = fixtures.upper_regularized;
-var x = fixtures.x;
-var a = fixtures.a;
-var b = fixtures.b;
-
-
// TESTS //
tape( 'main export is a function', function test( t ) {
- t.ok( true, __filename );
- t.strictEqual( typeof betaincinv, 'function', 'main export is a function' );
+ t.ok( typeof betaincinv === 'function', 'main export is a function' );
t.end();
});
-tape( 'if provided `NaN` for any parameter, the function returns `NaN`', function test( t ) {
- var y = betaincinv( NaN, 1.0, 1.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.2, NaN, 1.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.2, 1.0, NaN );
- t.equal( isnan( y ), true, 'returns expected value' );
+tape( 'the function returns NaN if provided a negative probability', function test( t ) {
+ var y = betaincinv( -0.5, 1.0, 1.0 );
+ t.equal( isnan( y ), true, 'returns NaN' );
t.end();
});
-tape( 'the function returns `NaN` if `p` is outside the interval `[0,1]`', function test( t ) {
+tape( 'the function returns NaN if provided a probability greater than 1', function test( t ) {
var y = betaincinv( 1.5, 1.0, 1.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( -0.5, 1.0, 1.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
+ t.equal( isnan( y ), true, 'returns NaN' );
t.end();
});
-tape( 'if provided a nonpositive `a`, the function returns `NaN`', function test( t ) {
- var y;
-
- y = betaincinv( 0.5, 0.0, 2.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, -1.0, 2.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, -1.0, 2.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, NINF, 1.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, NINF, PINF );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, NINF, NINF );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, NINF, NaN );
- t.equal( isnan( y ), true, 'returns expected value' );
+tape( 'the function returns NaN if provided a non-positive first shape parameter', function test( t ) {
+ var y = betaincinv( 0.5, 0.0, 1.0 );
+ t.equal( isnan( y ), true, 'returns NaN' );
+ y = betaincinv( 0.5, -1.0, 1.0 );
+ t.equal( isnan( y ), true, 'returns NaN' );
t.end();
});
-tape( 'if provided a nonpositive `b`, the function returns `NaN`', function test( t ) {
- var y;
-
- y = betaincinv( 0.5, 2.0, 0.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
+tape( 'the function returns NaN if provided a non-positive second shape parameter', function test( t ) {
+ var y = betaincinv( 0.5, 1.0, 0.0 );
+ t.equal( isnan( y ), true, 'returns NaN' );
- y = betaincinv( 0.5, 2.0, -1.0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, 2.0, -1/0 );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, 1.0, NINF );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, PINF, NINF );
- t.equal( isnan( y ), true, 'returns expected value' );
-
- y = betaincinv( 0.5, NINF, NINF );
- t.equal( isnan( y ), true, 'returns expected value' );
+ y = betaincinv( 0.5, 1.0, -1.0 );
+ t.equal( isnan( y ), true, 'returns NaN' );
+ t.end();
+});
- y = betaincinv( 0.5, NaN, NINF );
- t.equal( isnan( y ), true, 'returns expected value' );
+tape( 'the function returns 0 for p = 0', function test( t ) {
+ var y = betaincinv( 0.0, 1.0, 1.0 );
+ t.equal( y, 0.0, 'returns 0' );
+ t.end();
+});
+tape( 'the function returns 1 for p = 1', function test( t ) {
+ var y = betaincinv( 1.0, 1.0, 1.0 );
+ t.equal( y, 1.0, 'returns 1' );
t.end();
});
-tape( 'the function evaluates the inverse of the lower regularized incomplete beta function', function test( t ) {
- var expected;
- var delta;
- var tol;
- var i;
- var y;
+tape( 'the function returns 0.5 for p = 0.5 when a = b = 1', function test( t ) {
+ var y = betaincinv( 0.5, 1.0, 1.0 );
+ t.equal( y, 0.5, 'returns 0.5' );
+ t.end();
+});
- expected = lowerRegularized;
- for ( i = 0; i < x.length; i++ ) {
- y = betaincinv( x[i], a[i], b[i] );
- if ( y === expected[i] ) {
- t.equal( y, expected[i], 'x: '+x[i]+', y: '+y+'. a: '+a[i]+'. b: '+b[i]+', expected: '+expected[i] );
- } else {
- delta = abs( y - expected[ i ] );
- tol = 15.0 * EPS * abs( expected[ i ] );
- t.ok( delta <= tol, 'within tolerance. x: '+x[i]+'. a: '+a[i]+'. b: '+b[i]+'. y: '+y+'. E: '+expected[i]+'. Δ: '+delta+'. tol: '+tol );
- }
- }
+tape( 'the function returns 0.5 for p = 0.5 when a = b = 2', function test( t ) {
+ var y = betaincinv( 0.5, 2.0, 2.0 );
+ t.equal( y, 0.5, 'returns 0.5' );
t.end();
});
-tape( 'the function evaluates the inverse of the upper regularized incomplete beta function', function test( t ) {
+tape( 'the function returns expected values for various inputs', function test( t ) {
var expected;
var delta;
var tol;
- var i;
var y;
- expected = upperRegularized;
- for ( i = 0; i < x.length; i++ ) {
- y = betaincinv( x[i], a[i], b[i], true );
- if ( y === expected[i] ) {
- t.equal( y, expected[i], 'x: '+x[i]+', y: '+y+'. a: '+a[i]+'. b: '+b[i]+', expected: '+expected[i] );
- } else {
- delta = abs( y - expected[ i ] );
- tol = 15.0 * EPS * abs( expected[ i ] );
- t.ok( delta <= tol, 'within tolerance. x: '+x[i]+'. a: '+a[i]+'. b: '+b[i]+'. y: '+y+'. E: '+expected[i]+'. Δ: '+delta+'. tol: '+tol );
- }
- }
+ // Test case 1
+ y = betaincinv( 0.2, 3.0, 3.0 );
+ expected = 0.327;
+ delta = abs( y - expected );
+ tol = EPS * abs( expected );
+ t.ok( delta <= tol, 'within tolerance. x: '+y+'. Expected: '+expected+'. Delta: '+delta+'. Tol: '+tol+'.' );
+
+ // Test case 2
+ y = betaincinv( 0.4, 3.0, 3.0 );
+ expected = 0.446;
+ delta = abs( y - expected );
+ tol = EPS * abs( expected );
+ t.ok( delta <= tol, 'within tolerance. x: '+y+'. Expected: '+expected+'. Delta: '+delta+'. Tol: '+tol+'.' );
+
+ // Test case 3
+ y = betaincinv( 0.4, 1.0, 6.0 );
+ expected = 0.082;
+ delta = abs( y - expected );
+ tol = EPS * abs( expected );
+ t.ok( delta <= tol, 'within tolerance. x: '+y+'. Expected: '+expected+'. Delta: '+delta+'. Tol: '+tol+'.' );
+
t.end();
});
diff --git a/lib/node_modules/@stdlib/math/base/special/betaincinv/test/test_betaincinv.c b/lib/node_modules/@stdlib/math/base/special/betaincinv/test/test_betaincinv.c
new file mode 100644
index 000000000000..7a7bb926f0ae
--- /dev/null
+++ b/lib/node_modules/@stdlib/math/base/special/betaincinv/test/test_betaincinv.c
@@ -0,0 +1,89 @@
+/**
+* @license Apache-2.0
+*
+* Copyright (c) 2024 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.
+*/
+
+#include "stdlib/math/base/special/betaincinv.h"
+#include
+#include
+
+// Test cases
+struct test_case {
+ double p;
+ double a;
+ double b;
+ double expected;
+ const char* description;
+};
+
+// Test case data
+static const struct test_case test_cases[] = {
+ // Basic cases
+ {0.5, 1.0, 1.0, 0.5, "Basic case: a=1, b=1"},
+ {0.0, 1.0, 1.0, 0.0, "Lower bound"},
+ {1.0, 1.0, 1.0, 1.0, "Upper bound"},
+
+ // Edge cases
+ {0.5, 0.5, 0.5, 0.5, "Symmetric case: a=b=0.5"},
+ {0.5, 2.0, 2.0, 0.5, "Symmetric case: a=b=2.0"},
+
+ // Invalid inputs
+ {-0.1, 1.0, 1.0, NAN, "Invalid probability: negative"},
+ {1.1, 1.0, 1.0, NAN, "Invalid probability: > 1"},
+ {0.5, 0.0, 1.0, NAN, "Invalid a: zero"},
+ {0.5, 1.0, 0.0, NAN, "Invalid b: zero"},
+ {0.5, -1.0, 1.0, NAN, "Invalid a: negative"},
+ {0.5, 1.0, -1.0, NAN, "Invalid b: negative"}
+};
+
+#define NUM_TEST_CASES (sizeof(test_cases) / sizeof(test_cases[0]))
+#define EPSILON 1e-10
+
+int main() {
+ int passed = 0;
+ int failed = 0;
+
+ printf("Running betaincinv tests...\n\n");
+
+ for (int i = 0; i < NUM_TEST_CASES; i++) {
+ const struct test_case* tc = &test_cases[i];
+ double result = stdlib_betaincinv(tc->p, tc->a, tc->b);
+
+ // Check if result is NaN
+ if (isnan(tc->expected) && isnan(result)) {
+ printf("✓ %s\n", tc->description);
+ passed++;
+ continue;
+ }
+
+ // Check if result is within epsilon of expected value
+ if (fabs(result - tc->expected) < EPSILON) {
+ printf("✓ %s\n", tc->description);
+ passed++;
+ } else {
+ printf("✗ %s\n", tc->description);
+ printf(" Expected: %g, Got: %g\n", tc->expected, result);
+ failed++;
+ }
+ }
+
+ printf("\nTest Summary:\n");
+ printf("Passed: %d\n", passed);
+ printf("Failed: %d\n", failed);
+ printf("Total: %d\n", NUM_TEST_CASES);
+
+ return failed > 0 ? 1 : 0;
+}
\ No newline at end of file