UPDATE: Dump of initial files
This commit is contained in:
183
base/src/functions/engineering/transcendental/test_bessel.rs
Normal file
183
base/src/functions/engineering/transcendental/test_bessel.rs
Normal file
@@ -0,0 +1,183 @@
|
||||
use crate::functions::engineering::transcendental::bessel_k;
|
||||
|
||||
use super::{
|
||||
bessel_i::bessel_i,
|
||||
bessel_j0_y0::{j0, y0},
|
||||
bessel_j1_y1::j1,
|
||||
bessel_jn_yn::{jn, yn},
|
||||
};
|
||||
|
||||
const EPS: f64 = 1e-13;
|
||||
const EPS_LOW: f64 = 1e-6;
|
||||
|
||||
// Known values computed with Arb via Nemo.jl in Julia
|
||||
// You can also use Mathematica
|
||||
/// But please do not use Excel or any other software without arbitrary precision
|
||||
|
||||
fn numbers_are_close(a: f64, b: f64) -> bool {
|
||||
if a == b {
|
||||
// avoid underflow if a = b = 0.0
|
||||
return true;
|
||||
}
|
||||
(a - b).abs() / ((a * a + b * b).sqrt()) < EPS
|
||||
}
|
||||
|
||||
fn numbers_are_somewhat_close(a: f64, b: f64) -> bool {
|
||||
if a == b {
|
||||
// avoid underflow if a = b = 0.0
|
||||
return true;
|
||||
}
|
||||
(a - b).abs() / ((a * a + b * b).sqrt()) < EPS_LOW
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bessel_j0_known_values() {
|
||||
let cases = [
|
||||
(2.4, 0.002507683297243813),
|
||||
(0.5, 0.9384698072408129),
|
||||
(1.0, 0.7651976865579666),
|
||||
(1.12345, 0.7084999488947348),
|
||||
(27.0, 0.07274191800588709),
|
||||
(33.0, 0.09727067223550946),
|
||||
(2e-4, 0.9999999900000001),
|
||||
(0.0, 1.0),
|
||||
(1e10, 2.175591750246892e-6),
|
||||
];
|
||||
for (value, known) in cases {
|
||||
let f = j0(value);
|
||||
assert!(
|
||||
numbers_are_close(f, known),
|
||||
"Got: {f}, expected: {known} for j0({value})"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bessel_y0_known_values() {
|
||||
let cases = [
|
||||
(2.4, 0.5104147486657438),
|
||||
(0.5, -0.4445187335067065),
|
||||
(1.0, 0.08825696421567692),
|
||||
(1.12345, 0.1783162909790613),
|
||||
(27.0, 0.1352149762078722),
|
||||
(33.0, 0.0991348255208796),
|
||||
(2e-4, -5.496017824512429),
|
||||
(1e10, -7.676508175792937e-6),
|
||||
(1e-300, -439.8351636227653),
|
||||
];
|
||||
for (value, known) in cases {
|
||||
let f = y0(value);
|
||||
assert!(
|
||||
numbers_are_close(f, known),
|
||||
"Got: {f}, expected: {known} for y0({value})"
|
||||
);
|
||||
}
|
||||
assert!(y0(0.0).is_infinite());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bessel_j1_known_values() {
|
||||
// Values computed with Maxima, the computer algebra system
|
||||
// TODO: Recompute
|
||||
let cases = [
|
||||
(2.4, 0.5201852681819311),
|
||||
(0.5, 0.2422684576748738),
|
||||
(1.0, 0.4400505857449335),
|
||||
(1.17232, 0.4910665691824317),
|
||||
(27.5, 0.1521418932046569),
|
||||
(42.0, -0.04599388822188721),
|
||||
(3e-5, 1.499999999831249E-5),
|
||||
(350.0, -0.02040531295214455),
|
||||
(0.0, 0.0),
|
||||
(1e12, -7.913802683850441e-7),
|
||||
];
|
||||
for (value, known) in cases {
|
||||
let f = j1(value);
|
||||
assert!(
|
||||
numbers_are_close(f, known),
|
||||
"Got: {f}, expected: {known} for j1({value})"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bessel_jn_known_values() {
|
||||
// Values computed with Maxima, the computer algebra system
|
||||
// TODO: Recompute
|
||||
let cases = [
|
||||
(3, 0.5, 0.002_563_729_994_587_244),
|
||||
(4, 0.5, 0.000_160_736_476_364_287_6),
|
||||
(-3, 0.5, -0.002_563_729_994_587_244),
|
||||
(-4, 0.5, 0.000_160_736_476_364_287_6),
|
||||
(3, 30.0, 0.129211228759725),
|
||||
(-3, 30.0, -0.129211228759725),
|
||||
(4, 30.0, -0.052609000321320355),
|
||||
(20, 30.0, 0.0048310199934040645),
|
||||
(7, 0.0, 0.0),
|
||||
];
|
||||
for (n, value, known) in cases {
|
||||
let f = jn(n, value);
|
||||
assert!(
|
||||
numbers_are_close(f, known),
|
||||
"Got: {f}, expected: {known} for jn({n}, {value})"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bessel_yn_known_values() {
|
||||
let cases = [
|
||||
(3, 0.5, -42.059494304723883),
|
||||
(4, 0.5, -499.272_560_819_512_3),
|
||||
(-3, 0.5, 42.059494304723883),
|
||||
(-4, 0.5, -499.272_560_819_512_3),
|
||||
(3, 35.0, -0.13191405300596323),
|
||||
(-12, 12.2, -0.310438011314211),
|
||||
(7, 1e12, 1.016_712_505_197_956_3e-7),
|
||||
(35, 3.0, -6.895_879_073_343_495e31),
|
||||
];
|
||||
for (n, value, known) in cases {
|
||||
let f = yn(n, value);
|
||||
assert!(
|
||||
numbers_are_close(f, known),
|
||||
"Got: {f}, expected: {known} for yn({n}, {value})"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bessel_in_known_values() {
|
||||
let cases = [
|
||||
(1, 0.5, 0.2578943053908963),
|
||||
(3, 0.5, 0.002645111968990286),
|
||||
(7, 0.2, 1.986608521182497e-11),
|
||||
(7, 0.0, 0.0),
|
||||
(0, -0.5, 1.0634833707413236),
|
||||
// worse case scenario
|
||||
(0, 3.7499, 9.118167894541882),
|
||||
(0, 3.7501, 9.119723897590003),
|
||||
];
|
||||
for (n, value, known) in cases {
|
||||
let f = bessel_i(n, value);
|
||||
assert!(
|
||||
numbers_are_somewhat_close(f, known),
|
||||
"Got: {f}, expected: {known} for in({n}, {value})"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bessel_kn_known_values() {
|
||||
let cases = [
|
||||
(1, 0.5, 1.656441120003301),
|
||||
(0, 0.5, 0.9244190712276659),
|
||||
(3, 0.5, 62.05790952993026),
|
||||
];
|
||||
for (n, value, known) in cases {
|
||||
let f = bessel_k(n, value);
|
||||
assert!(
|
||||
numbers_are_somewhat_close(f, known),
|
||||
"Got: {f}, expected: {known} for kn({n}, {value})"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user