chainrules/scalar_ad/
complex.rs1use super::ScalarAd;
2use num_complex::{Complex32, Complex64, ComplexFloat};
3use num_traits::{FloatConst, Zero};
4
5macro_rules! impl_scalar_ad_complex {
6 ($complex_ty:ty, $real_ty:ty, $one:expr) => {
7 impl ScalarAd for $complex_ty {
8 type Real = $real_ty;
9
10 fn conj(self) -> Self {
11 <$complex_ty>::conj(&self)
12 }
13
14 fn recip(self) -> Self {
15 <$complex_ty as ComplexFloat>::recip(self)
16 }
17
18 fn cbrt(self) -> Self {
19 <$complex_ty as ComplexFloat>::cbrt(self)
20 }
21
22 fn sqrt(self) -> Self {
23 <$complex_ty as ComplexFloat>::sqrt(self)
24 }
25
26 fn exp(self) -> Self {
27 <$complex_ty as ComplexFloat>::exp(self)
28 }
29
30 fn exp2(self) -> Self {
31 <$complex_ty as ComplexFloat>::exp2(self)
32 }
33
34 fn exp10(self) -> Self {
35 <$complex_ty as ComplexFloat>::exp(
36 self * <$complex_ty>::new(
37 <$real_ty as FloatConst>::LN_10(),
38 <$real_ty as Zero>::zero(),
39 ),
40 )
41 }
42
43 fn expm1(self) -> Self {
44 <$complex_ty as ComplexFloat>::exp(self) - $one
45 }
46
47 fn ln(self) -> Self {
48 <$complex_ty as ComplexFloat>::ln(self)
49 }
50
51 fn log1p(self) -> Self {
52 <$complex_ty as ComplexFloat>::ln(self + $one)
53 }
54
55 fn log2(self) -> Self {
56 <$complex_ty as ComplexFloat>::log2(self)
57 }
58
59 fn log10(self) -> Self {
60 <$complex_ty as ComplexFloat>::log10(self)
61 }
62
63 fn sin(self) -> Self {
64 <$complex_ty as ComplexFloat>::sin(self)
65 }
66
67 fn cos(self) -> Self {
68 <$complex_ty as ComplexFloat>::cos(self)
69 }
70
71 fn tan(self) -> Self {
72 <$complex_ty as ComplexFloat>::tan(self)
73 }
74
75 fn tanh(self) -> Self {
76 <$complex_ty as ComplexFloat>::tanh(self)
77 }
78
79 fn asin(self) -> Self {
80 <$complex_ty as ComplexFloat>::asin(self)
81 }
82
83 fn acos(self) -> Self {
84 <$complex_ty as ComplexFloat>::acos(self)
85 }
86
87 fn atan(self) -> Self {
88 <$complex_ty as ComplexFloat>::atan(self)
89 }
90
91 fn sinh(self) -> Self {
92 <$complex_ty as ComplexFloat>::sinh(self)
93 }
94
95 fn cosh(self) -> Self {
96 <$complex_ty as ComplexFloat>::cosh(self)
97 }
98
99 fn asinh(self) -> Self {
100 <$complex_ty as ComplexFloat>::asinh(self)
101 }
102
103 fn acosh(self) -> Self {
104 <$complex_ty as ComplexFloat>::acosh(self)
105 }
106
107 fn atanh(self) -> Self {
108 <$complex_ty as ComplexFloat>::atanh(self)
109 }
110
111 fn abs(self) -> Self::Real {
112 <$complex_ty as ComplexFloat>::abs(self)
113 }
114
115 fn abs2(self) -> Self::Real {
116 <$complex_ty>::norm_sqr(&self)
117 }
118
119 fn real(self) -> Self::Real {
120 self.re
121 }
122
123 fn imag(self) -> Self::Real {
124 self.im
125 }
126
127 fn angle(self) -> Self::Real {
128 <$complex_ty as ComplexFloat>::arg(self)
129 }
130
131 fn powf(self, exponent: Self::Real) -> Self {
132 <$complex_ty as ComplexFloat>::powf(self, exponent)
133 }
134
135 fn powi(self, exponent: i32) -> Self {
136 <$complex_ty as ComplexFloat>::powi(self, exponent)
137 }
138
139 fn pow(self, exponent: Self) -> Self {
140 <$complex_ty as ComplexFloat>::powc(self, exponent)
141 }
142
143 fn from_real(value: Self::Real) -> Self {
144 <$complex_ty>::new(value, 0.0)
145 }
146
147 fn from_i32(value: i32) -> Self {
148 <$complex_ty>::new(value as $real_ty, 0.0)
149 }
150 }
151 };
152}
153
154impl_scalar_ad_complex!(Complex32, f32, Complex32::new(1.0, 0.0));
155impl_scalar_ad_complex!(Complex64, f64, Complex64::new(1.0, 0.0));