rustymath_core/sqrts.rs
1//! Square roots: √x, and √(1 - x²), √(1 + x²) and √(x - 1) √(x + 1) without the digits that squaring x first loses or the overflow it risks. `complex.rs` computes all four at complex arguments.
2use crate::float::Native;
3
4/// √x, or the principal √z of a complex z, whose real part is never negative, as a function object. A negative x gives NaN.
5#[derive(Clone, Copy, Debug)]
6pub struct Sqrt;
7
8/// The real part of √x, or of the principal √z of a complex z, as a function object: √x for a positive x, and 0 at or below 0. Its formula is `recipe::real_sqrt`.
9#[derive(Clone, Copy, Debug)]
10pub struct RealSqrt;
11
12/// The real part of √(1 - x²), or of its principal value at a complex z, as a function object: √(1 - x²) for x from -1 to 1, and 0 beyond. The real part of `0○` and `0○⁻¹`.
13#[derive(Clone, Copy, Debug)]
14pub struct RealSqrt1mx2;
15
16/// The real part of √(x - 1) √(x + 1), or of its principal value at a complex z, as a function object: x's sign times √(x² - 1) for |x| at least 1, and 0 between -1 and 1. The real part of `4○⁻¹`, on APL's branch.
17#[derive(Clone, Copy, Debug)]
18pub struct RealSqrtx2m1;
19
20/// The real part of √(-1 - x²), or of its principal value at a complex z, negated where the flag is set, as a function object: 0 for every real x, whose `8○` is imaginary. The real part of `8○`, and of `8○⁻¹` with the flag.
21#[derive(Clone, Copy, Debug)]
22pub struct RealSqrtm1mx2(pub bool);
23
24/// √(1 - x²) as √((1 - x)(1 + x)). For |x| from 1/2 to 1, the factor that nears 0 is exact, and elsewhere neither factor loses digits. A magnitude beyond 1 gives NaN.
25#[inline]
26pub(crate) fn sqrt1mx2<R: Native, const FUSED: bool>(x: R) -> R { ((R::one() - x) * (R::one() + x)).sqrt() }
27
28/// √(1 + x²) as the hypotenuse of x and 1, which never overflows.
29#[inline]
30pub(crate) fn sqrt1px2<R: Native, const FUSED: bool>(x: R) -> R { crate::pow::hypot::<R, FUSED>(x, R::one()) }
31
32/// √(x - 1) √(x + 1): √(x² - 1) with the sign of x, computed as √((|x| - 1)(|x| + 1)). Where that product overflows, the root rounds to |x|. A magnitude below 1 gives NaN.
33#[inline]
34pub(crate) fn sqrtx2m1<R: Native, const FUSED: bool>(x: R) -> R {
35 let a = x.abs();
36 let p = (a - R::one()) * (a + R::one());
37 (if p == R::infinity() { a } else { p.sqrt() }).copysign(x)
38}
39
40#[derive(Clone, Copy, Debug)]
41pub struct Sqrtm1mx2(pub bool);