mixed_num/traits/
math_traits.rs

1use crate::*;
2
3pub trait MixedOps
4    where Self: MixedNumConversion<i32> + MixedNumConversion<i64>
5                + MixedNumConversion<f32> + MixedNumConversion<f64>
6                + core::cmp::PartialOrd
7                + core::marker::Sized
8                + core::ops::AddAssign
9                + core::ops::SubAssign
10                + core::ops::MulAssign
11                + num::traits::NumOps
12                + Copy
13{
14}
15
16pub trait MixedAbs
17{
18    /// Absolute value.
19    fn mixed_abs( &self ) -> Self;
20}
21
22pub trait MixedPowi
23{
24    /// Integer valued power.
25    fn mixed_powi( &self, exp: i32 ) -> Self;
26}
27
28pub trait MixedWrapPhase
29{
30    /// Wrapps `self` to the -π=<x<π range.
31    fn mixed_wrap_phase(&self) -> Self;
32}
33
34pub trait MixedTan
35{
36    /// Take the tan of `self`. Implementation varies with type.
37    fn mixed_tan(&self) -> Self;
38}
39
40pub trait MixedTanh
41{
42    /// Take the hyperbolic tangent (tanh) of `self`. Implementation varies with type.
43    fn mixed_tanh(&self) -> Self;
44    /// Take the inverse hyperbolic tangent (atanh) of `self`. Implementation varies with type.
45    fn mixed_atanh(&self) -> Self;
46}
47
48pub trait MixedAtan
49{
50    /// Take the atan of `self`. Implementation varies with type.
51    fn mixed_atan(&self) -> Self;
52    /// Take the atan2 of `self`/other. Implementation varies with type.
53    fn mixed_atan2(&self, other:Self) -> Self;
54    /// Calculate atan2(y,x) using a selection of polynomial approximations, one for each octant in the unit circle.
55    /// 
56    /// The method is accurat within 0.028 degrees.
57    /// 
58    /// \[1\] R. G. Lyons, Streamlining Digital Signal Processing, Second Edition, IEEE Press, 2012.
59    /// 
60    /// ## Comparisons
61    /// 
62    /// The figure below shows the comparison between the various implementations and the `std::f32::atan` implementation.
63    /// 
64    /// ![Alt version](https://github.com/ErikBuer/Fixed-Trigonometry/blob/main/figures/atan2_comparisons.png?raw=true)
65    /// 
66    fn mixed_atan2_poly(&self, other:Self) -> Self;
67}
68
69pub trait MixedSin
70{
71    /// Take the sin of `self`. Implementation varies with type.
72    fn mixed_sin(&self) -> Self;
73    /// Calculate the sin and cos of `self`. Implementation varies with type.
74    fn mixed_sincos(&self) -> (Self, Self) where Self:Sized;
75    /// Take the arcsin of `self`. Implementation varies with type.
76    fn mixed_asin(&self) -> Self;
77}
78
79pub trait MixedSinh
80{
81    /// Take the hyperbolic sin of `self`. Implementation varies with type.
82    fn mixed_sinh(&self) -> Self;
83    /// Take the inverse hyperbolic sin of `self`. Implementation varies with type.
84    fn mixed_asinh(&self) -> Self;
85}
86
87pub trait MixedCos
88{
89    /// Take the cos of `self`. Implementation varies with type.
90    fn mixed_cos(&self) -> Self;
91    /// Take the arccos of `self`. Implementation varies with type.
92    fn mixed_acos(&self) -> Self;
93}
94
95pub trait MixedCosh
96{
97    /// Take the cosh of `self`. Implementation varies with type.
98    fn mixed_cosh(&self) -> Self;
99    /// Take the arccosh of `self`. Implementation varies with type.
100    fn mixed_acosh(&self) -> Self;
101}
102
103// Trait kept for legacy reasons
104pub trait MixedTrigonometry: MixedSin + MixedCos + MixedAtan
105{
106}
107
108pub trait MixedExp
109{
110    /// Take the exponential, base e, of `self`.
111    fn mixed_exp(&self) -> Self;
112}
113
114pub trait MixedSqrt
115{
116    /// The generic square root implementation for the `MixedSqrt` trait.
117    fn mixed_sqrt(&self) -> Self;
118    /// A fast implementation of the square root using the Nonlinear IIR Filter (NIIRF) method \[1\].
119    /// 
120    /// Only valid for positive values of `self`. Negative values are forced positive before converison.
121    /// Accurate to 5*10⁻⁴ with two iterations \[2\].
122    /// 
123    /// The structure of the estimator is illustrated below \[1\].
124    /// 
125    /// ![Alt version](https://raw.githubusercontent.com/ErikBuer/Fixed-Trigonometry/main/figures/niirf.svg)
126    /// 
127    /// The method utilizes a lookup-table for the acceleration factor β.
128    /// 
129    /// β(x) can be calculated from the following formula, yielding even greater accuracy at a computational cost.
130    /// ```Julia
131    /// β(x) = 0.763x^2-1.5688x+1.314 
132    /// ```
133    /// 
134    /// \[1\] N.Mikami et al., A new DSP-oriented algorithm for calculation of square root using a non-linear digital filter, IEEE Trans. on Signal Processing, July 1992, pp. 1663-1669.
135    /// 
136    /// \[2\] R. G. Lyons, Streamlining Digital Signal Processing, Second Edition, IEEE Press, 2012.
137    /// 
138    /// 
139    /// ## Accuracy and Comparison
140    /// 
141    /// The figure below shows error of the NIIRF implementation, compared to the `std::f32::sqrt` implementation.
142    /// 
143    /// ![Alt version](https://github.com/ErikBuer/Fixed-Trigonometry/blob/main/figures/niirf_sqrt_comparison.png?raw=true)
144    /// 
145    /// Another fixed point implementation of the square root can be found in the cordic crate. 
146    /// 
147    /// Below is the error comparison between the two implementations.
148    /// 
149    /// ![Alt version](https://github.com/ErikBuer/Fixed-Trigonometry/blob/main/figures/sqrt_error_comparison.png?raw=true)
150    fn mixed_niirf(&self) -> Self;
151}
152
153pub trait MixedCbrt
154{
155    /// Take the cube root of self.
156    fn mixed_cbrt(&self) -> Self;
157}
158
159pub trait MixedExp10
160{
161    /// Take the exponential, base 10, of `self`.
162    fn mixed_exp10(&self) -> Self;
163}
164
165pub trait MixedExp2
166{
167    /// Take the exponential, base 10, of `self`.
168    fn mixed_exp2(&self) -> Self;
169}
170
171pub trait MixedPow
172{
173    /// Take the exponential, base 10, of `self`.
174    fn mixed_pow(&self, power:Self) -> Self;
175}
176
177pub trait Mixedlog
178{
179    /// Take natural logarithm, of `self`.
180    fn mixed_log(&self) -> Self;
181}
182
183pub trait Mixedlog10
184{
185    /// Take base 10 logarithm, of `self`.
186    fn mixed_log10(&self) -> Self;
187}
188
189pub trait Mixedlog2
190{
191    /// Take base 2 logarithm, of `self`.
192    fn mixed_log2(&self) -> Self;
193}
194
195pub trait DbMag
196{
197    /// Convert between magnitude in linear scale and Decibel (dB).
198    fn mixed_mag2db(&self) -> Self;
199    /// Convert between Decibell (dB) and linear scale magnitude.
200    fn mixed_db2mag(&self) -> Self;
201}
202
203pub trait DbPow
204{
205    /// Convert between power in linear scale and Decibel (dB).
206    fn mixed_pow2db(&self) -> Self;
207    /// Convert between Decibell (dB) and linear scale power.
208    fn mixed_db2pow(&self) -> Self;
209}