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}