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.";
|
||||
|
||||
// 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")
|
||||
|
||||
@ -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]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user