number_diff/functions/utils/
ops_impl.rs

1use super::super::calc::force_unwrap;
2use crate::Elementary::{self, *};
3use crate::Function;
4use std::iter::Sum;
5use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
6use std::sync::Arc;
7
8// operation implementations for Elementary enum
9impl Add for Elementary {
10    type Output = Self;
11    fn add(self, rhs: Self) -> Self::Output {
12        if let Con(numb) = self {
13            if numb == 0. {
14                return rhs;
15            }
16        } else if let Con(numb) = rhs {
17            if numb == 0. {
18                return self;
19            }
20        }
21        Self::Add(Arc::new(self), Arc::new(rhs))
22    }
23}
24impl Add<&mut Self> for Elementary {
25    type Output = Self;
26    fn add(self, rhs: &mut Self) -> Self::Output {
27        self + rhs.clone()
28    }
29}
30impl AddAssign for Elementary {
31    fn add_assign(&mut self, rhs: Self) {
32        *self = rhs + self.clone();
33    }
34}
35impl Sub for Elementary {
36    type Output = Self;
37    fn sub(self, rhs: Self) -> Self::Output {
38        Self::Sub(Arc::new(self), Arc::new(rhs))
39    }
40}
41impl Mul for Elementary {
42    type Output = Self;
43    fn mul(self, rhs: Self) -> Self::Output {
44        if let Con(numb) = self {
45            if numb == 1. {
46                return rhs;
47            } else if numb == 0. {
48                return self;
49            }
50        } else if let Con(numb) = rhs {
51            if numb == 1. {
52                return self;
53            } else if numb == 0. {
54                return rhs;
55            }
56        }
57        Self::Mul(Arc::new(self), Arc::new(rhs))
58    }
59}
60impl Mul<&mut Self> for Elementary {
61    type Output = Self;
62    fn mul(self, rhs: &mut Self) -> Self::Output {
63        self * rhs.clone()
64    }
65}
66impl MulAssign for Elementary {
67    fn mul_assign(&mut self, rhs: Self) {
68        *self = rhs * self.clone();
69    }
70}
71impl Div for Elementary {
72    type Output = Self;
73    fn div(self, rhs: Self) -> Self::Output {
74        Self::Div(Arc::new(self), Arc::new(rhs))
75    }
76}
77impl Div<&mut Self> for Elementary {
78    type Output = Self;
79    fn div(self, rhs: &mut Self) -> Self::Output {
80        self / rhs.clone()
81    }
82}
83impl DivAssign for Elementary {
84    fn div_assign(&mut self, rhs: Self) {
85        *self = self.clone() / rhs;
86    }
87}
88
89// operation implementations for Elementary enum (with constants)
90impl Add<f64> for Elementary {
91    type Output = Self;
92    fn add(self, rhs: f64) -> Self::Output {
93        Self::Add(Arc::new(self), Arc::new(Con(rhs)))
94    }
95}
96impl Sub<f64> for Elementary {
97    type Output = Self;
98    fn sub(self, rhs: f64) -> Self::Output {
99        Self::Sub(Arc::new(self), Arc::new(Con(rhs)))
100    }
101}
102impl Div<f64> for Elementary {
103    type Output = Self;
104    fn div(self, rhs: f64) -> Self::Output {
105        Self::Div(Arc::new(self), Arc::new(Con(rhs)))
106    }
107}
108impl Mul<f64> for Elementary {
109    type Output = Self;
110    fn mul(self, rhs: f64) -> Self::Output {
111        Self::Mul(Arc::new(self), Arc::new(Con(rhs)))
112    }
113}
114
115impl Sum<Self> for Elementary {
116    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
117        let terms: Vec<Elementary> = iter.collect();
118        let mut res = terms[0].clone();
119        for i in 1..terms.len() {
120            res += terms[i].clone();
121        }
122        res
123    }
124}
125
126// operation implementations for Function struct
127
128impl Add for Function {
129    type Output = Self;
130    fn add(self, rhs: Self) -> Self::Output {
131        Self::from(self.elementary() + rhs.elementary())
132    }
133}
134impl Add<&mut Self> for Function {
135    type Output = Self;
136    fn add(self, rhs: &mut Self) -> Self::Output {
137        Self::from(self.elementary() + rhs.elementary())
138    }
139}
140impl AddAssign for Function {
141    fn add_assign(&mut self, rhs: Self) {
142        self.set_function(self.elementary() + rhs.elementary());
143    }
144}
145
146impl Sub for Function {
147    type Output = Self;
148    fn sub(self, rhs: Self) -> Self::Output {
149        Self::from(self.elementary() - rhs.elementary())
150    }
151}
152impl SubAssign for Function {
153    fn sub_assign(&mut self, rhs: Self) {
154        self.set_function(self.elementary() - rhs.elementary())
155    }
156}
157
158impl Mul for Function {
159    type Output = Self;
160    fn mul(self, rhs: Self) -> Self::Output {
161        Self::from(self.elementary() * rhs.elementary())
162    }
163}
164impl Mul<&mut Self> for Function {
165    type Output = Self;
166    fn mul(self, rhs: &mut Self) -> Self::Output {
167        Self::from(self.elementary() * rhs.elementary())
168    }
169}
170impl MulAssign for Function {
171    fn mul_assign(&mut self, rhs: Self) {
172        self.set_function(self.elementary() * rhs.elementary())
173    }
174}
175impl Div for Function {
176    type Output = Self;
177    fn div(self, rhs: Self) -> Self::Output {
178        Self::from(self.elementary() / rhs.elementary())
179    }
180}
181impl Div<&mut Self> for Function {
182    type Output = Self;
183    fn div(self, rhs: &mut Self) -> Self::Output {
184        Self::from(self.elementary() / rhs.elementary())
185    }
186}
187impl DivAssign for Function {
188    fn div_assign(&mut self, rhs: Self) {
189        self.set_function(self.elementary() / rhs.elementary())
190    }
191}
192
193// operation implementations for Arc<Elementary>
194impl Add<Elementary> for Arc<Elementary> {
195    type Output = Elementary;
196    fn add(self, rhs: Elementary) -> Self::Output {
197        let elem = force_unwrap(&self);
198        elem + rhs
199    }
200}
201impl Sub<Elementary> for Arc<Elementary> {
202    type Output = Elementary;
203    fn sub(self, rhs: Elementary) -> Self::Output {
204        let elem = force_unwrap(&self);
205        elem - rhs
206    }
207}
208impl Mul<Elementary> for Arc<Elementary> {
209    type Output = Elementary;
210    fn mul(self, rhs: Elementary) -> Self::Output {
211        let elem = force_unwrap(&self);
212        elem * rhs
213    }
214}
215impl Div<Elementary> for Arc<Elementary> {
216    type Output = Elementary;
217    fn div(self, rhs: Elementary) -> Self::Output {
218        let elem = force_unwrap(&self);
219        elem / rhs
220    }
221}