1pub mod prelude{
5 use std::error::Error;
6 pub trait Plottable{
7 fn plot(self:&Self, output_file:&str, caption:&str, x_bound:(f32,f32), y_bound:(f32,f32), step:f32)->Result<(),Box<dyn Error>>;
8 }
9
10 pub trait Substitute{
11 fn substitute(self:&Self, x:f64)->f64;
12 }
13
14 pub trait Ordinal{
15 fn ord(self:&Self)->f64;
16 }
17 pub trait Bounded{
18 fn in_bounds(self:&Self, x:f64)->bool;
19 }
20
21 pub trait Calculus{
22 fn integrate(self: &Self)-> Self;
23 fn differenciate(self: &Self)->Self;
24 }
25}
26
27
28
29pub mod curves{
30 use plotters::prelude::*;
31 use super::prelude::*;
32 use std::{error::Error, f64::consts::PI, ops::{Add, Mul, Div, Sub, AddAssign, SubAssign, MulAssign, DivAssign}};
33 #[derive(Debug, Clone, Copy, PartialEq)]
34 pub enum Type{
35 Sine,
36 Cosine,
37 }
38 impl Type{
39 pub fn inv(self:&Self)->Type{
40 match self{
41 Type::Sine=>Type::Cosine,
42 Type::Cosine=>Type::Sine,
43 }
44 }
45 }
46
47 impl Add<f64> for Type{
48 type Output = f64;
49 fn add(self, rhs: f64) -> Self::Output {
50 match self{
51 Type::Sine=>rhs,
52 Type::Cosine=>rhs+PI/2.,
53 }
54 }
55 }
56
57 #[derive(Debug, Clone, Copy, PartialEq)]
60 pub struct Curve{
61 pub mag : f64,
62 pub fre : f64,
63 pub phase : Type,
64 }
65
66 impl Curve{
67 pub fn new(mag:f64, fre:f64, phase:Type)->Self{
68 Self{mag, fre, phase}
69 }
70 } impl Substitute for Curve{
73 fn substitute(self:&Self, x:f64)->f64{
74 self.mag*(self.fre*(self.phase + x)).sin()
75 }
76 }
77 impl Calculus for Curve{
78 fn integrate(self: &Self) -> Self {
79 match self.phase{
80 Type::Sine=>Self{
81 mag: self.mag/self.fre * -1.,
82 fre: self.fre,
83 phase: Type::Cosine,
84 },
85 Type::Cosine=>Self{
86 mag: self.mag/self.fre,
87 fre: self.fre,
88 phase: Type::Sine,
89 }
90 }
91 }
92 fn differenciate(self: &Self) ->Self {
93 match self.phase{
94 Type::Sine=>Self{
95 mag: self.mag*self.fre,
96 fre: self.fre,
97 phase: Type::Cosine,
98 },
99 Type::Cosine=>Self{
100 mag: self.mag*self.fre * -1.,
101 fre: self.fre,
102 phase: Type::Sine,
103 }
104 }
105 }
106 }
107 impl AddAssign for Curve{
108 fn add_assign(&mut self, rhs: Self) {
109 if let Some(c) = *self + rhs{
110 *self = c;
111 }
112 }
113 }
114 impl SubAssign for Curve{
115 fn sub_assign(&mut self, rhs: Self) {
116 if let Some(c) = *self - rhs{
117 *self = c;
118 }
119 }
120 }
121 impl MulAssign<f64> for Curve{
122 fn mul_assign(&mut self, rhs: f64) {
123 *self = *self * rhs;
124 }
125 }
126 impl DivAssign<f64> for Curve{
127 fn div_assign(&mut self, rhs: f64) {
128 *self = *self / rhs;
129 }
130 }
131 impl Add<Curve> for Curve{
132 type Output = Option<Curve>;
133 fn add(self, rhs: Self) -> Self::Output {
134 if self.fre == rhs.fre && self.phase == rhs.phase{
135 return Some(
136 Curve::new(
137 self.mag + rhs.mag,
138 self.fre,
139 self.phase
140 )
141 )
142 }
143 None
144 }
145 }
146 impl Sub<Curve> for Curve{
147 type Output = Option<Curve>;
148 fn sub(self, rhs: Self) -> Self::Output {
149 if self.fre == rhs.fre && self.phase == rhs.phase{
150 return Some(
151 Curve::new(
152 self.mag - rhs.mag,
153 self.fre,
154 self.phase
155 )
156 )
157 }
158 None
159 }
160 }
161 impl Mul<f64> for Curve{
162 type Output = Curve;
163 fn mul(self, rhs: f64) -> Self::Output {
164 Self::Output{
165 mag: self.mag*rhs,
166 fre:self.fre,
167 phase: self.phase,
168 }
169 }
170 }
171 impl Div<f64> for Curve{
172 type Output = Curve;
173 fn div(self, rhs:f64) -> Self::Output{
174 Self::Output{
175 mag : self.mag/rhs,
176 fre: self.fre,
177 phase : self.phase
178 }
179 }
180 }
181
182 #[derive(Debug, Clone)]
183 pub struct FourierCurve{
184 pub curves: Vec<Curve>,
185 }
186 impl FourierCurve{
187 pub fn new()->Self{
188 FourierCurve{
189 curves:Vec::new(),
190 }
191 }
192 pub fn push(self:& mut Self, curve: Curve){
194 self.curves.push(curve);
195 }
196 pub fn push_curve(self:&mut Self, mag:f64, fre:f64, phase:Type){
198 self.push(Curve::new(mag, fre, phase));
199 }
200
201 } impl Into<Vec<f64>> for FourierCurve{
203 fn into(self) -> Vec<f64> {
204 let mut result:Vec<f64> = Vec::new();
205 let x_axis = (-3.14..3.14).step(0.01);
206 for val in x_axis.values(){
207 result.push(self.substitute(val));
208 }
209 result
211 }
212 }
213 impl Calculus for FourierCurve{
214 fn integrate(self: &Self) -> Self {
215 let mut f = FourierCurve::new();
216 for c in &self.curves{
217 f = f + c.integrate();
218 }
219 f
220
221 }
222 fn differenciate(self: &Self) ->Self {
223 let mut f = FourierCurve::new();
224 for c in &self.curves{
225 f = f + c.differenciate();
226 }
227 f
228 }
229 }
230
231 impl Plottable for FourierCurve{
232
233 fn plot(self:&Self, output_file:&str, caption:&str, x_bound:(f32,f32), y_bound:(f32,f32), step:f32)->Result<(),Box<dyn Error>>{
234 let root = BitMapBackend::new(output_file,(640,480)).into_drawing_area();
235 root.fill(&WHITE)?;
236
237 let mut chart = ChartBuilder::on(&root)
238 .x_label_area_size(35)
239 .y_label_area_size(40)
240 .margin(5)
241 .caption(caption, ("sans-serif", 50.0))
242 .build_cartesian_2d(x_bound.0..x_bound.1, y_bound.0..y_bound.1)?;
243
244 chart.configure_mesh()
245 .x_labels(20)
246 .y_labels(10)
247 .disable_mesh()
248 .x_label_formatter(&|v| format!("{:.1}", v))
249 .y_label_formatter(&|v| format!("{:.1}", v))
250 .draw()?;
251
252 let x_axis = (x_bound.0..x_bound.1).step(step);
253 chart.draw_series(LineSeries::new(x_axis.values().map(|x| (x, self.substitute(x as f64) as f32)), &RED))?;
254 root.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir");
259 println!("Result has been saved to {}", output_file);
260 Ok(())
261
262 }
263 }impl Substitute for FourierCurve{
265 fn substitute(self:&Self, x:f64)->f64{
266 let mut sum = 0.0;
267 for c in &self.curves{
268 sum= sum + c.substitute(x);
269 }
270 sum
271 }
272 }
273 impl PartialEq for FourierCurve{
274 fn eq(&self, other: &Self) -> bool {
275 for a in &self.curves{
276 if !other.curves.contains(a){
277 return false
278 }
279 }
280 true
281 }
282 }
283 impl Mul<f64> for FourierCurve{
284 type Output = FourierCurve;
285 fn mul(self, rhs: f64) -> Self::Output {
286 let mut f = self;
287 for a in f.curves.iter_mut(){
288 *a = *a * rhs;
289 }
290 f
291 }
292 }
293
294 impl Add<FourierCurve> for FourierCurve{
295 type Output = FourierCurve;
296 fn add(self, rhs: FourierCurve) -> Self::Output {
297 let mut f = self;
298 for c in rhs.curves{
299 f = f + c;
300 }
301 f
302 }
303 }
304 impl Add<Curve> for FourierCurve{
305 type Output = FourierCurve;
306 fn add(self, rhs: Curve) -> Self::Output {
307 let mut f = self;
308 let mut is_added = false;
309 for c in f.curves.iter_mut(){
310 match *c + rhs{
311 Some(curve)=>{
312 *c = curve;
313 is_added = true;
314 },
315 None=>{},
316 }
317 }
318 if !is_added{
319 f.curves.push(rhs);
320 }
321 f
322 }
323 }
324 impl Sub<Curve> for FourierCurve{
325 type Output = FourierCurve;
326 fn sub(self, rhs: Curve) -> Self::Output {
327 self + rhs * -1.
328 }
329 }
330 impl Sub<FourierCurve> for FourierCurve{
331 type Output = FourierCurve;
332 fn sub(self, rhs: FourierCurve) -> Self::Output {
333 self + rhs * -1.
334 }
335 }
336
337
338}pub mod functions{
341 use plotters::prelude::*;
342 use super::prelude::*;
343
344 use std::{error::Error, ops::{Sub, Add, Mul, Div}};
345
346 #[derive(Debug, Clone, PartialEq)]
348 pub struct Function{
349 pub funcs:Vec<BoundedPolynomial>,
350 }
351 impl Function{
352 pub fn new()->Self{
353 Self{funcs:Vec::new()}
354 }
355 }
356 impl Bounded for Function{
357 fn in_bounds(self:&Self, x:f64) ->bool {
358 for p in &self.funcs{
359 if p.in_bounds(x){
360 return true
361 }
362 }
363 false
364 }
365 }
366 impl Calculus for Function{
367 fn integrate(self: &Self) -> Self {
368 let mut f = Function::new();
369 for bp in &self.funcs{
370 f = (f + bp.integrate()).unwrap();
371 }
372 f
373 }
374 fn differenciate(self: &Self) ->Self {
375 let mut f = Function::new();
376 for bp in &self.funcs{
377 f = (f + bp.differenciate()).unwrap();
378 }
379 f
380 }
381 }
382 impl Ordinal for Function{
383 fn ord(self:&Self) ->f64 {
384 let mut max = f64::NEG_INFINITY;
385 for f in & self.funcs{
386 if f.ord()>max{
387 max = f.ord();
388 }
389 }
390 max
391 }
392 }
393 impl Plottable for Function{
394 fn plot(self:&Self, output_file:&str, caption:&str, x_bound:(f32,f32), y_bound:(f32,f32), step:f32) ->Result<(),Box<dyn Error>> {
395 let root = BitMapBackend::new(output_file,(1080,920)).into_drawing_area();
396 root.fill(&WHITE)?;
397
398 let mut chart = ChartBuilder::on(&root)
399 .x_label_area_size(35)
400 .y_label_area_size(40)
401 .margin(5)
402 .caption(caption, ("sans-serif", 50.0))
403 .build_cartesian_2d(x_bound.0..x_bound.1, y_bound.0..y_bound.1)?;
404
405 chart.configure_mesh()
406 .x_labels(20)
407 .y_labels(10)
408 .disable_mesh()
409 .x_label_formatter(&|v| format!("{:.1}", v))
410 .y_label_formatter(&|v| format!("{:.1}", v))
411 .draw()?;
412
413 let x_axis = (x_bound.0..x_bound.1).step(step);
414 chart.draw_series(LineSeries::new(x_axis.values().map(|x| (x, self.substitute(x as f64) as f32)), &RED))?;
415 root.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir");
420 println!("Result has been saved to {}", output_file);
421 Ok(())
422 }
423 }
424 impl Substitute for Function{
425 fn substitute(self:&Self, x:f64) ->f64 {
426 let mut ret = 0.;
427 for t in &self.funcs{
428 ret +=t.substitute(x);
429 }
430 ret
431 }
432 }
433
434 impl Add<BoundedPolynomial> for Function{
435 type Output = Option<Function>;
436 fn add(self, rhs: BoundedPolynomial) -> Self::Output {
437 let mut f = self;
438 if f.in_bounds(rhs.bounds.0) || f.in_bounds(rhs.bounds.0){
439 return None;
440 }
441 f.funcs.push(rhs);
442 Some(f)
443 }
444 }
445 impl Sub<BoundedPolynomial> for Function{
447 type Output = Option<Function>;
448 fn sub(self, rhs: BoundedPolynomial) -> Self::Output {
449 self + rhs * -1.
450 }
451 }
452 impl Mul<Term> for Function{
453 type Output = Function;
454 fn mul(self, rhs: Term) -> Self::Output {
455 let mut f = Function::new();
456 for b in self.funcs{
457 f = (f + b * rhs).unwrap();
458 }
459 f
460 }
461 }
462 impl Mul<f64> for Function{
463 type Output = Function;
464 fn mul(self, rhs: f64) -> Self::Output {
465 let mut f = Function::new();
466 for b in self.funcs{
467 f = (f + b * rhs).unwrap();
468 }
469 f
470 }
471 }
472 impl Div<Term> for Function{
473 type Output = Function;
474 fn div(self, rhs: Term) -> Self::Output {
475 let mut f = Function::new();
476 for b in self.funcs{
477 f = (f + b / rhs).unwrap();
478 }
479 f
480 }
481 }
482 impl Div<f64> for Function{
483 type Output = Function;
484 fn div(self, rhs: f64) -> Self::Output {
485 let mut f = Function::new();
486 for b in self.funcs{
487 f = (f + b / rhs).unwrap();
488 }
489 f
490 }
491 }
492
493
494 #[derive(Debug, Clone, PartialEq)]
496 pub struct BoundedPolynomial{
497 pub poly:Polynomial,
498 pub bounds:(f64, f64),
499 }
500 impl BoundedPolynomial{
501 pub fn bounds_mut(self:&mut Self)-> &mut (f64, f64){
502 &mut self.bounds
503 }
504 }
505 impl Bounded for BoundedPolynomial{
506 fn in_bounds(self:&Self, x:f64)->bool{
507 self.bounds.0<=x && x< self.bounds.1
508 }
509 }
510 impl From<Polynomial> for BoundedPolynomial{
511 fn from(poly: Polynomial) -> Self {
512 Self{poly, bounds:(0.,10.)}
513 }
514 }
515 impl Ordinal for BoundedPolynomial{
516 fn ord(self:&Self) ->f64 {
517 self.poly.ord()
518 }
519 }
520 impl Calculus for BoundedPolynomial{
521 fn differenciate(self: &Self) ->Self {
522 Self{
523 poly : self.poly.differenciate(),
524 bounds: self.bounds,
525 }
526 }
527 fn integrate(self: &Self) -> Self {
528 Self{
529 poly : self.poly.integrate(),
530 bounds: self.bounds,
531 }
532 }
533 }
534 impl Substitute for BoundedPolynomial{
535 fn substitute(self:&Self, x:f64) ->f64 {
536 if self.bounds.0<x && self.bounds.1>x{
537 return self.poly.substitute(x);
538 }
539 0.
540 }
541 }
542
543 impl Add<Term> for BoundedPolynomial{
544 type Output = BoundedPolynomial;
545 fn add(self, rhs: Term) -> Self::Output {
546 Self::Output{
547 poly: self.poly + rhs,
548 bounds: self.bounds,
549 }
550 }
551 }
552 impl Sub<Term> for BoundedPolynomial{
553 type Output = BoundedPolynomial;
554 fn sub(self, rhs: Term) -> Self::Output {
555 Self::Output{
556 poly: self.poly - rhs,
557 bounds: self.bounds,
558 }
559 }
560 }
561
562 impl Mul<f64> for BoundedPolynomial{
563 type Output = BoundedPolynomial;
564 fn mul(self, rhs: f64) -> Self::Output {
565 Self::Output{
566 poly: self.poly * rhs,
567 bounds: self.bounds,
568 }
569 }
570 }
571 impl Mul<Term> for BoundedPolynomial{
572 type Output = BoundedPolynomial;
573 fn mul(self, rhs: Term) -> Self::Output {
574 Self::Output{
575 poly: self.poly * rhs,
576 bounds: self.bounds,
577 }
578 }
579 }
580
581
582 impl Div<f64> for BoundedPolynomial{
583 type Output = BoundedPolynomial;
584 fn div(self, rhs: f64) -> Self::Output {
585 Self::Output{
586 poly: self.poly / rhs,
587 bounds: self.bounds,
588 }
589 }
590 }
591 impl Div<Term> for BoundedPolynomial{
592 type Output = BoundedPolynomial;
593 fn div(self, rhs: Term) -> Self::Output {
594 Self::Output{
595 poly: self.poly / rhs,
596 bounds: self.bounds,
597 }
598 }
599 }
600
601
602 #[derive(Debug, Clone)]
603 pub struct Polynomial{
605 pub terms:Vec<Term>,
606 }
607 impl Polynomial{
608 pub fn new()->Self{
609 Self{terms: Vec::new()}
610 }
611 }
612 impl Ordinal for Polynomial{
613 fn ord(self:&Self) ->f64 {
614 let mut max = f64::NEG_INFINITY;
615 for t in &self.terms{
616 if t.pow>max{
617 max = t.pow;
618 }
619 }
620 max
621 }
622 }
623 impl Calculus for Polynomial{
624 fn integrate(self: &Self) -> Self {
625 let mut p = Polynomial::new();
626 for t in &self.terms{
627 p = p + t.integrate();
628 }
629 p
630 }
631 fn differenciate(self: &Self) ->Self {
632 let mut p = Polynomial::new();
633 for t in &self.terms{
634 p = p + t.differenciate();
635 }
636 p
637 }
638 }
639
640 impl Substitute for Polynomial{
641 fn substitute(self:&Self, x:f64) ->f64 {
642 let mut ret = 0.;
643 for t in &self.terms{
644 ret +=t.substitute(x);
645 }
646 ret
647 }
648 }
649 impl PartialEq for Polynomial{
650 fn eq(&self, other: &Self) -> bool {
651 for a in &self.terms{
652 if !other.terms.contains(a){
653 return false
654 }
655 }
656 true
657 }
658 }
659
660 impl Add<Polynomial> for Polynomial{
661 type Output = Polynomial;
662 fn add(self, rhs: Polynomial) -> Self::Output {
663 let mut poly = self;
664 for t in rhs.terms{
665 poly = poly + t;
666 }
667 poly
668 }
669 }
670 impl Add<Term> for Polynomial{
671 type Output = Polynomial;
672 fn add(self, rhs: Term) -> Self::Output {
673 let mut poly = self;
674 let mut is_added = false;
675 for t in poly.terms.iter_mut(){
676 match *t + rhs{
677 Some(term)=>{
678 *t = term;
679 is_added = true;
680 },
681 None=>{},
682 }
683 }
684 if !is_added{
685 poly.terms.push(rhs);
686 }
687 poly
688 }
689 }
690 impl Sub<Term> for Polynomial{
691 type Output = Polynomial;
692 fn sub(self, rhs: Term) -> Self::Output {
693 self + rhs * -1.
694 }
695 }
696 impl Sub<Polynomial> for Polynomial{
697 type Output = Polynomial;
698 fn sub(self, rhs: Polynomial) -> Self::Output {
699 self + rhs * -1.
700 }
701 }
702 impl Mul<f64> for Polynomial{
703 type Output = Polynomial;
704 fn mul(self, rhs: f64) -> Self::Output {
705 let mut p = Polynomial::new();
706 for t in self.terms{
707 p = p + t*rhs;
708 }
709 p
710 }
711 }
712 impl Mul<Term> for Polynomial{
713 type Output = Polynomial;
714 fn mul(self, rhs: Term) -> Self::Output {
715 let mut p = Polynomial::new();
716 for t in self.terms{
717 p = p + t*rhs;
718 }
719 p
720 }
721 }
722 impl Div<f64> for Polynomial{
723 type Output = Polynomial;
724 fn div(self, rhs: f64) -> Self::Output {
725 let mut p = Polynomial::new();
726 for t in self.terms{
727 p = p + t/rhs;
728 }
729 p
730 }
731 }
732 impl Div<Term> for Polynomial{
733 type Output = Polynomial;
734 fn div(self, rhs: Term) -> Self::Output {
735 let mut p = Polynomial::new();
736 for t in self.terms{
737 p = p + t/rhs;
738 }
739 p
740 }
741 }
742
743 #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
746 pub struct Term{
747 pub coef:f64,
748 pub pow:f64
749 }
750 impl Term{
751 pub fn new(coef:f64, pow:f64)->Self{
752 Self{pow, coef}
753 }
754 }
755 impl Substitute for Term{
756 fn substitute(self:&Self, x:f64)->f64{
757 self.coef* x.powf(self.pow)
758 }
759 }
760 impl Calculus for Term{
761 fn differenciate(self: &Self) ->Self {
762 Self{
763 coef: self.coef*self.pow,
764 pow: self.pow-1.
765 }
766 }
767 fn integrate(self: &Self) -> Self {
768 Self{
769 coef: self.coef/(self.pow+1.),
770 pow: self.pow+1.,
771 }
772 }
773 }
774 impl Sub<Term> for Term{
776 type Output = Option<Term>;
777 fn sub(self, rhs: Self) -> Self::Output {
778 if self.pow == rhs.pow{
779 return Some(Self{
780 coef: self.coef-rhs.coef,
781 pow:self.pow,
782 })
783 }
784 None
785 }
786 }
787 impl Add<Term> for Term{
788 type Output = Option<Term>;
789 fn add(self, rhs: Self) -> Self::Output {
790 if self.pow == rhs.pow{
791 return Some(Self{
792 coef: self.coef+rhs.coef,
793 pow:self.pow,
794 })
795 }
796 None
797 }
798 }
799 impl Mul<Term> for Term{
800 type Output = Term;
801 fn mul(self, rhs: Term) -> Self::Output {
802 Self::Output{
803 coef:self.coef*rhs.coef,
804 pow:self.pow+rhs.pow,
805 }
806 }
807 }
808 impl Div<Term> for Term{
809 type Output = Term;
810 fn div(self, rhs: Term) -> Self::Output {
811 Self::Output{
812 coef:self.coef/rhs.coef,
813 pow:self.pow-rhs.pow,
814 }
815 }
816 }
817 impl Mul<f64> for Term{
818 type Output = Term;
819 fn mul(self, rhs: f64) -> Self::Output {
820 Self::Output{
821 coef: self.coef*rhs,
822 pow: self.pow,
823 }
824 }
825 }
826 impl Div<f64> for Term{
827 type Output = Term;
828 fn div(self, rhs: f64) -> Self::Output {
829 Self::Output{
830 coef: self.coef/rhs,
831 pow: self.pow,
832 }
833 }
834 }
835
836}
837
838
839
840
841
842#[cfg(test)]
843mod tests{
844 use crate::{prelude::*, functions::*, curves::{*, Type::*}};
845
846 mod test_plots{
847 use super::*;
848
849 #[test]
850 fn first(){
851 let mut curve = FourierCurve::new();
852 curve.push(Curve::new(1.,1., Sine));
853 curve.push(Curve::new(0.5,3., Sine));
854 curve.push(Curve::new(1./4.,5., Sine));
855 curve.push(Curve::new(1./8., 7., Sine));
856
857 curve.plot("plotters-doc-data/first_test.png","test 1", (0.0,20.0), (-10.0, 20.0), 0.01).unwrap();
858
859
860 }
861 #[test]
862 fn square(){
863 let mut curve = FourierCurve::new();
864 curve.push(Curve::new(4.0,1., Sine));
865 curve.push(Curve::new(4./3.,3.0, Sine));
866 curve.push(Curve::new(4./5.,5.0,Sine));
867 curve.push(Curve::new(4./7.,7., Sine));
868
869 curve.plot("plotters-doc-data/square.png","square", (0.0,20.0), (-10.0, 20.0), 0.01).unwrap();
870
871
872 }
873 #[test]
874 fn saw_tooth(){
875 let mut curve = FourierCurve::new();
876 curve.push(Curve::new(-2.,1., Sine));
877 curve.push(Curve::new(1.,2., Sine));
878 curve.push(Curve::new(-2./3.,3., Sine));
879 curve.push(Curve::new(0.5, 4., Sine));
880
881
882 curve.plot("plotters-doc-data/saw_tooth.png","Saw Tooth", (0.0,20.0), (-10.0, 20.0), 0.01).unwrap();
883
884
885 }
886 } mod test_function{
888 use super::*;
889 #[test]
890 fn test_functions(){
891 let mut curve = Function::new();
892 curve = (curve +BoundedPolynomial{
893 poly:Polynomial{
894 terms:vec![Term::new(1., 1.), Term::new(2., 2.), Term::new(3., 3.)]
895 },
896 bounds:(-1000., 1000.),
897 }).unwrap();
898 curve.plot("plotters-doc-data/test_func.png", "Test Function", (-100.,100.), (-1000.,1000.), 0.01).unwrap();
899 }
900 #[test]
901 fn function_binary(){
902 let mut p = Polynomial::new();
904
905 p = p + Term::new(1., 1.);
907 assert_eq!(
908 p,
909 Polynomial{
910 terms:vec!(
911 Term::new(1., 1.),
912 )
913 }
914 );
915 p = p + Term::new(2., 1.);
917 assert_eq!(
918 p,
919 Polynomial{
920 terms:vec!(Term::new(3., 1.))
921 }
922 );
923 p = p + Term::new(2., 2.) + Term::new(3., 3.);
925 assert_eq!(p,
926 Polynomial{
927 terms:vec!(
928 Term::new(3., 3.),
929 Term::new(3., 1.),
930 Term::new(2.,2.),
931 )
932 }
933 );
934 let t = Term::new(1., 1.);
936
937 assert_eq!(t + Term::new(2., 1.), Some(Term::new(3., 1.)));
940 assert_eq! (t + Term::new(2., 2.), None);
941 assert_eq!(t-Term::new(0.5, 1.), Some(Term::new(0.5, 1.)));
943 assert_eq!(t-Term::new(2., 1.), Some(Term::new(-1., 1.)));
944
945 assert_eq!(t * 2. , Term::new(2., 1.));
948 assert_eq!(t / 5., Term::new(1./5., 1.));
950
951 assert_eq!(t * Term::new(2., 1.), Term::new(2., 2.));
954 assert_eq!(t * Term::new(3., 2.), Term::new(3., 3.));
955 assert_eq!(t / Term::new(3., 2.), Term::new(1./3., -1.));
957 }
958 #[test]
959 fn test_bounds(){
960 let mut bp = BoundedPolynomial::from(Polynomial{
961 terms: vec!(
962 Term::new(1.,2.),
963 Term::new(2.,3.),
964 )
965 });
966 assert!(bp.in_bounds(-1.) == false);
967 assert!(bp.in_bounds(5.) == true);
968 assert!(bp.in_bounds(11.) == false);
969
970 let b = bp.bounds_mut();
971 b.0 = -10.0;
972
973 assert!(bp.in_bounds(-1.) == true);
974 assert!(bp.in_bounds(5.) == true);
975 assert!(bp.in_bounds(11.) == false);
976
977 assert!(bp.in_bounds(-10.) == true);
978
979 assert!(bp.in_bounds(10.) == false);
980
981 let mut f = Function::new();
982 f = (f +
983 BoundedPolynomial{
984 poly : Polynomial{
985 terms: vec!(
986 Term::new(3., 2.),
987 )
988 },
989 bounds: (0., 10.),
990 }).unwrap();
991 assert!(
992 (f.clone() + BoundedPolynomial{
993 poly : Polynomial{
994 terms: vec!(
995 Term::new(3., 2.),
996 )
997 },
998 bounds: (9., 20.),
999 }) == None);
1000
1001 assert!((f + BoundedPolynomial{
1002 poly : Polynomial{
1003 terms: vec!(
1004 Term::new(3., 2.),
1005 )
1006 },
1007 bounds: (10., 20.),
1008 }) == Some( Function{
1009 funcs: vec!(
1010 BoundedPolynomial{
1011 poly : Polynomial{
1012 terms: vec!(
1013 Term::new(3., 2.),
1014 )
1015 },
1016 bounds: (0., 10.),
1017 },
1018 BoundedPolynomial{
1019 poly : Polynomial{
1020 terms: vec!(
1021 Term::new(3., 2.),
1022 )
1023 },
1024 bounds: (10., 20.),
1025 }
1026 )
1027 }
1028
1029 ));
1030
1031 }
1032
1033 #[test]
1034 fn test_calculus(){
1035 let t = Term::new(2., 3.);
1036 assert_eq!(
1037 t.integrate(),
1038 Term::new(2./4., 4.)
1039 );
1040 assert_eq!(
1041 t.differenciate(),
1042 Term::new(2.*3., 2.)
1043 );
1044
1045
1046 let mut p = Polynomial{
1047 terms : vec!(
1048 Term::new(2., 3.)
1049 )
1050 };
1051 assert_eq!(
1052 p.integrate(),
1053 Polynomial{
1054 terms : vec!(
1055 Term::new(2., 3.).integrate(),
1056 )
1057 }
1058 );
1059 p = p + Term::new(3., 5.);
1060
1061 assert_eq!(
1062 p.integrate(),
1063 Polynomial{
1064 terms : vec!(
1065 Term::new(2., 3.).integrate(),
1066 Term::new(3., 5.).integrate(),
1067 )
1068 }
1069 );
1070
1071 let mut f = Function::new();
1072 f =( f +
1073 BoundedPolynomial{
1074 poly: Polynomial{
1075 terms: vec!(
1076 Term::new(2., 3.),
1077 )
1078 },
1079 bounds: (0., 10.),
1080 }
1081 ).unwrap();
1082
1083 assert_eq!(
1084 f.integrate(),
1085 Function{
1086 funcs: vec!(
1087 BoundedPolynomial{
1088 poly: Polynomial{
1089 terms: vec!(
1090 Term::new(2., 3.).integrate(),
1091 )
1092 },
1093 bounds: (0., 10.),
1094 }
1095 )
1096 }
1097 );
1098
1099 f = ( f +
1100 BoundedPolynomial{
1101 poly: Polynomial{
1102 terms: vec!(
1103 Term::new(2., 4.),
1104 )
1105 },
1106 bounds: (10., 20.),
1107 }
1108 ).unwrap();
1109
1110 assert_eq!(
1111 f.integrate(),
1112 Function{
1113 funcs: vec!(
1114 BoundedPolynomial{
1115 poly: Polynomial{
1116 terms: vec!(
1117 Term::new(2., 3.).integrate(),
1118 )
1119 },
1120 bounds: (0., 10.),
1121 },
1122 BoundedPolynomial{
1123 poly: Polynomial{
1124 terms: vec!(
1125 Term::new(2., 4.).integrate(),
1126 )
1127 },
1128 bounds: (10., 20.),
1129 }
1130 )
1131 }
1132 );
1133 }
1134 } mod test_curves{
1136 use super::*;
1137 #[test]
1138 fn curves_binary(){
1139 let c = Curve::new(1., 1., Sine);
1140 assert_eq!(
1141 c + Curve::new( 2., 1., Sine) ,
1142 Some(Curve::new(3., 1., Sine))
1143 );
1144
1145 assert_eq!(
1146 c + Curve::new( 2., 1., Cosine) ,
1147 None
1148 );
1149
1150 assert_eq!(
1151 c + Curve::new( 2., 2., Sine) ,
1152 None
1153 );
1154
1155 assert_eq!(
1156 c + Curve::new( 2., 2., Cosine) ,
1157 None
1158 );
1159
1160 let mut f = FourierCurve{
1161 curves: vec!(
1162 Curve::new(1., 1., Sine),
1163 )
1164 };
1165
1166 f = f + Curve::new(2., 1., Sine);
1167 assert_eq!(
1168 f ,
1169 FourierCurve{
1170 curves: vec!(
1171 Curve::new(3., 1., Sine),
1172 )
1173 }
1174 );
1175 f = f + Curve::new(2., 2., Sine);
1176 assert_eq!(
1177 f,
1178 FourierCurve{
1179 curves: vec!(
1180 Curve::new(3., 1., Sine),
1181 Curve::new(2., 2., Sine),
1182 )
1183 }
1184 );
1185 }#[test]
1188 fn curves_calculus(){
1189 let c = Curve::new(2., 3., Sine);
1190 assert_eq!(
1192 c.integrate(),
1193 Curve::new(-2./3., 3., Cosine)
1194 );
1195
1196 assert_eq!(
1198 c.differenciate(),
1199 Curve::new(2.*3., 3., Cosine)
1200 );
1201
1202 let f = FourierCurve{
1203 curves:vec!(
1204 Curve::new(2., 3., Sine)
1205 )
1206 };
1207 assert_eq!(
1208 f.integrate(),
1209 FourierCurve{
1210 curves:vec!(
1211 Curve::new(2., 3., Sine).integrate()
1212 )
1213 }
1214 );
1215
1216 }
1217 } }