nth derivative support

This commit is contained in:
Simon Gardling 2022-03-04 14:17:12 -05:00
parent 5e9328ce85
commit 79894c4cad
2 changed files with 40 additions and 14 deletions

View File

@ -77,8 +77,9 @@ const HELP_PANEL: &str =
- The 'Info' button provides information on the build currently running.";
// Used in the "Functions" section of the Help window
const HELP_FUNCTION: &str = "- The 'X' button before the ∫ symbol allows you to delete the function in question. Deleting a function is prevented if only 1 function exists.
- The button (between the 'd/dx' and 'X' buttons) indicates whether estimating an integral for that function is enabled or not.
const HELP_FUNCTION: &str = "- The 'X' button before the 'O' symbol allows you to delete the function in question. Deleting a function is prevented if only 1 function exists.
- The 'O' button after the 'X' button opens a window where you can configure some settings in relation to the function in question.
- The button (between the 'O' and 'd/dx' buttons) indicates whether estimating an integral for that function is enabled or not.
- The 'd/dx' button next to the function input indicates whether or not calculating the derivative is enabled or not.";
// Misc help info
@ -111,6 +112,9 @@ struct AppSettings {
// Stores how integrals should be displayed
pub integral_display_type: IntegralDisplay,
// List of functions whose windows are open
pub opened_functions: Vec<usize>,
}
impl Default for AppSettings {
@ -124,6 +128,7 @@ impl Default for AppSettings {
integral_max_x: DEFAULT_MAX_X,
integral_num: DEFAULT_INTEGRAL_NUM,
integral_display_type: IntegralDisplay::Rectangles,
opened_functions: Vec::new(),
}
}
}
@ -235,6 +240,30 @@ impl MathApp {
// Entry for a function
ui.horizontal(|ui| {
ui.label("Function:");
if ui
.add(Button::new("O"))
.on_hover_text("Open Function Settings")
.clicked()
| self.settings.opened_functions.contains(&i)
{
self.settings.opened_functions.push(i);
Window::new(function.get_func_str())
.default_pos([200.0, 200.0])
.resizable(false)
.collapsible(false)
.show(ctx, |ui| {
if ui
.add(
Slider::new(&mut function.nth_derivative, 0..=2) // Derivatives go insane after the value 3, probably inaccuracies in the handling of floating point numbers. more investigation needed.
.text("Derivative"),
)
.changed()
{
function.invalidate_derivative_cache();
}
});
}
if ui
.add(Button::new("X"))
.on_hover_text("Delete Function")

View File

@ -165,10 +165,9 @@ impl FunctionEntry {
Option<(Vec<Bar>, Vec<Value>, f64)>,
Option<Vec<Value>>,
) {
let resolution: f64 = (self.pixel_width as f64 / (self.max_x - self.min_x).abs()) as f64;
let back_values: Vec<Value> = {
if self.back_cache.is_none() {
let resolution: f64 =
(self.pixel_width as f64 / (self.max_x - self.min_x).abs()) as f64;
self.back_cache = Some(
(0..self.pixel_width)
.map(|x| (x as f64 / resolution as f64) + self.min_x)
@ -183,16 +182,11 @@ impl FunctionEntry {
let derivative_values: Option<Vec<Value>> = match self.derivative {
true => {
if self.derivative_cache.is_none() {
let back_cache = self.back_cache.as_ref().unwrap().clone();
self.derivative_cache = Some(
back_cache
.iter()
.map(|ele| {
let x = ele.x;
let (x1, x2) = (x - EPSILON, x + EPSILON);
let (y1, y2) = (self.run_func(x1), self.run_func(x2));
let slope = (y2 - y1) / (EPSILON * 2.0);
Value::new(x, slope)
(0..self.pixel_width)
.map(|x| (x as f64 / resolution as f64) + self.min_x)
.map(|x| {
Value::new(x, self.function.derivative(x, self.nth_derivative))
})
.collect(),
);
@ -282,6 +276,8 @@ impl FunctionEntry {
// Set func_str to an empty string
pub fn empty_func_str(&mut self) { self.func_str = String::new(); }
pub fn get_func_str(&self) -> String { self.func_str.clone() }
// Updates riemann value and invalidates front_cache if needed
pub fn update_riemann(mut self, riemann: RiemannSum) -> Self {
if self.sum != riemann {
@ -297,7 +293,6 @@ impl FunctionEntry {
self
}
// Toggles integral
pub fn integral_num(mut self, integral_num: usize) -> Self {
self.integral_num = integral_num;
self
@ -317,6 +312,8 @@ impl FunctionEntry {
self.integral_max_x = max_x;
self
}
pub fn invalidate_derivative_cache(&mut self) { self.derivative_cache = None; }
}
#[test]