init
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Cargo.lock
|
||||
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "MonteCarlo-Rust"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies.rand]
|
||||
version = "0.8.5"
|
||||
30
src/bounds.rs
Normal file
30
src/bounds.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use crate::linear_bounds::LinearBounds;
|
||||
use crate::point::Point;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Bounds {
|
||||
x: LinearBounds,
|
||||
y: LinearBounds,
|
||||
}
|
||||
|
||||
impl Bounds {
|
||||
pub fn new(x: LinearBounds, y: LinearBounds) -> Bounds {
|
||||
return Bounds {x, y};
|
||||
}
|
||||
|
||||
pub fn get_area(self) -> f64 {
|
||||
return self.x.get_length() * self.y.get_length();
|
||||
}
|
||||
|
||||
pub fn get_random_point(self) -> Point {
|
||||
return Point::new(self.x.get_random_value(), self.y.get_random_value());
|
||||
}
|
||||
|
||||
pub fn get_x(self) -> LinearBounds {
|
||||
return self.x;
|
||||
}
|
||||
|
||||
pub fn get_y(self) -> LinearBounds {
|
||||
return self.y;
|
||||
}
|
||||
}
|
||||
31
src/linear_bounds.rs
Normal file
31
src/linear_bounds.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use rand::rngs::ThreadRng;
|
||||
use rand::{Rng, thread_rng};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LinearBounds {
|
||||
lower: f64,
|
||||
higher: f64,
|
||||
}
|
||||
|
||||
impl LinearBounds {
|
||||
pub fn new(lower: f64, higher: f64) -> LinearBounds {
|
||||
return LinearBounds {lower, higher};
|
||||
}
|
||||
|
||||
pub fn get_length(self) -> f64 {
|
||||
return (self.higher - self.lower).abs();
|
||||
}
|
||||
|
||||
pub fn get_random_value(self) -> f64 {
|
||||
let mut rand: ThreadRng = thread_rng();
|
||||
return self.lower + self.get_length() * rand.gen::<f64>();
|
||||
}
|
||||
|
||||
pub fn get_lower(self) -> f64 {
|
||||
return self.lower;
|
||||
}
|
||||
|
||||
pub fn get_higher(self) -> f64 {
|
||||
return self.higher;
|
||||
}
|
||||
}
|
||||
67
src/main.rs
Normal file
67
src/main.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
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<JoinHandle<u64>> = 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);
|
||||
}
|
||||
19
src/point.rs
Normal file
19
src/point.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Point {
|
||||
x: f64,
|
||||
y: f64,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
pub fn new(x: f64, y: f64) -> Point {
|
||||
return Point {x, y};
|
||||
}
|
||||
|
||||
pub fn get_x(self) -> f64 {
|
||||
return self.x;
|
||||
}
|
||||
|
||||
pub fn get_y(self) -> f64 {
|
||||
return self.y;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user