Skip to content

Instantly share code, notes, and snippets.

@eisterman
Last active May 5, 2018 14:01
Show Gist options
  • Save eisterman/e7bfbca3a03d99a7bd87d0997e54393c to your computer and use it in GitHub Desktop.
Save eisterman/e7bfbca3a03d99a7bd87d0997e54393c to your computer and use it in GitHub Desktop.
Numeric integral CLI in Rust!
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);
}
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