这是不正确的:
__host__ __device__ double carg(const Complex& z) {return atan2(cuCreal(z), cuCimag(z));}
The 复数的极角 http://algebra.nipissingu.ca/tutorials/complex_numbers.html由复数的虚部除以实部的反正切给出。这对应于第一个参数除以第二个参数的比率atan2 http://docs.nvidia.com/cuda/cuda-math-api/group__CUDA__MATH__SINGLE.html#group__CUDA__MATH__SINGLE_1gd89b766e91b1c84f2e8e81beb750707d
因此你应该使用:
__host__ __device__ double carg(const Complex& z) {return atan2(cuCimag(z), cuCreal(z));}
我不确定你的幂函数(cpow
) 任何一个。你有没有尝试过德莫弗定理 http://algebra.nipissingu.ca/tutorials/complex_numbers.html?我不知道最好的计算方法,但似乎首要任务是得到正确的答案。
补充笔记:
- 我认为这个问题与CUBLAS没有任何关系
- 当发布这样的问题时,如果您给出您正在观察的实际结果以及预期结果,将会很有帮助。
这是一个基于德莫弗定理的有效示例:
$ cat t233.cu
#include <iostream>
#include <math.h>
#include <cuComplex.h>
#include <complex>
typedef double rtype;
typedef cuDoubleComplex ctype;
#define rpart(x) (cuCreal(x))
#define ipart(x) (cuCimag(x))
#define cmplx(x,y) (make_cuDoubleComplex(x,y))
__host__ __device__ rtype carg(const ctype& z) {return (rtype)atan2(ipart(z), rpart(z));} // polar angle
__host__ __device__ rtype cabs(const ctype& z) {return (rtype)cuCabs(z);}
__host__ __device__ ctype cp2c(const rtype d, const rtype a) {return cmplx(d*cos(a), d*sin(a));}
__host__ __device__ ctype cpow(const ctype& z, const int &n) {return cmplx((pow(cabs(z), n)*cos(n*carg(z))), (pow(cabs(z), n)*sin(n*carg(z))));}
int main(){
double r = 0.34;
double i = 0.56;
int n = 2;
std::complex<double> stl_num(r,i);
std::complex<double> cn(n,0);
ctype cu_num = cmplx(r,i);
std::complex<double> stl_ans = std::pow(stl_num, cn);
ctype cu_ans = cpow(cu_num, n);
std::cout << "STL real: " << std::real(stl_ans) << " STL imag: " << std::imag(stl_ans) << std::endl;
std::cout << "CU real: " << rpart(cu_ans) << " CU imag: " << ipart(cu_ans) << std::endl;
return 0;
}
$ nvcc -arch=sm_20 -O3 -o t233 t233.cu
$ ./t233
STL real: -0.198 STL imag: 0.3808
CU real: -0.198 CU imag: 0.3808
$
我并不是说这是经过彻底测试的代码,但它似乎处于正确的轨道上,并为您的测试用例提供了正确的答案。