COS(ATAN2(Y,X))相对于使用复杂的<双>,C的精度++
-
24-09-2019 - |
题
我正在写一些坐标变换(更具体的Joukoswky变换,维基百科茹科夫斯基变换 ),以及我感兴趣的性能,但当然精度。我试图做的坐标转换有两种方式:
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;
其中志和Z是具有双x和y为成员简单结构。
2)使用复杂的:
Z = 0.5 * (chi + (1.0 / chi));
其中Z和志是复杂的。有有趣的是,确实如此1)速度更快(约20%),但精度差,使第三十进制数错误逗号后逆变换之后,而复杂还给确切的数字。 那么,问题是在COS(ATAN2),罪(ATAN2)?但如果是,如何在复杂的句柄?
编辑:只是想通了,这不完全是我想到的问题。我必须做的一般转化,如
上述Z = 1/2 *(卡^ 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);
另外校正上Z.y的错误。
解决方案
我认为在1)它应该是
Z.y = 0.5*(si*sq - si/sq);
如果你想真正好的表现,你可能想回到第一的原则,并观察
1/(a+ib) = (a-ib)/(a*a+b*b)
没有sqrt()
,atan2()
或cos()
或sin()
。
其他提示
鉴于r = sqrt(x*x+y*y)
:
cos(atan2(y,x)) == x/r
sin(atan2(y,x)) == y/r
计算这种方式应该是更精确和更快。
当你插入这些值代入公式Z.x和Z.y,平方根将抵消一样,所以你会只剩下基本的算术运算。
不隶属于 StackOverflow