Skip to content

Commit ef0435b

Browse files
authored
feat: add Wald distribution PDF
PR-URL: stdlib-js#9324 Closes: stdlib-js#209 Reviewed-by: Philipp Burckhardt <pburckhardt@outlook.com>
1 parent 518339b commit ef0435b

File tree

32 files changed

+3204
-0
lines changed

32 files changed

+3204
-0
lines changed
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2026 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+
# Probability Density Function
22+
23+
> [Wald][wald-distribution] distribution probability density function (PDF).
24+
25+
<section class="intro">
26+
27+
The [probability density function][pdf] (PDF) for a [Wald][wald-distribution] random variable is
28+
29+
<!-- <equation class="equation" label="eq:wald_pdf" align="center" raw="f(x;\mu,\lambda)=\sqrt{\frac{\lambda}{2\pi x^3}}\, e^{-\frac{\lambda(x-\mu)^2}{2\mu^2 x}}" alt="Probability density function (PDF) for a Wald distribution."> -->
30+
31+
```math
32+
f(x;\mu,\lambda)=\sqrt{\frac{\lambda}{2\pi x^3}}\, e^{-\frac{\lambda(x-\mu)^2}{2\mu^2 x}}
33+
```
34+
35+
<!-- <div class="equation" align="center" data-raw-text="f(x;\mu,\lambda)=\sqrt{\frac{\lambda}{2\pi x^3}}\, e^{-\frac{\lambda(x-\mu)^2}{2\mu^2 x}}" data-equation="eq:wald_pdf">
36+
<img src="https://cdn.jsdelivr.net/gh/stdlib-js/stdlib@51534079fef45e990850102147e8945fb023d1d0/lib/node_modules/@stdlib/stats/base/dists/wald/pdf/docs/img/equation_wald_pdf.svg" alt="Probability density function (PDF) for a Wald distribution.">
37+
<br>
38+
</div> -->
39+
40+
<!-- </equation> -->
41+
42+
where `µ > 0` is the mean and `λ > 0` is the shape parameter.
43+
44+
</section>
45+
46+
<!-- /.intro -->
47+
48+
<section class="usage">
49+
50+
## Usage
51+
52+
```javascript
53+
var pdf = require( '@stdlib/stats/base/dists/wald/pdf' );
54+
```
55+
56+
#### pdf( x, mu, lambda )
57+
58+
Evaluates the [probability density function][pdf] (PDF) for a [Wald][wald-distribution] distribution with parameters `mu` (mean) and `lambda` (shape parameter).
59+
60+
```javascript
61+
var y = pdf( 2.0, 1.0, 1.0 );
62+
// returns ~0.110
63+
64+
y = pdf( 0.5, 2.0, 3.0 );
65+
// returns ~0.362
66+
```
67+
68+
If provided `NaN` as any argument, the function returns `NaN`.
69+
70+
```javascript
71+
var y = pdf( NaN, 1.0, 1.0 );
72+
// returns NaN
73+
74+
y = pdf( 1.0, NaN, 1.0 );
75+
// returns NaN
76+
77+
y = pdf( 1.0, 1.0, NaN );
78+
// returns NaN
79+
```
80+
81+
If provided `mu <= 0`, the function returns `NaN`.
82+
83+
```javascript
84+
var y = pdf( 2.0, 0.0, 1.0 );
85+
// returns NaN
86+
87+
y = pdf( 2.0, -1.0, 1.0 );
88+
// returns NaN
89+
```
90+
91+
If provided `lambda < 0`, the function returns `NaN`.
92+
93+
```javascript
94+
var y = pdf( 2.0, 1.0, -1.0 );
95+
// returns NaN
96+
```
97+
98+
If provided `lambda = 0`, the function evaluates the [PDF][pdf] of a [degenerate distribution][degenerate-distribution] centered at `mu`.
99+
100+
```javascript
101+
var y = pdf( 2.0, 1.0, 0.0 );
102+
// returns 0.0
103+
104+
y = pdf( 1.0, 1.0, 0.0 );
105+
// returns Infinity
106+
```
107+
108+
If provided `x <= 0`, the function returns `0.0`.
109+
110+
```javascript
111+
var y = pdf( 0.0, 1.0, 1.0 );
112+
// returns 0.0
113+
114+
y = pdf( -1.0, 1.0, 1.0 );
115+
// returns 0.0
116+
```
117+
118+
#### pdf.factory( mu, lambda )
119+
120+
Partially applies `mu` and `lambda` to create a reusable `function` for evaluating the PDF.
121+
122+
```javascript
123+
var mypdf = pdf.factory( 1.0, 1.0 );
124+
125+
var y = mypdf( 2.0 );
126+
// returns ~0.110
127+
128+
y = mypdf( 0.5 );
129+
// returns ~0.879
130+
```
131+
132+
</section>
133+
134+
<!-- /.usage -->
135+
136+
<section class="examples">
137+
138+
## Examples
139+
140+
<!-- eslint no-undef: "error" -->
141+
142+
```javascript
143+
var uniform = require( '@stdlib/random/array/uniform' );
144+
var logEachMap = require( '@stdlib/console/log-each-map' );
145+
var EPS = require( '@stdlib/constants/float64/eps' );
146+
var pdf = require( '@stdlib/stats/base/dists/wald/pdf' );
147+
148+
var opts = {
149+
'dtype': 'float64'
150+
};
151+
var x = uniform( 10, EPS, 10.0, opts );
152+
var mu = uniform( 10, EPS, 10.0, opts );
153+
var lambda = uniform( 10, EPS, 20.0, opts );
154+
155+
logEachMap( 'x: %0.4f, µ: %0.4f, λ: %0.4f, f(x;µ,λ): %0.4f', x, mu, lambda, pdf );
156+
```
157+
158+
</section>
159+
160+
<!-- /.examples -->
161+
162+
<!-- C interface documentation. -->
163+
164+
* * *
165+
166+
<section class="c">
167+
168+
## C APIs
169+
170+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
171+
172+
<section class="intro">
173+
174+
</section>
175+
176+
<!-- /.intro -->
177+
178+
<!-- C usage documentation. -->
179+
180+
<section class="usage">
181+
182+
### Usage
183+
184+
```c
185+
#include "stdlib/stats/base/dists/wald/pdf.h"
186+
```
187+
188+
#### stdlib_base_dists_wald_pdf( x, mu, lambda )
189+
190+
Evaluates the [probability density function][pdf] (PDF) for a [Wald][wald-distribution] distribution with parameters `mu` (mean) and `lambda` (shape parameter).
191+
192+
```c
193+
double y = stdlib_base_dists_wald_pdf( 2.0, 1.0, 1.0 );
194+
// returns ~0.110
195+
```
196+
197+
The function accepts the following arguments:
198+
199+
- **x**: `[in] double` input value.
200+
- **mu**: `[in] double` mean.
201+
- **lambda**: `[in] double` shape parameter.
202+
203+
```c
204+
double stdlib_base_dists_wald_pdf( const double x, const double mu, const double lambda );
205+
```
206+
207+
</section>
208+
209+
<!-- /.usage -->
210+
211+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
212+
213+
<section class="notes">
214+
215+
</section>
216+
217+
<!-- /.notes -->
218+
219+
<!-- C API usage examples. -->
220+
221+
<section class="examples">
222+
223+
### Examples
224+
225+
```c
226+
#include "stdlib/stats/base/dists/wald/pdf.h"
227+
#include "stdlib/constants/float64/eps.h"
228+
#include <stdlib.h>
229+
#include <stdio.h>
230+
231+
static double random_uniform( const double min, const double max ) {
232+
double v = (double)rand() / ( (double)RAND_MAX + 1.0 );
233+
return min + ( v*(max-min) );
234+
}
235+
236+
int main( void ) {
237+
double lambda;
238+
double mu;
239+
double x;
240+
double y;
241+
int i;
242+
243+
for ( i = 0; i < 10; i++ ) {
244+
x = random_uniform( 0.0, 10.0 );
245+
mu = random_uniform( STDLIB_CONSTANT_FLOAT64_EPS, 10.0 );
246+
lambda = random_uniform( STDLIB_CONSTANT_FLOAT64_EPS, 20.0 );
247+
y = stdlib_base_dists_wald_pdf( x, mu, lambda );
248+
printf( "x: %lf, µ: %lf, λ: %lf, f(x;µ,λ): %lf\n", x, mu, lambda, y );
249+
}
250+
}
251+
```
252+
253+
</section>
254+
255+
<!-- /.examples -->
256+
257+
</section>
258+
259+
<!-- /.c -->
260+
261+
<!-- 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. -->
262+
263+
<section class="references">
264+
265+
</section>
266+
267+
<!-- /.references -->
268+
269+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
270+
271+
<section class="related">
272+
273+
</section>
274+
275+
<!-- /.related -->
276+
277+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
278+
279+
<section class="links">
280+
281+
[pdf]: https://en.wikipedia.org/wiki/Probability_density_function
282+
283+
[wald-distribution]: https://en.wikipedia.org/wiki/Inverse_Gaussian_distribution
284+
285+
[degenerate-distribution]: https://en.wikipedia.org/wiki/Degenerate_distribution
286+
287+
</section>
288+
289+
<!-- /.links -->
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 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 runiform = require( '@stdlib/random/array/uniform' );
25+
var uniform = require( '@stdlib/random/base/uniform' );
26+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
27+
var EPS = require( '@stdlib/constants/float64/eps' );
28+
var format = require( '@stdlib/string/format' );
29+
var pkg = require( './../package.json' ).name;
30+
var pdf = require( './../lib' );
31+
32+
33+
// MAIN //
34+
35+
bench( pkg, function benchmark( b ) {
36+
var lambda;
37+
var len;
38+
var mu;
39+
var x;
40+
var y;
41+
var i;
42+
43+
len = 100;
44+
x = runiform( len, EPS, 100.0 );
45+
mu = runiform( len, EPS, 50.0 );
46+
lambda = runiform( len, EPS, 20.0 );
47+
48+
b.tic();
49+
for ( i = 0; i < b.iterations; i++ ) {
50+
y = pdf( x[ i%len ], mu[ i%len ], lambda[ i%len ] );
51+
if ( isnan( y ) ) {
52+
b.fail( 'should not return NaN' );
53+
}
54+
}
55+
b.toc();
56+
if ( isnan( y ) ) {
57+
b.fail( 'should not return NaN' );
58+
}
59+
b.pass( 'benchmark finished' );
60+
b.end();
61+
});
62+
63+
bench( format( '%s:factory', pkg ), function benchmark( b ) {
64+
var lambda;
65+
var mypdf;
66+
var mu;
67+
var x;
68+
var y;
69+
var i;
70+
71+
mu = 1.0;
72+
lambda = 1.5;
73+
mypdf = pdf.factory( mu, lambda );
74+
75+
b.tic();
76+
for ( i = 0; i < b.iterations; i++ ) {
77+
x = uniform( EPS, 10.0 );
78+
y = mypdf( x );
79+
if ( isnan( y ) ) {
80+
b.fail( 'should not return NaN' );
81+
}
82+
}
83+
b.toc();
84+
if ( isnan( y ) ) {
85+
b.fail( 'should not return NaN' );
86+
}
87+
b.pass( 'benchmark finished' );
88+
b.end();
89+
});

0 commit comments

Comments
 (0)