为什么`x = x *(1.5f-(xhalf * x * x));`可以是牛顿方法迭代?

时间:2013-07-04 16:46:54

标签: algorithm math square-root newtons-method

好的,到目前为止,我想很多人都知道着名的fast inverse square root(请参阅Writing your own square root function0x5f3759df上的详情)

这是代码

float FastInvSqrt(float x) {
  float xhalf = 0.5f * x;
  int i = *(int*)&x;         // evil floating point bit level hacking
  i = 0x5f3759df - (i >> 1);  // what the fuck?
  x = *(float*)&i;
  x = x*(1.5f-(xhalf*x*x)); // one Newton Method iteration
  return x;
}

好的,我不需要知道更多魔法0x5f3759df

我不明白为什么x*(1.5f-(xhalf*x*x))Newton Method次迭代?

我试过分析,但却无法得到它。

因此,假设r是实数,x是r的倒数sqrt。

1 / (x^2) = r,然后是f(x) = r*(x^2)-1f'(x) = 2 * r * x

所以一次迭代应该是x1 = x - f(x)/f'(x) = x / 2 + 1 / (2 * r * x),对吗?

x * (1.5 - ((r / 2) * x * x))怎么来?(注意我在这里用xhalf替换了r / 2


修改

好的f(x) = x^2 - 1/r是另一种形式,让我计算

f(x) = x^2 - 1 / r

f'(x) = 2 * x

所以x1 = x - (f(x)/f'(x)) = x - (x^2 -(1 / r))/(2*x) = x / 2 + 1 / (2 * r * x),它仍然与代码中使用的公式完全不同,对吗?

2 个答案:

答案 0 :(得分:6)

维基百科说功能是(使用您的变量名称):

  

f(x)= 1 / x 2 - r

然后我们有:

  

f'(x)= -2 / x 3

迭代是:

  

x - f(x)/ f'(x)=

     

x - (1 / x 2 - r)/( - 2 / x 3 )=

     

x + x 3 / 2 *(1 / x 2 - r)=

     

x + x / 2 - r / 2 * x 3 =

     

x *(1.5 - r / 2 * x * x)

这就是你在代码中看到的。

答案 1 :(得分:3)

Newton's method是根据迭代定义的

  

x i + 1 = x i - f(x i )/ f'(x i

(其中f'(x)是f(x)的一阶导数)。要找到r的反向根,需要找到函数f(x)= x - 1 / sqrt(r)的零(或等效地,f(x)= x 2 - 1 / R)。只需获取衍生物,将其插入到迭代步骤的定义中,简化并获得答案。

实际上,代码中使用的确切形式来自于使用第三种等效形式:

  

f(x)= x -2 - r

有关推导的详细步骤,请参阅this article。它也来自Wikipedia article on fast inverse square root