Browse Source

implement ops for Expr and Unknown

eqn_relations
Alex Mikhalev 6 years ago
parent
commit
6cede1f2dd
  1. 37
      src/math/eqn.rs
  2. 8
      src/math/mod.rs
  3. 184
      src/math/ops.rs

37
src/math/eqn.rs

@ -108,9 +108,7 @@ fn sum_fold(l: Expr, r: Expr) -> Expr { @@ -108,9 +108,7 @@ fn sum_fold(l: Expr, r: Expr) -> Expr {
(Product(mut l), r) | (r, Product(mut l)) => {
let comm = remove_term(&mut l, &r);
match comm {
Some(_) => {
Expr::new_product(r, Expr::new_sum(Product(l), Const(1.))).simplify()
}
Some(_) => Expr::new_product(r, Expr::new_sum(Product(l), Const(1.))).simplify(),
None => Expr::new_sum(Product(l), r),
}
}
@ -604,14 +602,14 @@ mod tests { @@ -604,14 +602,14 @@ mod tests {
let eqn = Eqn(e2.clone(), e1.clone());
assert_eq!(eqn.solve(u1), Some(Const(1.)));
let e3 = Expr::new_sum(Const(1.), Expr::new_sum(Const(1.), Const(2.)));
let e3: Expr = Expr::from(1.) + 1. + 2.;
let eqn = Eqn(e1.clone(), e3.clone());
assert_eq!(eqn.solve(u1), Some(Const(4.)));
let e3 = Expr::new_minus(Const(1.), Const(1.));
let e3 = Expr::from(1.) - 1.;
let eqn = Eqn(e1.clone(), e3.clone());
assert_eq!(eqn.solve(u1), Some(Const(0.)));
let e1 = Expr::new_div(Const(2.), Expr::new_minus(Const(1.), Const(4.)));
let e1 = Expr::from(2.) / (Expr::from(1.) - 4.);
let e2 = Expr::new_minus(Const(1.), Unkn(u1));
let eqn = Eqn(e1, e2);
info!("eqn: {} => {}", eqn, eqn.clone().simplify());
@ -619,8 +617,8 @@ mod tests { @@ -619,8 +617,8 @@ mod tests {
assert!(const_expr(e.clone()).is_some());
assert!(relative_eq!(const_expr(e.clone()).unwrap(), 5. / 3.));
let e1 = Expr::new_product(Const(2.), Expr::new_minus(Const(1.), Const(4.)));
let e2 = Expr::new_minus(Expr::new_product(Unkn(u1), Const(2.)), Unkn(u1));
let e1 = Expr::from(2.) * (Expr::from(1.) - 4.);
let e2 = (u1 * 2.) - u1;
info!(
"e1==e2: {}=={} => {}=={}",
e1,
@ -633,14 +631,8 @@ mod tests { @@ -633,14 +631,8 @@ mod tests {
assert!(const_expr(e.clone()).is_some());
assert!(relative_eq!(const_expr(e.clone()).unwrap(), -6.));
let e1 = Expr::new_product(Const(2.), Expr::new_minus(Const(1.), Const(4.)));
let e2 = Expr::new_div(
Expr::new_sum(
Expr::new_product(Unkn(u1), Const(2.)),
Expr::new_product(Unkn(u1), Unkn(u1)),
),
Unkn(u1),
);
let e1 = Expr::from(2.) * (Expr::from(1.) - 4.);
let e2 = ((u1 * 2.) + (u1 * u1)) / u1;
info!(
"{}=={} distrib=> {}=={}",
e1,
@ -660,17 +652,8 @@ mod tests { @@ -660,17 +652,8 @@ mod tests {
assert!(const_expr(e.clone()).is_some());
assert!(relative_eq!(const_expr(e.clone()).unwrap(), -8.));
let e1 = Expr::new_product(Const(2.), Expr::new_minus(Const(1.), Const(4.)));
let e2 = Expr::new_div(
Expr::new_sum(
Expr::new_product(Unkn(u1), Const(2.)),
Expr::new_sum(
Expr::new_sum(Expr::new_product(Unkn(u1), Unkn(u1)), Unkn(u1)),
Expr::new_minus(Const(2.), Const(1. + 1.)),
),
),
Unkn(u1),
);
let e1 = Expr::from(2.) * (Expr::from(1.) - (4.));
let e2 = ((u1 * 2.) + (((u1 * u1) + u1) + (Expr::from(2.) - (1. + 1.)))) / u1;
info!(
"e1==e2: {}=={} => {}=={}",
e1,

8
src/math/mod.rs

@ -1,6 +1,14 @@ @@ -1,6 +1,14 @@
pub mod eqn;
pub mod ops;
pub use eqn::Unknown;
pub use ops::*;
pub type Scalar = f64;
pub enum Value {
Known(Scalar),
Unkn(Unknown),
}
pub type Vec2 = nalgebra::Vector2<Scalar>;
pub type Point2 = nalgebra::Point2<Scalar>;

184
src/math/ops.rs

@ -0,0 +1,184 @@ @@ -0,0 +1,184 @@
use std::ops;
use super::eqn::{Expr, Unknown};
use super::Scalar;
impl From<Scalar> for Expr {
fn from(c: Scalar) -> Expr {
Expr::Const(c)
}
}
impl From<Unknown> for Expr {
fn from(u: Unknown) -> Expr {
Expr::Unkn(u)
}
}
impl ops::Add<Expr> for Expr {
type Output = Expr;
fn add(self, rhs: Expr) -> Expr {
Expr::new_sum(self, rhs)
}
}
impl ops::Add<Scalar> for Expr {
type Output = Expr;
fn add(self, rhs: Scalar) -> Expr {
Expr::new_sum(self, rhs.into())
}
}
impl ops::Add<Unknown> for Expr {
type Output = Expr;
fn add(self, rhs: Unknown) -> Expr {
Expr::new_sum(self, rhs.into())
}
}
impl ops::Sub<Expr> for Expr {
type Output = Expr;
fn sub(self, rhs: Expr) -> Expr {
Expr::new_minus(self, rhs)
}
}
impl ops::Sub<Scalar> for Expr {
type Output = Expr;
fn sub(self, rhs: Scalar) -> Expr {
Expr::new_minus(self, rhs.into())
}
}
impl ops::Sub<Unknown> for Expr {
type Output = Expr;
fn sub(self, rhs: Unknown) -> Expr {
Expr::new_minus(self, rhs.into())
}
}
impl ops::Mul<Expr> for Expr {
type Output = Expr;
fn mul(self, rhs: Expr) -> Expr {
Expr::new_product(self, rhs)
}
}
impl ops::Mul<Scalar> for Expr {
type Output = Expr;
fn mul(self, rhs: Scalar) -> Expr {
Expr::new_product(self, rhs.into())
}
}
impl ops::Mul<Unknown> for Expr {
type Output = Expr;
fn mul(self, rhs: Unknown) -> Expr {
Expr::new_product(self, rhs.into())
}
}
impl ops::Div<Expr> for Expr {
type Output = Expr;
fn div(self, rhs: Expr) -> Expr {
Expr::new_div(self, rhs)
}
}
impl ops::Div<Scalar> for Expr {
type Output = Expr;
fn div(self, rhs: Scalar) -> Expr {
Expr::new_div(self, rhs.into())
}
}
impl ops::Div<Unknown> for Expr {
type Output = Expr;
fn div(self, rhs: Unknown) -> Expr {
Expr::new_div(self, rhs.into())
}
}
impl ops::Add<Expr> for Unknown {
type Output = Expr;
fn add(self, rhs: Expr) -> Expr {
Expr::new_sum(self.into(), rhs)
}
}
impl ops::Add<Scalar> for Unknown {
type Output = Expr;
fn add(self, rhs: Scalar) -> Expr {
Expr::new_sum(self.into(), rhs.into())
}
}
impl ops::Add<Unknown> for Unknown {
type Output = Expr;
fn add(self, rhs: Unknown) -> Expr {
Expr::new_sum(self.into(), rhs.into())
}
}
impl ops::Sub<Expr> for Unknown {
type Output = Expr;
fn sub(self, rhs: Expr) -> Expr {
Expr::new_minus(self.into(), rhs)
}
}
impl ops::Sub<Scalar> for Unknown {
type Output = Expr;
fn sub(self, rhs: Scalar) -> Expr {
Expr::new_minus(self.into(), rhs.into())
}
}
impl ops::Sub<Unknown> for Unknown {
type Output = Expr;
fn sub(self, rhs: Unknown) -> Expr {
Expr::new_minus(self.into(), rhs.into())
}
}
impl ops::Mul<Expr> for Unknown {
type Output = Expr;
fn mul(self, rhs: Expr) -> Expr {
Expr::new_product(self.into(), rhs)
}
}
impl ops::Mul<Scalar> for Unknown {
type Output = Expr;
fn mul(self, rhs: Scalar) -> Expr {
Expr::new_product(self.into(), rhs.into())
}
}
impl ops::Mul<Unknown> for Unknown {
type Output = Expr;
fn mul(self, rhs: Unknown) -> Expr {
Expr::new_product(self.into(), rhs.into())
}
}
impl ops::Div<Expr> for Unknown {
type Output = Expr;
fn div(self, rhs: Expr) -> Expr {
Expr::new_div(self.into(), rhs)
}
}
impl ops::Div<Scalar> for Unknown {
type Output = Expr;
fn div(self, rhs: Scalar) -> Expr {
Expr::new_div(self.into(), rhs.into())
}
}
impl ops::Div<Unknown> for Unknown {
type Output = Expr;
fn div(self, rhs: Unknown) -> Expr {
Expr::new_div(self.into(), rhs.into())
}
}
Loading…
Cancel
Save