use std::sync::Arc; use std::thread::JoinHandle; use crate::bounds::Bounds; use crate::linear_bounds::LinearBounds; use crate::point::Point; #[derive(Clone, Copy)] pub struct Function{} fn f(x: &f64) -> f64 { return x.powi(4) - 4_f64 * x.powi(3) + 18_f64 * x.powi(2) - 12_f64 * x - 69_f64 } fn big_f(x: &f64) -> f64 { return 0.2 * x.powi(5) - x.powi(4) + 6_f64 * x.powi(3) - 6_f64 * x.powi(2) - 69_f64 * x; } impl Function { pub fn new() -> Function { return Function {}; } pub fn integrate(&self, bounds: &LinearBounds) -> f64 { return big_f(&bounds.get_higher()) - big_f(&bounds.get_lower()); } fn includes(&self, point: &Point) -> bool { let y_0: f64 = f(&point.get_x()); return y_0.abs() > point.get_y().abs() && y_0 * point.get_y() >= 0_f64; } pub fn approximate(&self, bounds: &Bounds, samples: usize, thread_cnt: usize) -> f64 { let mut hits: u64 = 0; let mut threads: Vec> = vec![]; let function: Arc = Arc::new(*self); let bounds: Arc = Arc::new(*bounds); for _ in 0..thread_cnt { let function = function.clone(); let bounds = bounds.clone(); threads.push(std::thread::spawn(move || { let mut hits: u64 = 0; for _ in 0..samples/thread_cnt { let point: Point = bounds.get_random_point(); if function.includes(&point) { hits += 1; } } return hits; })) } for _ in 0..samples % thread_cnt { let point: Point = bounds.get_random_point(); if function.includes(&point) { hits += 1; } } for thread in threads { hits += thread.join().unwrap(); } return (hits as f64 / samples as f64) * bounds.get_area(); } }