arr_rs/math/operations/exp_log.rs
1use crate::{
2 core::prelude::*,
3 errors::prelude::*,
4 numeric::prelude::*,
5};
6
7/// `ArrayTrait` - Array `ExpLog` functions
8pub trait ArrayExpLog<N: Numeric> where Self: Sized + Clone {
9
10 /// Computes the exponential of array elements
11 ///
12 /// # Examples
13 ///
14 /// ```
15 /// use arr_rs::prelude::*;
16 ///
17 /// let arr = Array::flat(vec![1., 2., 3., 4.]);
18 /// assert_eq!(Array::flat(vec![std::f64::consts::E, 7.38905609893065, 20.085536923187668, 54.598150033144236]), arr.exp());
19 /// ```
20 ///
21 /// # Errors
22 ///
23 /// may returns `ArrayError`
24 fn exp(&self) -> Result<Array<N>, ArrayError>;
25
26 /// Computes 2**element of array elements
27 ///
28 /// # Examples
29 ///
30 /// ```
31 /// use arr_rs::prelude::*;
32 ///
33 /// let arr = Array::flat(vec![1., 2., 3., 4.]);
34 /// assert_eq!(Array::flat(vec![2., 4., 8., 16.]), arr.exp2());
35 /// ```
36 ///
37 /// # Errors
38 ///
39 /// may returns `ArrayError`
40 fn exp2(&self) -> Result<Array<N>, ArrayError>;
41
42 /// Computes exp - 1 of array elements
43 ///
44 /// # Examples
45 ///
46 /// ```
47 /// use arr_rs::prelude::*;
48 ///
49 /// let arr = Array::flat(vec![1., 2., 3., 4.]);
50 /// assert_eq!(Array::flat(vec![1.718281828459045, 6.38905609893065, 19.085536923187668, 53.598150033144236]), arr.exp_m1());
51 /// ```
52 ///
53 /// # Errors
54 ///
55 /// may returns `ArrayError`
56 fn exp_m1(&self) -> Result<Array<N>, ArrayError>;
57
58 /// Computes natural logarithm of array elements
59 ///
60 /// # Examples
61 ///
62 /// ```
63 /// use arr_rs::prelude::*;
64 ///
65 /// let arr = Array::flat(vec![1., 4., 8., 16.]);
66 /// assert_eq!(Array::flat(vec![0., 1.3862943611198906, 2.0794415416798357, 2.772588722239781]), arr.log());
67 /// ```
68 ///
69 /// # Errors
70 ///
71 /// may returns `ArrayError`
72 fn log(&self) -> Result<Array<N>, ArrayError>;
73
74 /// Computes logarithm base 2 of array elements
75 ///
76 /// # Examples
77 ///
78 /// ```
79 /// use arr_rs::prelude::*;
80 ///
81 /// let arr = Array::flat(vec![1., 4., 8., 16.]);
82 /// assert_eq!(Array::flat(vec![0., 2., 3., 4.]), arr.log2());
83 /// ```
84 ///
85 /// # Errors
86 ///
87 /// may returns `ArrayError`
88 fn log2(&self) -> Result<Array<N>, ArrayError>;
89
90 /// Computes logarithm base 10 of array elements
91 ///
92 /// # Examples
93 ///
94 /// ```
95 /// use arr_rs::prelude::*;
96 ///
97 /// let arr = Array::flat(vec![1., 10., 100.]);
98 /// assert_eq!(Array::flat(vec![0., 1., 2.]), arr.log10());
99 /// ```
100 ///
101 /// # Errors
102 ///
103 /// may returns `ArrayError`
104 fn log10(&self) -> Result<Array<N>, ArrayError>;
105
106 /// Computes log(1 + x) of array elements
107 ///
108 /// # Examples
109 ///
110 /// ```
111 /// use arr_rs::prelude::*;
112 ///
113 /// let arr = Array::flat(vec![2., 4., 8., 20.]);
114 /// assert_eq!(Array::flat(vec![1.0986122886681096, 1.6094379124341003, 2.1972245773362196, 3.044522437723423]), arr.log_1p());
115 /// ```
116 ///
117 /// # Errors
118 ///
119 /// may returns `ArrayError`
120 fn log_1p(&self) -> Result<Array<N>, ArrayError>;
121
122 /// Computes logarithm base n of array elements
123 ///
124 /// # Arguments
125 ///
126 /// * `value` - log array to perform the operation with
127 ///
128 /// # Examples
129 ///
130 /// ```
131 /// use arr_rs::prelude::*;
132 ///
133 /// let arr = Array::flat(vec![2., 4., 8., 20.]);
134 /// assert_eq!(Array::flat(vec![1., 2., 3., 1.301029995663981]), arr.logn(&Array::flat(vec![2., 2., 2., 10.]).unwrap()));
135 /// ```
136 ///
137 /// # Errors
138 ///
139 /// may returns `ArrayError`
140 fn logn(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
141
142 /// Computes log(exp(x1) + exp(x2)) of array elements
143 ///
144 /// # Arguments
145 ///
146 /// * `value` - log array to perform the operation with
147 ///
148 /// # Examples
149 ///
150 /// ```
151 /// use arr_rs::prelude::*;
152 ///
153 /// let arr_1 = Array::flat(vec![2., 4., 8., 20.]);
154 /// let arr_2 = Array::flat(vec![2., 2., 2., 10.]).unwrap();
155 /// assert_eq!(Array::flat(vec![2.6931471805599454, 4.126928011042972, 8.00247568513773, 20.000045398899218]), arr_1.log_add_exp(&arr_2));
156 /// ```
157 ///
158 /// # Errors
159 ///
160 /// may returns `ArrayError`
161 fn log_add_exp(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
162
163 /// Computes log2(2**x1 + 2**x2) of array elements
164 ///
165 /// # Arguments
166 ///
167 /// * `value` - log array to perform the operation with
168 ///
169 /// # Examples
170 ///
171 /// ```
172 /// use arr_rs::prelude::*;
173 ///
174 /// let arr_1 = Array::flat(vec![2., 4., 8., 20.]);
175 /// let arr_2 = Array::flat(vec![2., 2., 2., 10.]).unwrap();
176 /// assert_eq!(Array::flat(vec![3., 4.321928094887363, 6.087462841250339, 8.965784284662087]), arr_1.log_add_exp2(&arr_2));
177 /// ```
178 ///
179 /// # Errors
180 ///
181 /// may returns `ArrayError`
182 fn log_add_exp2(&self, value: &Array<N>) -> Result<Array<N>, ArrayError>;
183}
184
185impl <N: Numeric> ArrayExpLog<N> for Array<N> {
186
187 fn exp(&self) -> Result<Self, ArrayError> {
188 self.map(|i| N::from(i.to_f64().exp()))
189 }
190
191 fn exp2(&self) -> Result<Self, ArrayError> {
192 self.map(|i| N::from(i.to_f64().exp2()))
193 }
194
195 fn exp_m1(&self) -> Result<Self, ArrayError> {
196 self.map(|i| N::from(i.to_f64().exp_m1()))
197 }
198
199 fn log(&self) -> Result<Self, ArrayError> {
200 self.logn(&Self::single(N::from(std::f64::consts::E)).unwrap())
201 }
202
203 fn log2(&self) -> Result<Self, ArrayError> {
204 self.map(|i| N::from(i.to_f64().log2()))
205 }
206
207 fn log10(&self) -> Result<Self, ArrayError> {
208 self.map(|i| N::from(i.to_f64().log10()))
209 }
210
211 fn log_1p(&self) -> Result<Self, ArrayError> {
212 self.map(|i| N::from(i.to_f64().ln_1p()))
213 }
214
215 fn logn(&self, value: &Self) -> Result<Self, ArrayError> {
216 let broadcasted = self.broadcast(value)?;
217 let elements = broadcasted.clone().into_iter()
218 .map(|tuple| N::from(tuple.0.to_f64().log(tuple.1.to_f64())))
219 .collect();
220 Self::new(elements, broadcasted.get_shape()?)
221 }
222
223 fn log_add_exp(&self, value: &Self) -> Result<Self, ArrayError> {
224 let broadcasted = self.broadcast(value)?;
225 let elements = broadcasted.clone().into_iter()
226 .map(|tuple| N::from((tuple.0.to_f64().exp() + tuple.1.to_f64().exp()).ln()))
227 .collect();
228 Self::new(elements, broadcasted.get_shape()?)
229 }
230
231 fn log_add_exp2(&self, value: &Self) -> Result<Self, ArrayError> {
232 let broadcasted = self.broadcast(value)?;
233 let elements = broadcasted.clone().into_iter()
234 .map(|tuple| N::from(tuple.0.to_f64().mul_add(tuple.0.to_f64(), tuple.1.to_f64().powi(2)).log2()))
235 .collect();
236 Self::new(elements, broadcasted.get_shape()?)
237 }
238}
239
240impl <N: Numeric> ArrayExpLog<N> for Result<Array<N>, ArrayError> {
241
242 fn exp(&self) -> Self {
243 self.clone()?.exp()
244 }
245
246 fn exp2(&self) -> Self {
247 self.clone()?.exp2()
248 }
249
250 fn exp_m1(&self) -> Self {
251 self.clone()?.exp_m1()
252 }
253
254 fn log(&self) -> Self {
255 self.clone()?.log()
256 }
257
258 fn log2(&self) -> Self {
259 self.clone()?.log2()
260 }
261
262 fn log10(&self) -> Self {
263 self.clone()?.log10()
264 }
265
266 fn log_1p(&self) -> Self {
267 self.clone()?.log_1p()
268 }
269
270 fn logn(&self, value: &Array<N>) -> Self {
271 self.clone()?.logn(value)
272 }
273
274 fn log_add_exp(&self, value: &Array<N>) -> Self {
275 self.clone()?.log_add_exp(value)
276 }
277
278 fn log_add_exp2(&self, value: &Array<N>) -> Self {
279 self.clone()?.log_add_exp2(value)
280 }
281}