11 #ifndef EIGEN_COMPLEX_CUDA_H 
   12 #define EIGEN_COMPLEX_CUDA_H 
   22 #if defined(EIGEN_CUDACC) && defined(EIGEN_GPU_COMPILE_PHASE) 
   31 #if !(defined(EIGEN_COMP_ICC) && defined(_USE_COMPLEX_SPECIALIZATION_)) 
   34 #define EIGEN_USING_STD_COMPLEX_OPERATORS           \ 
   35   using Eigen::complex_operator_detail::operator+;  \ 
   36   using Eigen::complex_operator_detail::operator-;  \ 
   37   using Eigen::complex_operator_detail::operator*;  \ 
   38   using Eigen::complex_operator_detail::operator/;  \ 
   39   using Eigen::complex_operator_detail::operator+=; \ 
   40   using Eigen::complex_operator_detail::operator-=; \ 
   41   using Eigen::complex_operator_detail::operator*=; \ 
   42   using Eigen::complex_operator_detail::operator/=; \ 
   43   using Eigen::complex_operator_detail::operator==; \ 
   44   using Eigen::complex_operator_detail::operator!=; 
   49 namespace complex_operator_detail {
 
   53 std::complex<T> complex_multiply(
const std::complex<T>& 
a, 
const std::complex<T>& 
b) {
 
   58   return std::complex<T>(
 
   59       a_real * b_real - a_imag * b_imag,
 
   60       a_imag * b_real + a_real * b_imag);
 
   65 std::complex<T> complex_divide_fast(
const std::complex<T>& 
a, 
const std::complex<T>& 
b) {
 
   70   const T norm = (b_real * b_real + b_imag * b_imag);
 
   71   return std::complex<T>((a_real * b_real + a_imag * b_imag) / norm,
 
   72                           (a_imag * b_real - a_real * b_imag) / norm);
 
   77 std::complex<T> complex_divide_stable(
const std::complex<T>& 
a, 
const std::complex<T>& 
b) {
 
   85   const T rscale = scale_imag ? 
T(1) : b_real / b_imag;
 
   86   const T iscale = scale_imag ? b_imag / b_real : 
T(1);
 
   88   return std::complex<T>((a_real * 
rscale + a_imag * 
iscale) / denominator, 
 
   94 std::complex<T> complex_divide(
const std::complex<T>& 
a, 
const std::complex<T>& 
b) {
 
   96   return complex_divide_fast(
a, 
b);
 
   98   return complex_divide_stable(
a, 
b);
 
  107 #define EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(T)                                    \ 
  109 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  110 std::complex<T> operator+(const std::complex<T>& a) { return a; }                               \ 
  112 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  113 std::complex<T> operator-(const std::complex<T>& a) {                                           \ 
  114   return std::complex<T>(-numext::real(a), -numext::imag(a));                                   \ 
  117 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  118 std::complex<T> operator+(const std::complex<T>& a, const std::complex<T>& b) {                 \ 
  119   return std::complex<T>(numext::real(a) + numext::real(b), numext::imag(a) + numext::imag(b)); \ 
  122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  123 std::complex<T> operator+(const std::complex<T>& a, const T& b) {                               \ 
  124   return std::complex<T>(numext::real(a) + b, numext::imag(a));                                 \ 
  127 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  128 std::complex<T> operator+(const T& a, const std::complex<T>& b) {                               \ 
  129   return std::complex<T>(a + numext::real(b), numext::imag(b));                                 \ 
  132 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  133 std::complex<T> operator-(const std::complex<T>& a, const std::complex<T>& b) {                 \ 
  134   return std::complex<T>(numext::real(a) - numext::real(b), numext::imag(a) - numext::imag(b)); \ 
  137 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  138 std::complex<T> operator-(const std::complex<T>& a, const T& b) {                               \ 
  139   return std::complex<T>(numext::real(a) - b, numext::imag(a));                                 \ 
  142 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  143 std::complex<T> operator-(const T& a, const std::complex<T>& b) {                               \ 
  144   return std::complex<T>(a - numext::real(b), -numext::imag(b));                                \ 
  147 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  148 std::complex<T> operator*(const std::complex<T>& a, const std::complex<T>& b) {                 \ 
  149   return complex_multiply(a, b);                                                                \ 
  152 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  153 std::complex<T> operator*(const std::complex<T>& a, const T& b) {                               \ 
  154   return std::complex<T>(numext::real(a) * b, numext::imag(a) * b);                             \ 
  157 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  158 std::complex<T> operator*(const T& a, const std::complex<T>& b) {                               \ 
  159   return std::complex<T>(a * numext::real(b), a * numext::imag(b));                             \ 
  162 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  163 std::complex<T> operator/(const std::complex<T>& a, const std::complex<T>& b) {                 \ 
  164   return complex_divide(a, b);                                                                  \ 
  167 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  168 std::complex<T> operator/(const std::complex<T>& a, const T& b) {                               \ 
  169   return std::complex<T>(numext::real(a) / b, numext::imag(a) / b);                             \ 
  172 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  173 std::complex<T> operator/(const T& a, const std::complex<T>& b) {                               \ 
  174   return complex_divide(std::complex<T>(a, 0), b);                                              \ 
  177 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  178 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                                                           \ 
  185 std::complex<T>& operator-=(std::complex<T>& a, const std::complex<T>& b) {                     \ 
  186   numext::real_ref(a) -= numext::real(b);                                                       \ 
  187   numext::imag_ref(a) -= numext::imag(b);                                                       \ 
  191 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  192 std::complex<T>& operator*=(std::complex<T>& a, const std::complex<T>& b) {                     \ 
  193   a = complex_multiply(a, b);                                                                   \ 
  197 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  198 std::complex<T>& operator/=(std::complex<T>& a, const std::complex<T>& b) {                     \ 
  199   a = complex_divide(a, b);                                                                     \ 
  203 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  204 bool operator==(const std::complex<T>& a, const std::complex<T>& b) {                           \ 
  205   return numext::real(a) == numext::real(b) && numext::imag(a) == numext::imag(b);              \ 
  208 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  209 bool operator==(const std::complex<T>& a, const T& b) {                                         \ 
  210   return numext::real(a) == b && numext::imag(a) == 0;                                          \ 
  213 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  214 bool operator==(const T& a, const std::complex<T>& b) {                                         \ 
  215   return a  == numext::real(b) && 0 == numext::imag(b);                                         \ 
  218 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  219 bool operator!=(const std::complex<T>& a, const std::complex<T>& b) {                           \ 
  223 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  224 bool operator!=(const std::complex<T>& a, const T& b) {                                         \ 
  228 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                                                           \ 
  229 bool operator!=(const T& a, const std::complex<T>& b) {                                         \ 
  234 EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(
float)
 
  235 EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS(
double)
 
  237 #undef EIGEN_CREATE_STD_COMPLEX_OPERATOR_SPECIALIZATIONS 
  242 EIGEN_USING_STD_COMPLEX_OPERATORS
 
  245 EIGEN_USING_STD_COMPLEX_OPERATORS
 
  249 EIGEN_USING_STD_COMPLEX_OPERATORS
 
  254 #endif  // !(EIGEN_COMP_ICC && _USE_COMPLEX_SPECIALIZATION_) 
  256 #endif  // EIGEN_CUDACC && EIGEN_GPU_COMPILE_PHASE 
  258 #endif  // EIGEN_COMPLEX_CUDA_H