11 #ifndef EIGEN_COMPLEX_GPU_H
12 #define EIGEN_COMPLEX_GPU_H
33 #if defined(EIGEN_GPUCC) && defined(EIGEN_GPU_COMPILE_PHASE)
42 #if !(EIGEN_COMP_ICC && defined(_USE_COMPLEX_SPECIALIZATION_))
45 #define EIGEN_USING_STD_COMPLEX_OPERATORS \
46 using Eigen::complex_operator_detail::operator+; \
47 using Eigen::complex_operator_detail::operator-; \
48 using Eigen::complex_operator_detail::operator*; \
49 using Eigen::complex_operator_detail::operator/; \
50 using Eigen::complex_operator_detail::operator+=; \
51 using Eigen::complex_operator_detail::operator-=; \
52 using Eigen::complex_operator_detail::operator*=; \
53 using Eigen::complex_operator_detail::operator/=; \
54 using Eigen::complex_operator_detail::operator==; \
55 using Eigen::complex_operator_detail::operator!=;
57 #include "../../InternalHeaderCheck.h"
62 namespace complex_operator_detail {
66 std::complex<T> complex_multiply(
const std::complex<T>&
a,
const std::complex<T>&
b) {
71 return std::complex<T>(
72 a_real * b_real - a_imag * b_imag,
73 a_imag * b_real + a_real * b_imag);
78 std::complex<T> complex_divide_fast(
const std::complex<T>&
a,
const std::complex<T>&
b) {
83 const T norm = (b_real * b_real + b_imag * b_imag);
84 return std::complex<T>((a_real * b_real + a_imag * b_imag) / norm,
85 (a_imag * b_real - a_real * b_imag) / norm);
90 std::complex<T> complex_divide_stable(
const std::complex<T>&
a,
const std::complex<T>&
b) {
98 const T rscale = scale_imag ?
T(1) : b_real / b_imag;
99 const T iscale = scale_imag ? b_imag / b_real :
T(1);
100 const T denominator = b_real * rscale + b_imag * iscale;
101 return std::complex<T>((a_real * rscale + a_imag * iscale) / denominator,
102 (a_imag * rscale - a_real * iscale) / denominator);
107 std::complex<T> complex_divide(
const std::complex<T>&
a,
const std::complex<T>&
b) {
109 return complex_divide_fast(
a,
b);
111 return complex_divide_stable(
a,
b);
120 #define EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(T) \
122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
123 std::complex<T> operator+(const std::complex<T>& a) { return a; } \
125 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
126 std::complex<T> operator-(const std::complex<T>& a) { \
127 return std::complex<T>(-numext::real(a), -numext::imag(a)); \
130 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
131 std::complex<T> operator+(const std::complex<T>& a, const std::complex<T>& b) { \
132 return std::complex<T>(numext::real(a) + numext::real(b), numext::imag(a) + numext::imag(b)); \
135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
136 std::complex<T> operator+(const std::complex<T>& a, const T& b) { \
137 return std::complex<T>(numext::real(a) + b, numext::imag(a)); \
140 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
141 std::complex<T> operator+(const T& a, const std::complex<T>& b) { \
142 return std::complex<T>(a + numext::real(b), numext::imag(b)); \
145 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
146 std::complex<T> operator-(const std::complex<T>& a, const std::complex<T>& b) { \
147 return std::complex<T>(numext::real(a) - numext::real(b), numext::imag(a) - numext::imag(b)); \
150 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
151 std::complex<T> operator-(const std::complex<T>& a, const T& b) { \
152 return std::complex<T>(numext::real(a) - b, numext::imag(a)); \
155 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
156 std::complex<T> operator-(const T& a, const std::complex<T>& b) { \
157 return std::complex<T>(a - numext::real(b), -numext::imag(b)); \
160 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
161 std::complex<T> operator*(const std::complex<T>& a, const std::complex<T>& b) { \
162 return complex_multiply(a, b); \
165 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
166 std::complex<T> operator*(const std::complex<T>& a, const T& b) { \
167 return std::complex<T>(numext::real(a) * b, numext::imag(a) * b); \
170 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
171 std::complex<T> operator*(const T& a, const std::complex<T>& b) { \
172 return std::complex<T>(a * numext::real(b), a * numext::imag(b)); \
175 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
176 std::complex<T> operator/(const std::complex<T>& a, const std::complex<T>& b) { \
177 return complex_divide(a, b); \
180 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
181 std::complex<T> operator/(const std::complex<T>& a, const T& b) { \
182 return std::complex<T>(numext::real(a) / b, numext::imag(a) / b); \
185 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
186 std::complex<T> operator/(const T& a, const std::complex<T>& b) { \
187 return complex_divide(std::complex<T>(a, 0), b); \
190 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
191 std::complex<T>& operator+=(std::complex<T>& a, const std::complex<T>& b) { \
192 numext::real_ref(a) += numext::real(b); \
193 numext::imag_ref(a) += numext::imag(b); \
197 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
198 std::complex<T>& operator-=(std::complex<T>& a, const std::complex<T>& b) { \
199 numext::real_ref(a) -= numext::real(b); \
200 numext::imag_ref(a) -= numext::imag(b); \
204 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
205 std::complex<T>& operator*=(std::complex<T>& a, const std::complex<T>& b) { \
206 a = complex_multiply(a, b); \
210 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
211 std::complex<T>& operator/=(std::complex<T>& a, const std::complex<T>& b) { \
212 a = complex_divide(a, b); \
216 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
217 bool operator==(const std::complex<T>& a, const std::complex<T>& b) { \
218 return numext::real(a) == numext::real(b) && numext::imag(a) == numext::imag(b); \
221 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
222 bool operator==(const std::complex<T>& a, const T& b) { \
223 return numext::real(a) == b && numext::imag(a) == 0; \
226 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
227 bool operator==(const T& a, const std::complex<T>& b) { \
228 return a == numext::real(b) && 0 == numext::imag(b); \
231 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
232 bool operator!=(const std::complex<T>& a, const std::complex<T>& b) { \
236 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
237 bool operator!=(const std::complex<T>& a, const T& b) { \
241 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE \
242 bool operator!=(const T& a, const std::complex<T>& b) { \
247 EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(
float)
248 EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(
double)
250 #undef EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS
255 EIGEN_USING_STD_COMPLEX_OPERATORS
258 EIGEN_USING_STD_COMPLEX_OPERATORS
262 EIGEN_USING_STD_COMPLEX_OPERATORS
const ImagReturnType imag() const
RealReturnType real() const
#define EIGEN_DEVICE_FUNC
Eigen::Triplet< double > T
EIGEN_ALWAYS_INLINE std::enable_if_t< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real > abs(const T &x)