Skip to content

Commit f502733

Browse files
committed
general derivatives for the hermite polynomials
1 parent 519e311 commit f502733

File tree

2 files changed

+105
-19
lines changed

2 files changed

+105
-19
lines changed

src/math/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,10 @@
9898
//! - [`laguerre_assoc_next`]
9999
//! - Hermite Polynomials
100100
//! - [`hermite_h`]
101+
//! - [`hermite_h_derivative`]
101102
//! - [`hermite_h_next`]
102103
//! - [`hermite_he`]
104+
//! - [`hermite_he_derivative`]
103105
//! - [`hermite_he_next`]
104106
//! - Gegenbauer Polynomials
105107
//! - [`gegenbauer`]

src/math/special_functions/hermite.rs

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,41 @@ pub fn hermite_h_next(n: u32, x: f64, pn: f64, pn_prev: f64) -> f64 {
2121
2.0 * hermite_he_next(n, x, pn, pn_prev)
2222
}
2323

24+
/// Hermite Polynomial *H<sub>n</sub>(x)*
25+
///
26+
/// Note that this is the "physicist's" Hermite polynomial.
27+
///
28+
/// This is a pure rust implementation equivalent to the `boost::math::hermite(n, x)` C++ function.
29+
/// <https://boost.org/doc/libs/latest/libs/math/doc/html/math_toolkit/sf_poly/hermite.html>
30+
pub fn hermite_h(n: u32, x: f64) -> f64 {
31+
// Implement Hermite polynomials via recurrence:
32+
let (mut p0, mut p1) = (1.0, 2.0 * x);
33+
if n == 0 {
34+
p0
35+
} else {
36+
for c in 1..n {
37+
(p0, p1) = (p1, hermite_h_next(c, x, p1, p0));
38+
}
39+
p1
40+
}
41+
}
42+
43+
/// *k*-th derivative of the Hermite polynomial *H<sub>n</sub>(x)*
44+
///
45+
/// This function does not exist in the Boost Math C++ library.
46+
#[doc(alias = "hermite_h_prime")]
47+
pub fn hermite_h_derivative(n: u32, x: f64, k: u32) -> f64 {
48+
if n < k {
49+
0.0
50+
} else {
51+
let mut p = hermite_h(n - k, x);
52+
for m in 0..k {
53+
p *= 2.0 * (n - m) as f64
54+
}
55+
p
56+
}
57+
}
58+
2459
/// Recurrence relation for [`hermite_he`]
2560
///
2661
/// *He<sub>n+1</sub>(x) = x He<sub>n</sub>(x) - n He<sub>n-1</sub>(x)*
@@ -42,25 +77,6 @@ pub fn hermite_he_next(n: u32, x: f64, pn: f64, pn_prev: f64) -> f64 {
4277
x * pn - (n as f64) * pn_prev
4378
}
4479

45-
/// Hermite Polynomial *H<sub>n</sub>(x)*
46-
///
47-
/// Note that this is the "physicist's" Hermite polynomial.
48-
///
49-
/// This is a pure rust implementation equivalent to the `boost::math::hermite(n, x)` C++ function.
50-
/// <https://boost.org/doc/libs/latest/libs/math/doc/html/math_toolkit/sf_poly/hermite.html>
51-
pub fn hermite_h(n: u32, x: f64) -> f64 {
52-
// Implement Hermite polynomials via recurrence:
53-
let (mut p0, mut p1) = (1.0, 2.0 * x);
54-
if n == 0 {
55-
p0
56-
} else {
57-
for c in 1..n {
58-
(p0, p1) = (p1, hermite_h_next(c, x, p1, p0));
59-
}
60-
p1
61-
}
62-
}
63-
6480
/// Monic Hermite Polynomial *He<sub>n</sub>(x)*
6581
///
6682
/// Note that this is the "probabilist's" Hermite polynomial, which is monic (leading coefficient
@@ -81,6 +97,22 @@ pub fn hermite_he(n: u32, x: f64) -> f64 {
8197
}
8298
}
8399

100+
/// *k*-th derivative of the Hermite polynomial *He<sub>n</sub>(x)*
101+
///
102+
/// This function does not exist in the Boost Math C++ library.
103+
#[doc(alias = "hermite_he_prime")]
104+
pub fn hermite_he_derivative(n: u32, x: f64, k: u32) -> f64 {
105+
if n < k {
106+
0.0
107+
} else {
108+
let mut p = hermite_he(n - k, x);
109+
for m in 0..k {
110+
p *= (n - m) as f64
111+
}
112+
p
113+
}
114+
}
115+
84116
#[cfg(test)]
85117
mod tests {
86118
use super::*;
@@ -115,4 +147,56 @@ mod tests {
115147
}
116148
}
117149
}
150+
151+
#[test]
152+
fn test_hermite_h_derivative() {
153+
for n in 0..20 {
154+
for x in -10..=10 {
155+
let x = x as f64 * 0.1;
156+
157+
let d0 = hermite_h_derivative(n, x, 0);
158+
assert_relative_eq!(d0, hermite_h(n, x));
159+
160+
let d1 = hermite_h_derivative(n, x, 1);
161+
if n >= 1 {
162+
assert_relative_eq!(d1, (2 * n) as f64 * hermite_h(n - 1, x));
163+
} else {
164+
assert_eq!(d1, 0.0)
165+
}
166+
167+
let d2 = hermite_h_derivative(n, x, 2);
168+
if n >= 2 {
169+
assert_relative_eq!(d2, (4 * n * (n - 1)) as f64 * hermite_h(n - 2, x));
170+
} else {
171+
assert_eq!(d2, 0.0)
172+
}
173+
}
174+
}
175+
}
176+
177+
#[test]
178+
fn test_hermite_he_derivative() {
179+
for n in 0..20 {
180+
for x in -10..=10 {
181+
let x = x as f64 * 0.1;
182+
183+
let d0 = hermite_he_derivative(n, x, 0);
184+
assert_relative_eq!(d0, hermite_he(n, x));
185+
186+
let d1 = hermite_he_derivative(n, x, 1);
187+
if n >= 1 {
188+
assert_relative_eq!(d1, n as f64 * hermite_he(n - 1, x));
189+
} else {
190+
assert_eq!(d1, 0.0)
191+
}
192+
193+
let d2 = hermite_he_derivative(n, x, 2);
194+
if n >= 2 {
195+
assert_relative_eq!(d2, (n * (n - 1)) as f64 * hermite_he(n - 2, x));
196+
} else {
197+
assert_eq!(d2, 0.0)
198+
}
199+
}
200+
}
201+
}
118202
}

0 commit comments

Comments
 (0)