use rayon parallel iterator when not on wasm
This commit is contained in:
parent
55d47121a4
commit
fd82c71652
@ -44,6 +44,7 @@ command-run = "1.1.1"
|
|||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
instant = { version = "0.1.12" }
|
instant = { version = "0.1.12" }
|
||||||
tracing-subscriber = "0.3.9"
|
tracing-subscriber = "0.3.9"
|
||||||
|
rayon = { git = "https://github.com/rayon-rs/rayon.git" }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
instant = { version = "0.1.12", features = ["wasm-bindgen"] }
|
instant = { version = "0.1.12", features = ["wasm-bindgen"] }
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::egui_app::AppSettings;
|
use crate::egui_app::AppSettings;
|
||||||
use crate::function_output::FunctionOutput;
|
use crate::function_output::FunctionOutput;
|
||||||
use crate::misc::{newtons_method, resolution_helper, step_helper, SteppedVector};
|
use crate::misc::{dyn_iter, newtons_method, resolution_helper, step_helper, SteppedVector};
|
||||||
use crate::parsing::BackingFunction;
|
use crate::parsing::BackingFunction;
|
||||||
use eframe::{egui, epaint};
|
use eframe::{egui, epaint};
|
||||||
use egui::{
|
use egui::{
|
||||||
@ -12,6 +12,9 @@ use egui::{
|
|||||||
use epaint::Color32;
|
use epaint::Color32;
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
use rayon::iter::ParallelIterator;
|
||||||
|
|
||||||
/// Represents the possible variations of Riemann Sums
|
/// Represents the possible variations of Riemann Sums
|
||||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
pub enum RiemannSum {
|
pub enum RiemannSum {
|
||||||
@ -98,13 +101,8 @@ impl FunctionEntry {
|
|||||||
|
|
||||||
let step = (integral_min_x - integral_max_x).abs() / (integral_num as f64);
|
let step = (integral_min_x - integral_max_x).abs() / (integral_num as f64);
|
||||||
|
|
||||||
let mut area: f64 = 0.0;
|
let data2: Vec<(f64, f64)> = dyn_iter(&step_helper(integral_num, integral_min_x, step))
|
||||||
let mut i: usize = 0;
|
|
||||||
let data2: Vec<(f64, f64)> = (step_helper(integral_num, integral_min_x, step))
|
|
||||||
.iter()
|
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
i += 1;
|
|
||||||
|
|
||||||
let step_offset = step * x.signum(); // store the offset here so it doesn't have to be calculated multiple times
|
let step_offset = step * x.signum(); // store the offset here so it doesn't have to be calculated multiple times
|
||||||
let x2: f64 = x + step_offset;
|
let x2: f64 = x + step_offset;
|
||||||
|
|
||||||
@ -121,15 +119,11 @@ impl FunctionEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !y.is_nan() {
|
|
||||||
area += y * step;
|
|
||||||
}
|
|
||||||
|
|
||||||
(x + (step_offset / 2.0), y)
|
(x + (step_offset / 2.0), y)
|
||||||
})
|
})
|
||||||
.filter(|(_, y)| !y.is_nan())
|
.filter(|(_, y)| !y.is_nan())
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(i, integral_num);
|
let area = data2.iter().map(|(_, y)| y * step).sum();
|
||||||
|
|
||||||
(data2, area)
|
(data2, area)
|
||||||
}
|
}
|
||||||
@ -160,8 +154,7 @@ impl FunctionEntry {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(
|
Some(
|
||||||
newtons_method_output
|
dyn_iter(&newtons_method_output)
|
||||||
.iter()
|
|
||||||
.map(|x| (*x, self.function.get(*x)))
|
.map(|x| (*x, self.function.get(*x)))
|
||||||
.map(|(x, y)| Value::new(x, y))
|
.map(|(x, y)| Value::new(x, y))
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -201,8 +194,7 @@ impl FunctionEntry {
|
|||||||
.collect::<Vec<f64>>()
|
.collect::<Vec<f64>>()
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let back_data: Vec<Value> = resolution_iter
|
let back_data: Vec<Value> = dyn_iter(&resolution_iter)
|
||||||
.iter()
|
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
if let Some(i) = x_data.get_index(x) {
|
if let Some(i) = x_data.get_index(x) {
|
||||||
@ -216,8 +208,7 @@ impl FunctionEntry {
|
|||||||
self.output.back = Some(back_data);
|
self.output.back = Some(back_data);
|
||||||
|
|
||||||
let derivative_cache = self.output.derivative.as_ref().unwrap();
|
let derivative_cache = self.output.derivative.as_ref().unwrap();
|
||||||
let new_derivative_data: Vec<Value> = resolution_iter
|
let new_derivative_data: Vec<Value> = dyn_iter(&resolution_iter)
|
||||||
.iter()
|
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
if let Some(i) = x_data.get_index(*x) {
|
if let Some(i) = x_data.get_index(*x) {
|
||||||
derivative_cache[i]
|
derivative_cache[i]
|
||||||
@ -246,9 +237,7 @@ impl FunctionEntry {
|
|||||||
if !partial_regen {
|
if !partial_regen {
|
||||||
self.output.back = Some({
|
self.output.back = Some({
|
||||||
if self.output.back.is_none() {
|
if self.output.back.is_none() {
|
||||||
let data: Vec<Value> = resolution_iter
|
let data: Vec<Value> = dyn_iter(&resolution_iter)
|
||||||
.clone()
|
|
||||||
.iter()
|
|
||||||
.map(|x| Value::new(*x, self.function.get(*x)))
|
.map(|x| Value::new(*x, self.function.get(*x)))
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(data.len(), pixel_width + 1);
|
assert_eq!(data.len(), pixel_width + 1);
|
||||||
@ -261,8 +250,7 @@ impl FunctionEntry {
|
|||||||
|
|
||||||
self.output.derivative = {
|
self.output.derivative = {
|
||||||
if self.output.derivative.is_none() {
|
if self.output.derivative.is_none() {
|
||||||
let data: Vec<Value> = resolution_iter
|
let data: Vec<Value> = dyn_iter(&resolution_iter)
|
||||||
.iter()
|
|
||||||
.map(|x| Value::new(*x, self.function.get_derivative_1(*x)))
|
.map(|x| Value::new(*x, self.function.get_derivative_1(*x)))
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(data.len(), pixel_width + 1);
|
assert_eq!(data.len(), pixel_width + 1);
|
||||||
|
|||||||
14
src/misc.rs
14
src/misc.rs
@ -1,6 +1,20 @@
|
|||||||
use eframe::egui::plot::Value as EguiValue;
|
use eframe::egui::plot::Value as EguiValue;
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::Value as JsonValue;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
pub fn dyn_iter<'a, T>(input: &'a Vec<T>) -> impl Iterator<Item = &'a T> { input.iter() }
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
pub fn dyn_iter<'a, T>(input: &'a Vec<T>) -> <&'a [T] as IntoParallelIterator>::Iter
|
||||||
|
where
|
||||||
|
&'a [T]: IntoParallelIterator,
|
||||||
|
{
|
||||||
|
input.par_iter()
|
||||||
|
}
|
||||||
|
|
||||||
/// `SteppedVector` is used in order to efficiently sort through an ordered
|
/// `SteppedVector` is used in order to efficiently sort through an ordered
|
||||||
/// `Vec<f64>` Used in order to speedup the processing of cached data when
|
/// `Vec<f64>` Used in order to speedup the processing of cached data when
|
||||||
/// moving horizontally without zoom in `FunctionEntry`. Before this struct, the
|
/// moving horizontally without zoom in `FunctionEntry`. Before this struct, the
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user