cos(atan2(y,x))与使用复数<double>,C++的精度

Iva*_*van 0 c++ performance numbers complex-numbers atan2

我正在写一些坐标变换(更具体地说是Joukoswky变换,维基百科Joukowsky变换),我对性能很感兴趣,但当然精确.我试图以两种方式进行坐标转换:

1)使用双精度计算单独的实部和复杂部分,如下所示:

double r2 = chi.x*chi.x + chi.y*chi.y;

//double sq = pow(r2,-0.5*n) + pow(r2,0.5*n); //slow!!!
double sq = sqrt(r2); //way faster!
double co = cos(atan2(chi.y,chi.x));
double si = sin(atan2(chi.y,chi.x));

Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*si*sq;
Run Code Online (Sandbox Code Playgroud)

其中chi和Z是简单的结构,其中x和y为成员.

2)使用复杂:

Z = 0.5 * (chi + (1.0 / chi));
Run Code Online (Sandbox Code Playgroud)

Z和chi很复杂.有趣的是,确实情况1)更快(约20%),但精度差,在逆变换后的逗号后面的第三个十进制数中给出错误,而复数返回确切的数字.那么,问题在于cos(atan2),sin(atan2)?但如果是的话,复合体如何处理呢?

编辑:刚才发现这不是我想到的问题.我必须做一般转型,如

Z = 1/2*(chi ^ n +(1/chi)^ n),到目前为止,上面的代码是我想要的方式.更确切地说,

    double sq = pow(sqrt(r2),n); //way faster!
double co = cos(n*atan2(chi.y,chi.x));
double si = sin(n*atan2(chi.y,chi.x));

Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*(si*sq - sq/si);
Run Code Online (Sandbox Code Playgroud)

还纠正了Zy的错误

int*_*jay 5

鉴于r = sqrt(x*x+y*y):

cos(atan2(y,x)) == x/r
sin(atan2(y,x)) == y/r
Run Code Online (Sandbox Code Playgroud)

以这种方式计算应该更准确,更快速.

当您将这些值插入到Zx和Zy的公式中时,平方根也将被取消,因此您将只剩下基本的算术运算.