pub fn polevl(x: f64, coef: &[f64], n: usize) -> f64 {
let mut coef_iter = coef.iter().take(n+1);
let mut ans = *coef_iter.next().unwrap();
for i in coef_iter {
ans = ans * x + *i;
}
ans
}
pub fn p1evl(x: f64, coef: &[f64], n: usize) -> f64
{
let mut coef_iter = coef.iter().take(n);
let mut ans = x + *coef_iter.next().unwrap();
for i in coef_iter {
ans = ans * x + *i;
}
ans
}
pub fn ratevl(x: f64, num: &[f64], m: isize, denom: &[f64], n: isize) -> f64 {
let absx = x.abs();
let (dir, mut p, y) = if absx > 1.0 {
(-1_isize, m, 1.0 / x)
} else {
(1_isize, 0_isize, x)
};
let mut num_ans = num[p as usize];
p += dir;
for _ in 1..=m {
num_ans = num_ans * y + num[p as usize];
p += dir;
}
if absx > 1.0 {
p = n;
} else {
p = 0;
}
let mut denom_ans = denom[p as usize];
p += dir;
for _ in 1..=n {
denom_ans = denom_ans * y + denom[p as usize];
p += dir;
}
if absx > 1.0 {
let i = n - m;
x.powi(i as i32) * num_ans / denom_ans
} else {
num_ans / denom_ans
}
}
#[cfg(test)]
mod polevl_tests {
use super::*;
const TAYLOR0: [f64; 10] = [
-1.0000000009110164892,
-1.0000000057646759799,
-9.9999983138417361078e-1,
-1.0000013011460139596,
-1.000001940896320456,
-9.9987929950057116496e-1,
-1.000785194477042408,
-1.0031782279542924256,
-9.1893853320467274178e-1,
-1.5,
];
#[test]
fn polevl_test() {
let coefs = [2.0, 3.0, 4.0];
assert_eq!(polevl(1.0, &coefs, 1), 5.0);
assert_eq!(polevl(1.0, &coefs, 2), 9.0);
assert_eq!(polevl(2.0, &coefs, 2), 18.0);
}
}