1
1
// Keeps us from accidentally creating a recursive impl rather than a real one.
2
2
#![ deny( unconditional_recursion) ]
3
+ #![ cfg( any( feature = "std" , feature = "libm" ) ) ]
3
4
4
- use num_traits:: { float:: FloatCore , Float , FloatConst } ;
5
+ use core:: ops:: Neg ;
6
+
7
+ use num_traits:: { float:: FloatCore , Float , FloatConst , Num , NumCast , Signed } ;
5
8
6
9
use crate :: Complex ;
7
10
11
+ mod private {
12
+ use num_traits:: { float:: FloatCore , Float , FloatConst , Signed } ;
13
+
14
+ use crate :: Complex ;
15
+
16
+ pub trait Seal { }
17
+
18
+ impl < T > Seal for T where T : Float + FloatConst { }
19
+ impl < T : Float + FloatCore + FloatConst + Signed > Seal for Complex < T > { }
20
+ }
21
+
8
22
/// Generic trait for floating point complex numbers
9
23
/// This trait defines methods which are common to complex floating point numbers and regular floating point numbers.
10
- #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
11
- pub trait ComplexFloat {
12
- type Real ;
24
+ /// This trait is sealed to prevent it from being implemented by anything other than floating point scalars and [Complex] floats.
25
+ pub trait ComplexFloat : Num + NumCast + Copy + Neg < Output = Self > + private:: Seal {
26
+ /// The type used to represent the real coefficients of this complex number.
27
+ type Real : Float + FloatConst ;
13
28
14
29
/// Returns `true` if this value is `NaN` and false otherwise.
15
30
fn is_nan ( self ) -> bool ;
@@ -22,11 +37,10 @@ pub trait ComplexFloat {
22
37
fn is_finite ( self ) -> bool ;
23
38
24
39
/// Returns `true` if the number is neither zero, infinite,
25
- /// [subnormal][subnormal], or `NaN`.
26
- /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
40
+ /// [subnormal](http://en.wikipedia.org/wiki/Denormal_number), or `NaN`.
27
41
fn is_normal ( self ) -> bool ;
28
42
29
- /// Take the reciprocal (inverse) of a number, `1/x`.
43
+ /// Take the reciprocal (inverse) of a number, `1/x`. See also [Complex::finv].
30
44
fn recip ( self ) -> Self ;
31
45
32
46
/// Raises `self` to a signed integer power.
@@ -47,6 +61,9 @@ pub trait ComplexFloat {
47
61
/// Returns `2^(self)`.
48
62
fn exp2 ( self ) -> Self ;
49
63
64
+ /// Returns `base^(self)`.
65
+ fn expf ( self , base : Self :: Real ) -> Self ;
66
+
50
67
/// Returns the natural logarithm of the number.
51
68
fn ln ( self ) -> Self ;
52
69
@@ -106,16 +123,21 @@ pub trait ComplexFloat {
106
123
/// Returns the real part of the number.
107
124
fn re ( self ) -> Self :: Real ;
108
125
109
- /// Returns the imaginary part of the number which equals to zero .
126
+ /// Returns the imaginary part of the number.
110
127
fn im ( self ) -> Self :: Real ;
111
128
112
- /// Returns the absolute value of the number.
129
+ /// Returns the absolute value of the number. See also [Complex::norm]
113
130
fn abs ( self ) -> Self :: Real ;
114
131
132
+ /// Returns the L1 norm `|re| + |im|` -- the [Manhattan distance] from the origin.
133
+ ///
134
+ /// [Manhattan distance]: https://en.wikipedia.org/wiki/Taxicab_geometry
135
+ fn l1_norm ( & self ) -> Self :: Real ;
136
+
115
137
/// Computes the argument of the number.
116
138
fn arg ( self ) -> Self :: Real ;
117
139
118
- /// Comutes the complex conjugate of `self` .
140
+ /// Computes the complex conjugate of the number .
119
141
///
120
142
/// Formula: `a+bi -> a-bi`
121
143
fn conj ( self ) -> Self ;
@@ -141,7 +163,6 @@ macro_rules! forward_ref {
141
163
) * } ;
142
164
}
143
165
144
- #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
145
166
impl < T > ComplexFloat for T
146
167
where
147
168
T : Float + FloatConst ,
@@ -156,7 +177,7 @@ where
156
177
T :: zero ( )
157
178
}
158
179
159
- fn abs ( self ) -> Self :: Real {
180
+ fn l1_norm ( & self ) -> Self :: Real {
160
181
self . abs ( )
161
182
}
162
183
@@ -178,6 +199,10 @@ where
178
199
self
179
200
}
180
201
202
+ fn expf ( self , base : Self :: Real ) -> Self {
203
+ base. powf ( self )
204
+ }
205
+
181
206
forward ! {
182
207
Float :: is_normal( self ) -> bool ;
183
208
Float :: is_infinite( self ) -> bool ;
@@ -206,11 +231,11 @@ where
206
231
Float :: asinh( self ) -> Self ;
207
232
Float :: acosh( self ) -> Self ;
208
233
Float :: atanh( self ) -> Self ;
234
+ Float :: abs( self ) -> Self ;
209
235
}
210
236
}
211
237
212
- #[ cfg( any( feature = "std" , feature = "libm" ) ) ]
213
- impl < T : Float + FloatCore + FloatConst > ComplexFloat for Complex < T > {
238
+ impl < T : Float + FloatCore + FloatConst + Signed > ComplexFloat for Complex < T > {
214
239
type Real = T ;
215
240
216
241
fn re ( self ) -> Self :: Real {
@@ -229,6 +254,10 @@ impl<T: Float + FloatCore + FloatConst> ComplexFloat for Complex<T> {
229
254
self . finv ( )
230
255
}
231
256
257
+ fn l1_norm ( & self ) -> Self :: Real {
258
+ Complex :: l1_norm ( self )
259
+ }
260
+
232
261
forward ! {
233
262
Complex :: arg( self ) -> Self :: Real ;
234
263
Complex :: powc( self , exp: Complex <Self :: Real >) -> Complex <Self :: Real >;
@@ -244,6 +273,7 @@ impl<T: Float + FloatCore + FloatConst> ComplexFloat for Complex<T> {
244
273
Complex :: sqrt( self ) -> Self ;
245
274
Complex :: cbrt( self ) -> Self ;
246
275
Complex :: exp( self ) -> Self ;
276
+ Complex :: expf( self , base: Self :: Real ) -> Self ;
247
277
Complex :: ln( self ) -> Self ;
248
278
Complex :: sin( self ) -> Self ;
249
279
Complex :: cos( self ) -> Self ;
0 commit comments