Skip to content

Commit 3c703bd

Browse files
Aadish JainAadish Jain
authored andcommitted
feat(negative-binomial-variance): adding code required for negative binomial variance
1 parent f2db85a commit 3c703bd

File tree

19 files changed

+1439
-12
lines changed

19 files changed

+1439
-12
lines changed

lib/node_modules/@stdlib/math/base/napi/binary/include/stdlib/math/base/napi/binary.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,48 @@
616616
}; \
617617
NAPI_MODULE( NODE_GYP_MODULE_NAME, stdlib_math_base_napi_ll_d_init )
618618

619+
/**
620+
* Macro for registering a Node-API module exporting an interface invoking a binary function accepting signed 64-bit integers and a double-precision floating-point and returning a double-precision floating-point number.
621+
*
622+
* @param fcn binary function
623+
*
624+
* @example
625+
* #include <stdint.h>
626+
*
627+
* static double fcn( const int_64 x, const double y ) {
628+
* // ...
629+
* }
630+
*
631+
* // ...
632+
*
633+
* // Register a Node-API module:
634+
* STDLIB_MATH_BASE_NAPI_MODULE_LD_D( fcn );
635+
*/
636+
#define STDLIB_MATH_BASE_NAPI_MODULE_LD_D( fcn ) \
637+
static napi_value stdlib_math_base_napi_ld_d_wrapper( \
638+
napi_env env, \
639+
napi_callback_info info \
640+
) { \
641+
return stdlib_math_base_napi_ld_d( env, info, fcn ); \
642+
}; \
643+
static napi_value stdlib_math_base_napi_ld_d_init( \
644+
napi_env env, \
645+
napi_value exports \
646+
) { \
647+
napi_value fcn; \
648+
napi_status status = napi_create_function( \
649+
env, \
650+
"exports", \
651+
NAPI_AUTO_LENGTH, \
652+
stdlib_math_base_napi_ld_d_wrapper, \
653+
NULL, \
654+
&fcn \
655+
); \
656+
assert( status == napi_ok ); \
657+
return fcn; \
658+
}; \
659+
NAPI_MODULE( NODE_GYP_MODULE_NAME, stdlib_math_base_napi_ld_d_init )
660+
619661
/**
620662
* Macro for registering a Node-API module exporting an interface invoking a binary function accepting signed 32-bit integers and returning a single-precision floating-point number.
621663
*
@@ -730,6 +772,11 @@ napi_value stdlib_math_base_napi_cf_c( napi_env env, napi_callback_info info, st
730772
*/
731773
napi_value stdlib_math_base_napi_ll_d( napi_env env, napi_callback_info info, double (*fcn)( int64_t, int64_t ) );
732774

775+
/**
776+
* Invokes a binary function accepting a signed 64-bit integer and a double-precision floating-point number and returning a double-precision floating-point number.
777+
*/
778+
napi_value stdlib_math_base_napi_ld_d( napi_env env, napi_callback_info info, double (*fcn)( int64_t, double ) );
779+
733780
/**
734781
* Invokes a binary function accepting signed 32-bit integers and returning a single-precision floating-point number.
735782
*/

