Skip to content

Commit 093b515

Browse files
committed
feat: implement entropy for hypergeometric distribution
--- 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: passed - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - 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: missing_dependencies - task: lint_c_examples status: missing_dependencies - task: lint_c_benchmarks status: missing_dependencies - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed ---
1 parent 626f31e commit 093b515

28 files changed

Lines changed: 2075 additions & 0 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2018 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# Entropy
22+
23+
> [Hypergeometric][hypergeometric-distribution] distribution [entropy][entropy].
24+
25+
The [entropy][entropy] (in nats) for a [hypergeometric][hypergeometric-distribution] random variable is
26+
27+
<div class="equation" align="center" data-raw-text="H(X) = -\sum_{k=\max(0, n+K-N)}^{\min(n, K)} P(X=k) \ln(P(X=k))" data-equation="eq:entropy">
28+
<img src="https://cdn.jsdelivr.net/gh/stdlib-js/stdlib@515340d9d7170753/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/entropy/docs/img/equation_entropy.svg" alt="Entropy for a hypergeometric distribution.">
29+
<br>
30+
</div>
31+
32+
where `N` is the population size, `K` is the subpopulation size, and `n` is the number of draws.
33+
34+
<section class="usage">
35+
36+
## Usage
37+
38+
```javascript
39+
var entropy = require( '@stdlib/stats/base/dists/hypergeometric/entropy' );
40+
```
41+
42+
#### entropy( N, K, n )
43+
44+
Returns the [entropy][entropy] of a [hypergeometric][hypergeometric-distribution] distribution with parameters `N` (population size), `K` (subpopulation size), and `n` (number of draws).
45+
46+
```javascript
47+
var v = entropy( 16, 11, 4 );
48+
// returns ~1.216
49+
50+
v = entropy( 2, 1, 1 );
51+
// returns ~0.693
52+
```
53+
54+
If provided `NaN` for any parameter, the function returns `NaN`.
55+
56+
```javascript
57+
var v = entropy( NaN, 10, 4 );
58+
// returns NaN
59+
60+
v = entropy( 20, NaN, 4 );
61+
// returns NaN
62+
63+
v = entropy( 20, 10, NaN );
64+
// returns NaN
65+
```
66+
67+
If provided a parameter that is not a nonnegative integer, the function returns `NaN`.
68+
69+
```javascript
70+
var v = entropy( 10.5, 5, 2 );
71+
// returns NaN
72+
73+
v = entropy( 10, 1.5, 2 );
74+
// returns NaN
75+
76+
v = entropy( 10, 5, -2.0 );
77+
// returns NaN
78+
```
79+
80+
If the number of draws `n` exceeds the population size `N`, the function returns `NaN`.
81+
82+
```javascript
83+
var v = entropy( 10, 5, 12 );
84+
// returns NaN
85+
```
86+
87+
If the subpopulation size `K` exceeds the population size `N`, the function returns `NaN`.
88+
89+
```javascript
90+
var v = entropy( 10, 12, 5 );
91+
// returns NaN
92+
```
93+
94+
</section>
95+
96+
<!-- /.usage -->
97+
98+
<section class="examples">
99+
100+
## Examples
101+
102+
```javascript
103+
var entropy = require( '@stdlib/stats/base/dists/hypergeometric/entropy' );
104+
105+
var v = entropy( 16, 11, 4 );
106+
console.log( v );
107+
// => 1.2156868611027067
108+
109+
v = entropy( 2, 1, 1 );
110+
console.log( v );
111+
// => 0.6931471805599453
112+
113+
v = entropy( 10, 5, 12 );
114+
console.log( v );
115+
// => NaN
116+
```
117+
118+
</section>
119+
120+
<!-- /.examples -->
121+
122+
<section class="references">
123+
124+
</section>
125+
126+
<!-- /.references -->
127+
128+
<section class="related">
129+
130+
</section>
131+
132+
<!-- /.related -->
133+
134+
<section class="links">
135+
136+
[hypergeometric-distribution]: https://en.wikipedia.org/wiki/Hypergeometric_distribution
137+
138+
[entropy]: https://en.wikipedia.org/wiki/Entropy_%28information_theory%29
139+
140+
</section>
141+
142+
<!-- /.links -->
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) 2018 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 bench = require( '@stdlib/bench' );
24+
var Float64Array = require( '@stdlib/array/float64' );
25+
var discreteUniform = require( '@stdlib/random/base/discrete-uniform' );
26+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
27+
var pkg = require( './../package.json' ).name;
28+
var mean = require( './../lib' );
29+
30+
31+
// MAIN //
32+
33+
bench( pkg, function benchmark( b ) {
34+
var len;
35+
var N;
36+
var K;
37+
var n;
38+
var y;
39+
var i;
40+
41+
len = 100;
42+
N = new Float64Array( len );
43+
K = new Float64Array( len );
44+
n = new Float64Array( len );
45+
for ( i = 0; i < len; i++ ) {
46+
N[ i ] = discreteUniform( 1, 100 );
47+
K[ i ] = discreteUniform( 1, N[ i ] );
48+
n[ i ] = discreteUniform( 1, N[ i ] );
49+
}
50+
51+
b.tic();
52+
for ( i = 0; i < b.iterations; i++ ) {
53+
y = mean( N[ i % len ], K[ i % len ], n[ i % len ] );
54+
if ( isnan( y ) ) {
55+
b.fail( 'should not return NaN' );
56+
}
57+
}
58+
b.toc();
59+
if ( isnan( y ) ) {
60+
b.fail( 'should not return NaN' );
61+
}
62+
b.pass( 'benchmark finished' );
63+
b.end();
64+
});
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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 discreteUniform = require( '@stdlib/random/base/discrete-uniform' );
27+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
28+
var tryRequire = require( '@stdlib/utils/try-require' );
29+
var pkg = require( './../package.json' ).name;
30+
31+
32+
// VARIABLES //
33+
34+
var mean = tryRequire( resolve( __dirname, './../lib/native.js' ) );
35+
var opts = {
36+
'skip': ( mean instanceof Error )
37+
};
38+
39+
40+
// MAIN //
41+
42+
bench( pkg+'::native', opts, function benchmark( b ) {
43+
var len;
44+
var N;
45+
var K;
46+
var n;
47+
var y;
48+
var i;
49+
50+
len = 100;
51+
N = new Float64Array( len );
52+
K = new Float64Array( len );
53+
n= new Float64Array( len );
54+
for ( i = 0; i < len; i++ ) {
55+
N[ i ] = discreteUniform( 1, 100 );
56+
K[ i ] = discreteUniform( 1, N[ i ] );
57+
n[ i ] = discreteUniform( 1, N[ i ] );
58+
}
59+
b.tic();
60+
for ( i = 0; i < b.iterations; i++ ) {
61+
y = mean( N[ i % len ], K[ i % len ], n[ i % len ] );
62+
if ( isnan( y ) ) {
63+
b.fail( 'should not return NaN' );
64+
}
65+
}
66+
b.toc();
67+
if ( isnan( y ) ) {
68+
b.fail( 'should not return NaN' );
69+
}
70+
b.pass( 'benchmark finished' );
71+
b.end();
72+
});

0 commit comments

Comments
 (0)