Last active
May 5, 2018 14:01
-
-
Save eisterman/e7bfbca3a03d99a7bd87d0997e54393c to your computer and use it in GitHub Desktop.
Numeric integral CLI in Rust!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate argparse; | |
extern crate meval; | |
extern crate crossbeam; | |
extern crate num_cpus; | |
#[macro_use] | |
extern crate generator; | |
use argparse::{ArgumentParser, Store}; | |
use meval::Expr; | |
use generator::Gn; | |
fn main() { | |
let mut text_func = "x^2".to_string(); | |
let mut low_bound = 0_f64; | |
let mut high_bound = 1_f64; | |
let mut epsilon = 1e-4_f64; | |
{ | |
let mut ap = ArgumentParser::new(); | |
ap.set_description("Calculate numerical monodimensional intwgrals."); | |
ap.refer(&mut text_func) | |
.add_argument("function", Store, | |
"Integrand function. Use \"\" for enclose the function and x as incognita.") | |
.required(); | |
ap.refer(&mut low_bound) | |
.add_argument("low_bound", Store, | |
"Lower integral bound.") | |
.required(); | |
ap.refer(&mut high_bound) | |
.add_argument("high_bound", Store, | |
"Higher integral bound.") | |
.required(); | |
ap.refer(&mut epsilon) | |
.add_option(&["-e", "--epsilon"], Store, | |
"Numerical epsilon/step."); | |
ap.parse_args_or_exit(); | |
} | |
let expr: Expr = text_func.parse().unwrap(); | |
let threads = num_cpus::get(); | |
let mut results = vec![0_f64;threads]; | |
{ | |
let refs: Vec<&mut f64> = results.iter_mut().collect(); | |
crossbeam::scope(|spawner| { | |
for (i,out_ref) in refs.into_iter().enumerate(){ | |
let lb = low_bound + (high_bound - low_bound)/(threads as f64) * (i as f64); | |
let hb = low_bound + (high_bound - low_bound)/(threads as f64) * (i as f64 + 1_f64); | |
let eps = epsilon.clone(); | |
let g = Gn::new_scoped(move |mut s: generator::Scope<(), f64>| { | |
let mut i: f64 = lb.clone(); | |
while i < hb { | |
i += eps; | |
s.yield_(i); | |
} | |
done!(); | |
}); | |
let ex = expr.clone(); | |
spawner.spawn(move ||{ | |
let func = ex.bind("x").unwrap(); | |
let partial = g.map(&*func).fold(0_f64, |acc, x| acc + (x * epsilon) ); | |
*out_ref += partial; | |
}); | |
} | |
}); | |
} | |
let output: f64 = results.iter().sum(); | |
println!("Result: {}", output); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate argparse; | |
extern crate meval; | |
#[macro_use] | |
extern crate generator; | |
use argparse::{ArgumentParser, Store}; | |
use meval::Expr; | |
use generator::Gn; | |
fn main() { | |
let mut text_func = "x^2".to_string(); | |
let mut low_bound = 0_f64; | |
let mut high_bound = 1_f64; | |
let mut epsilon = 1e-4_f64; | |
{ | |
let mut ap = ArgumentParser::new(); | |
ap.set_description("Calculate numerical monodimensional intwgrals."); | |
ap.refer(&mut text_func) | |
.add_argument("function", Store, | |
"Integrand function. Use \"\" for enclose the function and x as incognita.") | |
.required(); | |
ap.refer(&mut low_bound) | |
.add_argument("low_bound", Store, | |
"Lower integral bound.") | |
.required(); | |
ap.refer(&mut high_bound) | |
.add_argument("high_bound", Store, | |
"Higher integral bound.") | |
.required(); | |
ap.refer(&mut epsilon) | |
.add_option(&["-e", "--epsilon"], Store, | |
"Numerical epsilon/step."); | |
let result = ap.parse_args(); | |
if let Err(c) = result { | |
let args: Vec<String> = std::env::args().collect(); | |
let name = if args.len() > 0 { &args[0][..] } else { "unknown" }; | |
ap.print_help(name, &mut std::io::stdout()).unwrap(); | |
std::process::exit(c); | |
} | |
} | |
let expr: Expr = text_func.parse().unwrap(); | |
let func = expr.bind("x").unwrap(); | |
let g = Gn::new_scoped(|mut s| { | |
let mut i = low_bound.clone(); | |
while i < high_bound { | |
i += epsilon; | |
s.yield_(i); | |
} | |
done!(); | |
}); | |
let result: f64 = g.map(&*func).fold(0_f64, |acc, x| acc + (x * epsilon) ); | |
println!("Result: {}", result); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment