1use super::Complex;
2
3use core::ops::Neg;
4#[cfg(feature = "std")]
5use traits::Float;
6use traits::{Num, One, Pow};
7
8macro_rules! pow_impl {
9 ($U:ty, $S:ty) => {
10 impl<'a, T: Clone + Num> Pow<$U> for &'a Complex<T> {
11 type Output = Complex<T>;
12
13 #[inline]
14 fn pow(self, mut exp: $U) -> Self::Output {
15 if exp == 0 {
16 return Complex::one();
17 }
18 let mut base = self.clone();
19
20 while exp & 1 == 0 {
21 base = base.clone() * base;
22 exp >>= 1;
23 }
24
25 if exp == 1 {
26 return base;
27 }
28
29 let mut acc = base.clone();
30 while exp > 1 {
31 exp >>= 1;
32 base = base.clone() * base;
33 if exp & 1 == 1 {
34 acc = acc * base.clone();
35 }
36 }
37 acc
38 }
39 }
40
41 impl<'a, 'b, T: Clone + Num> Pow<&'b $U> for &'a Complex<T> {
42 type Output = Complex<T>;
43
44 #[inline]
45 fn pow(self, exp: &$U) -> Self::Output {
46 self.pow(*exp)
47 }
48 }
49
50 impl<'a, T: Clone + Num + Neg<Output = T>> Pow<$S> for &'a Complex<T> {
51 type Output = Complex<T>;
52
53 #[inline]
54 fn pow(self, exp: $S) -> Self::Output {
55 if exp < 0 {
56 Pow::pow(&self.inv(), exp.wrapping_neg() as $U)
57 } else {
58 Pow::pow(self, exp as $U)
59 }
60 }
61 }
62
63 impl<'a, 'b, T: Clone + Num + Neg<Output = T>> Pow<&'b $S> for &'a Complex<T> {
64 type Output = Complex<T>;
65
66 #[inline]
67 fn pow(self, exp: &$S) -> Self::Output {
68 self.pow(*exp)
69 }
70 }
71 };
72}
73
74pow_impl!(u8, i8);
75pow_impl!(u16, i16);
76pow_impl!(u32, i32);
77pow_impl!(u64, i64);
78pow_impl!(usize, isize);
79#[cfg(has_i128)]
80pow_impl!(u128, i128);
81
82macro_rules! powf_impl {
88 ($F:ty) => {
89 #[cfg(feature = "std")]
90 impl<'a, T: Float> Pow<$F> for &'a Complex<T>
91 where
92 $F: Into<T>,
93 {
94 type Output = Complex<T>;
95
96 #[inline]
97 fn pow(self, exp: $F) -> Self::Output {
98 self.powf(exp.into())
99 }
100 }
101
102 #[cfg(feature = "std")]
103 impl<'a, 'b, T: Float> Pow<&'b $F> for &'a Complex<T>
104 where
105 $F: Into<T>,
106 {
107 type Output = Complex<T>;
108
109 #[inline]
110 fn pow(self, &exp: &$F) -> Self::Output {
111 self.powf(exp.into())
112 }
113 }
114
115 #[cfg(feature = "std")]
116 impl<T: Float> Pow<$F> for Complex<T>
117 where
118 $F: Into<T>,
119 {
120 type Output = Complex<T>;
121
122 #[inline]
123 fn pow(self, exp: $F) -> Self::Output {
124 self.powf(exp.into())
125 }
126 }
127
128 #[cfg(feature = "std")]
129 impl<'b, T: Float> Pow<&'b $F> for Complex<T>
130 where
131 $F: Into<T>,
132 {
133 type Output = Complex<T>;
134
135 #[inline]
136 fn pow(self, &exp: &$F) -> Self::Output {
137 self.powf(exp.into())
138 }
139 }
140 };
141}
142
143powf_impl!(f32);
144powf_impl!(f64);
145
146#[cfg(feature = "std")]
150impl<'a, T: Float> Pow<Complex<T>> for &'a Complex<T> {
151 type Output = Complex<T>;
152
153 #[inline]
154 fn pow(self, exp: Complex<T>) -> Self::Output {
155 self.powc(exp)
156 }
157}
158
159#[cfg(feature = "std")]
160impl<'a, 'b, T: Float> Pow<&'b Complex<T>> for &'a Complex<T> {
161 type Output = Complex<T>;
162
163 #[inline]
164 fn pow(self, &exp: &'b Complex<T>) -> Self::Output {
165 self.powc(exp)
166 }
167}
168
169#[cfg(feature = "std")]
170impl<T: Float> Pow<Complex<T>> for Complex<T> {
171 type Output = Complex<T>;
172
173 #[inline]
174 fn pow(self, exp: Complex<T>) -> Self::Output {
175 self.powc(exp)
176 }
177}
178
179#[cfg(feature = "std")]
180impl<'b, T: Float> Pow<&'b Complex<T>> for Complex<T> {
181 type Output = Complex<T>;
182
183 #[inline]
184 fn pow(self, &exp: &'b Complex<T>) -> Self::Output {
185 self.powc(exp)
186 }
187}