Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern crate rand;
- use rand::Rng;
- use rand::chacha::ChaChaRng;
- const PI: f64 = std::f64::consts::PI;
- fn sin(x: f64) -> f64 {
- x.sin()
- }
- fn cos(x: f64) -> f64 {
- x.cos()
- }
- pub struct ExpressionBuilder {
- rng: ChaChaRng,
- }
- impl ExpressionBuilder {
- fn new() -> ExpressionBuilder {
- ExpressionBuilder {
- rng: ChaChaRng::new_unseeded(),
- }
- }
- fn build_expression<'a, T>(&mut self, x: &'a T, y: &'a T, probability: f64) -> &'a T
- where &'a T: Evaluate + New
- {
- self.rng.choose(&[x, y]).unwrap()
- }
- }
- pub trait Evaluate {
- fn eval(&self, x: f64, y: f64) -> f64;
- }
- pub trait New {
- fn new() -> Self;
- }
- pub struct X {
- }
- impl New for X {
- fn new() -> X {
- X { }
- }
- }
- impl Evaluate for X {
- fn eval(&self, x: f64, y: f64) -> f64 {
- assert!(x >= -1.0 && y <= 1.0);
- x
- }
- }
- pub struct Y {
- }
- impl New for Y {
- fn new() -> Y {
- Y { }
- }
- }
- impl Evaluate for Y {
- fn eval(&self, x: f64, y: f64) -> f64 {
- assert!(x >= -1.0 && y <= 1.0);
- y
- }
- }
- pub struct SinPi {
- expression: Box<Evaluate>
- }
- impl SinPi {
- pub fn new(expression: Box<Evaluate>) -> SinPi {
- SinPi {
- expression
- }
- }
- }
- impl Evaluate for SinPi {
- fn eval(&self, x: f64, y: f64) -> f64 {
- assert!(x >= -1.0 && y <= 1.0);
- sin(PI * self.expression.eval(x, y))
- }
- }
- pub struct CosPi {
- expression: Box<Evaluate>
- }
- impl CosPi {
- pub fn new(expression: Box<Evaluate>) -> CosPi {
- CosPi {
- expression
- }
- }
- }
- impl Evaluate for CosPi {
- fn eval(&self, x: f64, y: f64) -> f64 {
- assert!(x >= -1.0 && y <= 1.0);
- cos(PI * self.expression.eval(x, y))
- }
- }
- pub struct Product {
- a: Box<Evaluate>,
- b: Box<Evaluate>,
- }
- impl Product {
- pub fn new(a: Box<Evaluate>, b: Box<Evaluate>) -> Product {
- Product {
- a,
- b,
- }
- }
- }
- impl Evaluate for Product {
- fn eval(&self, x: f64, y: f64) -> f64 {
- assert!(x >= -1.0 && y <= 1.0);
- self.a.eval(x, y) * self.b.eval(x, y)
- }
- }
- #[cfg(test)]
- mod tests {
- use super::*;
- #[test]
- fn eval_x() {
- let x = X::new();
- assert_eq!(x.eval(-1.0, 1.0), -1.0);
- }
- #[test]
- fn eval_y() {
- let y = Y::new();
- assert_eq!(y.eval(-1.0, 1.0), 1.0);
- }
- }
Add Comment
Please, Sign In to add comment