@@ -35,7 +35,7 @@ pub type Complex = Cmplx<float>;
3535pub type Complex32 = Cmplx < f32 > ;
3636pub type Complex64 = Cmplx < f64 > ;
3737
38- impl < T : Copy + Num > Cmplx < T > {
38+ impl < T : Clone + Num > Cmplx < T > {
3939 /// Create a new Cmplx
4040 #[ inline]
4141 pub fn new ( re : T , im : T ) -> Cmplx < T > {
@@ -55,7 +55,7 @@ impl<T: Copy + Num> Cmplx<T> {
5555 /// Returns the complex conjugate. i.e. `re - i im`
5656 #[ inline]
5757 pub fn conj ( & self ) -> Cmplx < T > {
58- Cmplx :: new ( self . re , -self . im )
58+ Cmplx :: new ( self . re . clone ( ) , -self . im )
5959 }
6060
6161
@@ -80,62 +80,91 @@ impl<T: Copy + Num> Cmplx<T> {
8080 }
8181}
8282
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+
83112/* arithmetic */
84113// (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 > {
86115 #[ inline]
87116 fn add ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
88117 Cmplx :: new ( self . re + other. re , self . im + other. im )
89118 }
90119}
91120// (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 > {
93122 #[ inline]
94123 fn sub ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
95124 Cmplx :: new ( self . re - other. re , self . im - other. im )
96125 }
97126}
98127// (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 > {
100129 #[ inline]
101130 fn mul ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
102131 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 )
104133 }
105134}
106135
107136// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
108137// == [(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 > {
110139 #[ inline]
111140 fn div ( & self , other : & Cmplx < T > ) -> Cmplx < T > {
112141 let norm_sqr = other. norm_sqr ( ) ;
113142 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)
115144 }
116145}
117146
118- impl < T : Copy + Num > Neg < Cmplx < T > > for Cmplx < T > {
147+ impl < T : Clone + Num > Neg < Cmplx < T > > for Cmplx < T > {
119148 #[ inline]
120149 fn neg ( & self ) -> Cmplx < T > {
121150 Cmplx :: new ( -self . re , -self . im )
122151 }
123152}
124153
125154/* constants */
126- impl < T : Copy + Num > Zero for Cmplx < T > {
155+ impl < T : Clone + Num > Zero for Cmplx < T > {
127156 #[ inline]
128157 fn zero ( ) -> Cmplx < T > {
129158 Cmplx :: new ( Zero :: zero ( ) , Zero :: zero ( ) )
130159 }
131160
132161 #[ inline]
133162 fn is_zero ( & self ) -> bool {
134- * self == Zero :: zero ( )
163+ self . re . is_zero ( ) && self . im . is_zero ( )
135164 }
136165}
137166
138- impl < T : Copy + Num > One for Cmplx < T > {
167+ impl < T : Clone + Num > One for Cmplx < T > {
139168 #[ inline]
140169 fn one ( ) -> Cmplx < T > {
141170 Cmplx :: new ( One :: one ( ) , Zero :: zero ( ) )
@@ -166,7 +195,7 @@ impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
166195#[ cfg( test) ]
167196mod test {
168197 use super :: * ;
169- use core:: num:: { Zero , One } ;
198+ use core:: num:: { Zero , One , Real } ;
170199
171200 pub static _0_0i : Complex = Cmplx { re : 0 f, im : 0 f } ;
172201 pub static _1_0i : Complex = Cmplx { re : 1 f, im : 0 f } ;
@@ -193,9 +222,10 @@ mod test {
193222 }
194223
195224 #[ test]
196- fn test_norm_sqr ( ) {
225+ fn test_norm ( ) {
197226 fn test ( c : Complex , ns : float ) {
198227 assert_eq ! ( c. norm_sqr( ) , ns) ;
228+ assert_eq ! ( c. norm( ) , ns. sqrt( ) )
199229 }
200230 test ( _0_0i, 0 f) ;
201231 test ( _1_0i, 1 f) ;
@@ -235,6 +265,25 @@ mod test {
235265 _0_0i. inv ( ) ;
236266 }
237267
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+ }
238287
239288 mod arith {
240289 use super :: * ;
0 commit comments