68 lines
1.9 KiB
Rust
68 lines
1.9 KiB
Rust
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<JoinHandle<u64>> = vec![];
|
|
|
|
let function: Arc<Function> = Arc::new(*self);
|
|
let bounds: Arc<Bounds> = 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();
|
|
}
|
|
} |