rust_math/
lib.rs

1//TODO: Binary search and some sorting functions needed to be added
2pub mod numbers {
3    pub fn pi() -> f32 {
4        return 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679;
5    }
6}
7
8#[allow(dead_code)]
9pub mod list {
10    //This function is used to sort the list. (Bubble sort)
11    pub fn bubble_sort(list: &mut [usize]) {
12        for _ in 0..list.len() {
13            for j in 0..(&list.len() - 1) {
14                if list[j] > list[j + 1] {
15                    list.swap(j, j + 1);
16                }
17            }
18        }
19    }
20
21    pub fn reverse_bsort(list: &mut [usize]) {
22        for _ in 0..list.len() {
23            for j in 0..(&list.len() - 1) {
24                if list[j] < list[j + 1] {
25                    list.swap(j, j + 1);
26                }
27            }
28        }
29    }
30
31    //THIS FUNCTION NEEDS SORTED ARRAY
32    pub fn med(list: &[usize]) -> i32 {
33        let len = list.len();
34        if len % 2 == 0 {
35            let med1 = list[len / 2];
36            let med2 = list[len / 2 - 1];
37            let med = (med1 + med2) / 2;
38            return med as i32;
39        } else {
40            let med = list[(len - 1) / 2];
41            return med as i32;
42        }
43    }
44
45    //This function works whether the list is sorted or not, if sorted, returns med of the list, else -1. Uses extra resource. (May be a problem for old systems)
46    pub fn safe_med(list: &[usize]) -> i32 {
47        if check_sorted(list) {
48            return med(list);
49        } else {
50            return -1;
51        }
52    }
53
54    //This function returns the average of the list.
55    pub fn avg(list: &[usize]) -> f32 {
56        let mut sum = 0;
57        for i in list {
58            sum += i;
59        }
60        let avg = sum as f32 / list.len() as f32;
61        return avg;
62    }
63
64    //This function returns the mode of the list.
65    pub fn mode(list: &[usize]) -> i32 {
66        let mut mode = 0;
67        let mut max = 0;
68        for i in list {
69            let mut count = 0;
70            for j in list {
71                if i == j {
72                    count += 1;
73                }
74            }
75            if count > max {
76                max = count;
77                mode = *i;
78            }
79        }
80        return mode as i32;
81    }
82
83    //This function returns the standard deviation of the list.
84    pub fn std_deviation(list: &[usize]) -> f32 {
85        let avg = avg(list);
86        let mut sum: f32 = 0.00;
87        let len = list.len() as f32 - 1.00;
88        for i in list {
89            sum += super::num::abs((*i as f32 - avg).powf(2.00));
90        }
91        let std_dev = (sum / len).sqrt();
92        return std_dev;
93    }
94
95    //This function returns the highest number in the list.
96    pub fn highest(list: &[usize]) -> i32 {
97        let mut peak = list[0];
98        for i in list {
99            if *i > peak {
100                peak = *i;
101            }
102        }
103        return peak as i32;
104    }
105
106    //This function returns the lowest number in the list.
107    pub fn lowest(list: &[usize]) -> i32 {
108        let mut low = list[0];
109        for i in list {
110            if *i < low {
111                low = *i;
112            }
113        }
114        return low as i32;
115    }
116
117    //This function returns the true if the list is forted, else false.
118    pub fn check_sorted(list: &[usize]) -> bool {
119        for i in 0..list.len() - 1 {
120            if list[i] > list[i + 1] {
121                return false;
122            }
123        }
124        return true;
125    }
126}
127
128#[allow(dead_code)]
129pub mod num {
130    pub fn abs(num: f32) -> f32 {
131        if num < 0.0 {
132            return -num;
133        } else {
134            return num;
135        }
136    }
137
138    pub fn sqrt(num: f32) -> f32 {
139        let mut number = num;
140        while abs(num - number * number) > 0.00001 {
141            number = (number + num / number) / 2.00;
142        }
143        return number;
144    }
145    //This function returns the factorial of the number.
146    pub fn factorial(num: i32) -> i128 {
147        if num == 0 {
148            return 1;
149        } else if num > 0 {
150            return num as i128 * factorial(num - 1);
151        } else {
152            return -1;
153        }
154    }
155
156    //This function checks if number prime or not
157    pub fn is_prime(number: i32) -> bool {
158        /*
159        Using 6k + 1 optimization: all numbers are expresible as 6k + i with i = {-1, 0, 1, 2, 3, 4}.
160        Test if n is divisible by 2 or 3, with that you remove: 6k, 6k + 2, 6k + 4, 6k + 3.
161        This means that you only have to test numbers of the form 6k - 1 and 6k + 1 less than sqrt(n)
162        These numbers are 5, 11, 17, 23, 29, 35... and 7, 13, 19, 25, 31, 37...
163        */
164        if number == 2 || number == 3 {
165            return true;
166        }
167        if number % 2 == 0 || number % 3 == 0 {
168            return false;
169        }
170
171        for i in (1..).map(|k| 6 * k - 1).take_while(|m| m * m <= number) {
172            if number % i == 0 || number % (i + 2) == 0 {
173                return false;
174            }
175        }
176
177        return true;
178    }
179
180    //This function finds greatest common divisor of two numbers
181    pub fn gcd(a: i32, b: i32) -> i32 {
182        if a == 0 {
183            return b;
184        } else {
185            return gcd(b % a, a);
186        }
187    }
188
189    //This function finds least common multiple of two numbers
190    pub fn lcm(a: i32, b: i32) -> i32 {
191        return a * b / gcd(a, b);
192    }
193
194    //This is for finding prime factors
195    pub fn prime_factor(int32: i32) -> Vec<i32> {
196        let mut c = 2;
197        let mut iint32 = int32;
198        let mut ret: Vec<i32> = Vec::new();
199        while iint32 > 1 {
200            if iint32 % c == 0 {
201                ret.push(c);
202                iint32 /= c;
203            } else {
204                c += 1;
205            }
206        }
207        return ret;
208    }
209}
210
211#[allow(dead_code)]
212pub mod trigonometry {
213    use super::numbers::pi;
214    //This function converts a number from degrees to radians.
215    pub fn deg2rad(x: f32) -> f32 {
216        return x * pi() / 180.00;
217    }
218
219    //This function finds quadrant of angle.
220    pub fn find_quadrant(angle: f32) -> i32 {
221        if angle >= 360.00 {
222            return find_quadrant(angle - 360.00);
223        } else if angle <= 0.00 {
224            return find_quadrant(angle + 360.00);
225        } else {
226            return ((angle / 90.00) + 1.00) as i32;
227        }
228    }
229
230    //This function convert the number from radians to degrees.
231    pub fn rad2deg(x: f32) -> f32 {
232        return x * 180.00 / pi();
233    }
234
235    //This function finds the sine of the angle.
236    pub fn sin(ang: f32) -> f32 {
237        //Algorithm for calculating sine
238        //1. Use periodicity
239        //If angle is between 0 and 360, no problem, but if not, reduce x so that it lies in the range 0≤x≤360° by adding or subtracting a suitable multiple of 360° from it (we are assuming that angle x is measured in degrees).
240
241        let mut angle = ang;
242        while angle < 0.0 {
243            angle += 360.0;
244        }
245        while angle > 360.0 {
246            angle -= 360.0;
247        }
248
249        //2. Using symetry
250        //If angle is quadrant 1, go to step 3.
251        let quadrant = find_quadrant(angle);
252        if quadrant == 2 {
253            angle = 180.0 - angle;
254        } else if quadrant == 3 {
255            angle = 180.0 - angle;
256        } else if quadrant == 4 {
257            angle = angle - 360.0;
258        }
259
260        //3. Using the cofunction
261        if angle >= 45.0 {
262            return cos(90.0 - angle);
263        } else if angle < 45.0 {
264            //4. Using the sine polynomial
265            angle = deg2rad(angle);
266            return angle - (angle.powf(3.0) / 6.0) + (angle.powf(5.0) / 120.0);
267        }
268        return -1.0;
269    }
270
271    pub fn cos(ang: f32) -> f32 {
272        //1. Use periodicity
273        let mut angle = ang;
274        while angle < 0.0 {
275            angle += 360.0;
276        }
277        while angle > 360.0 {
278            angle -= 360.0;
279        }
280        //2. Use symetry
281        let quadrant = find_quadrant(angle);
282        if quadrant == 1 {
283            //3. Using cofunction
284            if angle >= 45.0 {
285                return sin(90.0 - angle);
286            } else if angle < 45.0 {
287                angle = deg2rad(angle);
288                //4. Using cosine polynomial
289                return 1.0 - (angle.powf(2.0) / 2.0) + (angle.powf(4.0) / 24.0)
290                    - (angle.powf(6.0) / 720.0);
291            }
292        } else if quadrant == 2 {
293            angle = 180.0 - angle;
294            return -1.0 * cos(angle);
295        } else if quadrant == 3 {
296            angle = angle - 180.0;
297            return -1.0 * cos(angle);
298        } else if quadrant == 4 {
299            angle = 360.0 - angle;
300            return cos(angle);
301        }
302        return -1.0;
303    }
304    pub fn tan(ang: f32) -> f32 {
305        let mut angle = ang;
306
307        //1. Reduce angle between 180 and 0
308        while angle > 180.0 {
309            angle -= 180.0;
310        }
311        while angle < 0.0 {
312            angle += 180.0;
313        }
314
315        //2. Reduce angle between 90 and 0
316        let quadrant = find_quadrant(angle);
317        if quadrant == 2 {
318            return -1.0 * tan(180.0 - angle);
319        } else if quadrant == 1 {
320            if angle >= 45.0 {
321                //3. Cofunction
322                return 1.0 / tan(90.0 - angle);
323            } else if angle < 45.0 {
324                if angle >= 22.5 {
325                    return (2.0 * tan(angle / 2.0)) / (1.0 - tan(angle / 2.0).powf(2.0));
326                } else if angle < 22.5 {
327                    angle = deg2rad(angle);
328                    return angle
329                        + (angle.powf(3.0) / 3.0)
330                        + (2.0 * angle.powf(5.0) / 15.0)
331                        + (17.0 * angle.powf(7.0) / 315.0);
332                }
333            }
334        }
335        return -1.0;
336    }
337    pub fn cotan(ang: f32) -> f32 {
338        return 1.0 / tan(ang);
339    }
340    pub fn sec(ang: f32) -> f32 {
341        return 1.0 / cos(ang);
342    }
343    pub fn cosec(ang: f32) -> f32 {
344        return 1.0 / sin(ang);
345    }
346    pub fn arctan(x: f32) -> f32 {
347        let y = x;
348        if y < 0.0 {
349            return -1.0 * arctan(-1.0 * y);
350        } else
351        /* if positive */
352        {
353            if y < 1.0 {
354                if y <= 0.267949 {
355                    return y - (y.powf(3.0) / 3.0) + (y.powf(5.0) / 5.0);
356                } else {
357                    return rad2deg(
358                        (super::numbers::pi() / 6.0)
359                            + arctan((super::num::sqrt(3.0) * y) - 1.0)
360                                / arctan(super::num::sqrt(3.0) + y),
361                    );
362                }
363            } else {
364                return (super::numbers::pi() / 2.0) - arctan(1.0 / y);
365            }
366        }
367    }
368    pub fn arcsin(x: f32) -> f32 {
369        return arctan(x / super::num::sqrt(1.0 - x.powf(2.0)));
370    }
371    pub fn arccos(x: f32) -> f32 {
372        return arctan(super::num::sqrt(1.0 - x.powf(2.0)) / x);
373    }
374}