gpt4 book ai didi

c++ - 一次计算正弦和余弦

转载 作者:可可西里 更新时间:2023-11-01 16:45:13 32 4
gpt4 key购买 nike

我有一个科学代码,它使用同一参数的正弦和余弦(我基本上需要该参数的复指数)。我想知道是否有可能比分别调用正弦和余弦函数更快地执行此操作。

此外,我只需要大约 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

最佳答案

如果您寻求使用幂级数获得良好(但不高)准确度的快速评估,您应该使用切比雪夫多项式的展开:将系数制成表格(您需要非常少的 0.1% 准确度)并使用递归关系评估展开对于这些多项式(这真的很容易)。

引用资料:

  1. 制表系数:http://www.ams.org/mcom/1980-34-149/S0025-5718-1980-0551302-5/S0025-5718-1980-0551302-5.pdf
  2. 切比雪夫展开的评估:https://en.wikipedia.org/wiki/Chebyshev_polynomials

您需要 (a) 在 -pi/2..+pi/2 范围内获取“减少的”参数,然后 (b) 在参数实际应该出现时处理结果中的符号完整基本区间的“另一半”-pi..+pi。这些方面应该不会造成重大问题:

  1. 确定(并“记住”为整数 1 或 -1)原始角度的符号并继续计算绝对值。
  2. 使用模函数减少到区间 0..2PI
  3. 确定(并“记住”为整数 1 或 -1)它是否在“第二”一半,如果是,则减去 pi*3/2,否则减去 pi/2。注意:这有效地互换了正弦和余弦(符号除外);在最终评估中考虑到这一点。

这完成了在 -pi/2..+pi/2 中获取角度的步骤在使用 Cheb 展开计算正弦和余弦后,应用上面步骤 1 和 3 的“标志”以获得值中的正确符号。

关于c++ - 一次计算正弦和余弦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31814105/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com