complex.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //---------------------------------------------------------------------------//
  2. // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. // See http://boostorg.github.com/compute for more information.
  9. //---------------------------------------------------------------------------//
  10. #ifndef BOOST_COMPUTE_TYPES_COMPLEX_HPP
  11. #define BOOST_COMPUTE_TYPES_COMPLEX_HPP
  12. #include <complex>
  13. #include <boost/compute/functional.hpp>
  14. #include <boost/compute/types/fundamental.hpp>
  15. #include <boost/compute/type_traits/make_vector_type.hpp>
  16. #include <boost/compute/type_traits/type_name.hpp>
  17. #include <boost/compute/detail/meta_kernel.hpp>
  18. namespace boost {
  19. namespace compute {
  20. namespace detail {
  21. template<class T>
  22. meta_kernel& operator<<(meta_kernel &kernel, const std::complex<T> &x)
  23. {
  24. typedef typename std::complex<T> value_type;
  25. kernel << "(" << type_name<value_type>() << ")"
  26. << "(" << x.real() << ", " << x.imag() << ")";
  27. return kernel;
  28. }
  29. // get<N>() result type specialization for std::complex<>
  30. template<size_t N, class T>
  31. struct get_result_type<N, std::complex<T> >
  32. {
  33. typedef T type;
  34. };
  35. // get<N>() specialization for std::complex<>
  36. template<size_t N, class Arg, class T>
  37. inline meta_kernel& operator<<(meta_kernel &kernel,
  38. const invoked_get<N, Arg, std::complex<T> > &expr)
  39. {
  40. BOOST_STATIC_ASSERT(N < 2);
  41. return kernel << expr.m_arg << (N == 0 ? ".x" : ".y");
  42. }
  43. } // end detail namespace
  44. // returns the real component of a complex<T>
  45. template<class T>
  46. struct real
  47. {
  48. typedef T result_type;
  49. template<class Arg>
  50. detail::invoked_get<0, Arg, std::complex<T> >
  51. operator()(const Arg &x) const
  52. {
  53. return detail::invoked_get<0, Arg, std::complex<T> >(x);
  54. }
  55. };
  56. // returns the imaginary component of a complex<T>
  57. template<class T>
  58. struct imag
  59. {
  60. typedef T result_type;
  61. template<class Arg>
  62. detail::invoked_get<1, Arg, std::complex<T> >
  63. operator()(const Arg &x) const
  64. {
  65. return detail::invoked_get<1, Arg, std::complex<T> >(x);
  66. }
  67. };
  68. namespace detail {
  69. template<class Arg1, class Arg2, class T>
  70. struct invoked_complex_multiplies
  71. {
  72. typedef typename std::complex<T> result_type;
  73. invoked_complex_multiplies(const Arg1 &x, const Arg2 &y)
  74. : m_x(x),
  75. m_y(y)
  76. {
  77. }
  78. Arg1 m_x;
  79. Arg2 m_y;
  80. };
  81. template<class Arg1, class Arg2, class T>
  82. inline meta_kernel& operator<<(meta_kernel &kernel,
  83. const invoked_complex_multiplies<Arg1, Arg2, T> &expr)
  84. {
  85. typedef typename std::complex<T> value_type;
  86. kernel << "(" << type_name<value_type>() << ")"
  87. << "(" << expr.m_x << ".x*" << expr.m_y << ".x-"
  88. << expr.m_x << ".y*" << expr.m_y << ".y,"
  89. << expr.m_x << ".y*" << expr.m_y << ".x+"
  90. << expr.m_x << ".x*" << expr.m_y << ".y" << ")";
  91. return kernel;
  92. }
  93. template<class Arg, class T>
  94. struct invoked_complex_conj
  95. {
  96. typedef typename std::complex<T> result_type;
  97. invoked_complex_conj(const Arg &arg)
  98. : m_arg(arg)
  99. {
  100. }
  101. Arg m_arg;
  102. };
  103. template<class Arg, class T>
  104. inline meta_kernel& operator<<(meta_kernel &kernel,
  105. const invoked_complex_conj<Arg, T> &expr)
  106. {
  107. typedef typename std::complex<T> value_type;
  108. kernel << "(" << type_name<value_type>() << ")"
  109. << "(" << expr.m_arg << ".x" << ", -" << expr.m_arg << ".y" << ")";
  110. return kernel;
  111. }
  112. } // end detail namespace
  113. // specialization for multiplies<T>
  114. template<class T>
  115. class multiplies<std::complex<T> > :
  116. public function<std::complex<T> (std::complex<T>, std::complex<T>)>
  117. {
  118. public:
  119. multiplies() :
  120. function<
  121. std::complex<T> (std::complex<T>, std::complex<T>)
  122. >("complex_multiplies")
  123. {
  124. }
  125. template<class Arg1, class Arg2>
  126. detail::invoked_complex_multiplies<Arg1, Arg2, T>
  127. operator()(const Arg1 &x, const Arg2 &y) const
  128. {
  129. return detail::invoked_complex_multiplies<Arg1, Arg2, T>(x, y);
  130. }
  131. };
  132. // returns the complex conjugate of a complex<T>
  133. template<class T>
  134. struct conj
  135. {
  136. typedef typename std::complex<T> result_type;
  137. template<class Arg>
  138. detail::invoked_complex_conj<Arg, T>
  139. operator()(const Arg &x) const
  140. {
  141. return detail::invoked_complex_conj<Arg, T>(x);
  142. }
  143. };
  144. namespace detail {
  145. // type_name() specialization for std::complex
  146. template<class T>
  147. struct type_name_trait<std::complex<T> >
  148. {
  149. static const char* value()
  150. {
  151. typedef typename make_vector_type<T, 2>::type vector_type;
  152. return type_name<vector_type>();
  153. }
  154. };
  155. } // end detail namespace
  156. } // end compute namespace
  157. } // end boost namespace
  158. #endif // BOOST_COMPUTE_TYPES_COMPLEX_HPP