Skip to content

Commit d1007dd

Browse files
feat: add c implementation for stats/base/dists/negative-binomial/pmf
--- 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: passed - task: lint_package_json status: passed - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: passed - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: passed - task: lint_c_examples status: passed - task: lint_c_benchmarks status: passed - 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 4bbd4bd commit d1007dd

File tree

17 files changed

+1494
-9
lines changed

17 files changed

+1494
-9
lines changed

lib/node_modules/@stdlib/stats/base/dists/negative-binomial/pmf/README.md

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ f(x; r, p) = P(X = x; r,p) = \binom{k+r-1}{x} p^r(1-p)^x \quad\text{for }x = 0,
3939

4040
<!-- </equation> -->
4141

42-
where `r > 0` is the number of successes until experiment is stopped and `0 < p <= 1` is the success probability. The random variable `X` denotes the number of failures until the `r` success is reached.
42+
where `r > 0` is the number of successes until experiment is stopped and `0 < p <= 1` is the success probability. The random variable `X` denotes the number of failures until the `r` success is reached.
4343

4444
</section>
4545

@@ -161,6 +161,102 @@ for ( i = 0; i < 10; i++ ) {
161161

162162
<!-- /.examples -->
163163

164+
<!-- C interface documentation. -->
165+
166+
* * *
167+
168+
<section class="c">
169+
170+
## C APIs
171+
172+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
173+
174+
<section class="intro">
175+
176+
</section>
177+
178+
<!-- /.intro -->
179+
180+
<!-- C usage documentation. -->
181+
182+
<section class="usage">
183+
184+
### Usage
185+
186+
```c
187+
#include "stdlib/stats/base/dists/negative-binomial/pmf.h"
188+
```
189+
190+
#### stdlib_base_dists_negative_binomial_mode( x, r, p )
191+
192+
Evaluates the probability mass function (PMF) for a negative binomial distribution with number of successes until experiment is stopped `r` and success probability `p`.
193+
194+
```c
195+
double y = stdlib_base_dists_negative_binomial_mode( 5.0, 20.0, 0.8 );
196+
// returns ~0.157
197+
```
198+
199+
The function accepts the following arguments:
200+
201+
- **x**: `[in] double` input value.
202+
- **r**: `[in] double` number of failures until experiment is stopped .
203+
- **p**: `[in] double` success probability .
204+
205+
```c
206+
double stdlib_base_dists_negative_binomial_mode( const double x, const double r, const double p );
207+
```
208+
209+
</section>
210+
211+
<!-- /.usage -->
212+
213+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
214+
215+
<section class="notes">
216+
217+
</section>
218+
219+
<!-- /.notes -->
220+
221+
<!-- C API usage examples. -->
222+
223+
<section class="examples">
224+
225+
### Examples
226+
227+
```c
228+
#include "stdlib/stats/base/dists/negative-binomial/pmf.h"
229+
#include "stdlib/math/base/special/round.h"
230+
#include "stdlib/constants/float64/eps"
231+
#include <stdlib.h>
232+
#include <stdio.h>
233+
234+
static double random_uniform( const double min, const double max ) {
235+
double v = (double)rand() / ( (double)RAND_MAX + 1.0 );
236+
return min + ( v*(max-min) );
237+
}
238+
239+
int main( void ) {
240+
double x;
241+
double r;
242+
double p;
243+
double y;
244+
int i;
245+
246+
for ( i = 0; i < 10; i++ ) {
247+
x = stdlib_base_round( random_uniform( 0.0, 30.0 ) );
248+
r = random_uniform( 0.0, 50.0 );
249+
p = random_uniform( 0.0, 1.0 );
250+
y = stdlib_base_dists_negative_binomial_pmf( x, r, p );
251+
printf("x: %f, r: %f, p: %.4f, P(X=x;r,p): %.4f\n", x, r, p, y);
252+
}
253+
}
254+
```
255+
256+
</section>
257+
258+
<!-- /.examples -->
259+
164260
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
165261

166262
<section class="related">

lib/node_modules/@stdlib/stats/base/dists/negative-binomial/pmf/benchmark/benchmark.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var ceil = require( '@stdlib/math/base/special/ceil' );
24+
var Float64Array = require( '@stdlib/array/float64' );
25+
var discreteUniform = require( '@stdlib/random/base/discrete-uniform' );
2526
var uniform = require( '@stdlib/random/base/uniform' );
26-
var randu = require( '@stdlib/random/base/randu' );
2727
var isnan = require( '@stdlib/math/base/assert/is-nan' );
2828
var EPS = require( '@stdlib/constants/float64/eps' );
2929
var pkg = require( './../package.json' ).name;
@@ -33,18 +33,26 @@ var pmf = require( './../lib' );
3333
// MAIN //
3434

3535
bench( pkg, function benchmark( b ) {
36+
var len;
3637
var r;
3738
var p;
3839
var x;
3940
var y;
4041
var i;
4142

43+
len = 100;
44+
x = new Float64Array( len );
45+
r = new Float64Array( len );
46+
p = new Float64Array( len );
47+
for ( i = 0; i < len; i++ ) {
48+
x[ i ] = discreteUniform( 0.0, 100.0 );
49+
r[ i ] = discreteUniform( 0.0, 100.0 );
50+
p[ i ] = uniform( EPS, 1.0 );
51+
}
52+
4253
b.tic();
4354
for ( i = 0; i < b.iterations; i++ ) {
44-
x = ceil( randu()*100.0 );
45-
r = ceil( randu()*100.0 );
46-
p = uniform( EPS, 1.0 );
47-
y = pmf( x, r, p );
55+
y = pmf( x[ i % len ], r[ i % len ], p[ i % len ] );
4856
if ( isnan( y ) ) {
4957
b.fail( 'should not return NaN' );
5058
}
@@ -59,20 +67,26 @@ bench( pkg, function benchmark( b ) {
5967

6068
bench( pkg+':factory', function benchmark( b ) {
6169
var mypmf;
70+
var len;
6271
var r;
6372
var p;
6473
var x;
6574
var y;
6675
var i;
6776

77+
len = 100;
6878
r = 80;
6979
p = 0.4;
7080
mypmf = pmf.factory( r, p );
81+
x = new Float64Array( len );
82+
83+
for ( i = 0; i < len; i++ ) {
84+
x[ i ] = uniform( 0.0, 80.0 );
85+
}
7186

7287
b.tic();
7388
for ( i = 0; i < b.iterations; i++ ) {
74-
x = ( randu()*80 );
75-
y = mypmf( x );
89+
y = mypmf( x[ i % len ] );
7690
if ( isnan( y ) ) {
7791
b.fail( 'should not return NaN' );
7892
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2025 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 tryRequire = require( '@stdlib/utils/try-require' );
27+
var discreteUniform = require( '@stdlib/random/base/discrete-uniform' );
28+
var uniform = require( '@stdlib/random/base/uniform' );
29+
var EPS = require( '@stdlib/constants/float64/eps' );
30+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
31+
var pkg = require( './../package.json' ).name;
32+
33+
34+
// VARIABLES //
35+
36+
var pmf = tryRequire( resolve( __dirname, './../lib/native.js' ) );
37+
var opts = {
38+
'skip': ( pmf instanceof Error )
39+
};
40+
41+
42+
// MAIN //
43+
44+
bench( pkg+'::native', opts, function benchmark( b ) {
45+
var len;
46+
var r;
47+
var p;
48+
var x;
49+
var y;
50+
var i;
51+
52+
len = 100;
53+
x = new Float64Array( len );
54+
r = new Float64Array( len );
55+
p = new Float64Array( len );
56+
for ( i = 0; i < len; i++ ) {
57+
x[ i ] = discreteUniform( 0.0, 100.0 );
58+
r[ i ] = discreteUniform( 0.0, 100.0 );
59+
p[ i ] = uniform( EPS, 1.0 );
60+
}
61+
62+
b.tic();
63+
for ( i = 0; i < b.iterations; i++ ) {
64+
y = pmf( x[ i % len ], r[ i % len ], p[ i % len ] );
65+
if ( isnan( y ) ) {
66+
b.fail( 'should not return NaN' );
67+
}
68+
}
69+
b.toc();
70+
if ( isnan( y ) ) {
71+
b.fail( 'should not return NaN' );
72+
}
73+
b.pass( 'benchmark finished' );
74+
b.end();
75+
});

0 commit comments

Comments
 (0)