↑Programmieren in Rust
fn bisection(
mut a: f64, mut b: f64, epsilon: f64,
f: &dyn Fn(f64) -> f64
) -> f64 {
for _ in 0..100 {
let c = 0.5*(a + b);
if f(c) == 0.0 {return c;}
if f(a).signum() != f(c).signum() {b = c;} else {a = c;}
if (b - a).abs() < epsilon {break;}
}
0.5*(a + b)
}
fn checked_bisection(
mut a: f64, mut b: f64, epsilon: f64, nmax: u32,
f: &dyn Fn(f64) -> f64
) -> Option<f64> {
if !(f(a) < 0.0 && f(b) > 0.0 || f(a) > 0.0 && f(b) < 0.0) {
return None;
}
for _ in 0..nmax {
let c = 0.5*(a + b);
if f(c) == 0.0 {return Some(c);}
if f(a).signum() != f(c).signum() {b = c;} else {a = c;}
if (b - a).abs() < epsilon {return Some(0.5*(a + b));}
}
None
}
fn diff(f: &dyn Fn(f64) -> f64, x: f64) -> f64 {
let h = 0.001;
(f(x+h) - f(x-h))/(2.0*h)
}
fn diff2(f: &dyn Fn(f64) -> f64, x: f64) -> f64 {
let h = 0.001;
(f(x+h) - 2.0*f(x) + f(x-h))/(h*h)
}
fn diff3(f: &dyn Fn(f64) -> f64, x: f64) -> f64 {
let h = 0.004;
(0.5*f(x+2.0*h) - f(x+h) + f(x-h) - 0.5*f(x-2.0*h))/(h*h*h)
}
fn simpson(f: &dyn Fn(f64) -> f64, a: f64, b: f64, n: u32) -> f64 {
let h = (b - a)/(n as f64);
let mut s = 0.0;
for i in 0..n {
let x = a + h*(i as f64);
s += f(x) + 4.0*f(x + 0.5*h) + f(x + h);
}
s*h/6.0
}
static GL32: [[f64; 2]; 32] = [
[-0.9972638618494816, 0.007018610009470141],
[-0.9856115115452684, 0.01627439473090563],
[-0.9647622555875064, 0.02539206530926208],
[-0.9349060759377397, 0.03427386291302148],
[-0.8963211557660522, 0.04283589802222668],
[-0.8493676137325699, 0.05099805926237622],
[-0.7944837959679425, 0.05868409347853551],
[-0.7321821187402897, 0.06582222277636184],
[-0.6630442669302152, 0.07234579410884850],
[-0.5877157572407623, 0.07819389578707028],
[-0.5068999089322295, 0.08331192422694673],
[-0.4213512761306354, 0.08765209300440380],
[-0.3318686022821277, 0.09117387869576390],
[-0.2392873622521371, 0.09384439908080457],
[-0.1444719615827965, 0.09563872007927489],
[-0.04830766568773831,0.09654008851472778],
[ 0.04830766568773831,0.09654008851472778],
[ 0.1444719615827965, 0.09563872007927489],
[ 0.2392873622521371, 0.09384439908080457],
[ 0.3318686022821277, 0.09117387869576390],
[ 0.4213512761306354, 0.08765209300440380],
[ 0.5068999089322295, 0.08331192422694673],
[ 0.5877157572407623, 0.07819389578707028],
[ 0.6630442669302152, 0.07234579410884850],
[ 0.7321821187402897, 0.06582222277636184],
[ 0.7944837959679425, 0.05868409347853551],
[ 0.8493676137325699, 0.05099805926237622],
[ 0.8963211557660522, 0.04283589802222668],
[ 0.9349060759377397, 0.03427386291302148],
[ 0.9647622555875064, 0.02539206530926208],
[ 0.9856115115452684, 0.01627439473090563],
[ 0.9972638618494816, 0.007018610009470141]
];
fn gauss(f: &dyn Fn(f64) -> f64, a: f64, b: f64, n: u32) -> f64 {
let h = (b - a)/(n as f64);
let p = 0.5*h;
let mut s = 0.0;
for j in 0..n {
let q = p + a + (j as f64)*h;
let mut sj = 0.0;
for t in &GL32 {
sj += t[1]*f(p*t[0] + q);
}
s += sj;
}
p*s
}
// Für äquidistante Stützstellen [x0 + k*d, y[k]].
fn pli(x0: f64, d: f64, y: Vec<f64>) -> impl Fn(f64) -> f64 {
let n = y.len() as isize;
move |x| {
let k = f64::floor((x-x0)/d) as isize;
if k < 0 || k+1 >= n {f64::NAN}
else {
let k = k as usize;
y[k] + (y[k+1] - y[k])/d*(x - x0 - (k as f64)*d)
}
}
}