@@ -35,7 +35,7 @@ pub type Complex = Cmplx<float>;
35
35
pub type Complex32 = Cmplx < f32 > ;
36
36
pub type Complex64 = Cmplx < f64 > ;
37
37
38
- impl < T : Copy + Num > Cmplx < T > {
38
+ impl < T : Clone + Num > Cmplx < T > {
39
39
/// Create a new Cmplx
40
40
#[ inline]
41
41
pub fn new ( re : T , im : T ) -> Cmplx < T > {
@@ -55,7 +55,7 @@ impl<T: Copy + Num> Cmplx<T> {
55
55
/// Returns the complex conjugate. i.e. `re - i im`
56
56
#[ inline]
57
57
pub fn conj ( & self ) -> Cmplx < T > {
58
- Cmplx :: new ( self . re , -self . im )
58
+ Cmplx :: new ( self . re . clone ( ) , -self . im )
59
59
}
60
60
61
61
@@ -80,62 +80,91 @@ impl<T: Copy + Num> Cmplx<T> {
80
80
}
81
81
}
82
82
83
+ #[ cfg( not( stage0) ) ] // Fixed by #4228
84
+ impl < T : Clone + Algebraic + Num > Cmplx < T > {
85
+ /// Calculate |self|
86
+ #[ inline( always) ]
87
+ pub fn norm ( & self ) -> T {
88
+ self . re . hypot ( & self . im )
89
+ }
90
+ }
91
+
92
+ #[ cfg( not( stage0) ) ] // Fixed by #4228
93
+ impl < T : Clone + Trigonometric + Algebraic + Num > Cmplx < T > {
94
+ /// Calculate the principal Arg of self.
95
+ #[ inline( always) ]
96
+ pub fn arg ( & self ) -> T {
97
+ self . im . atan2 ( & self . re )
98
+ }
99
+ /// Convert to polar form (r, theta), such that `self = r * exp(i
100
+ /// * theta)`
101
+ #[ inline]
102
+ pub fn to_polar ( & self ) -> ( T , T ) {
103
+ ( self . norm ( ) , self . arg ( ) )
104
+ }
105
+ /// Convert a polar representation into a complex number.
106
+ #[ inline]
107
+ pub fn from_polar ( r : & T , theta : & T ) -> Cmplx < T > {
108
+ Cmplx :: new ( r * theta. cos ( ) , r * theta. sin ( ) )
109
+ }
110
+ }
111
+
83
112
/* arithmetic */
84
113
// (a + i b) + (c + i d) == (a + c) + i (b + d)
85
- impl < T : Copy + Num > Add < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
114
+ impl < T : Clone + Num > Add < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
86
115
#[ inline]
87
116
fn add ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
88
117
Cmplx :: new ( self . re + other. re , self . im + other. im )
89
118
}
90
119
}
91
120
// (a + i b) - (c + i d) == (a - c) + i (b - d)
92
- impl < T : Copy + Num > Sub < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
121
+ impl < T : Clone + Num > Sub < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
93
122
#[ inline]
94
123
fn sub ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
95
124
Cmplx :: new ( self . re - other. re , self . im - other. im )
96
125
}
97
126
}
98
127
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
99
- impl < T : Copy + Num > Mul < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
128
+ impl < T : Clone + Num > Mul < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
100
129
#[ inline]
101
130
fn mul ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
102
131
Cmplx :: new ( self . re * other. re - self . im * other. im ,
103
- self . re * other. im + self . im * other. re )
132
+ self . re * other. im + self . im * other. re )
104
133
}
105
134
}
106
135
107
136
// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
108
137
// == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
109
- impl < T : Copy + Num > Div < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
138
+ impl < T : Clone + Num > Div < Cmplx < T > , Cmplx < T > > for Cmplx < T > {
110
139
#[ inline]
111
140
fn div ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
112
141
let norm_sqr = other. norm_sqr ( ) ;
113
142
Cmplx :: new ( ( self . re * other. re + self . im * other. im ) / norm_sqr,
114
- ( self . im * other. re - self . re * other. im ) / norm_sqr)
143
+ ( self . im * other. re - self . re * other. im ) / norm_sqr)
115
144
}
116
145
}
117
146
118
- impl < T : Copy + Num > Neg < Cmplx < T > > for Cmplx < T > {
147
+ impl < T : Clone + Num > Neg < Cmplx < T > > for Cmplx < T > {
119
148
#[ inline]
120
149
fn neg ( & self ) -> Cmplx < T > {
121
150
Cmplx :: new ( -self . re , -self . im )
122
151
}
123
152
}
124
153
125
154
/* constants */
126
- impl < T : Copy + Num > Zero for Cmplx < T > {
155
+ impl < T : Clone + Num > Zero for Cmplx < T > {
127
156
#[ inline]
128
157
fn zero ( ) -> Cmplx < T > {
129
158
Cmplx :: new ( Zero :: zero ( ) , Zero :: zero ( ) )
130
159
}
131
160
132
161
#[ inline]
133
162
fn is_zero ( & self ) -> bool {
134
- * self == Zero :: zero ( )
163
+ self . re . is_zero ( ) && self . im . is_zero ( )
135
164
}
136
165
}
137
166
138
- impl < T : Copy + Num > One for Cmplx < T > {
167
+ impl < T : Clone + Num > One for Cmplx < T > {
139
168
#[ inline]
140
169
fn one ( ) -> Cmplx < T > {
141
170
Cmplx :: new ( One :: one ( ) , Zero :: zero ( ) )
@@ -166,7 +195,7 @@ impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
166
195
#[ cfg( test) ]
167
196
mod test {
168
197
use super :: * ;
169
- use core:: num:: { Zero , One } ;
198
+ use core:: num:: { Zero , One , Real } ;
170
199
171
200
pub static _0_0i : Complex = Cmplx { re : 0 f, im : 0 f } ;
172
201
pub static _1_0i : Complex = Cmplx { re : 1 f, im : 0 f } ;
@@ -193,9 +222,10 @@ mod test {
193
222
}
194
223
195
224
#[ test]
196
- fn test_norm_sqr ( ) {
225
+ fn test_norm ( ) {
197
226
fn test ( c : Complex , ns : float ) {
198
227
assert_eq ! ( c. norm_sqr( ) , ns) ;
228
+ assert_eq ! ( c. norm( ) , ns. sqrt( ) )
199
229
}
200
230
test ( _0_0i, 0 f) ;
201
231
test ( _1_0i, 1 f) ;
@@ -235,6 +265,25 @@ mod test {
235
265
_0_0i. inv ( ) ;
236
266
}
237
267
268
+ #[ test]
269
+ fn test_arg ( ) {
270
+ fn test ( c : Complex , arg : float ) {
271
+ assert ! ( c. arg( ) . approx_eq( & arg) )
272
+ }
273
+ test ( _1_0i, 0 f) ;
274
+ test ( _1_1i, 0.25 f * Real :: pi ( ) ) ;
275
+ test ( _neg1_1i, 0.75 f * Real :: pi ( ) ) ;
276
+ test ( _05_05i, 0.25 f * Real :: pi ( ) ) ;
277
+ }
278
+
279
+ #[ test]
280
+ fn test_polar_conv ( ) {
281
+ fn test ( c : Complex ) {
282
+ let ( r, theta) = c. to_polar ( ) ;
283
+ assert ! ( ( c - Cmplx :: from_polar( & r, & theta) ) . norm( ) < 1e-6 ) ;
284
+ }
285
+ for all_consts. each |& c| { test ( c) ; }
286
+ }
238
287
239
288
mod arith {
240
289
use super :: * ;
0 commit comments