grd*_*fgr 9 c++ algorithm trigonometry
我有一个使用相同参数的正弦和余弦的科学代码(我基本上需要该参数的复数指数).我想知道是否有可能比分别调用正弦和余弦函数更快.
另外我只需要0.1%的精度.那么有什么方法可以找到默认的触发功能并截断功率系列的速度?
我想到的另一件事是,有没有办法执行余数运算,结果总是积极的?在我自己使用的算法中,x=fmod(x,2*pi);但如果x为负数,我需要加2pi(较小的域意味着我可以使用较短的幂级数)
编辑:LUT原来是最好的方法,但我很高兴我了解了其他近似技术.我还建议使用明确的中点近似.这就是我最终做的事情:
const int N = 10000;//about 3e-4 error for 1000//3e-5 for 10 000//3e-6 for 100 000
double *cs = new double[N];
double *sn = new double[N];
for(int i =0;i<N;i++){
double A= (i+0.5)*2*pi/N;
cs[i]=cos(A);
sn[i]=sin(A);
}
Run Code Online (Sandbox Code Playgroud)
以下部分近似(中点)sincos(2*pi*(wc2 + t [j]*(cotp*t [j] -wc)))
double A=(wc2+t[j]*(cotp*t[j]-wc));
int B =(int)N*(A-floor(A));
re += cs[B]*f[j];
im += sn[B]*f[j];
Run Code Online (Sandbox Code Playgroud)
另一种方法可能是使用切比雪夫分解.您可以使用orthogonality属性来查找系数.针对指数进行了优化,它看起来像这样:
double fastsin(double x){
x=x-floor(x/2/pi)*2*pi-pi;//this line can be improved, both inside this
//function and before you input it into the function
double x2 = x*x;
return (((0.00015025063885163012*x2-
0.008034350857376128)*x2+ 0.1659789684145034)*x2-0.9995812174943602)*x;} //7th order chebyshev approx
Run Code Online (Sandbox Code Playgroud)
如果您寻求使用幂级数以良好(但不高)精度进行快速评估,您应该使用切比雪夫多项式的扩展:将系数制成表格(您需要非常少的系数才能达到 0.1% 的精度)并使用这些多项式的递归关系评估扩展(这真的很容易)。
参考:
您需要 (a) 获得 -pi/2..+pi/2 范围内的“简化”参数,然后 (b) 当参数实际上应该位于“其他”中时,处理结果中的符号" 完整基本区间的一半 -pi..+pi。这些方面不应构成主要问题:
这样就完成了获取 -pi/2..+pi/2 角度的步骤。使用 Cheb 展开式评估正弦和余弦后,应用上面步骤 1 和 3 的“标志”以获得值中的正确符号。
| 归档时间: |
|
| 查看次数: |
2116 次 |
| 最近记录: |