math_analize/ma/functions/
mod.rs

1pub mod function;
2use function::Function;
3use crate::ma::options::Limits;
4
5/// Linear function structure
6pub struct Linear {
7    k: f64,
8    b: f64,
9    
10    limits: Limits,
11}
12
13/// Quadratic function structure
14pub struct Quadratic { 
15    a: f64,
16    b: f64,
17    c: f64,
18    
19    limits: Limits,
20}
21
22/// Power function structure
23pub struct Power {
24    n: f64,
25
26    limits: Limits,
27}
28
29/// Fractional-Linear function structure
30pub struct FractionalLinear {
31    a: f64,
32    b: f64,
33    c: f64,
34    d: f64,
35    
36    limits: Limits,
37}
38
39/// Exponential function structure
40pub struct Exponential {
41    a: f64,
42    
43    limits: Limits,
44}
45// implementations
46
47// Linear Function
48
49impl Function for Linear {
50    fn newton(&self, limits: &Limits) -> Result<f64, &'static str> {
51        let integral: f64 = (self.k*(limits.limit_b.powf(2.0)/2.0) + self.b*limits.limit_b) - (self.k * (limits.limit_a.powf(2.0)/2.0) - self.b*limits.limit_a);
52        Ok(integral)
53    }
54    fn solve(&self) -> Option<Vec<f64>> {
55        let mut solves: Vec<f64> = Vec::new(); 
56        solves.push(self.k/self.b);
57        Some(solves)
58    }
59    fn derivative_solve(&self) -> Option<Vec<f64>> {
60        None
61    }
62    fn f(&self, x: &f64) -> f64 {
63        self.k*x+self.b
64    }
65    fn derivative_f(&self, _x: &f64) -> f64 {
66        self.k
67    }
68    fn limits(&self) -> Limits {
69        self.limits
70    }
71}
72impl Linear {
73    /// To create an object of function you need to use "new" method. After passing all the coefficients of the function, you need to pass the limits on which this function will exist
74    pub fn new(k: f64, b: f64, limit_a: f64, limit_b: f64) -> Linear {
75        Linear {
76            k,
77            b,
78            limits: Limits {
79                limit_a,
80                limit_b,
81            },
82        }
83    }
84    /// Function "set_limits" is used to change the limits on which your function will exist
85    pub fn set_limits(&mut self, limit_a: f64, limit_b: f64) {
86        self.limits = Limits {
87            limit_a,
88            limit_b,
89        };
90    }
91}
92
93// Quadratic Function
94
95impl Function for Quadratic {
96    fn newton(&self, limits: &Limits) -> Result<f64, &'static str> {
97        let integral: f64 = (self.a * (limits.limit_b.powf(3.0) / 3.0) + self.b * (limits.limit_b.powf(2.0)/2.0) + self.c * limits.limit_b) - (self.a * (limits.limit_a.powf(3.0) / 3.0) + self.b * (limits.limit_a.powf(2.0)/2.0) + self.c * limits.limit_a);
98        Ok(integral)
99    }
100    fn solve(&self) -> Option<Vec<f64>> {
101        let mut solves: Vec<f64> = Vec::new(); 
102        let d: f64 = self.b.powf(2.0) - 4.0*self.a*self.c;
103        if d < 0.0 { None }
104        else if d == 0.0 {
105            solves.push((self.b*-1.0 + d.sqrt()) / 2.0*self.a);
106            Some(solves.clone())
107        }
108        else {
109            solves.push((self.b*-1.0 + d.sqrt()) / 2.0*self.a);
110            solves.push((self.b*-1.0 - d.sqrt()) / 2.0*self.a);
111            Some(solves.clone())
112        }
113    }
114    fn derivative_solve(&self) -> Option<Vec<f64>> {
115        let mut derivative_solve: Vec<f64> = Vec::new();
116        derivative_solve.push(-self.b/2.0*self.a);
117        Some(derivative_solve.clone())
118    }
119    fn f(&self, x: &f64) -> f64 {
120        self.a * x.powf(2.0) + self.b*x + self.c
121    }
122    fn derivative_f(&self, _x: &f64) -> f64 {
123        2.0*self.a + self.b
124    }
125    fn limits(&self) -> Limits {
126        self.limits
127    }
128}
129impl Quadratic {
130    pub fn new(a: f64, b: f64, c: f64, limit_a: f64, limit_b: f64) -> Quadratic {
131        Quadratic {
132            a,
133            b,
134            c,
135            limits: Limits {
136                limit_a,
137                limit_b,
138            },
139        }
140    }
141    pub fn set_limits(&mut self, limit_a: f64, limit_b: f64) {
142        self.limits = Limits {
143            limit_a,
144            limit_b,
145        };
146    }
147}
148
149// Power Function
150
151impl Function for Power {
152    fn newton(&self, limits: &Limits) -> Result<f64, &'static str> {
153        let integral: f64 = (limits.limit_b.powf(self.n+1.0)) / self.n + 1.0;
154        Ok(integral)
155    }
156    fn solve(&self) -> Option<Vec<f64>> {
157        Some(vec![0.0])
158    }
159    fn derivative_solve(&self) -> Option<Vec<f64>> {
160        Some(vec![0.0])
161    }
162    fn f(&self, x: &f64) -> f64 {
163        x.powf(self.n)
164    }
165
166    fn derivative_f(&self, x: &f64) -> f64 {
167        self.n * x.powf(self.n-1.0)
168    }
169    fn limits(&self) -> Limits {
170        self.limits
171    }
172}
173impl Power {
174    pub fn new(n: f64, limit_a: f64, limit_b: f64) -> Power {
175        Power {
176            n,
177            limits: Limits {
178                limit_a,
179                limit_b,
180            },
181        }
182    }
183    pub fn set_limits(&mut self, limit_a: f64, limit_b: f64) {
184        self.limits = Limits {
185            limit_a,
186            limit_b,
187        };
188    }
189}
190
191// Fractional-Linear Function
192
193impl Function for FractionalLinear {
194    fn newton(&self, _limits: &Limits) -> Result<f64, &'static str> {
195        Err("Integral of Fractional-Linear function Can not be calculated with Newton's method. Try another one")
196    }
197    fn solve(&self) -> Option<Vec<f64>> {
198        let mut solves: Vec<f64> = Vec::new();
199        solves.push(self.b / self.a);
200        Some(solves.clone())
201    }
202    fn derivative_solve(&self) -> Option<Vec<f64>> {
203        Some(vec![0.0])
204    }
205    fn f(&self, x: &f64) -> f64 {
206        (self.a * x + self.b) / (self.c *x + self.d)
207    }
208    fn derivative_f(&self, x: &f64) -> f64 {
209        (self.a * self.d - self.b * self.c) / ((self.c * x).powf(2.0))
210    }
211    fn limits(&self) -> Limits {
212        self.limits
213    }
214}
215impl FractionalLinear {
216    pub fn new(a: f64, b:f64, c:f64, d:f64, limit_a: f64, limit_b: f64) -> Result<FractionalLinear, &'static str> {
217        if (c == 0.0) && (d == 0.0) { return Err("Error") }
218        Ok(FractionalLinear {
219            a,
220            b,
221            c,
222            d,
223            limits: Limits {
224                limit_a,
225                limit_b,
226            },
227        }) 
228    }
229    pub fn set_limits(&mut self, limit_a: f64, limit_b: f64) {
230        self.limits = Limits {
231            limit_a,
232            limit_b,
233        };
234    }
235}
236
237// Exponential Function
238
239impl Function for Exponential {
240    fn newton(&self, limits: &Limits) -> Result<f64, &'static str> {
241        let integral: f64 = (1.0/(self.a.ln()) * self.a.powf(limits.limit_b)) - (1.0/(self.a.ln()) * self.a.powf(limits.limit_a));
242        Ok(integral) 
243    }
244    fn solve(&self) -> Option<Vec<f64>> {
245        None
246    }
247    fn derivative_solve(&self) -> Option<Vec<f64>> {
248        None
249    }
250    fn f(&self, x: &f64) -> f64 {
251        self.a.powf(*x)
252    }
253    fn derivative_f(&self, x: &f64) -> f64 {
254        self.a.powf(*x)
255    }
256    fn limits(&self) -> Limits {
257        self.limits
258    }
259}
260impl Exponential {
261    pub fn new(a: f64, limit_a: f64, limit_b: f64) -> Exponential {
262        Exponential {
263            a,
264            limits: Limits {
265                limit_a,
266                limit_b,
267            },
268        }
269    }
270    pub fn set_limits(&mut self, limit_a: f64, limit_b: f64) {
271        self.limits = Limits {
272            limit_a,
273            limit_b,
274        };
275    }
276}