Skip to content

Commit 519e311

Browse files
committed
Monic Hermite polynomials
1 parent ea8ca62 commit 519e311

File tree

2 files changed

+71
-14
lines changed

2 files changed

+71
-14
lines changed

src/math/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@
9999
//! - Hermite Polynomials
100100
//! - [`hermite_h`]
101101
//! - [`hermite_h_next`]
102+
//! - [`hermite_he`]
103+
//! - [`hermite_he_next`]
102104
//! - Gegenbauer Polynomials
103105
//! - [`gegenbauer`]
104106
//! - [`gegenbauer_derivative`]

src/math/special_functions/hermite.rs

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,39 @@
77
/// # Examples
88
///
99
/// ```
10-
/// # use boost::math::{hermite, hermite_next};
10+
/// # use boost::math::{hermite_h, hermite_h_next};
1111
/// let x = 0.42;
12-
/// let h0 = hermite(0, x); // 1
13-
/// let h1 = hermite(1, x); // 2x
14-
/// let h2 = hermite(2, x); // 4x² - 2
15-
/// let h3 = hermite(3, x); // 8x³ - 12x
16-
/// assert_eq!(hermite_next(1, x, h1, h0), h2);
17-
/// assert_eq!(hermite_next(2, x, h2, h1), h3);
12+
/// let p0 = hermite_h(0, x); // 1
13+
/// let p1 = hermite_h(1, x); // 2x
14+
/// let p2 = hermite_h(2, x); // 4x² - 2
15+
/// let p3 = hermite_h(3, x); // 8x³ - 12x
16+
/// assert_eq!(hermite_h_next(1, x, p1, p0), p2);
17+
/// assert_eq!(hermite_h_next(2, x, p2, p1), p3);
1818
/// ```
19-
#[allow(non_snake_case)]
2019
#[inline(always)]
21-
pub fn hermite_h_next(n: u32, x: f64, Hn: f64, Hn_prev: f64) -> f64 {
22-
2.0 * (x * Hn - (n as f64) * Hn_prev)
20+
pub fn hermite_h_next(n: u32, x: f64, pn: f64, pn_prev: f64) -> f64 {
21+
2.0 * hermite_he_next(n, x, pn, pn_prev)
22+
}
23+
24+
/// Recurrence relation for [`hermite_he`]
25+
///
26+
/// *He<sub>n+1</sub>(x) = x He<sub>n</sub>(x) - n He<sub>n-1</sub>(x)*
27+
///
28+
/// # Examples
29+
///
30+
/// ```
31+
/// # use boost::math::{hermite_he, hermite_he_next};
32+
/// let x = 0.42;
33+
/// let p0 = hermite_he(0, x); // 1
34+
/// let p1 = hermite_he(1, x); // 2x
35+
/// let p2 = hermite_he(2, x); // 4x² - 2
36+
/// let p3 = hermite_he(3, x); // 8x³ - 12x
37+
/// assert_eq!(hermite_he_next(1, x, p1, p0), p2);
38+
/// assert_eq!(hermite_he_next(2, x, p2, p1), p3);
39+
/// ```
40+
#[inline(always)]
41+
pub fn hermite_he_next(n: u32, x: f64, pn: f64, pn_prev: f64) -> f64 {
42+
x * pn - (n as f64) * pn_prev
2343
}
2444

2545
/// Hermite Polynomial *H<sub>n</sub>(x)*
@@ -41,22 +61,57 @@ pub fn hermite_h(n: u32, x: f64) -> f64 {
4161
}
4262
}
4363

64+
/// Monic Hermite Polynomial *He<sub>n</sub>(x)*
65+
///
66+
/// Note that this is the "probabilist's" Hermite polynomial, which is monic (leading coefficient
67+
/// is 1). It is related to the "physicist's" Hermite polynomial ([`hermite_h`]) by
68+
///
69+
/// *He<sub>n</sub>(x) = 2<sup>-n/2</sup> H<sub>n</sub>(x / √2)*
70+
///
71+
/// This function does not exist in the Boost Math C++ library.
72+
pub fn hermite_he(n: u32, x: f64) -> f64 {
73+
let (mut p0, mut p1) = (1.0, x);
74+
if n == 0 {
75+
p0
76+
} else {
77+
for c in 1..n {
78+
(p0, p1) = (p1, hermite_he_next(c, x, p1, p0));
79+
}
80+
p1
81+
}
82+
}
83+
4484
#[cfg(test)]
4585
mod tests {
4686
use super::*;
87+
use core::f64::consts::FRAC_1_SQRT_2;
4788

48-
const RTOL: f64 = 1e-14;
89+
const ATOL: f64 = 1e-15;
90+
const RTOL: f64 = 1e-12;
4991

5092
fn hermite_h_ffi(n: u32, x: f64) -> f64 {
5193
unsafe { crate::ffi::math_hermite(n as core::ffi::c_uint, x) }
5294
}
5395

5496
#[test]
55-
fn test_hermite() {
97+
fn test_hermite_h() {
98+
for n in 0..20 {
99+
for x in -10..=10 {
100+
let x = x as f64 * 0.1;
101+
let h = hermite_h_ffi(n, x);
102+
assert_relative_eq!(hermite_h(n, x), h, epsilon = ATOL, max_relative = RTOL);
103+
}
104+
}
105+
}
106+
107+
#[test]
108+
fn test_hermite_he() {
56109
for n in 0..20 {
57-
for x in -2..=2 {
110+
let c = FRAC_1_SQRT_2.powi(n as i32);
111+
for x in -10..=10 {
58112
let x = x as f64 * 0.1;
59-
assert_relative_eq!(hermite_h(n, x), hermite_h_ffi(n, x), max_relative = RTOL);
113+
let h = c * hermite_h(n, FRAC_1_SQRT_2 * x);
114+
assert_relative_eq!(hermite_he(n, x), h, epsilon = ATOL, max_relative = RTOL);
60115
}
61116
}
62117
}

0 commit comments

Comments
 (0)