如何做CUBLAS的复数的权力? [英] how to do power of complex number in CUBLAS?
问题描述
我正在将我的c ++代码移植到CUDA& CUBLAS。我使用stl :: complex的复杂计算(即pow,log,exp等),但我没有看到相同的功能定义在CuComplex库。我不知道如何创建这些函数,但我发现了一些代码在线
I am porting my c++ code to CUDA & CUBLAS. I use stl::complex for complex computation (i.e. pow, log, exp, etc.) but I didn't see the same functions defined in CuComplex library. I don't know how to create those functions but I found some codes online
#include <iostream>
#include <cublas_v2.h>
#include <cuComplex.h>
using namespace std;
typedef cuDoubleComplex Complex;
#define complex(x, y) make_cuDoubleComplex(x, y)
__host__ __device__ double cabs(const Complex& z) {return cuCabs(z);}
__host__ __device__ double carg(const Complex& z) {return atan2(cuCreal(z), cuCimag(z));}
__host__ __device__ Complex polar(const double &magnitude, const double &angle) {return complex(magnitude*cos(angle), magnitude*sin(angle));}
__host__ __device__ Complex cexp(const Complex& z) {return polar( exp(cuCreal(z)), cuCimag(z));}
__host__ __device__ Complex czlog(const Complex& z) {return complex( ::log(cabs(z)), carg(z) );}
__host__ __device__ Complex cpow(const Complex& z, const int &exponent) {return cexp( cuCmul(czlog(z), complex((double )exponent, 0)) );}
void main(void)
{
Complex z=complex(0.34, 0.56);
cout << cuCreal(cpow(z, 2)) << " " << cuCimag(cpow(z, 2)) << endl;
}
上述结果没有给出正确的答案。这是什么错误的cpow?
the above results didn't give right answer. Is that anything wrong with the cpow? Is that any better to do the power and other function on complex number?
推荐答案
这是不正确的:
__host__ __device__ double carg(const Complex& z) {return atan2(cuCreal(z), cuCimag(z));}
因此,您应该使用:
__host__ __device__ double carg(const Complex& z) {return atan2(cuCimag(z), cuCreal(z));}
$ b b
我不知道你的权力函数( cpow
)。您是否尝试过 DeMoivre定理?我不知道在计算上是最好的方法,但似乎第一次的业务是得到正确的答案。
I'm not sure about your power function (cpow
) either. Have you tried DeMoivre's theorem? I don't know computationally the best method, but it seems like the first order of business is to get the right answer.
其他注意事项:
- 我不认为这个问题与CUBLAS有什么关系。
- 当发布这样的问题时,
下面是一个基于DeMoivre定理的工作示例:
Here's a worked example based on DeMoivre's theorem:
$ 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
$
我不建议这是彻底测试代码,但它似乎是在正确的轨道,并给出正确的答案您的测试用例。
I'm not suggesting this is thoroughly tested code, but it seems to be on the right track and gives the right answer for your test case.
这篇关于如何做CUBLAS的复数的权力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!