简体   繁体   English

Carmack / Welsh逆平方根算法是否有偏差

[英]Is the Carmack/Welsh inverse square root algorithm biased

When implementing "Carmack's Inverse Square Root" algorithm I noticed that the results seem biased. 在实现“Carmack的反平方根”算法时,我注意到结果似乎有偏差。 The following code seems to give better results: 以下代码似乎可以提供更好的结果:

float InvSqrtF(float x)
{
    // Initial approximation by Greg Walsh.
    int i  = * ( int* ) &x;
    i  = 0x5f3759df - ( i >> 1 );
    float y  = * ( float * ) &i;
    // Two iterations of Newton-Raphson's method to refine the initial estimate.
    x *= 0.5f;
    float f = 1.5F;
    y  = y * ( f - ( x * y * y ) );
    y  = y * ( f - ( x * y * y ) );
    * ( int * )(&y) += 0x13; // More magic.
    return y;
}

The key difference is in the penultimate "more magic" line. 关键的区别在于倒数第二个“更神奇”的界限。 Since the initial results were too low by a fairly constant factor, this adds 19 * 2^(exponent(y)-bias) to the result with just a single instruction. 由于初始结果因相当恒定的因子而过低,因此仅使用一条指令就可将19 * 2 ^(指数(y) - 偏差)添加到结果中。 It seems to give me about 3 extra bits, but am I overlooking something? 它似乎给了我大约3个额外的位,但我忽略了什么?

Newton's method produces a bias. 牛顿的方法会产生偏差。 The function whose zero is to be found, 要找到零的函数,

f(y) = x - 1/y²

is concave, so - unless you start with an y ≥ √(3/x) - the Newton method only produces approximations ≤ 1/√x (and strictly smaller, unless you start with the exact result) with exact arithmetic. 是凹的,所以 - 除非你以≤ 1/√xy ≥ √(3/x) - 牛顿方法只产生近似值≤ 1/√x (严格地说,除非你从精确的结果开始,否则精确算术)。

Floating point arithmetic occasionally produces too large approximations, but typically not in the first two iterations (since the initial guess usually isn't close enough). 浮点运算有时会产生过大的近似值,但通常不会在前两次迭代中产生(因为初始猜测通常不够接近)。

So yes, there is a bias, and adding a small quantity generally improves the result. 所以是的,存在偏差,并且添加少量通常会改善结果。 But not always. 但不总是。 In the region around 1.25 or 0.85 for example, the results without the adjustment are better than with. 例如,在1.25或0.85附近的区域,没有调整的结果优于。 In other regions, the adjustment yields one bit of additional precision, in yet others more. 在其他地区,调整产生一点额外的精度,而在其他地区则更多。

In any case, the magic constant to add should be adjusted to the region from which x is most often taken for the best results. 在任何情况下,要添加的魔法常数应调整到最常采用x的区域以获得最佳结果。

As this method is an approximation, the result will be overestimated some times and underestimated some others. 由于这种方法是近似的,结果将被高估一些,而低估了其他一些。 You can find on McEniry's paper some nice figures about how this error is distributed for different configurations, and the math behind them. 您可以在McEniry的论文中找到关于如何针对不同配置分配此错误以及它们背后的数学一些很好的数据。

So, unless you have solid proofs that in your domain of application the result is clearly biased, I would prefer tuning the magic constant as suggested in Lomont's document :-) 所以,除非你有坚实的证据证明在你的应用领域中结果显然存在偏差,我宁愿根据Lomont的文件中的建议调整魔术常数:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM