1
2use std::sync::Arc;
10
11use std::ops::{
12 Add,
13 Sub,
14 Mul,
15 Div
16};
17
18
19fn make_domain(start: i32, end: i32, step: f32) -> Vec<f64> {
22 let start = (start as f32/step) as i64;
23 let end = (end as f32/step) as i64;
24 (start..=end).map(|x| {
25 (x as f64)*step as f64
26 }).collect()
27}
28
29pub trait Rational: Clone + Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self>
32 + From<f64> + PartialEq + std::fmt::Debug {
33 fn pow(self, rhs: Self) -> Self;
35}
36
37impl Rational for f64 {
38 fn pow(self, rhs: Self) -> Self {
39 self.powf(rhs)
40 }
41}
42
43#[derive(Clone)]
45pub struct Function<T = f64> where T: Rational, {
46 function: Arc<dyn Fn(T) -> T>
47}
48
49unsafe impl<T: Rational> Send for Function<T> {}
50
51
52impl<T: Rational + 'static> Function<T> {
53 pub fn new(value: T) -> Self {
54 Self { function: Arc::new(move |_x| value.clone())}
55 }
56
57 pub fn call(&self, x: T) -> T {
59 (self.function)(x)
60 }
61
62 pub fn polynomial_from_roots(roots: Vec<T>) -> Function<T> {
64 let function_roots = roots.into_iter().map(|root| {
65 Function::default()-Function::new(root)
66 }).collect::<Vec<Function<T>>>();
67
68 match function_roots.len() > 0 {
69 true => {
70 let mut tmp: Function<T> = Function::new(T::from(1.));
71 for func in function_roots.into_iter() {
72 tmp = tmp*func;
73 }
74 tmp
75 },
76 false => {
77 Function::new(T::from(0.))
78 }
79 }
80
81 }
82}
83
84impl<T: Rational + std::cmp::PartialOrd + 'static> Function<T> {
85
86 pub fn find_zeroes(&self, range: (i32, i32)) -> Vec<T> {
88 let domain = make_domain(range.0, range.1, 0.001);
90 let mut zeroes: Vec<T> = vec![];
91
92 let mut g0 = self.call(domain[0].into())>T::from(0.);
94 domain.into_iter().map(|x| {
95 T::from(x)
96 }).for_each(|x| {
97 if g0 != (self.call(x.clone()) > T::from(0.)) {
98 g0 = !g0;
99 zeroes.push(x);
100 }
101 });
102
103 zeroes
104 }
105}
106
107impl<T: Rational + 'static> std::fmt::Debug for Function<T> {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 write!(
111 f,
112 "f(-2) {:?}|f(-1) {:?}|f(0) {:?}|f(1) {:?}|f(2) {:?}",
113 self.call((-2.).into()),
114 self.call((-1.).into()),
115 self.call((0.).into()),
116 self.call((1.).into()),
117 self.call((2.).into()),
118 )
119 }
120}
121
122impl<T: Rational + 'static> From<T> for Function<T> {
123 fn from(x: T) -> Self {
124 Self { function: Arc::new(
125 move |_x| x.clone()
126 )}
127 }
128}
129
130impl<T: Rational> From<i64> for Function<T> {
131 fn from(x: i64) -> Self {
132 Self {
133 function: Arc::new(move |_x| (x as f64).into())
134 }
135 }
136}
137
138impl<T: Rational> Default for Function<T> {
139 fn default() -> Self {
142 Self {
143 function: Arc::new(|x| x)
144 }
145 }
146}
147
148impl<T: Rational + 'static> Add for Function<T> {
149 type Output = Self;
150 fn add(self, rhs: Self) -> Self {
151 Self { function: Arc::new(move |x| (self.function)(x.clone())+(rhs.function)(x)) }
152 }
153}
154impl<T: Rational + 'static> Add<T> for Function<T> {
155 type Output = Self;
156 fn add(self, rhs: T) -> Self {
157 self+Function::from(rhs)
158 }
159}
160
161impl<T: Rational + 'static> Sub for Function<T> {
162 type Output = Self;
163 fn sub(self, rhs: Self) -> Self {
164 Self { function: Arc::new(move |x| (self.function)(x.clone())-(rhs.function)(x)) }
165 }
166}
167impl<T: Rational + 'static> Sub<T> for Function<T> {
168 type Output = Self;
169 fn sub(self, rhs: T) -> Self {
170 self-Function::from(rhs)
171 }
172}
173
174impl<T: Rational + 'static> Mul for Function<T> {
175 type Output = Self;
176 fn mul(self, rhs: Self) -> Self {
177 Self { function: Arc::new(move |x| (self.function)(x.clone())*(rhs.function)(x)) }
178 }
179}
180impl<T: Rational + 'static> Mul<T> for Function<T> {
181 type Output = Self;
182 fn mul(self, rhs: T) -> Self {
183 self*Function::from(rhs)
184 }
185}
186
187impl<T: Rational + 'static> Div for Function<T> {
188 type Output = Self;
189 fn div(self, rhs: Self) -> Self {
190 Self { function: Arc::new(move |x| (self.function)(x.clone())/(rhs.function)(x)) }
191 }
192}
193impl<T: Rational + 'static> Div<T> for Function<T> {
194 type Output = Self;
195 fn div(self, rhs: T) -> Self {
196 self/Function::from(rhs)
197 }
198}
199
200impl<T: Rational> PartialEq for Function<T> {
201 fn eq(&self, rhs: &Self) -> bool {
202 let mut roughly_equal = true;
203 for iter in -10..=10 {
206 if (self.function)((iter as f64).into()) != (rhs.function)((iter as f64).into()) {roughly_equal = false;}
207 }
208 roughly_equal
209 }
210}
211
212impl<T: Rational + 'static> Rational for Function<T> where Function<T>: From<f64> {
213 fn pow(self, rhs: Self) -> Self {
214 Self { function: Arc::new(move |x| (self.function)(x.clone()).pow((rhs.function)(x))) }
215 }
216}
217
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222
223 type Func = Function<f64>;
224
225 fn define_shit() -> (Func, Func, Func, Func) {
227 return (Function::default(), Function::new(3.), Function::new(5.), Function::from(3.))
228 }
229
230 fn rounded_eq(a: Vec<f64>, b: Vec<f64>) {
231 let a = a.into_iter().map(|x| {
232 x.round()
233 }).collect::<Vec<f64>>();
235 let b = b.into_iter().map(|x| {
236 x.round()
237 }).collect::<Vec<f64>>();
239
240 assert_eq!(a, b);
241 }
242
243 #[test]
244 fn polynomial() {
245 assert_eq!(
246 Function::polynomial_from_roots(vec![2., 3.]),
247 (
248 (Func::default()+Func::new(-2.))*
249 (Func::default()+Func::new(-3.))
250 )
251 );
252 assert_eq!(
253 Function::polynomial_from_roots(vec![-2., -1., 3., 5.]),
254 (
255 (Func::default()+Func::new(2.))*
256 (Func::default()+Func::new(1.))*
257 (Func::default()+Func::new(-3.))*
258 (Func::default()+Func::new(-5.))
259 )
260 );
261 let x = Func::default();
262 assert_eq!(
263 Func::polynomial_from_roots(
264 vec![-3.5, -3., 3., 3.5]
265 ),
266 (x.clone()+3.5)*(x.clone()+3.)*(x.clone()-3.)*(x-3.5)
267 )
268 }
269
270 #[test]
271 fn test_find_zeroes() {
272 rounded_eq(
273 vec![-1., 1.],
274 Func::polynomial_from_roots(vec![1., -1.]).find_zeroes((-10, 10))
275 );
276 rounded_eq(
277 vec![-3., 2., 5.],
278 Func::polynomial_from_roots(vec![-3., 2., 5.]).find_zeroes((-10, 10))
279 )
280 }
281
282 #[test]
283 fn test_equality() {
284 let (y, f ,g , h) = define_shit();
285 assert_eq!(
286 f,
287 h
288 );
289 assert_eq!(
290 Func::from(4.),
291 Func::new(4.),
292 );
293 let (y, f ,g , h) = define_shit();
294 assert_eq!(
295 Func::from(1.)/y.clone(),
296 (f/h)/y,
297 );
298 }
299
300 #[test]
301 fn test_add() {
302 let (y, f ,g , h) = define_shit();
303 assert_eq!(
304 g+Func::new(4.),
305 f+Func::new(6.),
306 );
307 let (y, f ,g , h) = define_shit();
308 assert_eq!(
309 f+g.clone(),
310 g+h
311 );
312 }
313
314 #[test]
315 fn test_sub() {
316 let (y, f ,g , h) = define_shit();
317 assert_eq!(
318 g-h,
319 Func::new(2.)
320 );
321 let (y, f ,g , h) = define_shit();
322 assert_eq!(
323 f-g,
324 Func::new(-2.)
325 );
326 }
327
328 #[test]
329 fn test_mul() {
330 let (y, f ,g , h) = define_shit();
331 assert_eq!(
332 g.clone()*h,
333 f*g
334 );
335 let (y, f ,g , h) = define_shit();
336 assert_eq!(
337 f*g,
338 Func::new(15.)
339 );
340 }
341
342 #[test]
343 fn test_div() {
344 let (y, f ,g , h) = define_shit();
345 assert_eq!(
346 f/g,
347 Func::new(3./5.),
348 );
349 assert_eq!(
350 y/Func::new(1.),
351 Func::default()
352 );
353 }
354
355 #[test]
356 fn test_call() {
357 let (y, f, g, h) = define_shit();
358 assert_eq!(
359 g.call(2.),
360 5.
361 );
362 assert_eq!(
363 h.call(10000.47654),
364 3.
365 );
366 assert_eq!(
367 y.call(536.5),
368 536.5
369 );
370 }
371}
372
373
374