use std::thread::JoinHandle; use std::time::Instant; use crate::bounds::Bounds; use crate::linear_bounds::LinearBounds; use crate::point::Point; const SAMPLES: u64 = 1_000_000_000; const THREAD_CNT: u64 = 8; mod point; mod linear_bounds; mod bounds; 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 is_inside(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; } fn get_real_integral(bounds: LinearBounds) -> f64 { return big_f(bounds.get_higher()) - big_f(bounds.get_lower()); } 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; } fn main() { let start: Instant = Instant::now(); let mut points_inside: u64 = 0; let bounds: Bounds = Bounds::new(LinearBounds::new(0_f64, 20_f64), LinearBounds::new(-100_f64, 150000_f64)); let mut threads: Vec> = vec![]; for _ in 0..THREAD_CNT { threads.push(std::thread::spawn(move || { let mut points_inside: u64 = 0; for _ in 0..SAMPLES { let point: Point = bounds.get_random_point(); if is_inside(point) { points_inside += 1; } } return points_inside; })) } for thread in threads { points_inside += thread.join().unwrap(); } let total_samples: u64 = SAMPLES * THREAD_CNT; let approximated_integral: f64 = (points_inside as f64 / total_samples as f64) * bounds.get_area(); println!("The approximated Integral of the function is: {:.2}", approximated_integral); let real_integral: f64 = get_real_integral(bounds.get_x()); println!("The real Integral of the function is: {:.2}", real_integral); let error: f64 = (real_integral - approximated_integral).abs(); println!("That's an error of {:.2} or {:.5}%", error, (error/real_integral) * 100_f64); println!("And the whole thing took {:.5} Seconds for {} samples", start.elapsed().as_micros() as f64 / 1000000_f64, total_samples); }