nth derivative support
This commit is contained in:
parent
5e9328ce85
commit
79894c4cad
@ -77,8 +77,9 @@ const HELP_PANEL: &str =
|
|||||||
- The 'Info' button provides information on the build currently running.";
|
- The 'Info' button provides information on the build currently running.";
|
||||||
|
|
||||||
// Used in the "Functions" section of the Help window
|
// 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.
|
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 ∫ button (between the 'd/dx' and 'X' buttons) indicates whether estimating an integral for that function is enabled or not.
|
- 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.";
|
- The 'd/dx' button next to the function input indicates whether or not calculating the derivative is enabled or not.";
|
||||||
|
|
||||||
// Misc help info
|
// Misc help info
|
||||||
@ -111,6 +112,9 @@ struct AppSettings {
|
|||||||
|
|
||||||
// Stores how integrals should be displayed
|
// Stores how integrals should be displayed
|
||||||
pub integral_display_type: IntegralDisplay,
|
pub integral_display_type: IntegralDisplay,
|
||||||
|
|
||||||
|
// List of functions whose windows are open
|
||||||
|
pub opened_functions: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppSettings {
|
impl Default for AppSettings {
|
||||||
@ -124,6 +128,7 @@ impl Default for AppSettings {
|
|||||||
integral_max_x: DEFAULT_MAX_X,
|
integral_max_x: DEFAULT_MAX_X,
|
||||||
integral_num: DEFAULT_INTEGRAL_NUM,
|
integral_num: DEFAULT_INTEGRAL_NUM,
|
||||||
integral_display_type: IntegralDisplay::Rectangles,
|
integral_display_type: IntegralDisplay::Rectangles,
|
||||||
|
opened_functions: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,6 +240,30 @@ impl MathApp {
|
|||||||
// Entry for a function
|
// Entry for a function
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Function:");
|
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
|
if ui
|
||||||
.add(Button::new("X"))
|
.add(Button::new("X"))
|
||||||
.on_hover_text("Delete Function")
|
.on_hover_text("Delete Function")
|
||||||
|
|||||||
@ -165,10 +165,9 @@ impl FunctionEntry {
|
|||||||
Option<(Vec<Bar>, Vec<Value>, f64)>,
|
Option<(Vec<Bar>, Vec<Value>, f64)>,
|
||||||
Option<Vec<Value>>,
|
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> = {
|
let back_values: Vec<Value> = {
|
||||||
if self.back_cache.is_none() {
|
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(
|
self.back_cache = Some(
|
||||||
(0..self.pixel_width)
|
(0..self.pixel_width)
|
||||||
.map(|x| (x as f64 / resolution as f64) + self.min_x)
|
.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 {
|
let derivative_values: Option<Vec<Value>> = match self.derivative {
|
||||||
true => {
|
true => {
|
||||||
if self.derivative_cache.is_none() {
|
if self.derivative_cache.is_none() {
|
||||||
let back_cache = self.back_cache.as_ref().unwrap().clone();
|
|
||||||
self.derivative_cache = Some(
|
self.derivative_cache = Some(
|
||||||
back_cache
|
(0..self.pixel_width)
|
||||||
.iter()
|
.map(|x| (x as f64 / resolution as f64) + self.min_x)
|
||||||
.map(|ele| {
|
.map(|x| {
|
||||||
let x = ele.x;
|
Value::new(x, self.function.derivative(x, self.nth_derivative))
|
||||||
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)
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
@ -282,6 +276,8 @@ impl FunctionEntry {
|
|||||||
// Set func_str to an empty string
|
// Set func_str to an empty string
|
||||||
pub fn empty_func_str(&mut self) { self.func_str = String::new(); }
|
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
|
// Updates riemann value and invalidates front_cache if needed
|
||||||
pub fn update_riemann(mut self, riemann: RiemannSum) -> Self {
|
pub fn update_riemann(mut self, riemann: RiemannSum) -> Self {
|
||||||
if self.sum != riemann {
|
if self.sum != riemann {
|
||||||
@ -297,7 +293,6 @@ impl FunctionEntry {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggles integral
|
|
||||||
pub fn integral_num(mut self, integral_num: usize) -> Self {
|
pub fn integral_num(mut self, integral_num: usize) -> Self {
|
||||||
self.integral_num = integral_num;
|
self.integral_num = integral_num;
|
||||||
self
|
self
|
||||||
@ -317,6 +312,8 @@ impl FunctionEntry {
|
|||||||
self.integral_max_x = max_x;
|
self.integral_max_x = max_x;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn invalidate_derivative_cache(&mut self) { self.derivative_cache = None; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user