use crate::error::SpecialResult;
#[inline]
pub fn struve_h(nu: f64, x: f64) -> SpecialResult<f64> {
crate::struve::struve(nu, x)
}
#[inline]
pub fn struve_l(nu: f64, x: f64) -> SpecialResult<f64> {
crate::struve::mod_struve(nu, x)
}
#[inline]
pub fn struve_h0(x: f64) -> SpecialResult<f64> {
crate::struve::struve(0.0, x)
}
#[inline]
pub fn struve_h1(x: f64) -> SpecialResult<f64> {
crate::struve::struve(1.0, x)
}
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_relative_eq;
#[test]
fn test_struve_h0_at_zero() {
let val = struve_h0(0.0).expect("H_0(0)");
assert_relative_eq!(val, 0.0, epsilon = 1e-14);
}
#[test]
fn test_struve_h1_at_zero() {
let val = struve_h1(0.0).expect("H_1(0)");
assert_relative_eq!(val, 0.0, epsilon = 1e-14);
}
#[test]
fn test_struve_h_consistency_with_h0() {
for x in [0.5_f64, 1.0, 2.0, 5.0] {
let h = struve_h(0.0, x).expect("H");
let h0 = struve_h0(x).expect("H0");
assert!((h - h0).abs() < 1e-14, "at x={x}: struve_h={h}, struve_h0={h0}");
}
}
#[test]
fn test_struve_h_consistency_with_h1() {
for x in [0.5_f64, 1.0, 2.0, 5.0] {
let h = struve_h(1.0, x).expect("H");
let h1 = struve_h1(x).expect("H1");
assert!((h - h1).abs() < 1e-14, "at x={x}: struve_h={h}, struve_h1={h1}");
}
}
#[test]
fn test_struve_l0_positive() {
for x in [0.5_f64, 1.0, 2.0, 5.0] {
let l = struve_l(0.0, x).expect("L_0");
assert!(l > 0.0, "L_0({x}) should be positive, got {l}");
}
}
#[test]
fn test_struve_l_consistency_with_mod_struve() {
for x in [1.0_f64, 2.0, 3.0] {
let l = struve_l(0.0, x).expect("struve_l");
let ms = crate::struve::mod_struve(0.0, x).expect("mod_struve");
assert!((l - ms).abs() < 1e-14, "at x={x}: struve_l={l}, mod_struve={ms}");
}
}
#[test]
fn test_struve_h_small_argument() {
let x = 0.1_f64;
let h0 = struve_h0(x).expect("H_0(0.1)");
let approx = 2.0 * x / std::f64::consts::PI;
assert_relative_eq!(h0, approx, epsilon = 1e-4);
}
#[test]
fn test_struve_h_h1_small_argument() {
let x = 0.1_f64;
let h1 = struve_h1(x).expect("H_1(0.1)");
let approx = 2.0 * x * x / (3.0 * std::f64::consts::PI);
assert_relative_eq!(h1, approx, epsilon = 1e-4);
}
#[test]
fn test_struve_h_finite() {
for nu in [0.0_f64, 1.0, 2.0, 0.5, 1.5] {
for x in [0.0_f64, 1.0, 5.0, 10.0] {
let val = struve_h(nu, x).expect("struve_h");
assert!(val.is_finite(), "H_{nu}({x}) should be finite, got {val}");
}
}
}
#[test]
fn test_struve_l_monotone() {
let l1 = struve_l(0.0, 1.0).expect("L_0(1)");
let l2 = struve_l(0.0, 2.0).expect("L_0(2)");
let l3 = struve_l(0.0, 3.0).expect("L_0(3)");
assert!(l2 > l1, "L_0 should increase: L(1)={l1}, L(2)={l2}");
assert!(l3 > l2, "L_0 should increase: L(2)={l2}, L(3)={l3}");
}
}