math_analize/ma/functions/function/
mod.rs

1use crate::ma::options::{ Limits, Points };
2
3/// Funtion's Trait. You can use it for creating your own function structure 
4pub trait Function {
5    fn f(&self, x: &f64) -> f64;
6    fn derivative_f(&self, x: &f64) -> f64;
7    fn solve(&self) -> Option<Vec<f64>>;
8    fn derivative_solve(&self) -> Option<Vec<f64>>;
9    fn newton(&self, limits: &Limits) -> Result<f64, &'static str>;
10    fn limits(&self) -> Limits;
11    fn trapezoid(&self, limits: &Limits) -> f64 {
12        let mut points = Points { x: Vec::new(), y: Vec::new() };
13        let a = limits.limit_a;
14        let b = limits.limit_b;
15
16        // if you want to change the step of calculating - change "step" variable. More accuracy on increasing. But you'll lose performance
17        
18        let step = 10;
19        let h = (b-a) / step as f64;
20        for i in 0..step+1 as usize {
21            points.x.push(a + i as f64 * h);
22            points.y.push(self.f(points.x.get(i).expect("Failed to get value")));
23        }
24
25        let mut y_sum: f64 = 0.0;
26        for i in 0..(step as usize)-1 {
27            y_sum += points.y.get(i+1).expect("Failed to get element");
28        }
29
30        let integral: f64 =
31            h * (
32            (points.y[0] + points.y[step as usize])
33            / 2.0 + y_sum
34        );
35
36        points.x.clear();
37        points.y.clear();
38
39        integral
40    }
41    fn simpson(&self, limits: &Limits) -> f64 {
42        let mut points = Points { x: Vec::new(), y: Vec::new() };
43        let a = limits.limit_a;
44        let b = limits.limit_b;
45        
46        // if you want to change the step of calculating - change "step" variable. More accuracy on increasing, but you'll lose performance
47
48        let step = 10;
49        let h = (b-a) / (2.0*step as f64);
50        for i in 0..step*2+1 as usize {
51            for j in (0..step*2+1).map(|value| value as f64 * h) {
52                points.x.push(j);
53            }
54            points.y.push(self.f(points.x.get(i).expect("Failed to get value")));
55        }
56
57        let mut y_even_sum: f64 = 0.0;
58        let mut y_odd_sum: f64 = 0.0;
59
60        for i in (2..2*step-1).step_by(2) {
61            y_even_sum += points.y.get(i).expect("Failed to get vaulue");
62        }
63        for i in (1..2*step).step_by(2) {
64            y_odd_sum += points.y.get(i).expect("Failed to get value");
65        }
66
67
68        let integral: f64 = (h/3.0) * ((points.y[0] + points.y[2*step]) + 2.0 * y_even_sum + 4.0 * y_odd_sum);
69        
70        points.x.clear();
71        points.y.clear();
72
73        integral
74    }
75    fn derivative_points(&self, limits: &Limits) -> Vec<f64> {    
76        let mut points = Points { x: Vec::new(), y: Vec::new() };
77        let dx: f64 = 0.1;
78        
79        let a = limits.limit_a as usize;
80        let b = limits.limit_b as usize;
81
82
83
84        for i in a..b+1 {
85            let i = f64::from(i as i32) * dx;
86            points.x.push(i);
87        } 
88        for i in 0..b+1 {
89            points.y.push((self.f(&(points.x[i]+dx)) - self.f(&points.x[i])) / dx);
90            // (f(X[i]+dx)-f(X[i]))/dx
91        }
92
93        let y_points = points.y.clone();
94        points.x.clear();
95        points.y.clear();
96
97        y_points
98    }
99    fn function_points(&self, limits: &Limits) -> Vec<f64> {
100        let mut points = Points { x: Vec::new(), y: Vec::new() };
101        let a = limits.limit_a as usize;
102        let b = limits.limit_b as usize;
103        
104        for i in a..b+1 {
105            points.x.push(i as f64);
106            points.y.push(self.f(&points.x[i]));
107        }
108
109        let y_points = points.y.clone();
110        points.x.clear();
111        points.y.clear();
112
113        y_points
114    }    
115    fn evenness(&self) -> &str {
116        let mut _result: &str = "";
117
118        if self.f(&(-1.0)) as i64 == self.f(&1.0) as i64 { _result = "even"; }
119        else if self.f(&(-1.0)) as i64 == -(self.f(&1.0)) as i64 { _result = "odd"; }
120        else { _result = "neither even nor odd"; }
121    
122        _result
123    }
124    fn calculate_point(&self, x: &f64) -> f64 {
125        self.f(x)
126    }
127    fn calculate_derivative_point(&self, x: &f64) -> f64 {
128        self.derivative_f(x)
129    }
130}