Skip to content

Commit 4060ff1

Browse files
committed
fix: change x parameter type from int32_t to double for consistency with pmf sibling
- Refactor C signature to (double x, int32_t n, double p) matching binomial/pmf - Add is_nan(x) and is_nonnegative_integer(x) checks matching JS implementation - Update NAPI macro from IID_D to DID_D - Remove unused pinf dependency from manifest.json - Use format() for benchmark description string - Standardize test assertion messages to 'returns expected value'
1 parent af22a78 commit 4060ff1

9 files changed

Lines changed: 56 additions & 46 deletions

File tree

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/README.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,12 @@ double out = stdlib_base_dists_binomial_logpmf( 3.0, 20, 0.2 );
183183

184184
The function accepts the following arguments:
185185

186-
- **x**: `[in] int32_t` input value.
186+
- **x**: `[in] double` input value.
187187
- **n**: `[in] int32_t` number of trials.
188188
- **p**: `[in] double` success probability.
189189

190190
```c
191-
double stdlib_base_dists_binomial_logpmf( const int32_t x, const int32_t n, const double p );
191+
double stdlib_base_dists_binomial_logpmf( const double x, const int32_t n, const double p );
192192
```
193193
194194
</section>
@@ -222,18 +222,18 @@ static double random_uniform( const double min, const double max ) {
222222
}
223223
224224
int main( void ) {
225+
double x;
225226
int32_t n;
226227
double p;
227-
int32_t x;
228228
double y;
229229
int i;
230230
231231
for ( i = 0; i < 25; i++ ) {
232+
x = stdlib_base_ceil( random_uniform( 0.0, 50.0 ) );
232233
n = stdlib_base_ceil( random_uniform( 0.0, 100.0 ) );
233234
p = random_uniform( 0.0, 1.0 );
234-
x = stdlib_base_ceil( random_uniform( 0.0, 50.0 ) );
235235
y = stdlib_base_dists_binomial_logpmf( x, n, p );
236-
printf( "x: %d, n: %d, p: %lf, ln(P(X=x;n,p)): %lf\n", x, n, p, y );
236+
printf( "x: %lf, n: %d, p: %lf, ln(P(X=x;n,p)): %lf\n", x, n, p, y );
237237
}
238238
239239
return 0;

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/benchmark/benchmark.native.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var tryRequire = require( '@stdlib/utils/try-require' );
2727
var uniform = require( '@stdlib/random/base/uniform' );
2828
var discreteUniform = require( '@stdlib/random/base/discrete-uniform' );
2929
var isnan = require( '@stdlib/math/base/assert/is-nan' );
30+
var format = require( '@stdlib/string/format' );
3031
var pkg = require( './../package.json' ).name;
3132

3233

@@ -40,7 +41,7 @@ var opts = {
4041

4142
// MAIN //
4243

43-
bench( pkg+'::native', opts, function benchmark( b ) {
44+
bench( format( '%s::native', pkg ), opts, function benchmark( b ) {
4445
var len;
4546
var n;
4647
var p;

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/benchmark/c/benchmark.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,17 @@ static double random_uniform( const double min, const double max ) {
9595
*/
9696
static double benchmark( void ) {
9797
double elapsed;
98+
double x[ 100 ];
9899
int32_t n[ 100 ];
99100
double p[ 100 ];
100-
int32_t x[ 100 ];
101101
double y;
102102
double t;
103103
int i;
104104

105105
for ( i = 0; i < 100; i++ ) {
106+
x[ i ] = stdlib_base_ceil( random_uniform( 0.0, 50.0 ) );
106107
n[ i ] = stdlib_base_ceil( random_uniform( 0.0, 100.0 ) );
107108
p[ i ] = random_uniform( 0.0, 1.0 );
108-
x[ i ] = stdlib_base_ceil( random_uniform( 0.0, 50.0 ) );
109109
}
110110

111111
t = tic();

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/examples/c/example.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ static double random_uniform( const double min, const double max ) {
2828
}
2929

3030
int main( void ) {
31+
double x;
3132
int32_t n;
3233
double p;
33-
int32_t x;
3434
double y;
3535
int i;
3636

3737
for ( i = 0; i < 25; i++ ) {
38+
x = stdlib_base_ceil( random_uniform( 0.0, 50.0 ) );
3839
n = stdlib_base_ceil( random_uniform( 0.0, 100.0 ) );
3940
p = random_uniform( 0.0, 1.0 );
40-
x = stdlib_base_ceil( random_uniform( 0.0, 50.0 ) );
4141
y = stdlib_base_dists_binomial_logpmf( x, n, p );
42-
printf( "x: %d, n: %d, p: %lf, ln(P(X=x;n,p)): %lf\n", x, n, p, y );
42+
printf( "x: %lf, n: %d, p: %lf, ln(P(X=x;n,p)): %lf\n", x, n, p, y );
4343
}
4444

4545
return 0;

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/include/stdlib/stats/base/dists/binomial/logpmf.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern "C" {
3232
/**
3333
* Evaluates the natural logarithm of the probability mass function (PMF) for a binomial distribution.
3434
*/
35-
double stdlib_base_dists_binomial_logpmf( const int32_t x, const int32_t n, const double p );
35+
double stdlib_base_dists_binomial_logpmf( const double x, const int32_t n, const double p );
3636

3737
#ifdef __cplusplus
3838
}

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/manifest.json‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@
4040
"dependencies": [
4141
"@stdlib/math/base/napi/ternary",
4242
"@stdlib/math/base/assert/is-nan",
43-
"@stdlib/constants/float64/pinf",
44-
"@stdlib/constants/float64/ninf",
4543
"@stdlib/math/base/assert/is-nonnegative-integer",
44+
"@stdlib/constants/float64/ninf",
4645
"@stdlib/math/base/special/binomcoefln",
4746
"@stdlib/math/base/special/log1p",
4847
"@stdlib/math/base/special/ln"
@@ -61,9 +60,8 @@
6160
"libpath": [],
6261
"dependencies": [
6362
"@stdlib/math/base/assert/is-nan",
64-
"@stdlib/constants/float64/pinf",
65-
"@stdlib/constants/float64/ninf",
6663
"@stdlib/math/base/assert/is-nonnegative-integer",
64+
"@stdlib/constants/float64/ninf",
6765
"@stdlib/math/base/special/binomcoefln",
6866
"@stdlib/math/base/special/log1p",
6967
"@stdlib/math/base/special/ln",
@@ -83,9 +81,8 @@
8381
"libpath": [],
8482
"dependencies": [
8583
"@stdlib/math/base/assert/is-nan",
86-
"@stdlib/constants/float64/pinf",
87-
"@stdlib/constants/float64/ninf",
8884
"@stdlib/math/base/assert/is-nonnegative-integer",
85+
"@stdlib/constants/float64/ninf",
8986
"@stdlib/math/base/special/binomcoefln",
9087
"@stdlib/math/base/special/log1p",
9188
"@stdlib/math/base/special/ln",

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/src/addon.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@
2020
#include "stdlib/math/base/napi/ternary.h"
2121

2222
// cppcheck-suppress shadowFunction
23-
STDLIB_MATH_BASE_NAPI_MODULE_IID_D( stdlib_base_dists_binomial_logpmf );
23+
STDLIB_MATH_BASE_NAPI_MODULE_DID_D( stdlib_base_dists_binomial_logpmf );

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/src/main.c‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "stdlib/stats/base/dists/binomial/logpmf.h"
2020
#include "stdlib/math/base/assert/is_nan.h"
21+
#include "stdlib/math/base/assert/is_nonnegative_integer.h"
2122
#include "stdlib/constants/float64/ninf.h"
2223
#include "stdlib/math/base/special/binomcoefln.h"
2324
#include "stdlib/math/base/special/log1p.h"
@@ -33,28 +34,34 @@
3334
* @return evaluated logPMF
3435
*
3536
* @example
36-
* double y = stdlib_base_dists_binomial_logpmf( 3, 20, 0.2 );
37+
* double y = stdlib_base_dists_binomial_logpmf( 3.0, 20, 0.2 );
3738
* // returns ~-1.583
3839
*/
39-
double stdlib_base_dists_binomial_logpmf( const int32_t x, const int32_t n, const double p ) {
40+
double stdlib_base_dists_binomial_logpmf( const double x, const int32_t n, const double p ) {
41+
double out;
42+
4043
if (
44+
stdlib_base_is_nan( x ) ||
4145
stdlib_base_is_nan( p ) ||
4246
n < 0 ||
4347
p < 0.0 ||
4448
p > 1.0
4549
) {
46-
return 0.0 / 0.0;
50+
return 0.0 / 0.0; // NaN
51+
}
52+
if ( !stdlib_base_is_nonnegative_integer( x ) ) {
53+
return STDLIB_CONSTANT_FLOAT64_NINF;
4754
}
48-
if ( x < 0 || x > n ) {
55+
if ( x > n ) {
4956
return STDLIB_CONSTANT_FLOAT64_NINF;
5057
}
5158
if ( p == 0.0 ) {
52-
return ( x == 0 ) ? 0.0 : STDLIB_CONSTANT_FLOAT64_NINF;
59+
return ( x == 0.0 ) ? 0.0 : STDLIB_CONSTANT_FLOAT64_NINF;
5360
}
5461
if ( p == 1.0 ) {
5562
return ( x == n ) ? 0.0 : STDLIB_CONSTANT_FLOAT64_NINF;
5663
}
57-
double out = stdlib_base_binomcoefln( n, x );
64+
out = stdlib_base_binomcoefln( n, x );
5865
out += ( x * stdlib_base_ln( p ) ) + ( ( n - x ) * stdlib_base_log1p( -p ) );
5966
return out;
6067
}

‎lib/node_modules/@stdlib/stats/base/dists/binomial/logpmf/test/test.native.js‎

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,29 @@ tape( 'main export is a function', opts, function test( t ) {
5454
t.end();
5555
});
5656

57-
tape( 'if provided `NaN` for any parameter, the function returns `NaN`', opts, function test( t ) {
57+
tape( 'if provided `NaN` for `x` or `p`, the function returns `NaN`', opts, function test( t ) {
5858
var y;
59-
y = logpmf( 0, 20, NaN );
60-
t.equal( isnan( y ), true, 'returns NaN' );
59+
60+
y = logpmf( NaN, 20, 0.5 );
61+
t.strictEqual( isnan( y ), true, 'returns expected value' );
62+
63+
y = logpmf( 0.0, 20, NaN );
64+
t.strictEqual( isnan( y ), true, 'returns expected value' );
65+
6166
t.end();
6267
});
6368

6469
tape( 'if provided a negative integer for `x` and a valid `n` and `p`, the function returns `-Infinity`', opts, function test( t ) {
6570
var y;
6671

6772
y = logpmf( -20, 20, 0.5 );
68-
t.equal( y, NINF, 'returns -Infinity' );
73+
t.strictEqual( y, NINF, 'returns expected value' );
6974

7075
y = logpmf( -100, 20, 0.5 );
71-
t.equal( y, NINF, 'returns -Infinity' );
76+
t.strictEqual( y, NINF, 'returns expected value' );
7277

7378
y = logpmf( -1, 20, 0.5 );
74-
t.equal( y, NINF, 'returns -Infinity' );
79+
t.strictEqual( y, NINF, 'returns expected value' );
7580

7681
t.end();
7782
});
@@ -80,7 +85,7 @@ tape( 'if provided `n` which is not a nonnegative integer, the function returns
8085
var y;
8186

8287
y = logpmf( 0, -1, 0.5 );
83-
t.equal( isnan( y ), true, 'returns NaN' );
88+
t.strictEqual( isnan( y ), true, 'returns expected value' );
8489

8590
t.end();
8691
});
@@ -89,16 +94,16 @@ tape( 'if provided a success probability `p` outside of `[0,1]`, the function re
8994
var y;
9095

9196
y = logpmf( 2, 20, -1.0 );
92-
t.equal( isnan( y ), true, 'returns NaN' );
97+
t.strictEqual( isnan( y ), true, 'returns expected value' );
9398

9499
y = logpmf( 0, 20, 1.5 );
95-
t.equal( isnan( y ), true, 'returns NaN' );
100+
t.strictEqual( isnan( y ), true, 'returns expected value' );
96101

97102
y = logpmf( 2, 20, NINF );
98-
t.equal( isnan( y ), true, 'returns NaN' );
103+
t.strictEqual( isnan( y ), true, 'returns expected value' );
99104

100105
y = logpmf( 2, 20, PINF );
101-
t.equal( isnan( y ), true, 'returns NaN' );
106+
t.strictEqual( isnan( y ), true, 'returns expected value' );
102107

103108
t.end();
104109
});
@@ -108,17 +113,17 @@ tape( 'if `p` or `n` equals `0`, the function evaluates a degenerate distributio
108113

109114
// Case: n = 8, p = 0.0
110115
y = logpmf( 0, 8, 0.0 );
111-
t.equal( y, 0.0, 'returns 0 for x equal to 0' );
116+
t.strictEqual( y, 0.0, 'returns expected value' );
112117

113118
y = logpmf( 1, 8, 0.0 );
114-
t.equal( y, NINF, 'returns -Infinity' );
119+
t.strictEqual( y, NINF, 'returns expected value' );
115120

116121
// Case: n = 0, p = 0.5
117122
y = logpmf( 0, 0, 0.5 );
118-
t.equal( y, 0.0, 'returns 0 for x equal to 0' );
123+
t.strictEqual( y, 0.0, 'returns expected value' );
119124

120125
y = logpmf( 1, 0, 0.5 );
121-
t.equal( y, NINF, 'returns -Infinity' );
126+
t.strictEqual( y, NINF, 'returns expected value' );
122127

123128
t.end();
124129
});
@@ -127,10 +132,10 @@ tape( 'if `p` equals `1.0`, the function evaluates a degenerate distribution cen
127132
var y;
128133

129134
y = logpmf( 8, 8, 1.0 );
130-
t.equal( y, 0.0, 'returns 0 for x equal to 8' );
135+
t.strictEqual( y, 0.0, 'returns expected value' );
131136

132137
y = logpmf( 1, 8, 1.0 );
133-
t.equal( y, NINF, 'returns -Infinity' );
138+
t.strictEqual( y, NINF, 'returns expected value' );
134139

135140
t.end();
136141
});
@@ -152,7 +157,7 @@ tape( 'the function evaluates the logpmf for `x` given large `n` and `p`', opts,
152157
for ( i = 0; i < x.length; i++ ) {
153158
y = logpmf( x[i], n[i], p[i] );
154159
if ( y === expected[i] ) {
155-
t.equal( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
160+
t.strictEqual( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
156161
} else {
157162
delta = abs( y - expected[i] );
158163
tol = 30.0 * EPS * abs( expected[i] );
@@ -179,7 +184,7 @@ tape( 'the function evaluates the logpmf for `x` given large `n` and small `p`',
179184
for ( i = 0; i < x.length; i++ ) {
180185
y = logpmf( x[i], n[i], p[i] );
181186
if ( y === expected[i] ) {
182-
t.equal( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
187+
t.strictEqual( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
183188
} else {
184189
delta = abs( y - expected[i] );
185190
tol = 20.0 * EPS * abs( expected[i] );
@@ -206,7 +211,7 @@ tape( 'the function evaluates the logpmf for `x` given small `n` and large `p`',
206211
for ( i = 0; i < x.length; i++ ) {
207212
y = logpmf( x[i], n[i], p[i] );
208213
if ( y === expected[i] ) {
209-
t.equal( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
214+
t.strictEqual( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
210215
} else {
211216
delta = abs( y - expected[i] );
212217
tol = 20.0 * EPS * abs( expected[i] );
@@ -233,7 +238,7 @@ tape( 'the function evaluates the logpmf for `x` given small `n` and `p`', opts,
233238
for ( i = 0; i < x.length; i++ ) {
234239
y = logpmf( x[i], n[i], p[i] );
235240
if ( y === expected[i] ) {
236-
t.equal( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
241+
t.strictEqual( y, expected[i], 'x: '+x[i]+', n: '+n[i]+', p: '+p[i]+', y: '+y+', expected: '+expected[i] );
237242
} else {
238243
delta = abs( y - expected[i] );
239244
tol = 10.0 * EPS * abs( expected[i] );

0 commit comments

Comments
 (0)