newton polynomial interpolation
This commit is contained in:
parent
1520c8af9d
commit
865f4cf564
@ -2,7 +2,16 @@
|
|||||||
name = "day9"
|
name = "day9"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
default-run = "main"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "main"
|
||||||
|
path= "src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "newton"
|
||||||
|
path= "src/main_newton.rs"
|
||||||
|
57
day9/src/main_newton.rs
Normal file
57
day9/src/main_newton.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
|
fn get_numbers_in_line_iter<T: std::str::FromStr>(str: &str) -> impl Iterator<Item=T> + '_ {
|
||||||
|
str.split_whitespace().filter_map(|substr| substr.parse::<T>().ok())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn polynomial_value(coeff: &Vec<f64>, x: f64) -> f64 {
|
||||||
|
let mut result: f64 = 0.;
|
||||||
|
let mut x_power: f64 = 1.;
|
||||||
|
for &c in coeff {
|
||||||
|
result += c * x_power;
|
||||||
|
x_power *= x;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn newton_interpolation(x: &Vec<f64>, y: &Vec<f64>) -> Vec<f64> {
|
||||||
|
let degree = std::cmp::min(x.len(), y.len());
|
||||||
|
if degree == 0 {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
let mut result: Vec<f64> = Vec::with_capacity(degree);
|
||||||
|
let mut w: Vec<f64> = Vec::with_capacity(degree);
|
||||||
|
result.push(y[0]);
|
||||||
|
w.push(x[0]);
|
||||||
|
for i in 1..degree {
|
||||||
|
w.push(1.);
|
||||||
|
for j in 0..i {
|
||||||
|
let xj = x[j];
|
||||||
|
w.push(0.);
|
||||||
|
for k in (0..=j).rev() {
|
||||||
|
w[k + 1] += w[k];
|
||||||
|
w[k] *= -xj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let a = (y[i] - polynomial_value(&result, x[i])) / polynomial_value(&w, x[i]);
|
||||||
|
for j in 0..i {
|
||||||
|
result[j] += a * w[j];
|
||||||
|
}
|
||||||
|
result.push(a * w[i]);
|
||||||
|
w.clear();
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {let mut sum1 = 0;
|
||||||
|
let mut sum2 = 0;
|
||||||
|
for line in read_to_string("input.txt").unwrap().lines() {
|
||||||
|
let y = get_numbers_in_line_iter::<f64>(line).collect::<Vec<_>>();
|
||||||
|
let x = (0..y.len()).map(|x| x as f64).collect::<Vec<_>>();
|
||||||
|
let coeff = newton_interpolation(&x, &y);
|
||||||
|
sum1 += polynomial_value(&coeff, y.len() as f64).round() as i32;
|
||||||
|
sum2 += polynomial_value(&coeff, -1.).round() as i32;
|
||||||
|
}
|
||||||
|
println!("Sum1: {}", sum1);
|
||||||
|
println!("Sum2: {}", sum2);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user