Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,27 @@ macro_rules! np_assert_allclose {
}};
// Internal implementation
(@impl $actual:expr, $expected:expr, $rtol:expr, $atol:expr) => {{
use $crate::xsf::fp_error_metrics::ExtendedErrorArg;
let actual = $actual;
let expected = $expected;
let rtol: f64 = $rtol;
let atol: f64 = $atol;

assert_eq!(actual.len(), expected.len());
for (&a, &e) in actual.iter().zip(expected.iter()) {
let a: f64 = a;
let e: f64 = e;
if e.is_nan() {
assert!(a.is_nan(), "expected NaN but got {}", a);
if e.xsf_is_nan() {
assert!(a.xsf_is_nan(), "expected NaN but got {:?}", a);
} else {
let (err, tol) = if atol == 0.0 {
($crate::xsf::extended_relative_error(a, e), rtol)
(a.xsf_extended_relative_error(e), rtol)
} else if rtol == 0.0 {
($crate::xsf::extended_absolute_error(a, e), atol)
(a.xsf_extended_absolute_error(e), atol)
} else {
($crate::xsf::extended_absolute_error(a, e), atol + rtol * e.abs())
(a.xsf_extended_absolute_error(e), atol + rtol * e.xsf_magnitude())
};
assert!(
err <= tol,
"actual: {}, desired: {}, error: {:.3e}, tol: {:.3e}", a, e, err, tol
"actual: {:?}, desired: {:?}, error: {:.3e}, tol: {:.3e}", a, e, err, tol
);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/xsf/erf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,7 @@ mod tests {
c64(3.76900557, 4.06069723),
];
// assert_allclose(erz, erzr, atol=1.5e-4, rtol=0)
crate::np_assert_allclose!(&erz.map(|z| z.re), &erzr.map(|z| z.re), atol = 1.5e-4);
crate::np_assert_allclose!(&erz.map(|z| z.im), &erzr.map(|z| z.im), atol = 1.5e-4);
crate::np_assert_allclose!(&erz, &erzr, atol = 1.5e-4);
}

// dawsn
Expand Down
9 changes: 3 additions & 6 deletions src/xsf/evalpoly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,22 @@ mod tests {
fn test_cevalpoly_0() {
// p(z) = 0
let y = crate::cevalpoly(&[], c64(2.0, 3.0));
assert_eq!(y.re, 0.0);
assert_eq!(y.im, 0.0);
assert_eq!(y, c64(0.0, 0.0));
}

#[test]
fn test_cevalpoly_1() {
// p(z) = 5
let y = crate::cevalpoly(&[5.0], c64(2.0, 3.0));
// p(2+3i) = 5
assert_eq!(y.re, 5.0);
assert_eq!(y.im, 0.0);
assert_eq!(y, c64(5.0, 0.0));
}

#[test]
fn test_cevalpoly_2() {
// p(z) = 2z + 3
let y = crate::cevalpoly(&[2.0, 3.0], c64(1.0, 1.0));
// p(1+i) = 5 + 2i
assert_eq!(y.re, 5.0);
assert_eq!(y.im, 2.0);
assert_eq!(y, c64(5.0, 2.0));
}
}
23 changes: 23 additions & 0 deletions src/xsf/fp_error_metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ mod sealed {
pub trait ExtendedErrorArg: sealed::Sealed {
fn xsf_extended_absolute_error(self, other: Self) -> f64;
fn xsf_extended_relative_error(self, other: Self) -> f64;
fn xsf_magnitude(self) -> f64;
fn xsf_is_nan(self) -> bool;
}

impl ExtendedErrorArg for f64 {
Expand All @@ -21,6 +23,16 @@ impl ExtendedErrorArg for f64 {
fn xsf_extended_relative_error(self, other: Self) -> f64 {
unsafe { crate::ffi::xsf::extended_relative_error(self, other) }
}

#[inline(always)]
fn xsf_magnitude(self) -> f64 {
self.abs()
}

#[inline(always)]
fn xsf_is_nan(self) -> bool {
self.is_nan()
}
}

impl ExtendedErrorArg for Complex<f64> {
Expand All @@ -33,6 +45,17 @@ impl ExtendedErrorArg for Complex<f64> {
fn xsf_extended_relative_error(self, other: Self) -> f64 {
unsafe { crate::ffi::xsf::extended_relative_error_1(self.into(), other.into()) }
}

#[inline(always)]
fn xsf_magnitude(self) -> f64 {
// L2 norm requires `sqrt`, which isn't available in `no_std` mode, so use L1 norm instead
self.l1_norm()
}

#[inline(always)]
fn xsf_is_nan(self) -> bool {
self.is_nan()
}
}

/// Extended absolute error metric between two `f64` or `Complex<f64>` values
Expand Down
19 changes: 4 additions & 15 deletions src/xsf/fresnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,9 @@ mod tests {
/// Ported from `scipy.special.tests.test_basic.TestFresnel.test_fresnel_zeros`
#[test]
fn test_fresnel_zeros() {
fn assert_allclose(
actual: &[num_complex::Complex<f64>],
expected: &[num_complex::Complex<f64>],
atol: f64,
) {
assert_eq!(actual.len(), expected.len());
for (&a, &e) in actual.iter().zip(expected.iter()) {
assert!((a - e).norm() <= atol);
}
}

// szo, czo = special.fresnel_zeros(5)
let (szo, czo) = crate::fresnel_zeros(5);
assert_allclose(
crate::np_assert_allclose!(
&szo,
&[
c64(2.0093, 0.2885),
Expand All @@ -161,9 +150,9 @@ mod tests {
c64(4.0026, 0.2009),
c64(4.4742, 0.1877),
],
1.5e-3,
atol = 1.5e-3
);
assert_allclose(
crate::np_assert_allclose!(
&czo,
&[
c64(1.7437, 0.3057),
Expand All @@ -172,7 +161,7 @@ mod tests {
c64(3.8757, 0.2047),
c64(4.3611, 0.1907),
],
1.5e-3,
atol = 1.5e-3
);

// vals1 = special.fresnel(szo)[0]
Expand Down
Loading