lib/node_modules/@stdlib/math/base/napi/binary/src/main.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,67 @@ napi_value stdlib_math_base_napi_dd_d( napi_env env, napi_callback_info info, do
8787

8888
return v;
8989
}
90+
/**
91+
* Invokes a binary function accepting a signed 64-bit integer and a double-precision floating-point number and returning double-precision floating-point numbers.
92+
*
93+
* ## Notes
94+
*
95+
* - This function expects that the callback `info` argument provides access to the following JavaScript arguments:
96+
*
97+
* - `x`: input value.
98+
* - `y`: input value.
99+
*
100+
* @param env environment under which the function is invoked
101+
* @param info callback data
102+
* @param fcn binary function
103+
* @return function return value as a Node-API double-precision floating-point number
104+
*/
105+
napi_value stdlib_math_base_napi_ld_d( napi_env env, napi_callback_info info, double (*fcn)( int64_t, double ) ) {
106+
napi_status status;
107+
108+
size_t argc = 2;
109+
napi_value argv[ 2 ];
110+
status = napi_get_cb_info( env, info, &argc, argv, NULL, NULL );
111+
assert( status == napi_ok );
112+
113+
if ( argc < 2 ) {
114+
status = napi_throw_error( env, NULL, "invalid invocation. Must provide two numbers." );
115+
assert( status == napi_ok );
116+
return NULL;
117+
}
118+
119+
napi_valuetype vtype0;
120+
status = napi_typeof( env, argv[ 0 ], &vtype0 );
121+
assert( status == napi_ok );
122+
if ( vtype0 != napi_number ) {
123+
status = napi_throw_type_error( env, NULL, "invalid argument. First argument must be a number." );
124+
assert( status == napi_ok );
125+
return NULL;
126+
}
127+
128+
napi_valuetype vtype1;
129+
status = napi_typeof( env, argv[ 1 ], &vtype1 );
130+
assert( status == napi_ok );
131+
if ( vtype1 != napi_number ) {
132+
status = napi_throw_type_error( env, NULL, "invalid argument. Second argument must be a number." );
133+
assert( status == napi_ok );
134+
return NULL;
135+
}
136+
137+
int64_t x;
138+
status = napi_get_value_int64( env, argv[ 0 ], &x );
139+
assert( status == napi_ok );
140+
141+
double y;
142+
status = napi_get_value_double( env, argv[ 1 ], &y );
143+
assert( status == napi_ok );
144+
145+
napi_value v;
146+
status = napi_create_double( env, fcn( x, y ), &v );
147+
assert( status == napi_ok );
148+
149+
return v;
150+
}
90151

