Skip to content

Commit 340c836

Browse files
committed
feat: add the JS native and its benchmark and test files
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent f165f33 commit 340c836

File tree

3 files changed

+243
-0
lines changed

3 files changed

+243
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 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+
'use strict';
20+
21+
// MODULES //
22+
23+
var resolve = require( 'path' ).resolve;
24+
var bench = require( '@stdlib/bench' );
25+
var Float64Array = require( '@stdlib/array/float64' );
26+
var randu = require( '@stdlib/random/base/randu' );
27+
var ceil = require( '@stdlib/math/base/special/ceil' );
28+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
29+
var tryRequire = require( '@stdlib/utils/try-require' );
30+
var EPS = require( '@stdlib/constants/float64/eps' );
31+
var pkg = require( './../package.json' ).name;
32+
33+
34+
// VARIABLES //
35+
36+
var mgf = tryRequire( resolve( __dirname, './../lib/native.js' ) );
37+
var opts = {
38+
'skip': ( mgf instanceof Error )
39+
};
40+
41+
42+
// MAIN //
43+
44+
bench( pkg+'::native', opts, function benchmark( b ) {
45+
var len;
46+
var t;
47+
var r;
48+
var p;
49+
var y;
50+
var i;
51+
52+
len = 100;
53+
t = new Float64Array( len );
54+
r = new Float64Array( len );
55+
p = new Float64Array( len );
56+
57+
for ( i = 0; i < len; i++ ) {
58+
t[ i ] = randu() * -2.0; // t values must be negative
59+
r[ i ] = ceil( randu() * 100.0 ); // r values must be positive integers
60+
p[ i ] = ( randu() * (1.0 - EPS) ) + EPS; // p values in (0,1)
61+
}
62+
63+
b.tic();
64+
for ( i = 0; i < b.iterations; i++ ) {
65+
y = mgf( t[ i % len ], r[ i % len ], p[ i % len ] );
66+
if ( isnan( y ) ) {
67+
b.fail( 'should not return NaN' );
68+
}
69+
}
70+
b.toc();
71+
if ( isnan( y ) ) {
72+
b.fail( 'should not return NaN' );
73+
}
74+
b.pass( 'benchmark finished' );
75+
b.end();
76+
});
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 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+
'use strict';
20+
21+
// MODULES //
22+
23+
var addon = require( './../src/addon.node' );
24+
25+
26+
// MAIN //
27+
28+
/**
29+
* Evaluates the moment-generating function (MGF) for a negative binomial distribution.
30+
*
31+
* @private
32+
* @param {number} t - input value
33+
* @param {PositiveNumber} r - number of successes until experiment is stopped
34+
* @param {Probability} p - success probability
35+
* @returns {number} evaluated MGF
36+
*
37+
* @example
38+
* var y = mgf( 0.05, 20.0, 0.8 );
39+
* // returns ~267.839
40+
*
41+
* @example
42+
* var y = mgf( 0.1, 20.0, 0.1 );
43+
* // returns ~9.347
44+
*
45+
* @example
46+
* var y = mgf( 0.5, 10.0, 0.4 );
47+
* // returns ~42822.023
48+
*
49+
* @example
50+
* var y = mgf( 0.1, 0.0, 0.5 );
51+
* // returns NaN
52+
*
53+
* @example
54+
* var y = mgf( NaN, 20.0, 0.5 );
55+
* // returns NaN
56+
*/
57+
function mgf( t, r, p ) {
58+
return addon( t, r, p );
59+
}
60+
61+
62+
// EXPORTS //
63+
64+
module.exports = mgf;
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2024 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+
'use strict';
20+
21+
// MODULES //
22+
23+
var tape = require( 'tape' );
24+
var resolve = require( 'path' ).resolve;
25+
var tryRequire = require( '@stdlib/utils/try-require' );
26+
27+
28+
// VARIABLES //
29+
30+
var mgf = tryRequire( resolve( __dirname, './../lib/native.js' ) );
31+
var opts = {
32+
'skip': ( mgf instanceof Error )
33+
};
34+
35+
36+
// TESTS //
37+
38+
tape( 'main export is a function', opts, function test( t ) {
39+
t.ok( true, __filename );
40+
t.strictEqual( typeof mgf, 'function', 'main export is a function' );
41+
t.end();
42+
});
43+
44+
tape( 'the function returns NaN if provided a NaN input for `t`', opts, function test( t ) {
45+
var y = mgf( NaN, 2.0, 0.5 );
46+
t.strictEqual( typeof y, 'number', 'returns a number' );
47+
t.ok( isNaN( y ), 'returns NaN' );
48+
t.end();
49+
});
50+
51+
tape( 'the function returns NaN if provided a NaN input for `r`', opts, function test( t ) {
52+
var y = mgf( 0.1, NaN, 0.5 );
53+
t.strictEqual( typeof y, 'number', 'returns a number' );
54+
t.ok( isNaN( y ), 'returns NaN' );
55+
t.end();
56+
});
57+
58+
tape( 'the function returns NaN if provided a NaN input for `p`', opts, function test( t ) {
59+
var y = mgf( 0.1, 2.0, NaN );
60+
t.strictEqual( typeof y, 'number', 'returns a number' );
61+
t.ok( isNaN( y ), 'returns NaN' );
62+
t.end();
63+
});
64+
65+
tape( 'the function evaluates the MGF for valid inputs', opts, function test( t ) {
66+
var y = mgf( 0.0, 1.0, 0.9 );
67+
t.strictEqual( y, 1.0, 'returns 1 when t is 0' );
68+
69+
y = mgf( 0.05, 20.0, 0.8 );
70+
t.ok( Math.abs( y - 267.839 ) < 1e-3, 'returns ~267.839' );
71+
72+
y = mgf( 0.1, 20.0, 0.1 );
73+
t.ok( Math.abs( y - 9.347 ) < 1e-3, 'returns ~9.347' );
74+
75+
y = mgf( 0.5, 10.0, 0.4 );
76+
t.ok( Math.abs( y - 42822.023 ) < 1e-3, 'returns ~42822.023' );
77+
78+
t.end();
79+
});
80+
81+
tape( 'the function returns NaN if `p` is outside the interval [0,1]', opts, function test( t ) {
82+
var y = mgf( 0.1, 2.0, -0.5 );
83+
t.strictEqual( typeof y, 'number', 'returns a number' );
84+
t.ok( isNaN( y ), 'returns NaN' );
85+
86+
y = mgf( 0.1, 2.0, 1.5 );
87+
t.strictEqual( typeof y, 'number', 'returns a number' );
88+
t.ok( isNaN( y ), 'returns NaN' );
89+
90+
t.end();
91+
});
92+
93+
tape( 'the function returns NaN if `r` is less than or equal to 0', opts, function test( t ) {
94+
var y = mgf( 0.1, -2.0, 0.5 );
95+
t.strictEqual( typeof y, 'number', 'returns a number' );
96+
t.ok( isNaN( y ), 'returns NaN' );
97+
98+
y = mgf( 0.1, 0.0, 0.5 );
99+
t.strictEqual( typeof y, 'number', 'returns a number' );
100+
t.ok( isNaN( y ), 'returns NaN' );
101+
102+
t.end();
103+
});

0 commit comments

Comments
 (0)