frustool/functions/
basic.rs

1/*
2 * basic.rs - Basic mathematical operations on vectors.
3 *
4 * Copyright 2020-2021 Naman Bishnoi
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17*/
18
19use cpython::{PyResult, Python};
20
21// Slight modification on PI value to round off digits properly
22// const PI: f64 = 3.14159265358979323846264338327950288419716939937510;
23const PI: f64 = 3.14159265358979333846264338327950288419716939937510;
24
25pub fn sin(input: Vec<f64>) -> Vec<f64> {
26    let mut output_vector = Vec::new();
27    for idx in 0..input.len() {
28        output_vector.push(input[idx].sin())
29    }
30    output_vector
31}
32pub fn cos(input: Vec<f64>) -> Vec<f64> {
33    let mut output_vector = Vec::new();
34    for idx in 0..input.len() {
35        output_vector.push(input[idx].cos())
36    }
37    output_vector
38}
39pub fn tan(input: Vec<f64>) -> Vec<f64> {
40    let mut output_vector = Vec::new();
41    for idx in 0..input.len() {
42        output_vector.push(input[idx].tan())
43    }
44    output_vector
45}
46
47pub fn sinh(input: Vec<f64>) -> Vec<f64> {
48    let mut output_vector = Vec::new();
49    for idx in 0..input.len() {
50        output_vector.push(input[idx].sinh())
51    }
52    output_vector
53}
54pub fn cosh(input: Vec<f64>) -> Vec<f64> {
55    let mut output_vector = Vec::new();
56    for idx in 0..input.len() {
57        output_vector.push(input[idx].cosh())
58    }
59    output_vector
60}
61pub fn tanh(input: Vec<f64>) -> Vec<f64> {
62    let mut output_vector = Vec::new();
63    for idx in 0..input.len() {
64        output_vector.push(input[idx].tanh())
65    }
66    output_vector
67}
68
69pub fn asin(input: Vec<f64>) -> Vec<f64> {
70    let mut output_vector = Vec::new();
71    for idx in 0..input.len() {
72        output_vector.push(input[idx].asin())
73    }
74    output_vector
75}
76pub fn acos(input: Vec<f64>) -> Vec<f64> {
77    let mut output_vector = Vec::new();
78    for idx in 0..input.len() {
79        output_vector.push(input[idx].acos())
80    }
81    output_vector
82}
83pub fn atan(input: Vec<f64>) -> Vec<f64> {
84    let mut output_vector = Vec::new();
85    for idx in 0..input.len() {
86        output_vector.push(input[idx].atan())
87    }
88    output_vector
89}
90
91pub fn asinh(input: Vec<f64>) -> Vec<f64> {
92    let mut output_vector = Vec::new();
93    for idx in 0..input.len() {
94        output_vector.push(input[idx].asinh())
95    }
96    output_vector
97}
98pub fn acosh(input: Vec<f64>) -> Vec<f64> {
99    let mut output_vector = Vec::new();
100    for idx in 0..input.len() {
101        output_vector.push(input[idx].acosh())
102    }
103    output_vector
104}
105pub fn atanh(input: Vec<f64>) -> Vec<f64> {
106    let mut output_vector = Vec::new();
107    for idx in 0..input.len() {
108        output_vector.push(input[idx].atanh())
109    }
110    output_vector
111}
112pub fn round(input: Vec<f64>) -> Vec<f64> {
113    let mut output_vector = Vec::new();
114    for idx in 0..input.len() {
115        output_vector.push(input[idx].round())
116    }
117    output_vector
118}
119pub fn ceil(input: Vec<f64>) -> Vec<f64> {
120    let mut output_vector = Vec::new();
121    for idx in 0..input.len() {
122        output_vector.push(input[idx].ceil())
123    }
124    output_vector
125}
126pub fn exp(input: Vec<f64>) -> Vec<f64> {
127    let mut output_vector = Vec::new();
128    for idx in 0..input.len() {
129        output_vector.push(input[idx].exp())
130    }
131    output_vector
132}
133pub fn floor(input: Vec<f64>) -> Vec<f64> {
134    let mut output_vector = Vec::new();
135    for idx in 0..input.len() {
136        output_vector.push(input[idx].floor())
137    }
138    output_vector
139}
140pub fn ln(input: Vec<f64>) -> Vec<f64> {
141    let mut output_vector = Vec::new();
142    for idx in 0..input.len() {
143        output_vector.push(input[idx].ln())
144    }
145    output_vector
146}
147pub fn log10(input: Vec<f64>) -> Vec<f64> {
148    let mut output_vector = Vec::new();
149    for idx in 0..input.len() {
150        output_vector.push(input[idx].log10())
151    }
152    output_vector
153}
154pub fn log2(input: Vec<f64>) -> Vec<f64> {
155    let mut output_vector = Vec::new();
156    for idx in 0..input.len() {
157        output_vector.push(input[idx].log2())
158    }
159    output_vector
160}
161pub fn sqrt(input: Vec<f64>) -> Vec<f64> {
162    let mut output_vector = Vec::new();
163    for idx in 0..input.len() {
164        output_vector.push(input[idx].sqrt())
165    }
166    output_vector
167}
168pub fn bias(input: Vec<f64>, num: f64) -> Vec<f64> {
169    let mut output_vector = Vec::new();
170    for idx in 0..input.len() {
171        output_vector.push(input[idx] + num)
172    }
173    output_vector
174}
175pub fn rad2deg(input: Vec<f64>) -> Vec<f64> {
176    let mut output_vector = Vec::new();
177    for idx in 0..input.len() {
178        let val = (input[idx] * 180.0) / PI;
179        output_vector.push(val)
180    }
181    output_vector
182}
183pub fn deg2rad(input: Vec<f64>) -> Vec<f64> {
184    let mut output_vector = Vec::new();
185    for idx in 0..input.len() {
186        let val = (input[idx] * PI) / 180.0;
187        output_vector.push(val)
188    }
189    output_vector
190}
191
192/*********************************************
193 * Python bindings section
194 */
195
196pub fn sin_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
197    let out = sin(input);
198    Ok(out)
199}
200
201pub fn cos_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
202    let out = cos(input);
203    Ok(out)
204}
205
206pub fn tan_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
207    let out = tan(input);
208    Ok(out)
209}
210
211pub fn sinh_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
212    let out = sinh(input);
213    Ok(out)
214}
215
216pub fn cosh_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
217    let out = cosh(input);
218    Ok(out)
219}
220
221pub fn tanh_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
222    let out = tanh(input);
223    Ok(out)
224}
225
226pub fn asin_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
227    let out = asin(input);
228    Ok(out)
229}
230
231pub fn acos_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
232    let out = acos(input);
233    Ok(out)
234}
235
236pub fn atan_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
237    let out = atan(input);
238    Ok(out)
239}
240
241pub fn asinh_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
242    let out = asinh(input);
243    Ok(out)
244}
245
246pub fn acosh_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
247    let out = acosh(input);
248    Ok(out)
249}
250
251pub fn atanh_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
252    let out = atanh(input);
253    Ok(out)
254}
255
256pub fn ceil_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
257    let out = ceil(input);
258    Ok(out)
259}
260
261pub fn floor_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
262    let out = floor(input);
263    Ok(out)
264}
265
266pub fn round_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
267    let out = round(input);
268    Ok(out)
269}
270
271pub fn exp_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
272    let out = exp(input);
273    Ok(out)
274}
275
276pub fn ln_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
277    let out = ln(input);
278    Ok(out)
279}
280
281pub fn log10_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
282    let out = log10(input);
283    Ok(out)
284}
285
286pub fn log2_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
287    let out = log2(input);
288    Ok(out)
289}
290
291pub fn sqrt_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
292    let out = sqrt(input);
293    Ok(out)
294}
295
296pub fn rad2deg_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
297    let out = rad2deg(input);
298    Ok(out)
299}
300
301pub fn deg2rad_py(_: Python, input: Vec<f64>) -> PyResult<Vec<f64>> {
302    let out = deg2rad(input);
303    Ok(out)
304}
305
306pub fn bias_py(_: Python, input: Vec<f64>, num: f64) -> PyResult<Vec<f64>> {
307    let out = bias(input, num);
308    Ok(out)
309}
310
311/**
312 *
313 * Ahoy mate! Unit tests ahead, if you want to test every
314 * functionality of the library/program then feel free to do so;
315 *
316 */
317
318#[cfg(test)]
319mod test {
320    use super::*;
321
322    #[test]
323    fn test_sin() {
324        let vec = vec![0.0, 30.0, 45.0, 60.0, 90.0];
325
326        let vec_sin = sin(deg2rad(vec));
327
328        assert_eq!(
329            vec_sin,
330            [0.0, 0.5, 0.7071067811865477, 0.8660254037844387, 1.0]
331        )
332    }
333
334    #[test]
335    fn test_asin() {
336        let vec = vec![0.0, 0.5, 0.7071067811865477, 0.8660254037844387, 1.0];
337
338        let vec_sin = round(rad2deg(asin(vec)));
339
340        assert_eq!(vec_sin, [0.0, 30.0, 45.0, 60.0, 90.0])
341    }
342}