如果你将fastSin中的return重新表述为
return (1-P) * y + P * (y * abs(y))
并将y重写为(对于x>0)
y = 4 * x * (pi-x) / (pi * pi)
你可以看到,y是对sin(x)的二次抛物线一阶逼近,选择它使它穿过(0,0),(pi/2,1)和(pi,0),并且关于x=pi/2对称。因此,我们只能期望我们的函数在0到pi之间是一个很好的逼近值。如果我们想要超出那个范围的值,我们可以使用sin(x)的2-pi周期性和sin(x+pi)=-sin(x)的性质。
y*abs(y)是一个“修正项”,也通过这三个点。 (我不确定为什么使用y*abs(y)而不只是y*y,因为在0-pi范围内y是正的)。
这种总体逼近函数的形式保证了两个函数y和y*y的线性混合,(1-P)*y+P*y*y也会穿过(0,0),(pi/2,1)和(pi,0)。
我们可能期望
y
是
sin(x)
的一个不错的近似值,但希望通过选择一个好的
P
值来获得更好的近似值。
一个问题是“如何选择P?”。个人而言,我会选择在0到pi/2区间上产生最小RMS误差的P值。(不确定这是否是选择
此 P的方法)
将此最小化得到P
这可以被重新排列并解决为p
沃尔夫拉姆阿尔法将初始积分计算为二次方程。
E = (16 π^5 p^2 - (96 π^5 + 100800 π^2 - 967680)p + 651 π^5 - 20160 π^2)/(1260 π^4)
最小值为
min(E) = -11612160/π^9 + 2419200/π^7 - 126000/π^5 - 2304/π^4 + 224/π^2 + (169 π)/420
≈ 5.582129689596371e-07
在
p = 3 + 30240/π^5 - 3150/π^3
≈ 0.2248391013559825
这个非常接近指定的 P=0.225
。
您可以通过添加额外的校正项来提高逼近精度,使其形式类似于 return (1-a-b)*y + a y * abs(y) + b y * y * abs(y)
。我会像上面那样找到a
和b
,这次需要解决两个关于a
和b
的线性方程组,而不是一个关于p
的方程。我不会推导,因为它很繁琐,转换成LaTeX图片也很麻烦... ;)
注意:回答另一个问题时,我想到了另一个有效的P选择。
问题在于使用反射将曲线延伸到(-pi,0)处在x=0处留下了一个折痕。但是,我怀疑我们可以选择P,使得折痕变得平滑。
为此,在x=0处取左右导数,并确保它们相等。这给出了一个关于P的方程。