Compare commits

...

13 Commits

Author SHA1 Message Date
853eead617 improved simulation for multiple samples 2024-06-06 11:21:34 +02:00
bcf0430bf6 reduced optimization for performance 2024-06-06 11:20:41 +02:00
a9231c64bc quick fix 2024-06-03 09:57:42 +02:00
df4bc1922f Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/main.rs
2024-06-03 09:55:48 +02:00
709ffb313f added file backups 2024-06-03 09:54:40 +02:00
2ea8ba5a39 removed print in simulation 2024-06-03 09:50:18 +02:00
afe317404f changed bounds 2024-06-02 14:41:13 +02:00
5ed2bfa730 changed function and integral 2024-06-02 14:40:51 +02:00
f9e9fb7e10 redone function 2024-06-02 14:37:15 +02:00
91fad47f31 called f by value 2024-06-02 14:36:30 +02:00
6b48a51be4 splitted simulate function from main 2024-05-12 01:07:41 +02:00
25d06948b4 added progress bar 2024-05-02 10:39:48 +02:00
71de7e63f6 made config const 2024-05-02 10:17:13 +02:00
4 changed files with 55 additions and 35 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,3 @@
/target /target
/Cargo.lock /Cargo.lock
*/output.json src/output*.json

View File

@@ -3,6 +3,14 @@ name = "montecarlo-rust"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[[bin]]
name = "monte-carlo"
path = "src/main.rs"
[profile.release]
strip = true # Automatically strip symbols from the binary.
opt-level = 2
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies.rand] [dependencies.rand]
@@ -17,4 +25,4 @@ version = "0.7.5"
features = ["json"] features = ["json"]
[dependencies.serde_json] [dependencies.serde_json]
version = "1.0.116" version = "1.0.116"

View File

@@ -5,33 +5,27 @@ use crate::linear_bounds::LinearBounds;
use crate::point::Point; use crate::point::Point;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Function{} pub struct Function{
f: fn(f64)->f64,
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 { impl Function {
pub fn new() -> Function { pub fn new(f: fn(f64) -> f64) -> Function {
return Function {}; return Function {f};
} }
pub fn integrate(&self, bounds: &LinearBounds) -> f64 { pub fn integrate(&self, _bounds: &LinearBounds) -> f64 {
return big_f(&bounds.get_higher()) - big_f(&bounds.get_lower()); 0.0
} }
fn includes(&self, point: &Point) -> bool { fn includes(&self, point: &Point) -> bool {
let y_0: f64 = f(&point.get_x()); let y_0: f64 = (self.f)(point.get_x());
return y_0.abs() > point.get_y().abs() && y_0 * point.get_y() >= 0_f64; 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 { pub fn approximate(&self, bounds: &Bounds, samples: usize, thread_cnt: usize) -> f64 {
let mut hits: u64 = 0; let mut hits: i64 = 0;
let mut threads: Vec<JoinHandle<u64>> = vec![]; let mut threads: Vec<JoinHandle<i64>> = vec![];
let function: Arc<Function> = Arc::new(*self); let function: Arc<Function> = Arc::new(*self);
let bounds: Arc<Bounds> = Arc::new(*bounds); let bounds: Arc<Bounds> = Arc::new(*bounds);
@@ -41,11 +35,12 @@ impl Function {
let bounds = bounds.clone(); let bounds = bounds.clone();
threads.push(std::thread::spawn(move || { threads.push(std::thread::spawn(move || {
let mut hits: u64 = 0; let mut hits: i64 = 0;
for _ in 0..samples/thread_cnt { for _ in 0..samples/thread_cnt {
let point: Point = bounds.get_random_point(); let point: Point = bounds.get_random_point();
if function.includes(&point) { if function.includes(&point) {
hits += 1; if point.get_y() >= 0.0 { hits += 1;}
else { hits -= 1; }
} }
} }
return hits; return hits;

View File

@@ -1,6 +1,8 @@
use std::f64::consts::E;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::io::Write; use std::io::Write;
use std::time::Instant;
use crate::bounds::Bounds; use crate::bounds::Bounds;
use crate::function::Function; use crate::function::Function;
use crate::linear_bounds::LinearBounds; use crate::linear_bounds::LinearBounds;
@@ -12,34 +14,49 @@ mod bounds;
mod function; mod function;
mod plot; mod plot;
const THREAD_CNT: usize = 8; const THREAD_CNT: usize = 20;
const SAMPLE_START: usize = 100_000_000_000;
const SAMPLE_LIMIT: usize = 1_000_000_000_000;
const SUB_SAMPLES: [usize; 3] = [1, 2, 5];
const SAMPLES_PER_ITERATION: usize = 250;
fn f(x: f64) -> f64 {
E.powf(x) * (1.0 / x.sin()).cos() + x.powf(2.0)
}
fn main() { fn main() {
let bounds: Bounds = Bounds::new(LinearBounds::new(0_f64, 20_f64), LinearBounds::new(-100_f64, 150000_f64)); let bounds: Bounds = Bounds::new(LinearBounds::new(3.1_f64, 3.2_f64), LinearBounds::new(-10_f64, 35_f64));
let func: Function = Function::new(); let func: Function = Function::new(f);
let sample_limit: usize = 1_000_000_000; //let start: Instant = Instant::now();
let sub_samples: Vec<usize> = vec![1, 2, 5]; //println!("{}\n{}ms", func.approximate(&bounds, 10_000_000, THREAD_CNT), start.elapsed().as_millis())
let samples_per_iteration: usize = 1;
simulate(&bounds, &func)
}
fn simulate(bounds: &Bounds, func: &Function) {
let mut result: Plot = Plot::new(); let mut result: Plot = Plot::new();
let mut sample_cnt: usize = 1; let mut sample_cnt: usize = 1;
while sample_cnt < sample_limit { while sample_cnt < SAMPLE_LIMIT {
for sub_sample in sub_samples.clone() { for sub_sample in SUB_SAMPLES.clone() {
let samples: usize = sub_sample * sample_cnt; let samples: usize = sub_sample * sample_cnt;
for _ in 0..samples_per_iteration { for sample in 0..SAMPLES_PER_ITERATION {
result.add_sample(samples, func.approximate(&bounds, samples, THREAD_CNT)); result.add_sample(samples, func.approximate(&bounds, samples, THREAD_CNT));
let progress: usize = (((sample + 1) as f64 / SAMPLES_PER_ITERATION as f64) * 25.0) as usize;
eprint!("\r{:12} [{}{}]", samples, "|".repeat(progress), " ".repeat(25 - progress));
} }
println!();
} }
sample_cnt *= 10; sample_cnt *= 10;
}
result.print();
let mut file: io::Result<File> = File::create("output.json"); let file: io::Result<File> = File::create(format!("out/output{}.json", sample_cnt.ilog10()));
if file.is_err() { if file.is_err() {
panic!("Error creating output file") panic!("Error creating output file")
} }
if let Err(_) = file.unwrap().write(result.to_json().to_string().as_bytes()) { panic!("Error writing to file") }; if let Err(_) = file.unwrap().write(result.to_json().to_string().as_bytes()) { panic!("Error writing to file") };
result = Plot::new();
}
} }