Решение на Polynomial от Мартин Георгиев

Обратно към всички решения

Към профила на Мартин Георгиев

Резултати

  • 15 точки от тестове
  • 0 бонус точки
  • 15 точки общо
  • 15 успешни тест(а)
  • 0 неуспешни тест(а)

Код

use std::ops::Mul;
use std::ops::Add;
use std::ops::Div;
#[derive(Debug, Clone)]
pub struct Polynomial {
coefs: Vec<f64>
}
impl Polynomial {
/// Ако имаме точка (x, y) тогава тя удовлетворява полинома P(X), ако `|P(x) - y| < 1e-10`.
pub fn has(&self, point: &(f64, f64)) -> bool {
let mut px: f64 = 0.0;
let mut x: f64 = 1.0;
for el in self.coefs.iter().rev() {
px += x*el;
x *= point.0;
}
(px - point.1).abs() < 1e-10
}
pub fn interpolate(points: Vec<(f64, f64)>) -> Option<Self> {
let mut res: Polynomial = Default::default();
for (i, pi) in points.iter().enumerate() {
let mut poly: Polynomial = Polynomial::from(vec![1.0]);
for (j, pj) in points.iter().enumerate() {
if i != j {
if pi.0 == pj.0 {
return None;
}
poly = poly * (Polynomial::from(vec![1.0, -pj.0]) / (pi.0 - pj.0));
}
}
res = res + (poly * pi.1);
}
return Some(Polynomial::from(res));
}
}
impl PartialEq for Polynomial {
fn eq(&self, rhs: &Self) -> bool {
if self.coefs.len() != rhs.coefs.len() {
return false;
}
for (self_el, rhs_el) in self.coefs.iter().zip(rhs.coefs.iter()) {
if (self_el - rhs_el).abs() > 1e-10 {
return false;
}
}
true
}
}
impl From<Vec<f64>> for Polynomial {
fn from(mut coefs: Vec<f64>) -> Self {
if coefs.len() == 0 {
return Default::default();
}
else {
let mut not_zero_index: i32 = -1;
for (i, el) in coefs.iter().enumerate() {
if el.abs() > 1e-10 {
not_zero_index = i as i32;
println!("{:?}",i);
break;
}
}
let mut res: Polynomial = Default::default();
if not_zero_index != -1 {
coefs.drain(..not_zero_index as usize);
res.coefs = coefs;
}
return res;
}
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial {
coefs: vec![0.0]
}
}
}
impl Mul<f64> for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: f64) -> Self::Output {
let mut coefs = self.coefs;
coefs = coefs.iter().map((|x| x*rhs)).collect();
Polynomial::from(coefs)
}
}
impl Div<f64> for Polynomial {
type Output = Polynomial;
fn div(self, rhs: f64) -> Self::Output {
if rhs.abs() < 1e-10 {
panic!("Error division by zero!");
}
let mut coefs = self.coefs;
coefs = coefs.iter().map((|x| x/rhs)).collect();
Polynomial::from(coefs)
}
}
impl Add for Polynomial {
type Output = Polynomial;
fn add(self, rhs: Polynomial) -> Self::Output {
let mut mut_self = self;
let mut mut_rhs = rhs;
if mut_self.coefs.len() >= mut_rhs.coefs.len() {
let diff = mut_self.coefs.len() - mut_rhs.coefs.len();
for (x1, x2) in mut_self.coefs[diff..].iter_mut().zip(mut_rhs.coefs.iter()) {
*x1 += *x2;
}
return Polynomial::from(mut_self.coefs);
}
let diff = mut_rhs.coefs.len() - mut_self.coefs.len();
for (x1, x2) in mut_rhs.coefs[diff..].iter_mut().zip(mut_self.coefs.iter()) {
*x1 += *x2;
}
Polynomial::from(mut_rhs.coefs)
}
}
impl Mul for Polynomial {
type Output = Polynomial;
fn mul(self, rhs: Polynomial) -> Self::Output {
let mut res: Polynomial = Default::default();
let mut mut_self = self;
for el in rhs.coefs.iter().rev() {
res = res + mut_self.clone() * *el;
mut_self.coefs.push(0.0);
}
Polynomial::from(res.coefs)
}
}

Лог от изпълнението

Compiling solution v0.1.0 (file:///tmp/d20171121-6053-k68vdg/solution)
    Finished dev [unoptimized + debuginfo] target(s) in 5.32 secs
     Running target/debug/deps/solution-200db9172ea1f728

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/solution_test-e3c9eb714e09105e

running 15 tests
test solution_test::test_add_poly ... ok
test solution_test::test_add_poly_zero_one ... ok
test solution_test::test_arithmetic_properties ... ok
test solution_test::test_create_poly ... ok
test solution_test::test_div_poly_f64 ... ok
test solution_test::test_div_poly_f64_zero ... ok
test solution_test::test_fp_comparison ... ok
test solution_test::test_has_point ... ok
test solution_test::test_lagrange_poly_1 ... ok
test solution_test::test_lagrange_poly_2 ... ok
test solution_test::test_lagrange_poly_err_eq_x ... ok
test solution_test::test_mul_poly ... ok
test solution_test::test_mul_poly_f64 ... ok
test solution_test::test_mul_poly_f64_zero ... ok
test solution_test::test_mul_poly_zero_one ... ok

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests solution

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

История (1 версия и 0 коментара)

Мартин качи първо решение на 18.11.2017 13:28 (преди почти 8 години)