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>),
|
Eval(Box<dyn Eval>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<f64> for Value {
|
||||||
|
fn from(f: f64) -> Self {
|
||||||
|
Self::Const(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Clone for Value {
|
impl Clone for Value {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
match 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 {
|
impl Derive for Op {
|
||||||
fn derive(&self) -> Value {
|
fn derive(&self) -> Value {
|
||||||
match self {
|
match self {
|
||||||
Self::Mul(a, b) => Op::Add(
|
Self::Mul(a, b) => Op::Add(
|
||||||
Op::Mul(a.derive(), b.clone()).into(),
|
Op::mul(a.derive(), b.clone()).into(),
|
||||||
Op::Mul(a.clone(), b.derive()).into(),
|
Op::mul(a.clone(), b.derive()).into(),
|
||||||
),
|
),
|
||||||
Self::Div(a, b) => Op::Div(
|
Self::Div(a, b) => Op::div(
|
||||||
Op::Sub(
|
Op::sub(
|
||||||
Op::Mul(a.derive(), b.clone()).into(),
|
Op::Mul(a.derive(), b.clone()),
|
||||||
Op::Mul(a.clone(), b.derive()).into(),
|
Op::Mul(a.clone(), b.derive()),
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
Op::Pow(b.clone(), Value::Const(2.0)).into(),
|
|
||||||
),
|
),
|
||||||
Self::Add(a, b) => Op::Add(a.derive(), b.derive()),
|
Op::pow(b.clone(), 2.0),
|
||||||
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 {
|
Self::Pow(a, b) => match b {
|
||||||
Value::Eval(e) => Op::Mul(
|
Value::Eval(e) => Op::mul(Op::ln(a.clone()), Op::pow(a.clone(), b.clone())),
|
||||||
Op::Ln(a.clone()).into(),
|
b => Op::pow(Op::mul(a.clone(), b.clone()), Op::sub(b.clone(), 1.0)),
|
||||||
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(),
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
Self::Ln(x) => Op::Div(Value::Const(1.0), x.clone()),
|
Self::Ln(x) => Op::div(1.0, x.clone()),
|
||||||
Self::Exp(x) => Op::Mul(x.derive(), Op::Exp(x.clone()).into()),
|
Self::Exp(x) => Op::mul(x.derive(), Op::exp(x.clone())),
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
@@ -211,7 +237,7 @@ fn newton_raphson<'a>(eq: &'a dyn Eval, x0: f64, precision: i32) -> impl Iterato
|
|||||||
dbg!(("Aborted after", i));
|
dbg!(("Aborted after", i));
|
||||||
}
|
}
|
||||||
same_counter = (same_counter + equal as usize) * (equal as usize);
|
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()
|
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 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 = n_root(9.4, 2.0);
|
||||||
let res = newton_raphson(&eq, 1.0, 10).last();
|
let res = newton_raphson(&eq, 1.0, 8).last();
|
||||||
println!("1.0 - {}/{} ==> {}", &eq, "", res.unwrap());
|
println!("1.0 - {}/{} ==> {}", &eq, "", res.unwrap());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user