【发布时间】:2015-08-04 16:04:19
【问题描述】:
我有一个科学代码,它使用同一参数的正弦和余弦(我基本上需要那个参数的复指数)。我想知道是否有可能比分别调用正弦和余弦函数更快。
另外,我只需要大约 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);
}
以下部分近似(中点) 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];
另一种方法可能是使用切比雪夫分解。您可以使用正交性属性来查找系数。针对指数进行了优化,它看起来像这样:
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
【问题讨论】:
-
cos^2(x) + sin^2(x) = 1。毕达哥拉斯恒等式。 -
我需要调用 sqrt,然后我仍然需要检查参数以查看结果是肯定的还是否定的。我不确定这是否会更快?
-
许多库,例如 Intel 的 MKL,实现了一个名为
sincos之类的函数,它可以满足您的需求。但与您对sin或cos的调用所期望的精度相同,因此可能无法满足您的要求。我认为这提供了对 x86 指令集成员的编程语言级访问。 -
0.1% precision建立查找表。 -
有几个类似的问题,但精度更高What is the fastest way to compute sin and cos together?,c++ libstd compute sin and cos simultaneously,但由于您不需要太多精度,因此简单的表查找或近似就足够了stackoverflow.com/q/18662261/995714stackoverflow.com/q/2088194/995714
标签: c++ algorithm trigonometry