e in math_constants.h and e^{i foo} calculations

Dear all,

I have 2 questions :

1)When I see /$(MY_CUDA_INSTALL_PATH)/include/math_constants.h I find most of what we normally use - PI in various precisions and forms, various roots etc. but I don’t see ``e" i.e Euler’s number anywhere, where e=2.718281828. I can always define e in my program, but it seems just convenient to have it in math_constants.h, pretty strange that its not there. Am I missing something? Is it located in another place? If yes, where?

2)My problem requires me to compute a lot of expressions of the form e^{i foo} where i is sqrt(-1) and foo can be various real or complex values or functions. I wanted to ask what would be the best way to go about it from both a performance and accuracy point of view. Currently I am doing the following :

#include <cuComplex.h>
.
.
.
double phase_diff = 9.4456*3.14;
cuDoubleComplex my_result, my_theta;
my_result = make_cuDoubleComplex(1.0, 0.0);
// e^{i phase_diff}
my_theta = make_cuDoubleComplex(cos(phase_diff), sin(phase_diff));
my_result = cuCmul(my_result,my_theta);
.
.
.

Is this the best way to do this calculation from both a performance and accuracy point of view? I am essentially using the property :

e^{i \theta} = cos \theta + i sin \theta

Is there a way I could do :

my_result = exp(my_theta);

That would be really convenient but I can’t seem to pass complex numbers to the exp() and expf(). Is there some other way to do it?

I am using CUDA 6.5, on a K20, and :

Distributor ID: Ubuntu
Description: Ubuntu 14.04.2 LTS
Release: 14.04
Codename: trusty

Linux mymachine 3.13.0-53-generic #89-Ubuntu SMP Wed May 20 10:34:39 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Thanks!

  • vihan

CUDA does not currently support standard math functions of complex argument. The rudimentary support for complex numbers that ships with CUDA is the bare minimum needed to facilitate the use of complex data with libraries like CUFFT and CUBLAS. Likewise, the constants declared in math_constants.h are there for the internal needs of the CUDA standard math library. Please note that constants like M_PI exported on some host platforms are also non-standard, this is not something specified by the C/C++ standards. You can easily define whatever constants you need yourself.

You should feel free to file an enhancement request for more extensive support of complex data types in CUDA with NVIDIA, using the bug reporting form linked from he registered developer website (prefix the subject line with “RFE:” to mark it as an enhancement request rather than a bug).

For your home-brew complex exp() function, you would want to utilize the sincos() function for optimal performance. Other than that, your approach is appropriate of using component-wise evaluation followed by joining the components into a new complex number.

thrust::complex (included in the version of thrust that ships with CUDA 7.0) also provides complex capability for both host and device codes, assuming CUDA C++ is in view.

It is not otherwise required to use thrust constructs (containers, algorithms) in order to use thrust::complex in CUDA C++ codes.

https://thrust.github.io/doc/group__complex__numbers.html

Dear njuffa,

Thanks a million for this! I have not tried out the sincos() function, so I will certainly do so. Filing an RFE with Nvidia is a good idea too, I think I will do that. From a longer term standpoint, the ability to do complex operations with complex data types which can also - without any additional abstractions or re-assignments work with cuFFT would be something awesome, lets see if Nvidia listens :-)

Dear txbob,

Thanks a million too! Unfortunately, my production code will stick to CUDA 6.5 for some more time. I will however, check if thrust::complex in the Thrust with CUDA 6.5 can do the job.

Thanks again both of you!

Cheers!

  • vihan