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!=; 58 #include "../../InternalHeaderCheck.h" 63 namespace complex_operator_detail {
66 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> complex_multiply(
const std::complex<T>& a,
67 const std::complex<T>& b) {
68 const T a_real = numext::real(a);
69 const T a_imag = numext::imag(a);
70 const T b_real = numext::real(b);
71 const T b_imag = numext::imag(b);
72 return std::complex<T>(a_real * b_real - a_imag * b_imag, a_imag * b_real + a_real * b_imag);
76 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> complex_divide_fast(
const std::complex<T>& a,
77 const std::complex<T>& b) {
78 const T a_real = numext::real(a);
79 const T a_imag = numext::imag(a);
80 const T b_real = numext::real(b);
81 const T b_imag = numext::imag(b);
82 const T norm = (b_real * b_real + b_imag * b_imag);
83 return std::complex<T>((a_real * b_real + a_imag * b_imag) / norm, (a_imag * b_real - a_real * b_imag) / norm);
87 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> complex_divide_stable(
const std::complex<T>& a,
88 const std::complex<T>& b) {
89 const T a_real = numext::real(a);
90 const T a_imag = numext::imag(a);
91 const T b_real = numext::real(b);
92 const T b_imag = numext::imag(b);
95 const bool scale_imag = numext::abs(b_imag) <= numext::abs(b_real);
96 const T rscale = scale_imag ? T(1) : b_real / b_imag;
97 const T iscale = scale_imag ? b_imag / b_real : T(1);
98 const T denominator = b_real * rscale + b_imag * iscale;
99 return std::complex<T>((a_real * rscale + a_imag * iscale) / denominator,
100 (a_imag * rscale - a_real * iscale) / denominator);
103 template <
typename T>
104 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> complex_divide(
const std::complex<T>& a,
105 const std::complex<T>& b) {
107 return complex_divide_fast(a, b);
109 return complex_divide_stable(a, b);
118 #define EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(T) \ 120 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator+(const std::complex<T>& a) { return a; } \ 122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator-(const std::complex<T>& a) { \ 123 return std::complex<T>(-numext::real(a), -numext::imag(a)); \ 126 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator+(const std::complex<T>& a, \ 127 const std::complex<T>& b) { \ 128 return std::complex<T>(numext::real(a) + numext::real(b), numext::imag(a) + numext::imag(b)); \ 131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator+(const std::complex<T>& a, const T& b) { \ 132 return std::complex<T>(numext::real(a) + b, numext::imag(a)); \ 135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator+(const T& a, const std::complex<T>& b) { \ 136 return std::complex<T>(a + numext::real(b), numext::imag(b)); \ 139 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator-(const std::complex<T>& a, \ 140 const std::complex<T>& b) { \ 141 return std::complex<T>(numext::real(a) - numext::real(b), numext::imag(a) - numext::imag(b)); \ 144 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator-(const std::complex<T>& a, const T& b) { \ 145 return std::complex<T>(numext::real(a) - b, numext::imag(a)); \ 148 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator-(const T& a, const std::complex<T>& b) { \ 149 return std::complex<T>(a - numext::real(b), -numext::imag(b)); \ 152 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator*(const std::complex<T>& a, \ 153 const std::complex<T>& b) { \ 154 return complex_multiply(a, b); \ 157 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator*(const std::complex<T>& a, const T& b) { \ 158 return std::complex<T>(numext::real(a) * b, numext::imag(a) * b); \ 161 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator*(const T& a, const std::complex<T>& b) { \ 162 return std::complex<T>(a * numext::real(b), a * numext::imag(b)); \ 165 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator/(const std::complex<T>& a, \ 166 const std::complex<T>& b) { \ 167 return complex_divide(a, b); \ 170 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator/(const std::complex<T>& a, const T& b) { \ 171 return std::complex<T>(numext::real(a) / b, numext::imag(a) / b); \ 174 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator/(const T& a, const std::complex<T>& b) { \ 175 return complex_divide(std::complex<T>(a, 0), b); \ 178 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T>& operator+=(std::complex<T>& a, const std::complex<T>& b) { \ 179 numext::real_ref(a) += numext::real(b); \ 180 numext::imag_ref(a) += numext::imag(b); \ 184 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T>& operator-=(std::complex<T>& a, const std::complex<T>& b) { \ 185 numext::real_ref(a) -= numext::real(b); \ 186 numext::imag_ref(a) -= numext::imag(b); \ 190 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T>& operator*=(std::complex<T>& a, const std::complex<T>& b) { \ 191 a = complex_multiply(a, b); \ 195 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T>& operator/=(std::complex<T>& a, const std::complex<T>& b) { \ 196 a = complex_divide(a, b); \ 200 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator==(const std::complex<T>& a, const std::complex<T>& b) { \ 201 return numext::real(a) == numext::real(b) && numext::imag(a) == numext::imag(b); \ 204 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator==(const std::complex<T>& a, const T& b) { \ 205 return numext::real(a) == b && numext::imag(a) == 0; \ 208 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator==(const T& a, const std::complex<T>& b) { \ 209 return a == numext::real(b) && 0 == numext::imag(b); \ 212 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator!=(const std::complex<T>& a, const std::complex<T>& b) { \ 216 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator!=(const std::complex<T>& a, const T& b) { return !(a == b); } \ 218 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator!=(const T& a, const std::complex<T>& b) { return !(a == b); } 221 EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(
float)
222 EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(
double)
224 #undef EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS 228 EIGEN_USING_STD_COMPLEX_OPERATORS
231 EIGEN_USING_STD_COMPLEX_OPERATORS
235 EIGEN_USING_STD_COMPLEX_OPERATORS
240 #endif // !(EIGEN_COMP_ICC && _USE_COMPLEX_SPECIALIZATION_) 242 #endif // EIGEN_GPUCC && EIGEN_GPU_COMPILE_PHASE 244 #endif // EIGEN_COMPLEX_GPU_H Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1