91152
/**
92153
* Invokes a binary function accepting and returning single-precision floating-point numbers.

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

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,103 @@ for ( i = 0; i < 10; i++ ) {
137137

138138
<!-- /.examples -->
139139

140+
<!-- C interface documentation. -->
141+
142+
* * *
143+
144+
<section class="c">
145+
146+
## C APIs
147+
148+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
149+
150+
<section class="intro">
151+
152+
</section>
153+
154+
<!-- /.intro -->
155+
156+
<!-- C usage documentation. -->
157+
158+
<section class="usage">
159+
160+
### Usage
161+
162+
```c
163+
#include "stdlib/stats/base/dists/negative-binomial/variance.h"
164+
```
165+
166+
#### stdlib_base_dists_negative_binomial_variance( r, p )
167+
168+
Returns the variance of a negative binomial distribution with parameters `r` (number of successes until experiment is stopped) and `p` (success probability).
169+
170+
```c
171+
double v = stdlib_base_dists_negative_binomial_variance( 100, 0.2 );
172+
// returns ~2000.0
173+
```
174+
175+
The function accepts the following arguments:
176+
177+
- **r**: `[in] int` number of successes until experiment is stopped.
178+
- **p**: `[in] double` success probability.
179+
180+
```c
181+
double stdlib_base_dists_negative_binomial_variance( const int64_t r, const double p );
182+
```
183+
184+
</section>
185+
186+
<!-- /.usage -->
187+
188+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
189+
190+
<section class="notes">
191+
192+
</section>
193+
194+
<!-- /.notes -->
195+
196+
<!-- C API usage examples. -->
197+
198+
<section class="examples">
199+
200+
### Examples
201+
202+
```c
203+
#include "stdlib/stats/base/dists/negative-binomial/variance.h"
204+
#include <stdlib.h>
205+
#include <stdint.h>
206+
#include <stdio.h>
207+
208+
static double random_uniform( const double min, const double max ) {
209+
double v = (double)rand() / ( (double)RAND_MAX + 1.0 );
210+
return min + ( v*(max-min) );
211+
}
212+
213+
int main( void ) {
214+
int64_t r;
215+
double p;
216+
double v;
217+
int i;
218+
219+
220+
for ( i = 0; i < 10; i++ ) {
221+
r = (int64_t)random_uniform( -1.0, 100.0 );
222+
p = random_uniform( 0.0, 1.0 );
223+
v = stdlib_base_dists_negative_binomial_variance( r, p );
224+
printf( "r: %ld, p: %lf, Var(X;r,p): %lf\n", r, p, v );
225+
}
226+
}
227+
```
228+
229+
</section>
230+
231+
<!-- /.examples -->
232+
233+
</section>
234+
235+
<!-- /.c -->
236+
140237
<!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
141238

142239
<section class="references">

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

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,70 @@
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 uniform = require( '@stdlib/random/array/uniform' );
2526
var randu = require( '@stdlib/random/base/randu' );
2627
var isnan = require( '@stdlib/math/base/assert/is-nan' );
27-
var EPS = require( '@stdlib/constants/float64/eps' );
28+
var floor = require( '@stdlib/math/base/special/floor' );
2829
var pkg = require( './../package.json' ).name;
2930
var variance = require( './../lib' );
3031

3132

3233
// MAIN //
3334

34-
bench( pkg, function benchmark( b ) {
35+
bench(pkg, function benchmark(b) {
36+
var len;
3537
var r;
3638
var p;
3739
var y;
3840
var i;
3941

42+
len = 100;
43+
r = new Float64Array(len);
44+
p = new Float64Array(len);
45+
for (i = 0; i < len; i++) {
46+
r[i] = floor((randu() * 10.0) + 1.0); // Treat r as int64_t
47+
p[i] = (randu() * 0.8) + 0.1;
48+
}
49+
50+
b.tic();
51+
for (i = 0; i < b.iterations; i++) {
52+
y = variance(r[i % len], p[i % len]);
53+
if (isnan(y)) {
54+
b.fail('should not return NaN');
55+
}
56+
}
57+
b.toc();
58+
if (isnan(y)) {
59+
b.fail('should not return NaN');
60+
}
61+
b.pass('benchmark finished');
62+
b.end();
63+
});
64+
65+
bench(pkg + ':factory', function benchmark(b) {
66+
var myvariance;
67+
var r;
68+
var p;
69+
var y;
70+
var i;
71+
var x = uniform(100, 1.0, 10.0);
72+
73+
r = 5;
74+
p = 0.5;
75+
myvariance = variance.factory(r, p);
76+
4077
b.tic();
41-
for ( i = 0; i < b.iterations; i++ ) {
42-
r = ceil( randu()*100.0 );
43-
p = ( randu()*1.0 ) + EPS;
44-
y = variance( r, p );
45-
if ( isnan( y ) ) {
46-
b.fail( 'should not return NaN' );
78+
for (i = 0; i < b.iterations; i++) {
79+
y = myvariance(x[i % x.length]);
80+
if (isnan(y)) {
81+
b.fail('should not return NaN');
4782
}
4883
}
4984
b.toc();
50-
if ( isnan( y ) ) {
51-
b.fail( 'should not return NaN' );
85+
if (isnan(y)) {
86+
b.fail('should not return NaN');
5287
}
53-
b.pass( 'benchmark finished' );
88+
b.pass('benchmark finished');
5489
b.end();
5590
});
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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 isnan = require( '@stdlib/math/base/assert/is-nan' );
28+
var tryRequire = require( '@stdlib/utils/try-require' );
29+
var floor = require( '@stdlib/math/base/special/floor' );
30+
var pkg = require( './../package.json' ).name;
31+
32+
33+
// VARIABLES //
34+
35+
var variance = tryRequire(resolve(__dirname, './../lib/native.js'));
36+
var opts = {
37+
'skip': (variance instanceof Error)
38+
};
39+
40+
41+
// MAIN //
42+
43+
bench(pkg + '::native', opts, function benchmark(b) {
44+
var len;
45+
var r;
46+
var p;
47+
var y;
48+
var i;
49+
50+
len = 100;
51+
r = new Float64Array(len);
52+
p = new Float64Array(len);
53+
for (i = 0; i < len; i++) {
54+
r[i] = floor((randu() * 10.0) + 1.0);
55+
p[i] = (randu() * 0.8) + 0.1;
56+
}
57+
58+
b.tic();
59+
for (i = 0; i < b.iterations; i++) {
60+
y = variance(r[i % len], p[i % len]);
61+
if (isnan(y)) {
62+
b.fail('should not return NaN');
63+
}
64+
}
65+
b.toc();
66+
if (isnan(y)) {
67+
b.fail('should not return NaN');
68+
}
69+
b.pass('benchmark finished');
70+
b.end();
71+
});

0 commit comments

Comments
 (0)