Compare commits
15 Commits
74ea548338
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 853eead617 | |||
| bcf0430bf6 | |||
| a9231c64bc | |||
| df4bc1922f | |||
| 709ffb313f | |||
| 2ea8ba5a39 | |||
| afe317404f | |||
| 5ed2bfa730 | |||
| f9e9fb7e10 | |||
| 91fad47f31 | |||
| 6b48a51be4 | |||
| 25d06948b4 | |||
| 71de7e63f6 | |||
| 134ba50999 | |||
| ff3f3c12bf |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
|
src/output*.json
|
||||||
19
Cargo.toml
19
Cargo.toml
@@ -3,7 +3,26 @@ 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]
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
|
|
||||||
|
[dependencies.serde]
|
||||||
|
version = "1.0.200"
|
||||||
|
features = ["derive"]
|
||||||
|
|
||||||
|
[dependencies.axum]
|
||||||
|
version = "0.7.5"
|
||||||
|
features = ["json"]
|
||||||
|
|
||||||
|
[dependencies.serde_json]
|
||||||
|
version = "1.0.116"
|
||||||
|
|||||||
@@ -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,21 +35,29 @@ 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 {
|
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;
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _ in 0..samples % thread_cnt {
|
||||||
|
let point: Point = bounds.get_random_point();
|
||||||
|
if function.includes(&point) {
|
||||||
|
hits += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for thread in threads {
|
for thread in threads {
|
||||||
hits += thread.join().unwrap();
|
hits += thread.join().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (hits as f64 / (thread_cnt * samples) as f64) * bounds.get_area();
|
return (hits as f64 / samples as f64) * bounds.get_area();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
47
src/main.rs
47
src/main.rs
@@ -1,3 +1,8 @@
|
|||||||
|
use std::f64::consts::E;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
|
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;
|
||||||
@@ -9,27 +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;
|
//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 = 10;
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
let file: io::Result<File> = File::create(format!("out/output{}.json", sample_cnt.ilog10()));
|
||||||
|
if file.is_err() {
|
||||||
|
panic!("Error creating output file")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(_) = file.unwrap().write(result.to_json().to_string().as_bytes()) { panic!("Error writing to file") };
|
||||||
|
|
||||||
|
result = Plot::new();
|
||||||
}
|
}
|
||||||
result.print();
|
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/plot.rs
20
src/plot.rs
@@ -1,6 +1,9 @@
|
|||||||
use std::iter::zip;
|
use std::iter::zip;
|
||||||
|
use axum::extract::FromRef;
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Plot {
|
pub struct Plot {
|
||||||
x: Vec<usize>,
|
x: Vec<usize>,
|
||||||
y: Vec<Vec<f64>>,
|
y: Vec<Vec<f64>>,
|
||||||
@@ -21,9 +24,20 @@ impl Plot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print(self) -> () {
|
pub fn print(&self) -> () {
|
||||||
for (x, y) in zip(self.x, self.y) {
|
let plot: Plot = Plot::from_ref(self);
|
||||||
|
for (x, y) in zip(plot.x, plot.y) {
|
||||||
println!("{}: {:?}", x, y);
|
println!("{}: {:?}", x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_json(&self) -> Value {
|
||||||
|
return json!(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Plot {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
return Plot {x: self.x.clone(), y: self.y.clone()}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user