Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
add accuracy testcase
  • Loading branch information
pascalkuthe authored Dec 14, 2024
commit 6178de61f8fdfb1a934665a7a33393abb7250786
65 changes: 65 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2156,6 +2156,71 @@ pub(crate) mod test {
}
}


#[test]
#[allow(clippy::float_cmp)]
fn test_sqrt_accuract() {
fn naive_sqrt(c: Complex64) -> Complex64 {
let (r, theta) = c.to_polar();
Complex64::from_polar(r.sqrt(), theta / 2.0)
}

#[track_caller]
fn check_sqrt(re: f64, im: f64, exact_sqrt_re: f64, exact_sqrt_im: f64) {
let sqrt = Complex::new(re, im).sqrt();
assert_eq!(sqrt.re, exact_sqrt_re, "real(sqrt(c))e invalid for {re}");
assert_eq!(sqrt.im, exact_sqrt_im, "imag(sqrt(c))e invalid for {re}");
let naive_sqrt = naive_sqrt(Complex::new(re, im));
assert_ne!(naive_sqrt, sqrt, "invalid testcase {re} {im}");
}
// reference values were computed with numpy but are identical
// with musl and glibc, showing that we round correctly both
// in reasonable ranges and extremes cases. All of these tests
// fail with a naive sqrt implementation based on phase shift (this
// is checked as part of the tests).
//
// The testcases were generated by the following python script:
//
// import numpy as np
// vals = [
// (0.1, 0.1),
// (0.1, 1 / 3),
// (1 / 3, 0.1),
// (1 / 3, 1 / 3),
// (1.1, 1e-100),
// (1e-100, 0.1),
// (1e-100, 1.1),
// (1e-100, 1e-100),
// ]
// for re, im in vals:
// reference = np.sqrt(re + im * 1j)
// print(f"check_sqrt({re}, {im}, {reference.real}, {reference.imag});")

check_sqrt(0.1, 0.1, 0.34743442276011566, 0.14391204994250742);
check_sqrt(
0.1,
0.3333333333333333,
0.4732917794361556,
0.3521435907152684,
);
check_sqrt(
0.3333333333333333,
0.1,
0.5836709476652998,
0.08566470577300687,
);
check_sqrt(
0.3333333333333333,
0.3333333333333333,
0.6343255686650054,
0.26274625350107117,
);
check_sqrt(1.1, 1e-100, 1.0488088481701516, 4.767312946227961e-101);
check_sqrt(1e-100, 0.1, 0.22360679774997896, 0.223606797749979);
check_sqrt(1e-100, 1.1, 0.7416198487095663, 0.7416198487095663);
check_sqrt(1e-100, 1e-100, 1.09868411346781e-50, 4.550898605622274e-51);
}

#[test]
fn test_cbrt() {
assert!(close(_0_0i.cbrt(), _0_0i));
Expand Down