• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 #ifndef BOOST_COMPUTE_TYPES_COMPLEX_HPP
12 #define BOOST_COMPUTE_TYPES_COMPLEX_HPP
13 
14 #include <complex>
15 
16 #include <boost/compute/functional.hpp>
17 #include <boost/compute/types/fundamental.hpp>
18 #include <boost/compute/type_traits/make_vector_type.hpp>
19 #include <boost/compute/type_traits/type_name.hpp>
20 #include <boost/compute/detail/meta_kernel.hpp>
21 
22 namespace boost {
23 namespace compute {
24 namespace detail {
25 
26 template<class T>
operator <<(meta_kernel & kernel,const std::complex<T> & x)27 meta_kernel& operator<<(meta_kernel &kernel, const std::complex<T> &x)
28 {
29     typedef typename std::complex<T> value_type;
30 
31     kernel << "(" << type_name<value_type>() << ")"
32            << "(" << x.real() << ", " << x.imag() << ")";
33 
34     return kernel;
35 }
36 
37 // get<N>() result type specialization for std::complex<>
38 template<size_t N, class T>
39 struct get_result_type<N, std::complex<T> >
40 {
41     typedef T type;
42 };
43 
44 // get<N>() specialization for std::complex<>
45 template<size_t N, class Arg, class T>
operator <<(meta_kernel & kernel,const invoked_get<N,Arg,std::complex<T>> & expr)46 inline meta_kernel& operator<<(meta_kernel &kernel,
47                                const invoked_get<N, Arg, std::complex<T> > &expr)
48 {
49     BOOST_STATIC_ASSERT(N < 2);
50 
51     return kernel << expr.m_arg << (N == 0 ? ".x" : ".y");
52 }
53 
54 } // end detail namespace
55 
56 // returns the real component of a complex<T>
57 template<class T>
58 struct real
59 {
60     typedef T result_type;
61 
62     template<class Arg>
63     detail::invoked_get<0, Arg, std::complex<T> >
operator ()boost::compute::real64     operator()(const Arg &x) const
65     {
66         return detail::invoked_get<0, Arg, std::complex<T> >(x);
67     }
68 };
69 
70 // returns the imaginary component of a complex<T>
71 template<class T>
72 struct imag
73 {
74     typedef T result_type;
75 
76     template<class Arg>
77     detail::invoked_get<1, Arg, std::complex<T> >
operator ()boost::compute::imag78     operator()(const Arg &x) const
79     {
80         return detail::invoked_get<1, Arg, std::complex<T> >(x);
81     }
82 };
83 
84 namespace detail {
85 
86 template<class Arg1, class Arg2, class T>
87 struct invoked_complex_multiplies
88 {
89     typedef typename std::complex<T> result_type;
90 
invoked_complex_multipliesboost::compute::detail::invoked_complex_multiplies91     invoked_complex_multiplies(const Arg1 &x, const Arg2 &y)
92         : m_x(x),
93           m_y(y)
94     {
95     }
96 
97     Arg1 m_x;
98     Arg2 m_y;
99 };
100 
101 template<class Arg1, class Arg2, class T>
operator <<(meta_kernel & kernel,const invoked_complex_multiplies<Arg1,Arg2,T> & expr)102 inline meta_kernel& operator<<(meta_kernel &kernel,
103                                const invoked_complex_multiplies<Arg1, Arg2, T> &expr)
104 {
105     typedef typename std::complex<T> value_type;
106 
107     kernel << "(" << type_name<value_type>() << ")"
108            << "(" << expr.m_x << ".x*" << expr.m_y << ".x-"
109                   << expr.m_x << ".y*" << expr.m_y << ".y,"
110                   << expr.m_x << ".y*" << expr.m_y << ".x+"
111                   << expr.m_x << ".x*" << expr.m_y << ".y" << ")";
112 
113     return kernel;
114 }
115 
116 template<class Arg, class T>
117 struct invoked_complex_conj
118 {
119     typedef typename std::complex<T> result_type;
120 
invoked_complex_conjboost::compute::detail::invoked_complex_conj121     invoked_complex_conj(const Arg &arg)
122         : m_arg(arg)
123     {
124     }
125 
126     Arg m_arg;
127 };
128 
129 template<class Arg, class T>
operator <<(meta_kernel & kernel,const invoked_complex_conj<Arg,T> & expr)130 inline meta_kernel& operator<<(meta_kernel &kernel,
131                                const invoked_complex_conj<Arg, T> &expr)
132 {
133     typedef typename std::complex<T> value_type;
134 
135     kernel << "(" << type_name<value_type>() << ")"
136            << "(" << expr.m_arg << ".x" << ", -" << expr.m_arg << ".y" << ")";
137 
138     return kernel;
139 }
140 
141 } // end detail namespace
142 
143 // specialization for multiplies<T>
144 template<class T>
145 class multiplies<std::complex<T> > :
146     public function<std::complex<T> (std::complex<T>, std::complex<T>)>
147 {
148 public:
multiplies()149     multiplies() :
150         function<
151             std::complex<T> (std::complex<T>, std::complex<T>)
152         >("complex_multiplies")
153     {
154     }
155 
156     template<class Arg1, class Arg2>
157     detail::invoked_complex_multiplies<Arg1, Arg2, T>
operator ()(const Arg1 & x,const Arg2 & y) const158     operator()(const Arg1 &x, const Arg2 &y) const
159     {
160         return detail::invoked_complex_multiplies<Arg1, Arg2, T>(x, y);
161     }
162 };
163 
164 // returns the complex conjugate of a complex<T>
165 template<class T>
166 struct conj
167 {
168     typedef typename std::complex<T> result_type;
169 
170     template<class Arg>
171     detail::invoked_complex_conj<Arg, T>
operator ()boost::compute::conj172     operator()(const Arg &x) const
173     {
174         return detail::invoked_complex_conj<Arg, T>(x);
175     }
176 };
177 
178 namespace detail {
179 
180 // type_name() specialization for std::complex
181 template<class T>
182 struct type_name_trait<std::complex<T> >
183 {
valueboost::compute::detail::type_name_trait184     static const char* value()
185     {
186         typedef typename make_vector_type<T, 2>::type vector_type;
187 
188         return type_name<vector_type>();
189     }
190 };
191 
192 } // end detail namespace
193 } // end compute namespace
194 } // end boost namespace
195 
196 #endif // BOOST_COMPUTE_TYPES_COMPLEX_HPP
197