added helper for Op
This commit is contained in:
74
src/main.rs
74
src/main.rs
@@ -50,6 +50,12 @@ enum Value {
|
||||
Eval(Box<dyn Eval>),
|
||||
}
|
||||
|
||||
impl From<f64> 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<T: Into<Value>>(x: T) -> Self {
|
||||
Self::Exp(x.into())
|
||||
}
|
||||
|
||||
fn ln<T: Into<Value>>(x: T) -> Self {
|
||||
Self::Ln(x.into())
|
||||
}
|
||||
|
||||
fn sub<T: Into<Value>, U: Into<Value>>(a: T, b: U) -> Self {
|
||||
Self::Sub(a.into(), b.into())
|
||||
}
|
||||
|
||||
fn add<T: Into<Value>, U: Into<Value>>(a: T, b: U) -> Self {
|
||||
Self::Add(a.into(), b.into())
|
||||
}
|
||||
fn mul<T: Into<Value>, U: Into<Value>>(a: T, b: U) -> Self {
|
||||
Self::Mul(a.into(), b.into())
|
||||
}
|
||||
fn div<T: Into<Value>, U: Into<Value>>(a: T, b: U) -> Self {
|
||||
Self::Div(a.into(), b.into())
|
||||
}
|
||||
fn pow<T: Into<Value>, U: Into<Value>>(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());
|
||||
}
|
||||
|
Reference in New Issue
Block a user