number_diff/functions/
calc.rs

1use crate::{gamma_function, polygamma_function, Elementary::*, Factorial};
2use std::{f64::consts::E, sync::Arc};
3
4use crate::{Error, Func};
5
6use super::series_expansions::SeriesExpansion;
7
8// unit function f(x) -> x
9fn f() -> Func {
10    Box::new(move |x| x)
11}
12
13#[derive(Debug, Clone, PartialEq)]
14pub enum Elementary {
15    // Standard trig functions
16    Sin(Arc<Elementary>), // of the type sin(f(x))
17    Cos(Arc<Elementary>), // of the type cos(f(x))
18    Tan(Arc<Elementary>), // of the type tan(f(x))
19
20    Sec(Arc<Elementary>), // of the tyoe sec(f(x))
21    Csc(Arc<Elementary>), // of the type csc(f(x))
22    Cot(Arc<Elementary>), // of the type cot(f(x))
23
24    // Standard arcus functions
25    Asin(Arc<Elementary>), // of the type arcsin(f(x))
26    Acos(Arc<Elementary>), // of the type arccos(f(x))
27    Atan(Arc<Elementary>), // of the type arctan(f(x))
28
29    // hyperbolic trig functions
30    Sinh(Arc<Elementary>), // of the type sinh(f(x))
31    Cosh(Arc<Elementary>), // of the type cosh(f(x))
32    Tanh(Arc<Elementary>), // of the type tanh(f(x))
33
34    // Standard operations
35    Add(Arc<Elementary>, Arc<Elementary>), // of the type f(x) + g(x)
36    Sub(Arc<Elementary>, Arc<Elementary>), // of the type f(x) - g(x)
37    Mul(Arc<Elementary>, Arc<Elementary>), // of the type f(x) * g(x)
38    Div(Arc<Elementary>, Arc<Elementary>), // of the type f(x) / g(x)
39    Pow(Arc<Elementary>, Arc<Elementary>), // of the type f(x)^g(x)
40    Log(Arc<Elementary>, Arc<Elementary>), // of the type logb(f(x)) where b = g(x)
41
42    // special functions
43    Factorial(Arc<Elementary>),
44    // gamma function
45    Gamma(Arc<Elementary>),            // of the type 𝜞(f(x))
46    Polygamma(Arc<Elementary>, usize), // Of the type 𝝍m(f(x))
47
48    // Absolute value function
49    Abs(Arc<Elementary>),
50    // Constant function
51    Con(f64), // of the type c
52
53    X, // unit function f(x) = x. Any function dependant on a variable must include this
54       // function as it returns a function of type Func which returns the input value.
55       // X will represent the independant variable in each function
56}
57impl Elementary {
58    pub fn call(self) -> Func {
59        Box::new(move |x| match self.clone() {
60            Sin(func) => (*func).clone().call()(x).sin(),
61            Cos(func) => (*func).clone().call()(x).cos(),
62            Tan(func) => (*func).clone().call()(x).tan(),
63
64            Sec(func) => 1. / (*func).clone().call()(x).cos(),
65            Csc(func) => 1. / (*func).clone().call()(x).sin(),
66            Cot(func) => 1. / (*func).clone().call()(x).tan(),
67
68            Asin(func) => (*func).clone().call()(x).asin(),
69            Acos(func) => (*func).clone().call()(x).acos(),
70            Atan(func) => (*func).clone().call()(x).atan(),
71
72            Sinh(func) => {
73                (E.powf((*func).clone().call()(x)) - E.powf(-(*func).clone().call()(x))) / 2.
74            }
75            Cosh(func) => {
76                (E.powf((*func).clone().call()(x)) + E.powf(-(*func).clone().call()(x))) / 2.
77            }
78            Tanh(func) => Sinh(func.clone()).call()(x) / Cosh(func).call()(x),
79
80            Add(func1, func2) => (*func1).clone().call()(x) + (*func2).clone().call()(x),
81            Sub(func1, func2) => (*func1).clone().call()(x) - (*func2).clone().call()(x),
82            Mul(func1, func2) => (*func1).clone().call()(x) * (*func2).clone().call()(x),
83            Div(func1, func2) => (*func1).clone().call()(x) / (*func2).clone().call()(x),
84
85            Pow(func1, func2) => (*func1).clone().call()(x).powf((*func2).clone().call()(x)),
86            Log(func1, func2) => (*func2).clone().call()(x).log((*func1).clone().call()(x)),
87
88            Factorial(func) => (*func).clone().call()(x).factorial(),
89
90            Gamma(func) => gamma_function((*func).clone().call()(x)),
91            Polygamma(func, order) => polygamma_function((*func).clone().call()(x), order),
92
93            Abs(func) => (*func).clone().call()(x).abs(),
94
95            Con(numb) => numb,
96
97            X => f()(x),
98        })
99    }
100}
101
102// returns the inner Elementary value of the Arc or returns a clone
103pub fn force_unwrap(element: &Arc<Elementary>) -> Elementary {
104    if let Ok(inner) = Arc::try_unwrap(element.clone()) {
105        inner
106    } else {
107        (**element).clone()
108    }
109}
110
111// basic trig functions
112/// Creates a [Function](crate::Function) equal to the sine of the passed [Function](crate::Function)
113///
114/// i.e f(x) ⟹ sin(f(x))
115///
116/// Example:
117/// ```rust
118///     let x = Function::default();
119///     let sin_of_x = sin(x);
120///     assert_eq!(sin_of_x.call(PI / 2.), 1.);
121/// ```
122pub fn sin(func: Function) -> Function {
123    let new_function = Sin(Arc::new(func.elementary()));
124    Function::from(new_function)
125}
126
127/// Creates a [Function](crate::Function) equal to the cosine of the passed [Function](crate::Function)
128///
129/// i.e f(x) ⟹ cos(f(x))
130///
131/// Example:
132/// ```rust
133///     let x = Function::default();
134///     let cos_of_x = cos(x);
135///     assert_eq!(cos_of_x.call(0.), 1.);
136/// ```
137pub fn cos(func: Function) -> Function {
138    let new_function = Cos(Arc::new(func.elementary()));
139    Function::from(new_function)
140}
141
142/// Creates a [Function](crate::Function) equal to the tangent of the passed [Function](crate::Function)
143///
144/// i.e f(x) ⟹ tan(f(x))
145///
146/// Example:
147/// ```rust
148///     let x = Function::default();
149///     let tan_of_x = tan(x);
150///     assert_eq!(tan_of_x.call(PI / 4.), 1.);
151/// ```
152pub fn tan(func: Function) -> Function {
153    let new_function = Tan(Arc::new(func.elementary()));
154    Function::from(new_function)
155}
156
157/// Creates a [Function](crate::Function) equal to the secant of the passed [Function](crate::Function)
158///
159/// i.e f(x) ⟹ sec(f(x))
160///
161/// Example:
162/// ```rust
163///     let x = Function::default();
164///     let sec_of_x = sec(x);
165///     assert_eq!(sec_of_x.call(PI), -1.);
166/// ```
167pub fn sec(func: Function) -> Function {
168    let new_function = Sec(Arc::new(func.elementary()));
169    Function::from(new_function)
170}
171
172/// Creates a [Function](crate::Function) equal to the cosecant of the passed [Function](crate::Function)
173///
174/// i.e f(x) ⟹ csc(f(x))
175///
176/// Example:
177/// ```rust
178///     let x = Function::default();
179///     let csc_of_x = csc(x);
180///     assert_eq!(csc_of_x.call(3./2. * PI), -1.);
181/// ```
182pub fn csc(func: Function) -> Function {
183    let new_function = Csc(Arc::new(func.elementary()));
184    Function::from(new_function)
185}
186
187/// Creates a [Function](crate::Function) equal to the cotangent of the passed [Function](crate::Function)
188///
189/// i.e f(x) ⟹ cot(f(x))
190///
191/// Example:
192/// ```rust
193///     let x = Function::default();
194///     let cot_of_x = cot(x);
195///     assert_eq!(cot_of_x.call(PI/2.), 0.);
196/// ```
197pub fn cot(func: Function) -> Function {
198    let new_function = Cot(Arc::new(func.elementary()));
199    Function::from(new_function)
200}
201
202// basic arcus functions
203/// Creates a [Function](crate::Function) equal to the arcsine of the passed [Function](crate::Function)
204///
205/// i.e f(x) ⟹ asin(f(x))
206///
207/// Example:
208/// ```rust
209///     let x = function::default();
210///     let asin_of_x = asin(x);
211///     assert_eq!(asin_of_x.call(1.), PI/2.);
212/// ```
213pub fn asin(func: Function) -> Function {
214    let new_function = Asin(Arc::new(func.elementary()));
215    Function::from(new_function)
216}
217
218/// Creates a [Function](crate::Function) equal to the arccosine of the passed [Function](crate::Function)
219///
220/// i.e f(x) ⟹ acos(f(x))
221///
222/// Example:
223/// ```rust
224///     let x = function::default();
225///     let acos_of_x = acos(x);
226///     assert_eq!(acos_of_x.call(1.), 0.);
227/// ```
228pub fn acos(func: Function) -> Function {
229    let new_function = Acos(Arc::new(func.elementary()));
230    Function::from(new_function)
231}
232
233/// Creates a [Function](crate::Function) equal to the arctangent of the passed [Function](crate::Function)
234///
235/// i.e f(x) ⟹ atan(f(x))
236///
237/// Example:
238/// ```rust
239///     let x = function::default();
240///     let atan_of_x = atan(x);
241///     assert_eq!(atan_of_x.call(1.), PI/4.);
242/// ```
243pub fn atan(func: Function) -> Function {
244    let new_function = Atan(Arc::new(func.elementary()));
245    Function::from(new_function)
246}
247
248// hyperbolic functions
249
250/// Creates a [Function](crate::Function) equal to the hyperbolic sine of the passed [Function](crate::Function)
251///
252/// i.e f(x) ⟹ sinh(f(x))
253///
254/// Example:
255/// ```rust
256///     let x = function::default();
257///     let sinh_of_x = sinh(x);
258///     assert_eq!(sinh_of_x.call(0.), 0.);
259/// ```
260pub fn sinh(func: Function) -> Function {
261    let new_function = Sinh(Arc::new(func.elementary()));
262    Function::from(new_function)
263}
264
265/// Creates a [Function](crate::Function) equal to the hyperbolic cosine of the passed [Function](crate::Function)
266///
267/// i.e f(x) ⟹ cosh(f(x))
268///
269/// Example:
270/// ```rust
271///     let x = function::default();
272///     let cosh_of_x = cosh(x);
273///     assert_eq!(cosh_of_x.call(0.), 1.);
274/// ```
275pub fn cosh(func: Function) -> Function {
276    let new_function = Cosh(Arc::new(func.elementary()));
277    Function::from(new_function)
278}
279
280/// Creates a [Function](crate::Function) equal to the hyperbolic tangent of the passed [Function](crate::Function)
281///
282/// i.e f(x) ⟹ tanh(f(x))
283///
284/// Example:
285/// ```rust
286///     let x = function::default();
287///     let tanh_of_x = tanh(x);
288///     assert_eq!(tanh_of_x.call(0.), 0.);
289/// ```
290pub fn tanh(func: Function) -> Function {
291    let new_function = Tanh(Arc::new(func.elementary()));
292    Function::from(new_function)
293}
294// abs function
295/// Creates a [Function](crate::Function) equal to the absolute value of the passed [Function](crate::Function)
296///
297/// i.e f(x) ⟹ |f(x)|
298///
299/// Example:
300/// ```rust
301///     let x = function::default();
302///     let abs_of_x = abs(x);
303///     assert_eq!(abs_of_x.call(-1.), 1.);
304/// ```
305pub fn abs(func: Function) -> Function {
306    let new_function = Abs(Arc::new(func.elementary()));
307    Function::from(new_function)
308}
309
310// ln function
311/// Creates a [Function](crate::Function) equal to the natural logarithm (base e) of the passed [Function](crate::Function)
312///
313/// i.e f(x) ⟹  ln(f(x))
314///
315/// Example:
316/// ```rust
317///     let x = function::default();
318///     let ln_of_x = ln(x);
319///     assert_eq!(ln_of_x.call(E), 1.);
320/// ```
321pub fn ln(func: Function) -> Function {
322    let new_function = Log(Con(E).into(), func.elementary().into());
323    Function::from(new_function)
324}
325
326/// Creates a [Function](crate::Function) equal to the square root of the passed [Function](crate::Function)
327///
328/// i.e f(x) ⟹ √f(x)
329///
330/// Example:
331/// ```rust
332///     let x = function::default();
333///     let sqrt_of_x = sqrt(x);
334///     assert_eq!(sqrt_of_x.call(4.), 2.);
335/// ```
336pub fn sqrt(func: Function) -> Function {
337    let new_function = Pow(Arc::new(func.elementary()), Arc::new(Con(0.5)));
338    Function::from(new_function)
339}
340
341/// Creates a [Function](crate::Function) equal to the factorial of the passed [Function](crate::Function)
342///
343/// i.e f(x) ⟹  f(x)!
344///
345/// Example:
346/// ```rust
347///     let x = function::default();
348///     let factorial_of_x = factorial(x);
349///     assert_eq!(factorial_of_x.call(4.), 2.);
350/// ```
351pub fn factorial(func: Function) -> Function {
352    let new_function = Factorial(func.elementary().into());
353    Function::from(new_function)
354}
355
356/// Creates a [Function](crate::Function) equal to the nth root of the passed [Function](crate::Function)
357///
358/// i.e f(x) ⟹ √f(x)
359///
360/// Example:
361/// ```rust
362///     let x = function::default();
363///     let nth_root_of_x = nth_root(x, 3);
364///     assert_eq!(nth_root_of_x.call(8.), 2.);
365/// ```
366pub fn nth_root(func: Function, n: f64) -> Function {
367    let new_function = Pow(Arc::new(func.elementary()), Arc::new(Con(1.) / n));
368    Function::from(new_function)
369}
370
371pub struct Function {
372    func: Elementary,
373}
374
375impl Function {
376    /// Returns the Elementary absraction of the Function instance
377    pub fn elementary(&self) -> Elementary {
378        self.func.clone()
379    }
380
381    /// Sets the function to represent the provided Elementary abstraction
382    pub fn set_function(&mut self, element: Elementary) {
383        self.func = element;
384    }
385
386    /// Turns self into the derivative of self
387    ///
388    /// i.e. f(x) ⟹ f'(x)
389    ///
390    /// Example:
391    /// ```rust
392    /// let mut function = Function::from("cosh(x)");
393    ///
394    /// // take derivative
395    /// function.differentiate();
396    /// // cosh(x)' = sinh(x)
397    /// // sinh(0) = 0
398    /// assert_eq!(function.call(0.), 0.);
399    /// ```
400    ///
401    /// Do also note that differentiating a function will not simplify the result. This is to make
402    /// sure that this method can never fail, but it does also mean that there are instances where
403    /// the resulting derivative will return [NaN](f64::NAN) for certain values.
404    pub fn differentiate(&mut self) {
405        self.func = self.elementary().to_owned().derivative_unsimplified();
406    }
407
408    /// Turns the given [Function](crate::Function) instance into a Taylor series expansion centered around the value
409    /// of a.
410    ///
411    /// If the conversion fails, an [Error::ExpansionError](Error) is returned.
412    pub fn as_taylor_expansion(&mut self, order: u8, a: f64) -> Result<(), Error> {
413        self.func = self.func.expand_taylor(order, a)?.get_elementary();
414        Ok(())
415    }
416
417    /// Returns a Taylor expansion of the provided order of the function centered around the provided value a.
418    pub fn get_taylor_expansion(&self, order: u8, a: f64) -> Result<SeriesExpansion, Error> {
419        self.func.expand_taylor(order, a)
420    }
421
422    /// Returns a Maclaurin expansion of the provided order.
423    pub fn get_maclaurin_expansion(&self, order: u8) -> Result<SeriesExpansion, Error> {
424        self.func.expand_maclaurin(order)
425    }
426}
427impl Default for Function {
428    /// The default() method returns the unit function f(x) = x, returning the independant variable
429    /// for each input value.
430    fn default() -> Self {
431        Self { func: X }
432    }
433}
434
435/// A [Function](crate::Function) instance can be parsed from any string type using the from method.
436///
437/// Example:
438/// ```rust
439/// let func = Function::from("sin(ln(x))");
440///
441/// assert_eq!(func.call(1.), 0.);
442/// // ...or using the nightly feature
443/// // assert_eq!(func(1.), 0.);
444/// ```
445impl<'a> From<&'a str> for Function {
446    fn from(value: &'a str) -> Self {
447        let func = Elementary::from(value);
448        Self { func }
449    }
450}
451impl From<String> for Function {
452    fn from(value: String) -> Self {
453        let func = Elementary::from(&value[..]);
454        Self { func }
455    }
456}
457impl<'a> From<&'a String> for Function {
458    fn from(value: &'a String) -> Self {
459        let func = Elementary::from(&value[..]);
460        Self { func }
461    }
462}
463impl From<Elementary> for Function {
464    fn from(value: Elementary) -> Self {
465        Self { func: value }
466    }
467}
468/// A [Function](crate::Function) instance can be obtained from a SeriesExpansion instance using the from method.
469///
470/// Example:
471/// ```rust
472/// // create the Function instance
473/// let func = Function::from("sin(x)");
474///
475/// // Get the SeriesExpansion
476/// // In this instance we're creating a Taylor expansion of order 5 centered around 0
477/// let expansion = func.get_taylor_expansion(5, 0.);
478///
479/// // Convert the SeriesExpansion into a Function using the from method
480/// let func_expansion = Function::from(expansion);
481/// // Note that this could also be done using the get_function method:
482/// // let func_expansion = expansion.get_function()
483/// //
484/// // ... or using the as_taylor_expansion method to convert the original Function instance into a
485/// // Taylor expansion without creating the SeriesExpansion instance seperatly:
486/// // func.as_taylor_expansion()
487///
488/// ```
489impl From<SeriesExpansion> for Function {
490    fn from(value: SeriesExpansion) -> Self {
491        value.get_function()
492    }
493}
494impl From<&SeriesExpansion> for Function {
495    fn from(value: &SeriesExpansion) -> Self {
496        (*value).clone().get_function()
497    }
498}