This commit is contained in:
Simon Gardling
2022-05-05 10:39:34 -04:00
parent e170dee22a
commit 73e3760a8b
9 changed files with 57 additions and 64 deletions

View File

@@ -11,7 +11,7 @@ fn compare_len_reverse_alpha(a: &String, b: &String) -> Ordering {
/// Generates hashmap (well really a vector of tuple of strings that are then turned into a hashmap by phf)
#[allow(dead_code)]
pub fn compile_hashmap(data: Vec<String>) -> Vec<(String, String)> {
pub(crate) fn compile_hashmap(data: Vec<String>) -> Vec<(String, String)> {
let mut seen = HashSet::new();
let tuple_list_1: Vec<(String, String)> = data

View File

@@ -1,5 +1,6 @@
#![feature(const_trait_impl)]
#![feature(core_intrinsics)]
#![feature(const_default_impls)]
pub mod parsing;
pub mod suggestions;

View File

@@ -8,44 +8,33 @@ pub struct FlatExWrapper {
impl FlatExWrapper {
const EMPTY: FlatExWrapper = FlatExWrapper { func: None };
fn new(f: FlatEx<f64>) -> Self { Self { func: Some(f) } }
const fn new(f: FlatEx<f64>) -> Self { Self { func: Some(f) } }
fn eval(&self, x: &[f64]) -> f64 {
if let Some(ref f) = self.func {
f.eval(x).unwrap_or(f64::NAN)
} else {
f64::NAN
}
self.func
.as_ref()
.map(|f| f.eval(x).unwrap_or(f64::NAN))
.unwrap_or(f64::NAN)
}
fn partial(&self, x: usize) -> Self {
if let Some(ref f) = self.func {
match f.partial(x) {
Ok(a) => Self::new(a),
Err(_) => Self::EMPTY,
}
} else {
Self::EMPTY
}
self.func
.as_ref()
.map(|f| f.partial(x).map(|a| Self::new(a)).unwrap_or(Self::EMPTY))
.unwrap_or(Self::EMPTY)
}
fn get_string(&self) -> &str {
if let Some(ref f) = self.func {
f.unparse()
} else {
""
}
}
fn get_string(&self) -> &str { self.func.as_ref().map(|f| f.unparse()).unwrap_or("") }
fn partial_iter(&self, x: &[usize]) -> Self {
if let Some(ref f) = self.func {
match f.partial_iter(x.iter()) {
Ok(a) => Self::new(a),
Err(_) => Self::EMPTY,
}
} else {
Self::EMPTY
}
self.func
.as_ref()
.map(|f| {
f.partial_iter(x.iter())
.map(|a| Self::new(a))
.unwrap_or(Self::EMPTY)
})
.unwrap_or(Self::EMPTY)
}
}
@@ -58,18 +47,23 @@ impl const Default for FlatExWrapper {
pub struct BackingFunction {
/// f(x)
function: FlatExWrapper,
/// f'(x)
derivative_1: FlatExWrapper,
/// Mathematical representation of f'(x)
derivative_1_str: String,
/// f''(x)
derivative_2: FlatExWrapper,
/// Temporary cache for nth derivative
nth_derivative: Option<(usize, FlatExWrapper, String)>,
}
impl BackingFunction {
const EMPTY: BackingFunction = BackingFunction {
/// Empty [`BackingFunction`] instance
pub const EMPTY: BackingFunction = BackingFunction {
function: FlatExWrapper::EMPTY,
derivative_1: FlatExWrapper::EMPTY,
derivative_1_str: String::new(),
@@ -139,6 +133,7 @@ impl BackingFunction {
/// Calculate f''(x)
pub fn get_derivative_2(&self, x: f64) -> f64 { self.derivative_2.eval(&[x]) }
/// Get string relating to the nth derivative
pub fn get_nth_derivative_str(&self) -> &str { &self.nth_derivative.as_ref().unwrap().2 }
pub fn get_nth_derivative(&mut self, n: usize, x: f64) -> f64 {
@@ -168,7 +163,7 @@ impl BackingFunction {
}
fn prettyify_function_str(func: &str) -> String {
let new_str = func.to_owned().replace("{x}", "x");
let new_str = func.replace("{x}", "x");
if &new_str == "0/0" {
"Undefined".to_owned()
@@ -177,10 +172,10 @@ fn prettyify_function_str(func: &str) -> String {
}
}
pub const VALID_VARIABLES: [char; 5] = ['x', 'X', 'e', 'E', 'π'];
pub const VALID_VARIABLES: [char; 3] = ['x', 'e', 'π'];
#[inline]
pub fn is_variable(c: &char) -> bool { VALID_VARIABLES.contains(&c) }
pub fn is_variable(c: &char) -> bool { VALID_VARIABLES.contains(&c.to_ascii_lowercase()) }
/// Adds asterisks where needed in a function
pub fn process_func_str(function_in: &str) -> String {

View File

@@ -19,7 +19,7 @@ pub fn split_function(input: &str) -> Vec<String> {
&input
.replace("pi", "π") // replace "pi" text with pi symbol
.replace("**", "^") // support alternate manner of expressing exponents
.replace("exp", "\u{1fc93}") //stop-gap solution to fix the `exp` function
.replace("exp", "\u{1fc93}") // stop-gap solution to fix the `exp` function
.chars()
.collect::<Vec<char>>(),
)
@@ -64,7 +64,7 @@ pub fn split_function_chars(chars: &[char]) -> Vec<String> {
let isnumber = c.is_ascii_digit();
let isvariable = is_variable(c);
Self {
closing_parens: c == &')',
closing_parens: *c == ')',
number: isnumber,
letter: c.is_ascii_alphabetic(),
variable: isvariable,