From 66fc70e20e3dedf34e91db71d1e376b92ba2ae78 Mon Sep 17 00:00:00 2001 From: Shimun Date: Fri, 22 Nov 2019 15:57:17 +0100 Subject: [PATCH] added helper for Op --- src/main.rs | 74 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6c1966e..e602629 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,6 +50,12 @@ enum Value { Eval(Box), } +impl From for Value { + fn from(f: f64) -> Self { + Self::Const(f) + } +} + impl Clone for Value { fn clone(&self) -> Self { match self { @@ -148,35 +154,55 @@ impl Eval for Op { } } +impl Op { + fn exp>(x: T) -> Self { + Self::Exp(x.into()) + } + + fn ln>(x: T) -> Self { + Self::Ln(x.into()) + } + + fn sub, U: Into>(a: T, b: U) -> Self { + Self::Sub(a.into(), b.into()) + } + + fn add, U: Into>(a: T, b: U) -> Self { + Self::Add(a.into(), b.into()) + } + fn mul, U: Into>(a: T, b: U) -> Self { + Self::Mul(a.into(), b.into()) + } + fn div, U: Into>(a: T, b: U) -> Self { + Self::Div(a.into(), b.into()) + } + fn pow, U: Into>(a: T, b: U) -> Self { + Self::Pow(a.into(), b.into()) + } +} + impl Derive for Op { fn derive(&self) -> Value { match self { Self::Mul(a, b) => Op::Add( - Op::Mul(a.derive(), b.clone()).into(), - Op::Mul(a.clone(), b.derive()).into(), + Op::mul(a.derive(), b.clone()).into(), + Op::mul(a.clone(), b.derive()).into(), ), - Self::Div(a, b) => Op::Div( - Op::Sub( - Op::Mul(a.derive(), b.clone()).into(), - Op::Mul(a.clone(), b.derive()).into(), - ) - .into(), - Op::Pow(b.clone(), Value::Const(2.0)).into(), + Self::Div(a, b) => Op::div( + Op::sub( + Op::Mul(a.derive(), b.clone()), + Op::Mul(a.clone(), b.derive()), + ), + Op::pow(b.clone(), 2.0), ), - Self::Add(a, b) => Op::Add(a.derive(), b.derive()), - Self::Sub(a, b) => Op::Sub(a.derive(), b.derive()), + Self::Add(a, b) => Op::add(a.derive(), b.derive()), + Self::Sub(a, b) => Op::sub(a.derive(), b.derive()), Self::Pow(a, b) => match b { - Value::Eval(e) => Op::Mul( - Op::Ln(a.clone()).into(), - Op::Pow(a.clone(), b.clone()).into(), - ), - b => Op::Pow( - Op::Mul(a.clone(), b.clone()).into(), - Op::Sub(b.clone(), Value::Const(1.0)).into(), - ), + Value::Eval(e) => Op::mul(Op::ln(a.clone()), Op::pow(a.clone(), b.clone())), + b => Op::pow(Op::mul(a.clone(), b.clone()), Op::sub(b.clone(), 1.0)), }, - Self::Ln(x) => Op::Div(Value::Const(1.0), x.clone()), - Self::Exp(x) => Op::Mul(x.derive(), Op::Exp(x.clone()).into()), + Self::Ln(x) => Op::div(1.0, x.clone()), + Self::Exp(x) => Op::mul(x.derive(), Op::exp(x.clone())), } .into() } @@ -211,7 +237,7 @@ fn newton_raphson<'a>(eq: &'a dyn Eval, x0: f64, precision: i32) -> impl Iterato dbg!(("Aborted after", i)); } same_counter = (same_counter + equal as usize) * (equal as usize); - Some(x).filter(|_| !equal && same_counter < 3) + Some(x).filter(|_| !equal && same_counter < 3 && !x.is_nan()) }) } @@ -245,7 +271,7 @@ fn main() { Op::Pow(Value::Const(b), Var::val("x")).into() } let eq: Value = Op::Sub(Op::Add(pow_to_x(4.0), pow_to_x(6.0)).into(), pow_to_x(9.0)).into(); - let res = n_root(9.0, 2.0); - let res = newton_raphson(&eq, 1.0, 10).last(); + let res = n_root(9.4, 2.0); + let res = newton_raphson(&eq, 1.0, 8).last(); println!("1.0 - {}/{} ==> {}", &eq, "", res.unwrap()); }