pub fn eatanhe(x: f64, es: f64) -> f64 {
(es * (es * x).atanh()).abs()
}
pub fn taupf(tau: f64, es: f64) -> f64 {
let tau1: f64 = 1.0_f64.hypot(tau);
let sig = eatanhe(tau / tau1, es).sinh();
1.0_f64.hypot(sig) * tau - sig * tau1
}
pub fn tauf(taup: f64, es: f64) -> f64 {
let numit = 5;
let tol: f64 = f64::EPSILON.sqrt() / 10.0;
let e2m: f64 = 1.0 - es.powi(2);
let stol: f64 = tol * taup.abs().max(1.0);
let mut tau: f64 = taup / e2m;
for _ in (0..numit).rev() {
let taupa: f64 = taupf(tau, es);
let dtau: f64 = (taup - taupa) * (1.0 + e2m * tau.sqrt())
/ (e2m * 1.0_f64.hypot(tau) * 1.0_f64.hypot(taupa));
tau += dtau;
if dtau.abs() < stol {
break;
}
}
tau
}
pub fn fmod(a: f64, b: f64) -> f64 {
(a - b * (a / b).trunc()).trunc()
}
pub fn remainder(numer: f64, denom: f64) -> f64 {
numer - (numer / denom).round() * denom
}
pub fn angle_normalize(d: f64) -> f64 {
let x: f64 = remainder(d, 360.0);
(x == -180.0).then_some(180.0).unwrap_or(x)
}
pub fn angle_diff(x: f64, y: f64) -> f64 {
angle_normalize(remainder(-x, 360.0) + remainder(y, 360.0))
}
pub fn polyval(order: usize, coefficents: &[f64], x: f64) -> f64 {
let mut y: f64 = 0.0;
for item in coefficents[..order + 1].iter() {
y = y * x + item;
}
y
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_eatanhe() {
let a: f64 = 0.3;
let b: f64 = 1.1;
let x: f64 = eatanhe(a, b);
assert_eq!((x * 10000000000.0).trunc(), 3771110798.0);
}
#[test]
fn test_taupf() {
let a: f64 = 0.3;
let b: f64 = 1.1;
let x: f64 = taupf(a, b);
assert_eq!((x * 10000000000.0).trunc(), -643892020.0);
}
#[test]
fn test_fmod() {
let a: f64 = 5.3;
let b: f64 = 2.1;
let x: f64 = fmod(a, b);
assert_eq!(x, 1.0);
}
#[test]
fn test_remainder() {
let numer: f64 = 5.3;
let denom: f64 = 2.1;
let x: f64 = remainder(numer, denom);
assert_eq!(x, -1.0000000000000009);
}
#[test]
fn test_angle_normalize() {
let d: f64 = 453.0;
let x: f64 = angle_normalize(d);
assert_eq!(x, 93.0);
}
#[test]
fn test_angle_diff() {
let x: f64 = 453.0;
let y: f64 = 1832.0;
let z: f64 = angle_diff(x, y);
assert_eq!(z, -61.0);
}
#[test]
fn test_polyval() {
let order: usize = 5;
let coefficents = vec![1.0, -3.5, 0.0, 14.0, 28.1, -155.0];
let x: f64 = 2.7;
let y: f64 = polyval(order, &coefficents, x);
assert_eq!((y * 100000.0).trunc(), -1958528.0);
}
}