number_diff/functions/
series_expansions.rs1use std::sync::Arc;
2
3use crate::{
4 Elementary::{self, *},
5 Error, Factorial, Function,
6};
7
8#[derive(Debug, Clone)]
9pub enum SeriesExpansion {
11 MacLaurin(Elementary),
13 Taylor(Elementary),
16 Fourier(Elementary),
19}
20impl SeriesExpansion {
21 pub fn get_function(self) -> Function {
24 match self {
25 Self::MacLaurin(elem) => Function::from(elem),
26 Self::Taylor(elem) => Function::from(elem),
27 Self::Fourier(elem) => Function::from(elem),
28 }
29 }
30
31 pub fn get_elementary(self) -> Elementary {
34 match self {
35 Self::MacLaurin(elem) => elem,
36 Self::Taylor(elem) => elem,
37 Self::Fourier(elem) => elem,
38 }
39 }
40}
41
42impl Elementary {
43 pub fn expand_maclaurin(&self, order: u8) -> Result<SeriesExpansion, Error> {
44 let series = self.expand_taylor(order, 0.)?;
45
46 if let SeriesExpansion::Taylor(res) = series {
47 Ok(SeriesExpansion::MacLaurin(res))
48 } else {
49 unreachable!()
50 }
51 }
52
53 pub fn expand_taylor(&self, order: u8, centre: f64) -> Result<SeriesExpansion, Error> {
54 let mut terms: Vec<Elementary> = Vec::new();
55
56 let mut current_derivative = self.clone();
57
58 let first_term = current_derivative.clone().call()(centre);
59
60 terms.push(Con(first_term));
61
62 for i in 1..=order {
63 current_derivative = current_derivative.derivative_unsimplified();
64
65 let ith_term = Pow(Arc::new(X - centre), Arc::new(Con(i as f64)))
66 * current_derivative.clone().call()(centre)
67 / ((i as usize).factorial() as f64);
68
69 terms.push(ith_term);
70 }
71
72 let mut res = Con(0.);
73
74 for term in terms {
75 res += term;
76 }
77
78 res = res.simplify()?;
79
80 Ok(SeriesExpansion::Taylor(res))
84 }
85}