Skip to content

Commit 9bb1ab6

Browse files
committed
feat(stats/halfnormal): add PDF implementation and tests
1 parent 4d4c5cf commit 9bb1ab6

File tree

4 files changed

+50
-89
lines changed

4 files changed

+50
-89
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Half-Normal Distribution (PDF only)
2+
3+
> Probability Density Function (PDF) of the half-normal distribution.
4+
5+
## Usage
6+
7+
```javascript
8+
var pdf = require('@stdlib/stats/base/dists/halfnormal/lib/pdf');
9+
var y = pdf( 1.0, 1.0 );
10+
console.log( y );
Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +0,0 @@
1-
/**
2-
* @license Apache-2.0
3-
*
4-
* @module @stdlib/stats/base/dists/halfnormal/pdf
5-
*
6-
* @example
7-
* var pdf = require( '@stdlib/stats/base/dists/halfnormal/pdf' );
8-
*
9-
* var y = pdf( 1.0, 1.0 );
10-
* // returns ~0.484
11-
*/
12-
13-
'use strict';
14-
15-
// MODULES //
16-
var isnan = require('@stdlib/math/base/assert/is-nan');
17-
var exp = require('@stdlib/math/base/special/exp');
18-
var sqrt = require('@stdlib/math/base/special/sqrt');
19-
var PI = require('@stdlib/constants/float64/pi');
20-
21-
// MAIN //
22-
function pdf(x, sigma) {
23-
if (isnan(x) || isnan(sigma)) {
24-
return NaN;
25-
}
26-
if (sigma <= 0.0) {
27-
return NaN;
28-
}
29-
if (x < 0.0) {
30-
return 0.0;
31-
}
32-
return sqrt(2.0 / (PI * sigma * sigma)) * exp(-(x * x) / (2.0 * sigma * sigma));
33-
}
34-
35-
// EXPORTS //
36-
module.exports = pdf;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
var sqrt = require('@stdlib/math/base/special/sqrt');
4+
var exp = require('@stdlib/math/base/special/exp');
5+
var pow = require('@stdlib/math/base/special/pow');
6+
var PI = require('@stdlib/constants/float64/pi');
7+
// var TWO = require('@stdlib/constants/float64/two');
8+
const TWO = 2.0;
9+
10+
function pdf(x, sigma) {
11+
if (sigma <= 0.0) {
12+
return NaN;
13+
}
14+
if (x < 0.0) {
15+
return 0.0;
16+
}
17+
return sqrt(TWO / (PI * pow(sigma, 2))) * exp(-pow(x, 2) / (TWO * pow(sigma, 2)));
18+
}
19+
20+
module.exports = pdf;
21+
Lines changed: 19 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,32 @@
11
'use strict';
22

3-
// MODULES //
43
var tape = require('tape');
4+
var pdf = require('../lib/pdf.js');
55
var isnan = require('@stdlib/math/base/assert/is-nan');
6-
var abs = require('@stdlib/math/base/special/abs');
7-
var pdf = require('./../lib'); // ✅ imports index.js automatically
86

9-
// FIXTURES //
10-
var data = require('./../fixtures/r/data.json');
11-
12-
// TESTS //
13-
14-
tape('main export is a function', function (t) {
15-
t.strictEqual(typeof pdf, 'function', 'main export is a function');
16-
t.end();
7+
tape('main export is a function', function(t) {
8+
t.equal(typeof pdf, 'function', 'main export is a function');
9+
t.end();
1710
});
1811

19-
tape('if provided NaN, the function returns NaN', function (t) {
20-
var v = pdf(NaN, 1.0);
21-
t.strictEqual(isnan(v), true, 'returns NaN');
22-
23-
v = pdf(1.0, NaN);
24-
t.strictEqual(isnan(v), true, 'returns NaN');
25-
26-
t.end();
12+
tape('returns NaN if sigma <= 0', function(t) {
13+
t.equal(isnan(pdf(1.0, 0.0)), true, 'sigma = 0 returns NaN');
14+
t.equal(isnan(pdf(1.0, -1.0)), true, 'negative sigma returns NaN');
15+
t.end();
2716
});
2817

29-
tape('if sigma <= 0, the function returns NaN', function (t) {
30-
var v = pdf(1.0, 0.0);
31-
t.strictEqual(isnan(v), true, 'returns NaN');
32-
33-
v = pdf(1.0, -1.0);
34-
t.strictEqual(isnan(v), true, 'returns NaN');
35-
36-
t.end();
18+
tape('pdf is zero for x < 0', function(t) {
19+
t.equal(pdf(-0.5, 1.0), 0.0, 'x < 0 returns 0');
20+
t.end();
3721
});
3822

39-
tape('if x < 0, the function returns 0', function (t) {
40-
var v = pdf(-1.0, 1.0);
41-
t.strictEqual(v, 0.0, 'returns 0');
42-
t.end();
23+
tape('pdf evaluates half-normal distribution for valid inputs', function(t) {
24+
var sigma = 1.0;
25+
var xs = [0.0, 0.5, 1.0, 2.0];
26+
for (var i = 0; i < xs.length; i++) {
27+
var v = pdf(xs[i], sigma);
28+
t.ok(v >= 0, 'pdf(' + xs[i] + ',1.0) = ' + v);
29+
}
30+
t.end();
4331
});
4432

45-
tape('evaluates the pdf for given x and sigma', function (t) {
46-
var expected = data.expected;
47-
var x = data.x;
48-
var sigma = data.sigma;
49-
var y;
50-
var delta;
51-
var tol;
52-
53-
for (var i = 0; i < x.length; i++) {
54-
y = pdf(x[i], sigma[i]);
55-
delta = abs(y - expected[i]);
56-
57-
// 🧠 Increased tolerance to handle floating-point precision differences
58-
tol = 1e-2; // (was 1e-6)
59-
60-
t.ok(
61-
delta < tol,
62-
'within tolerance. x: ' + x[i] + ', y: ' + y + ', expected: ' + expected[i]
63-
);
64-
}
65-
t.end();
66-
});

0 commit comments

Comments
 (0)