Commit 81e0d2215b30a17309ce7ba7615f94e2eda5c67e

Authored by David Mayerich
1 parent 7b3948ab

separated executable arguments and options in the arglist class

1 -/*RTS Complex number class. This class is CUDA compatible,  
2 -and can therefore be used in CUDA code and on CUDA devices.  
3 -*/  
4 -  
5 -#ifndef RTS_COMPLEX  
6 -#define RTS_COMPLEX  
7 -  
8 -#include "../cuda/callable.h"  
9 -#include <cmath>  
10 -#include <string>  
11 -#include <sstream>  
12 -#include <iostream>  
13 -  
14 -namespace stim  
15 -{  
16 -  
17 -template <class T>  
18 -struct complex  
19 -{  
20 - T r, i;  
21 -  
22 - //default constructor  
23 - CUDA_CALLABLE complex()  
24 - {  
25 - r = 0;  
26 - i = 0;  
27 - }  
28 -  
29 - //constructor when given real and imaginary values  
30 - CUDA_CALLABLE complex(T r, T i = 0)  
31 - {  
32 - this->r = r;  
33 - this->i = i;  
34 - }  
35 -  
36 - //access methods  
37 - CUDA_CALLABLE T real()  
38 - {  
39 - return r;  
40 - }  
41 -  
42 - CUDA_CALLABLE T real(T r_val)  
43 - {  
44 - r = r_val;  
45 - return r_val;  
46 - }  
47 -  
48 - CUDA_CALLABLE T imag()  
49 - {  
50 - return i;  
51 - }  
52 - CUDA_CALLABLE T imag(T i_val)  
53 - {  
54 - i = i_val;  
55 - return i_val;  
56 - }  
57 -  
58 -  
59 -  
60 - //return the current value multiplied by i  
61 - CUDA_CALLABLE complex<T> imul()  
62 - {  
63 - complex<T> result;  
64 - result.r = -i;  
65 - result.i = r;  
66 -  
67 - return result;  
68 - }  
69 -  
70 - //returns the complex signum (-1, 0, 1)  
71 - CUDA_CALLABLE int sgn(){  
72 - if(r > 0) return 1;  
73 - else if(r < 0) return -1;  
74 - else return (0 < i - i < 0);  
75 - }  
76 -  
77 - //ARITHMETIC OPERATORS--------------------  
78 -  
79 - //binary + operator (returns the result of adding two complex values)  
80 - CUDA_CALLABLE complex<T> operator+ (const complex<T> rhs) const  
81 - {  
82 - complex<T> result;  
83 - result.r = r + rhs.r;  
84 - result.i = i + rhs.i;  
85 - return result;  
86 - }  
87 -  
88 - CUDA_CALLABLE complex<T> operator+ (const T rhs) const  
89 - {  
90 - complex<T> result;  
91 - result.r = r + rhs;  
92 - result.i = i;  
93 - return result;  
94 - }  
95 -  
96 - //binary - operator (returns the result of adding two complex values)  
97 - CUDA_CALLABLE complex<T> operator- (const complex<T> rhs) const  
98 - {  
99 - complex<T> result;  
100 - result.r = r - rhs.r;  
101 - result.i = i - rhs.i;  
102 - return result;  
103 - }  
104 -  
105 - //binary - operator (returns the result of adding two complex values)  
106 - CUDA_CALLABLE complex<T> operator- (const T rhs)  
107 - {  
108 - complex<T> result;  
109 - result.r = r - rhs;  
110 - result.i = i;  
111 - return result;  
112 - }  
113 -  
114 - //binary MULTIPLICATION operators (returns the result of multiplying complex values)  
115 - CUDA_CALLABLE complex<T> operator* (const complex<T> rhs) const  
116 - {  
117 - complex<T> result;  
118 - result.r = r * rhs.r - i * rhs.i;  
119 - result.i = r * rhs.i + i * rhs.r;  
120 - return result;  
121 - }  
122 - CUDA_CALLABLE complex<T> operator* (const T rhs)  
123 - {  
124 - return complex<T>(r * rhs, i * rhs);  
125 - }  
126 -  
127 - //binary DIVISION operators (returns the result of dividing complex values)  
128 - CUDA_CALLABLE complex<T> operator/ (const complex<T> rhs) const  
129 - {  
130 - complex<T> result;  
131 - T denom = rhs.r * rhs.r + rhs.i * rhs.i;  
132 - result.r = (r * rhs.r + i * rhs.i) / denom;  
133 - result.i = (- r * rhs.i + i * rhs.r) / denom;  
134 -  
135 - return result;  
136 - }  
137 - CUDA_CALLABLE complex<T> operator/ (const T rhs)  
138 - {  
139 - return complex<T>(r / rhs, i / rhs);  
140 - }  
141 -  
142 - //ASSIGNMENT operators-----------------------------------  
143 - CUDA_CALLABLE complex<T> & operator=(const complex<T> &rhs)  
144 - {  
145 - //check for self-assignment  
146 - if(this != &rhs)  
147 - {  
148 - this->r = rhs.r;  
149 - this->i = rhs.i;  
150 - }  
151 - return *this;  
152 - }  
153 - CUDA_CALLABLE complex<T> & operator=(const T &rhs)  
154 - {  
155 - this->r = rhs;  
156 - this->i = 0;  
157 -  
158 - return *this;  
159 - }  
160 -  
161 - //arithmetic assignment operators  
162 - CUDA_CALLABLE complex<T> operator+=(const complex<T> &rhs)  
163 - {  
164 - *this = *this + rhs;  
165 - return *this;  
166 - }  
167 - CUDA_CALLABLE complex<T> operator+=(const T &rhs)  
168 - {  
169 - *this = *this + rhs;  
170 - return *this;  
171 - }  
172 -  
173 - CUDA_CALLABLE complex<T> operator-=(const complex<T> &rhs)  
174 - {  
175 - *this = *this - rhs;  
176 - return *this;  
177 - }  
178 - CUDA_CALLABLE complex<T> operator-=(const T &rhs)  
179 - {  
180 - *this = *this - rhs;  
181 - return *this;  
182 - }  
183 -  
184 - CUDA_CALLABLE complex<T> operator*=(const complex<T> &rhs)  
185 - {  
186 - *this = *this * rhs;  
187 - return *this;  
188 - }  
189 - CUDA_CALLABLE complex<T> operator*=(const T &rhs)  
190 - {  
191 - *this = *this * rhs;  
192 - return *this;  
193 - }  
194 - //divide and assign  
195 - CUDA_CALLABLE complex<T> operator/=(const complex<T> &rhs)  
196 - {  
197 - *this = *this / rhs;  
198 - return *this;  
199 - }  
200 - CUDA_CALLABLE complex<T> operator/=(const T &rhs)  
201 - {  
202 - *this = *this / rhs;  
203 - return *this;  
204 - }  
205 -  
206 - //absolute value operator (returns the absolute value of the complex number)  
207 - CUDA_CALLABLE T abs()  
208 - {  
209 - return std::sqrt(r * r + i * i);  
210 - }  
211 -  
212 - CUDA_CALLABLE complex<T> log()  
213 - {  
214 - complex<T> result;  
215 - result.r = (T)std::log(std::sqrt(r * r + i * i));  
216 - result.i = (T)std::atan2(i, r);  
217 -  
218 -  
219 - return result;  
220 - }  
221 -  
222 - CUDA_CALLABLE complex<T> exp()  
223 - {  
224 - complex<T> result;  
225 -  
226 - T e_r = std::exp(r);  
227 - result.r = e_r * (T)std::cos(i);  
228 - result.i = e_r * (T)std::sin(i);  
229 -  
230 - return result;  
231 - }  
232 -  
233 - /*CUDA_CALLABLE complex<T> pow(int y)  
234 - {  
235 -  
236 - return pow((double)y);  
237 - }*/  
238 -  
239 - CUDA_CALLABLE complex<T> pow(T y)  
240 - {  
241 - complex<T> result;  
242 -  
243 - result = log() * y;  
244 -  
245 - return result.exp();  
246 - }  
247 -  
248 - CUDA_CALLABLE complex<T> sqrt()  
249 - {  
250 - complex<T> result;  
251 -  
252 - //convert to polar coordinates  
253 - T a = std::sqrt(r*r + i*i);  
254 - T theta = std::atan2(i, r);  
255 -  
256 - //find the square root  
257 - T a_p = std::sqrt(a);  
258 - T theta_p = theta/2.0f;  
259 -  
260 - //convert back to cartesian coordinates  
261 - result.r = a_p * std::cos(theta_p);  
262 - result.i = a_p * std::sin(theta_p);  
263 -  
264 - return result;  
265 - }  
266 -  
267 - std::string str()  
268 - {  
269 - std::stringstream ss;  
270 - ss<<"("<<r<<","<<i<<")";  
271 -  
272 - return ss.str();  
273 - }  
274 -  
275 - //COMPARISON operators  
276 - CUDA_CALLABLE bool operator==(complex<T> rhs)  
277 - {  
278 - if(r == rhs.r && i == rhs.i)  
279 - return true;  
280 - return false;  
281 - }  
282 -  
283 - CUDA_CALLABLE bool operator==(T rhs)  
284 - {  
285 - if(r == rhs && i == 0)  
286 - return true;  
287 - return false;  
288 - }  
289 -  
290 - CUDA_CALLABLE bool operator!=(T rhs)  
291 - {  
292 - if(r != rhs || i != 0)  
293 - return true;  
294 - return false;  
295 - }  
296 -  
297 - CUDA_CALLABLE bool operator<(complex<T> rhs){  
298 - return abs() < rhs.abs();  
299 - }  
300 - CUDA_CALLABLE bool operator<=(complex<T> rhs){  
301 - return abs() <= rhs.abs();  
302 - }  
303 - CUDA_CALLABLE bool operator>(complex<T> rhs){  
304 - return abs() > rhs.abs();  
305 - }  
306 - CUDA_CALLABLE bool operator >=(complex<T> rhs){  
307 - return abs() >= rhs.abs();  
308 - }  
309 -  
310 - //CASTING operators  
311 - template < typename otherT >  
312 - operator complex<otherT>()  
313 - {  
314 - complex<otherT> result((otherT)r, (otherT)i);  
315 - return result;  
316 - }  
317 - template< typename otherT >  
318 - complex( const complex<otherT> &rhs)  
319 - {  
320 - r = (T)rhs.r;  
321 - i = (T)rhs.i;  
322 - }  
323 - template< typename otherT >  
324 - complex& operator=(const complex<otherT> &rhs)  
325 - {  
326 - r = (T)rhs.r;  
327 - i = (T)rhs.i;  
328 - return *this;  
329 - }  
330 -  
331 -};  
332 -  
333 -} //end RTS namespace  
334 -  
335 -//addition  
336 -template<typename T>  
337 -CUDA_CALLABLE static stim::complex<T> operator+(const double a, const stim::complex<T> b)  
338 -{  
339 - return stim::complex<T>((T)a + b.r, b.i);  
340 -}  
341 -  
342 -//subtraction with a real value  
343 -template<typename T>  
344 -CUDA_CALLABLE static stim::complex<T> operator-(const double a, const stim::complex<T> b)  
345 -{  
346 - return stim::complex<T>((T)a - b.r, -b.i);  
347 -}  
348 -  
349 -//minus sign  
350 -template<typename T>  
351 -CUDA_CALLABLE static stim::complex<T> operator-(const stim::complex<T> &rhs)  
352 -{  
353 - return stim::complex<T>(-rhs.r, -rhs.i);  
354 -}  
355 -  
356 -//multiply a T value by a complex value  
357 -template<typename T>  
358 -CUDA_CALLABLE static stim::complex<T> operator*(const double a, const stim::complex<T> b)  
359 -{  
360 - return stim::complex<T>((T)a * b.r, (T)a * b.i);  
361 -}  
362 -  
363 -//divide a T value by a complex value  
364 -template<typename T>  
365 -CUDA_CALLABLE static stim::complex<T> operator/(const double a, const stim::complex<T> b)  
366 -{  
367 - stim::complex<T> result;  
368 -  
369 - T denom = b.r * b.r + b.i * b.i;  
370 -  
371 - result.r = ((T)a * b.r) / denom;  
372 - result.i = -((T)a * b.i) / denom;  
373 -  
374 - return result;  
375 -}  
376 -  
377 -  
378 -template<typename T>  
379 -CUDA_CALLABLE static stim::complex<T> pow(stim::complex<T> x, T y)  
380 -{  
381 - return x.pow(y);  
382 -}  
383 -template<typename T>  
384 -CUDA_CALLABLE static stim::complex<T> pow(stim::complex<T> x, int y)  
385 -{  
386 - return x.pow(y);  
387 -}  
388 -  
389 -//log function  
390 -template<typename T>  
391 -CUDA_CALLABLE static stim::complex<T> log(stim::complex<T> x)  
392 -{  
393 - return x.log();  
394 -}  
395 -  
396 -//exp function  
397 -template<typename T>  
398 -CUDA_CALLABLE static stim::complex<T> exp(stim::complex<T> x)  
399 -{  
400 - return x.exp();  
401 -}  
402 -  
403 -//sqrt function  
404 -template<typename T>  
405 -CUDA_CALLABLE static stim::complex<T> sqrt(stim::complex<T> x)  
406 -{  
407 - return x.sqrt();  
408 -}  
409 -  
410 -  
411 -template <typename T>  
412 -CUDA_CALLABLE static T abs(stim::complex<T> a)  
413 -{  
414 - return a.abs();  
415 -}  
416 -  
417 -template <typename T>  
418 -CUDA_CALLABLE static T real(stim::complex<T> a)  
419 -{  
420 - return a.r;  
421 -}  
422 -  
423 -//template <typename T>  
424 -CUDA_CALLABLE static float real(float a)  
425 -{  
426 - return a;  
427 -}  
428 -  
429 -template <typename T>  
430 -CUDA_CALLABLE static T imag(stim::complex<T> a)  
431 -{  
432 - return a.i;  
433 -}  
434 -  
435 -//trigonometric functions  
436 -//template<class A>  
437 -/*CUDA_CALLABLE static stim::complex<float> sinf(const stim::complex<float> x)  
438 -{  
439 - stim::complex<float> result;  
440 - result.r = sinf(x.r) * coshf(x.i);  
441 - result.i = cosf(x.r) * sinhf(x.i);  
442 -  
443 - return result;  
444 -}*/  
445 -  
446 -template<class A>  
447 -CUDA_CALLABLE stim::complex<A> sin(const stim::complex<A> x)  
448 -{  
449 - stim::complex<A> result;  
450 - result.r = (A)std::sin(x.r) * (A)std::cosh(x.i);  
451 - result.i = (A)std::cos(x.r) * (A)std::sinh(x.i);  
452 -  
453 - return result;  
454 -}  
455 -  
456 -//floating point template  
457 -//template<class A>  
458 -/*CUDA_CALLABLE static stim::complex<float> cosf(const stim::complex<float> x)  
459 -{  
460 - stim::complex<float> result;  
461 - result.r = cosf(x.r) * coshf(x.i);  
462 - result.i = -(sinf(x.r) * sinhf(x.i));  
463 -  
464 - return result;  
465 -}*/  
466 -  
467 -template<class A>  
468 -CUDA_CALLABLE stim::complex<A> cos(const stim::complex<A> x)  
469 -{  
470 - stim::complex<A> result;  
471 - result.r = (A)std::cos(x.r) * (A)std::cosh(x.i);  
472 - result.i = -((A)std::sin(x.r) * (A)std::sinh(x.i));  
473 -  
474 - return result;  
475 -}  
476 -  
477 -  
478 -template<class A>  
479 -std::ostream& operator<<(std::ostream& os, stim::complex<A> x)  
480 -{  
481 - os<<x.str();  
482 - return os;  
483 -}  
484 -  
485 -template<class A>  
486 -std::istream& operator>>(std::istream& is, stim::complex<A>& x)  
487 -{  
488 - A r, i;  
489 - r = i = 0; //initialize the real and imaginary parts to zero  
490 - is>>r; //parse  
491 - is>>i;  
492 -  
493 - x.real(r); //assign the parsed values to x  
494 - x.imag(i);  
495 -  
496 - return is; //return the stream  
497 -}  
498 -  
499 -//#if __GNUC__ > 3 && __GNUC_MINOR__ > 7  
500 -//template<class T> using rtsComplex = stim::complex<T>;  
501 -//#endif  
502 -  
503 -  
504 -  
505 -#endif 1 +/*RTS Complex number class. This class is CUDA compatible,
  2 +and can therefore be used in CUDA code and on CUDA devices.
  3 +*/
  4 +
  5 +#ifndef RTS_COMPLEX
  6 +#define RTS_COMPLEX
  7 +
  8 +#include "../cuda/callable.h"
  9 +#include <cmath>
  10 +#include <string>
  11 +#include <sstream>
  12 +#include <iostream>
  13 +
  14 +namespace stim
  15 +{
  16 +
  17 +template <class T>
  18 +struct complex
  19 +{
  20 + T r, i;
  21 +
  22 + //default constructor
  23 + CUDA_CALLABLE complex()
  24 + {
  25 + r = 0;
  26 + i = 0;
  27 + }
  28 +
  29 + //constructor when given real and imaginary values
  30 + CUDA_CALLABLE complex(T r, T i = 0)
  31 + {
  32 + this->r = r;
  33 + this->i = i;
  34 + }
  35 +
  36 + //access methods
  37 + CUDA_CALLABLE T real()
  38 + {
  39 + return r;
  40 + }
  41 +
  42 + CUDA_CALLABLE T real(T r_val)
  43 + {
  44 + r = r_val;
  45 + return r_val;
  46 + }
  47 +
  48 + CUDA_CALLABLE T imag()
  49 + {
  50 + return i;
  51 + }
  52 + CUDA_CALLABLE T imag(T i_val)
  53 + {
  54 + i = i_val;
  55 + return i_val;
  56 + }
  57 +
  58 +
  59 +
  60 + //return the current value multiplied by i
  61 + CUDA_CALLABLE complex<T> imul()
  62 + {
  63 + complex<T> result;
  64 + result.r = -i;
  65 + result.i = r;
  66 +
  67 + return result;
  68 + }
  69 +
  70 + //returns the complex signum (-1, 0, 1)
  71 + CUDA_CALLABLE int sgn(){
  72 + if(r > 0) return 1;
  73 + else if(r < 0) return -1;
  74 + else return (0 < i - i < 0);
  75 + }
  76 +
  77 + //ARITHMETIC OPERATORS--------------------
  78 +
  79 + //binary + operator (returns the result of adding two complex values)
  80 + CUDA_CALLABLE complex<T> operator+ (const complex<T> rhs) const
  81 + {
  82 + complex<T> result;
  83 + result.r = r + rhs.r;
  84 + result.i = i + rhs.i;
  85 + return result;
  86 + }
  87 +
  88 + CUDA_CALLABLE complex<T> operator+ (const T rhs) const
  89 + {
  90 + complex<T> result;
  91 + result.r = r + rhs;
  92 + result.i = i;
  93 + return result;
  94 + }
  95 +
  96 + //binary - operator (returns the result of adding two complex values)
  97 + CUDA_CALLABLE complex<T> operator- (const complex<T> rhs) const
  98 + {
  99 + complex<T> result;
  100 + result.r = r - rhs.r;
  101 + result.i = i - rhs.i;
  102 + return result;
  103 + }
  104 +
  105 + //binary - operator (returns the result of adding two complex values)
  106 + CUDA_CALLABLE complex<T> operator- (const T rhs)
  107 + {
  108 + complex<T> result;
  109 + result.r = r - rhs;
  110 + result.i = i;
  111 + return result;
  112 + }
  113 +
  114 + //binary MULTIPLICATION operators (returns the result of multiplying complex values)
  115 + CUDA_CALLABLE complex<T> operator* (const complex<T> rhs) const
  116 + {
  117 + complex<T> result;
  118 + result.r = r * rhs.r - i * rhs.i;
  119 + result.i = r * rhs.i + i * rhs.r;
  120 + return result;
  121 + }
  122 + CUDA_CALLABLE complex<T> operator* (const T rhs)
  123 + {
  124 + return complex<T>(r * rhs, i * rhs);
  125 + }
  126 +
  127 + //binary DIVISION operators (returns the result of dividing complex values)
  128 + CUDA_CALLABLE complex<T> operator/ (const complex<T> rhs) const
  129 + {
  130 + complex<T> result;
  131 + T denom = rhs.r * rhs.r + rhs.i * rhs.i;
  132 + result.r = (r * rhs.r + i * rhs.i) / denom;
  133 + result.i = (- r * rhs.i + i * rhs.r) / denom;
  134 +
  135 + return result;
  136 + }
  137 + CUDA_CALLABLE complex<T> operator/ (const T rhs)
  138 + {
  139 + return complex<T>(r / rhs, i / rhs);
  140 + }
  141 +
  142 + //ASSIGNMENT operators-----------------------------------
  143 + CUDA_CALLABLE complex<T> & operator=(const complex<T> &rhs)
  144 + {
  145 + //check for self-assignment
  146 + if(this != &rhs)
  147 + {
  148 + this->r = rhs.r;
  149 + this->i = rhs.i;
  150 + }
  151 + return *this;
  152 + }
  153 + CUDA_CALLABLE complex<T> & operator=(const T &rhs)
  154 + {
  155 + this->r = rhs;
  156 + this->i = 0;
  157 +
  158 + return *this;
  159 + }
  160 +
  161 + //arithmetic assignment operators
  162 + CUDA_CALLABLE complex<T> operator+=(const complex<T> &rhs)
  163 + {
  164 + *this = *this + rhs;
  165 + return *this;
  166 + }
  167 + CUDA_CALLABLE complex<T> operator+=(const T &rhs)
  168 + {
  169 + *this = *this + rhs;
  170 + return *this;
  171 + }
  172 +
  173 + CUDA_CALLABLE complex<T> operator-=(const complex<T> &rhs)
  174 + {
  175 + *this = *this - rhs;
  176 + return *this;
  177 + }
  178 + CUDA_CALLABLE complex<T> operator-=(const T &rhs)
  179 + {
  180 + *this = *this - rhs;
  181 + return *this;
  182 + }
  183 +
  184 + CUDA_CALLABLE complex<T> operator*=(const complex<T> &rhs)
  185 + {
  186 + *this = *this * rhs;
  187 + return *this;
  188 + }
  189 + CUDA_CALLABLE complex<T> operator*=(const T &rhs)
  190 + {
  191 + *this = *this * rhs;
  192 + return *this;
  193 + }
  194 + //divide and assign
  195 + CUDA_CALLABLE complex<T> operator/=(const complex<T> &rhs)
  196 + {
  197 + *this = *this / rhs;
  198 + return *this;
  199 + }
  200 + CUDA_CALLABLE complex<T> operator/=(const T &rhs)
  201 + {
  202 + *this = *this / rhs;
  203 + return *this;
  204 + }
  205 +
  206 + //absolute value operator (returns the absolute value of the complex number)
  207 + CUDA_CALLABLE T abs()
  208 + {
  209 + return std::sqrt(r * r + i * i);
  210 + }
  211 +
  212 + CUDA_CALLABLE complex<T> log()
  213 + {
  214 + complex<T> result;
  215 + result.r = (T)std::log(std::sqrt(r * r + i * i));
  216 + result.i = (T)std::atan2(i, r);
  217 +
  218 +
  219 + return result;
  220 + }
  221 +
  222 + CUDA_CALLABLE complex<T> exp()
  223 + {
  224 + complex<T> result;
  225 +
  226 + T e_r = std::exp(r);
  227 + result.r = e_r * (T)std::cos(i);
  228 + result.i = e_r * (T)std::sin(i);
  229 +
  230 + return result;
  231 + }
  232 +
  233 + /*CUDA_CALLABLE complex<T> pow(int y)
  234 + {
  235 +
  236 + return pow((double)y);
  237 + }*/
  238 +
  239 + CUDA_CALLABLE complex<T> pow(T y)
  240 + {
  241 + complex<T> result;
  242 +
  243 + result = log() * y;
  244 +
  245 + return result.exp();
  246 + }
  247 +
  248 + CUDA_CALLABLE complex<T> sqrt()
  249 + {
  250 + complex<T> result;
  251 +
  252 + //convert to polar coordinates
  253 + T a = std::sqrt(r*r + i*i);
  254 + T theta = std::atan2(i, r);
  255 +
  256 + //find the square root
  257 + T a_p = std::sqrt(a);
  258 + T theta_p = theta/2.0f;
  259 +
  260 + //convert back to cartesian coordinates
  261 + result.r = a_p * std::cos(theta_p);
  262 + result.i = a_p * std::sin(theta_p);
  263 +
  264 + return result;
  265 + }
  266 +
  267 + std::string str()
  268 + {
  269 + std::stringstream ss;
  270 + ss<<"("<<r<<","<<i<<")";
  271 +
  272 + return ss.str();
  273 + }
  274 +
  275 + //COMPARISON operators
  276 + CUDA_CALLABLE bool operator==(complex<T> rhs)
  277 + {
  278 + if(r == rhs.r && i == rhs.i)
  279 + return true;
  280 + return false;
  281 + }
  282 +
  283 + CUDA_CALLABLE bool operator==(T rhs)
  284 + {
  285 + if(r == rhs && i == 0)
  286 + return true;
  287 + return false;
  288 + }
  289 +
  290 + CUDA_CALLABLE bool operator!=(T rhs)
  291 + {
  292 + if(r != rhs || i != 0)
  293 + return true;
  294 + return false;
  295 + }
  296 +
  297 + CUDA_CALLABLE bool operator<(complex<T> rhs){
  298 + return abs() < rhs.abs();
  299 + }
  300 + CUDA_CALLABLE bool operator<=(complex<T> rhs){
  301 + return abs() <= rhs.abs();
  302 + }
  303 + CUDA_CALLABLE bool operator>(complex<T> rhs){
  304 + return abs() > rhs.abs();
  305 + }
  306 + CUDA_CALLABLE bool operator >=(complex<T> rhs){
  307 + return abs() >= rhs.abs();
  308 + }
  309 +
  310 + //CASTING operators
  311 + template < typename otherT >
  312 + operator complex<otherT>()
  313 + {
  314 + complex<otherT> result((otherT)r, (otherT)i);
  315 + return result;
  316 + }
  317 + template< typename otherT >
  318 + complex( const complex<otherT> &rhs)
  319 + {
  320 + r = (T)rhs.r;
  321 + i = (T)rhs.i;
  322 + }
  323 + template< typename otherT >
  324 + complex& operator=(const complex<otherT> &rhs)
  325 + {
  326 + r = (T)rhs.r;
  327 + i = (T)rhs.i;
  328 + return *this;
  329 + }
  330 +
  331 +};
  332 +
  333 +} //end RTS namespace
  334 +
  335 +//addition
  336 +template<typename T>
  337 +CUDA_CALLABLE static stim::complex<T> operator+(const double a, const stim::complex<T> b)
  338 +{
  339 + return stim::complex<T>((T)a + b.r, b.i);
  340 +}
  341 +
  342 +//subtraction with a real value
  343 +template<typename T>
  344 +CUDA_CALLABLE static stim::complex<T> operator-(const double a, const stim::complex<T> b)
  345 +{
  346 + return stim::complex<T>((T)a - b.r, -b.i);
  347 +}
  348 +
  349 +//minus sign
  350 +template<typename T>
  351 +CUDA_CALLABLE static stim::complex<T> operator-(const stim::complex<T> &rhs)
  352 +{
  353 + return stim::complex<T>(-rhs.r, -rhs.i);
  354 +}
  355 +
  356 +//multiply a T value by a complex value
  357 +template<typename T>
  358 +CUDA_CALLABLE static stim::complex<T> operator*(const double a, const stim::complex<T> b)
  359 +{
  360 + return stim::complex<T>((T)a * b.r, (T)a * b.i);
  361 +}
  362 +
  363 +//divide a T value by a complex value
  364 +template<typename T>
  365 +CUDA_CALLABLE static stim::complex<T> operator/(const double a, const stim::complex<T> b)
  366 +{
  367 + stim::complex<T> result;
  368 +
  369 + T denom = b.r * b.r + b.i * b.i;
  370 +
  371 + result.r = ((T)a * b.r) / denom;
  372 + result.i = -((T)a * b.i) / denom;
  373 +
  374 + return result;
  375 +}
  376 +
  377 +
  378 +template<typename T>
  379 +CUDA_CALLABLE static stim::complex<T> pow(stim::complex<T> x, T y)
  380 +{
  381 + return x.pow(y);
  382 +}
  383 +template<typename T>
  384 +CUDA_CALLABLE static stim::complex<T> pow(stim::complex<T> x, int y)
  385 +{
  386 + return x.pow(y);
  387 +}
  388 +
  389 +//log function
  390 +template<typename T>
  391 +CUDA_CALLABLE static stim::complex<T> log(stim::complex<T> x)
  392 +{
  393 + return x.log();
  394 +}
  395 +
  396 +//exp function
  397 +template<typename T>
  398 +CUDA_CALLABLE static stim::complex<T> exp(stim::complex<T> x)
  399 +{
  400 + return x.exp();
  401 +}
  402 +
  403 +//sqrt function
  404 +template<typename T>
  405 +CUDA_CALLABLE static stim::complex<T> sqrt(stim::complex<T> x)
  406 +{
  407 + return x.sqrt();
  408 +}
  409 +
  410 +
  411 +template <typename T>
  412 +CUDA_CALLABLE static T abs(stim::complex<T> a)
  413 +{
  414 + return a.abs();
  415 +}
  416 +
  417 +template <typename T>
  418 +CUDA_CALLABLE static T real(stim::complex<T> a)
  419 +{
  420 + return a.r;
  421 +}
  422 +
  423 +//template <typename T>
  424 +CUDA_CALLABLE static float real(float a)
  425 +{
  426 + return a;
  427 +}
  428 +
  429 +template <typename T>
  430 +CUDA_CALLABLE static T imag(stim::complex<T> a)
  431 +{
  432 + return a.i;
  433 +}
  434 +
  435 +//trigonometric functions
  436 +//template<class A>
  437 +/*CUDA_CALLABLE static stim::complex<float> sinf(const stim::complex<float> x)
  438 +{
  439 + stim::complex<float> result;
  440 + result.r = sinf(x.r) * coshf(x.i);
  441 + result.i = cosf(x.r) * sinhf(x.i);
  442 +
  443 + return result;
  444 +}*/
  445 +
  446 +template<class A>
  447 +CUDA_CALLABLE stim::complex<A> sin(const stim::complex<A> x)
  448 +{
  449 + stim::complex<A> result;
  450 + result.r = (A)std::sin(x.r) * (A)std::cosh(x.i);
  451 + result.i = (A)std::cos(x.r) * (A)std::sinh(x.i);
  452 +
  453 + return result;
  454 +}
  455 +
  456 +//floating point template
  457 +//template<class A>
  458 +/*CUDA_CALLABLE static stim::complex<float> cosf(const stim::complex<float> x)
  459 +{
  460 + stim::complex<float> result;
  461 + result.r = cosf(x.r) * coshf(x.i);
  462 + result.i = -(sinf(x.r) * sinhf(x.i));
  463 +
  464 + return result;
  465 +}*/
  466 +
  467 +template<class A>
  468 +CUDA_CALLABLE stim::complex<A> cos(const stim::complex<A> x)
  469 +{
  470 + stim::complex<A> result;
  471 + result.r = (A)std::cos(x.r) * (A)std::cosh(x.i);
  472 + result.i = -((A)std::sin(x.r) * (A)std::sinh(x.i));
  473 +
  474 + return result;
  475 +}
  476 +
  477 +
  478 +template<class A>
  479 +std::ostream& operator<<(std::ostream& os, stim::complex<A> x)
  480 +{
  481 + os<<x.str();
  482 + return os;
  483 +}
  484 +
  485 +template<class A>
  486 +std::istream& operator>>(std::istream& is, stim::complex<A>& x)
  487 +{
  488 + A r, i;
  489 + r = i = 0; //initialize the real and imaginary parts to zero
  490 + is>>r; //parse
  491 + is>>i;
  492 +
  493 + x.real(r); //assign the parsed values to x
  494 + x.imag(i);
  495 +
  496 + return is; //return the stream
  497 +}
  498 +
  499 +//#if __GNUC__ > 3 && __GNUC_MINOR__ > 7
  500 +//template<class T> using rtsComplex = stim::complex<T>;
  501 +//#endif
  502 +
  503 +
  504 +
  505 +#endif
math/complexfield.cuh
1 -#ifndef RTS_COMPLEXFIELD_H  
2 -#define RTS_COMPLEXFIELD_H  
3 -  
4 -#include "cublas_v2.h"  
5 -#include <cuda_runtime.h>  
6 -  
7 -#include "../math/field.cuh"  
8 -#include "../math/complex.h"  
9 -#include "../math/realfield.cuh"  
10 -  
11 -namespace stim{  
12 -  
13 -template<typename T>  
14 -__global__ void gpu_complexfield_mag(T* dest, complex<T>* source, unsigned int r0, unsigned int r1){  
15 -  
16 - int iu = blockIdx.x * blockDim.x + threadIdx.x;  
17 - int iv = blockIdx.y * blockDim.y + threadIdx.y;  
18 -  
19 - //make sure that the thread indices are in-bounds  
20 - if(iu >= r0 || iv >= r1) return;  
21 -  
22 - //compute the index into the field  
23 - int i = iv*r0 + iu;  
24 -  
25 - //calculate and store the result  
26 - dest[i] = source[i].abs();  
27 -}  
28 -  
29 -/*This class stores functions for saving images of complex fields  
30 -*/  
31 -template<typename T, unsigned int D = 1>  
32 -class complexfield : public field< stim::complex<T>, D >{  
33 - using field< stim::complex<T>, D >::R;  
34 - using field< stim::complex<T>, D >::X;  
35 - using field< stim::complex<T>, D >::shape;  
36 - using field< stim::complex<T>, D >::cuda_params;  
37 -  
38 -  
39 -  
40 -public:  
41 -  
42 - //find the maximum value of component n  
43 - stim::complex<T> find_max(unsigned int n){  
44 - cublasStatus_t stat;  
45 - cublasHandle_t handle;  
46 -  
47 - //create a CUBLAS handle  
48 - stat = cublasCreate(&handle);  
49 - if(stat != CUBLAS_STATUS_SUCCESS){  
50 - std::cout<<"CUBLAS Error: initialization failed"<<std::endl;  
51 - exit(1);  
52 - }  
53 -  
54 - int L = R[0] * R[1]; //compute the number of discrete points in a slice  
55 - int index; //result of the max operation  
56 - stim::complex<T> result;  
57 -  
58 - if(sizeof(T) == 8)  
59 - stat = cublasIcamax(handle, L, (const cuComplex*)X[n], 1, &index);  
60 - else  
61 - stat = cublasIzamax(handle, L, (const cuDoubleComplex*)X[n], 1, &index);  
62 -  
63 - index -= 1; //adjust for 1-based indexing  
64 -  
65 - //if there was a GPU error, terminate  
66 - if(stat != CUBLAS_STATUS_SUCCESS){  
67 - std::cout<<"CUBLAS Error: failure finding maximum value."<<std::endl;  
68 - exit(1);  
69 - }  
70 -  
71 - //retrieve the maximum value for this slice and store it in the maxVal array  
72 - std::cout<<X[n]<<std::endl;  
73 - HANDLE_ERROR(cudaMemcpy(&result, X[n] + index, sizeof(stim::complex<T>), cudaMemcpyDeviceToHost));  
74 - return result;  
75 - }  
76 -  
77 -public:  
78 -  
79 - enum attribute {magnitude, real, imaginary};  
80 -  
81 - //constructor (no parameters)  
82 - complexfield() : field<stim::complex<T>, D>(){};  
83 -  
84 - //constructor (resolution specified)  
85 - complexfield(unsigned int r0, unsigned int r1) : field<stim::complex<T>, D>(r0, r1){};  
86 -  
87 - //assignment from a field of complex values  
88 - complexfield & operator=(const field< stim::complex<T>, D > rhs){  
89 - field< complex<T>, D >::operator=(rhs);  
90 - return *this;  
91 - }  
92 -  
93 - //assignment operator (scalar value)  
94 - complexfield & operator= (const complex<T> rhs){  
95 -  
96 - field< complex<T>, D >::operator=(rhs);  
97 - return *this;  
98 - }  
99 -  
100 - //assignment operator (vector value)  
101 - complexfield & operator= (const vec< complex<T>, D > rhs){  
102 -  
103 - field< complex<T>, D >::operator=(rhs);  
104 - return *this;  
105 - }  
106 -  
107 - //cropping  
108 - complexfield crop(unsigned int width, unsigned int height){  
109 -  
110 - complexfield<T, D> result;  
111 - result = field< complex<T>, D>::crop(width, height);  
112 - return result;  
113 - }  
114 -  
115 - void toImage(std::string filename, attribute type = magnitude, unsigned int n=0){  
116 -  
117 - field<T, 1> rf(R[0], R[1]);  
118 -  
119 - //get cuda parameters  
120 - dim3 blocks, grids;  
121 - cuda_params(grids, blocks);  
122 -  
123 - if(type == magnitude){  
124 - gpu_complexfield_mag <<<grids, blocks>>> (rf.ptr(), X[n], R[0], R[1]);  
125 - rf.toImage(filename, n, true);  
126 - }  
127 -  
128 - }  
129 -  
130 -  
131 -};  
132 -  
133 -  
134 -} //end namespace rts  
135 -  
136 -  
137 -#endif 1 +#ifndef RTS_COMPLEXFIELD_H
  2 +#define RTS_COMPLEXFIELD_H
  3 +
  4 +#include "cublas_v2.h"
  5 +#include <cuda_runtime.h>
  6 +
  7 +#include "../math/field.cuh"
  8 +#include "../math/complex.h"
  9 +#include "../math/realfield.cuh"
  10 +
  11 +namespace stim{
  12 +
  13 +template<typename T>
  14 +__global__ void gpu_complexfield_mag(T* dest, complex<T>* source, unsigned int r0, unsigned int r1){
  15 +
  16 + int iu = blockIdx.x * blockDim.x + threadIdx.x;
  17 + int iv = blockIdx.y * blockDim.y + threadIdx.y;
  18 +
  19 + //make sure that the thread indices are in-bounds
  20 + if(iu >= r0 || iv >= r1) return;
  21 +
  22 + //compute the index into the field
  23 + int i = iv*r0 + iu;
  24 +
  25 + //calculate and store the result
  26 + dest[i] = source[i].abs();
  27 +}
  28 +
  29 +/*This class stores functions for saving images of complex fields
  30 +*/
  31 +template<typename T, unsigned int D = 1>
  32 +class complexfield : public field< stim::complex<T>, D >{
  33 + using field< stim::complex<T>, D >::R;
  34 + using field< stim::complex<T>, D >::X;
  35 + using field< stim::complex<T>, D >::shape;
  36 + using field< stim::complex<T>, D >::cuda_params;
  37 +
  38 +
  39 +
  40 +public:
  41 +
  42 + //find the maximum value of component n
  43 + stim::complex<T> find_max(unsigned int n){
  44 + cublasStatus_t stat;
  45 + cublasHandle_t handle;
  46 +
  47 + //create a CUBLAS handle
  48 + stat = cublasCreate(&handle);
  49 + if(stat != CUBLAS_STATUS_SUCCESS){
  50 + std::cout<<"CUBLAS Error: initialization failed"<<std::endl;
  51 + exit(1);
  52 + }
  53 +
  54 + int L = R[0] * R[1]; //compute the number of discrete points in a slice
  55 + int index; //result of the max operation
  56 + stim::complex<T> result;
  57 +
  58 + if(sizeof(T) == 8)
  59 + stat = cublasIcamax(handle, L, (const cuComplex*)X[n], 1, &index);
  60 + else
  61 + stat = cublasIzamax(handle, L, (const cuDoubleComplex*)X[n], 1, &index);
  62 +
  63 + index -= 1; //adjust for 1-based indexing
  64 +
  65 + //if there was a GPU error, terminate
  66 + if(stat != CUBLAS_STATUS_SUCCESS){
  67 + std::cout<<"CUBLAS Error: failure finding maximum value."<<std::endl;
  68 + exit(1);
  69 + }
  70 +
  71 + //retrieve the maximum value for this slice and store it in the maxVal array
  72 + std::cout<<X[n]<<std::endl;
  73 + HANDLE_ERROR(cudaMemcpy(&result, X[n] + index, sizeof(stim::complex<T>), cudaMemcpyDeviceToHost));
  74 + return result;
  75 + }
  76 +
  77 +public:
  78 +
  79 + enum attribute {magnitude, real, imaginary};
  80 +
  81 + //constructor (no parameters)
  82 + complexfield() : field<stim::complex<T>, D>(){};
  83 +
  84 + //constructor (resolution specified)
  85 + complexfield(unsigned int r0, unsigned int r1) : field<stim::complex<T>, D>(r0, r1){};
  86 +
  87 + //assignment from a field of complex values
  88 + complexfield & operator=(const field< stim::complex<T>, D > rhs){
  89 + field< complex<T>, D >::operator=(rhs);
  90 + return *this;
  91 + }
  92 +
  93 + //assignment operator (scalar value)
  94 + complexfield & operator= (const complex<T> rhs){
  95 +
  96 + field< complex<T>, D >::operator=(rhs);
  97 + return *this;
  98 + }
  99 +
  100 + //assignment operator (vector value)
  101 + complexfield & operator= (const vec< complex<T>, D > rhs){
  102 +
  103 + field< complex<T>, D >::operator=(rhs);
  104 + return *this;
  105 + }
  106 +
  107 + //cropping
  108 + complexfield crop(unsigned int width, unsigned int height){
  109 +
  110 + complexfield<T, D> result;
  111 + result = field< complex<T>, D>::crop(width, height);
  112 + return result;
  113 + }
  114 +
  115 + void toImage(std::string filename, attribute type = magnitude, unsigned int n=0){
  116 +
  117 + field<T, 1> rf(R[0], R[1]);
  118 +
  119 + //get cuda parameters
  120 + dim3 blocks, grids;
  121 + cuda_params(grids, blocks);
  122 +
  123 + if(type == magnitude){
  124 + gpu_complexfield_mag <<<grids, blocks>>> (rf.ptr(), X[n], R[0], R[1]);
  125 + rf.toImage(filename, n, true);
  126 + }
  127 +
  128 + }
  129 +
  130 +
  131 +};
  132 +
  133 +
  134 +} //end namespace rts
  135 +
  136 +
  137 +#endif
1 -#ifndef RTS_FIELD_CUH  
2 -#define RTS_FIELD_CUH  
3 -