牛顿迭代法求平方根

20201012193858

如图,一个曲线方程 \(f(x)\),在它的 \(f(x_n)\) 处画一条切线与 \(x\) 轴相交,交点为 \(x_{n+1}\),如果继续在它的 \(f(x_{n+1})\) 处画一条切线与 \(x\) 轴相交,会得到交点 \(x_{n+2}\)。然后重复这个过程,可以发现交点 \(x_{n+m}\) 会无限逼近方程 \(f(x)=0\) 的解,最终可以得到一个与理想值无限靠近的解。

关于为什么可以用这个方法,或者说,可以用这个方法的函数有什么条件,可以参考维基百科:

20201012205648

而我们这里讨论的是求平方根,很显然可以使用这个方法。比如,我们要求 N 的平方根。可以分为一下几个步骤:

  • 将问题转化为求方程 \(f(x) = x^2 - N\),当 \(f(x) = 0\) 时方程的解。
  • 函数 \(f(x)\) 的导函数是:\(f^{'}(x)=2x\)
  • 那么 \(f(x)\) 函数的曲线在 \((x_n,x_n^{\ 2}-N)\) 点处切线的斜率为:\(2x_n\)
  • 那么切线函数为:\(g(x) = 2x_n(x-x_n) + (x_n^{\ 2} - N)\),即:\(g(x) = 2x_nx - x_n^{\ 2} - N\)
  • 所以切线与 \(x\) 轴的交点 \(x_{n+1} = \displaystyle\frac{x_n + \frac{N}{x_n}}{2}\)
  • 最后,我们将得到的交点值的平方与 \(N\) 比较,循环以上过程直至得到满意的值。

对于 \(x_1\) 的值,我们选择 \(N\) 就好。

C 代码:

double abs(double x)
{
    return x < 0 ? -x : x;
}

/**
 * 精度为 0.00001
 * @param x
 * @return
 */
double sqrt(double x)
{
    if (x < 0)
        return 0;
    else
    {
        double err = 0.00001; // 设置误差范围,当误差小于这个值时我们认为得到了准确值
        double root = x;
        while (abs(x - root * root) > err)
            root = (root + x / root) / 2; // 运用牛顿迭代法的公式进行计算
        return root;
    }
}

参考:https://blog.csdn.net/chenrenxiang/article/details/78286599

posted @ 2020-10-12 21:16  模糊计算士  阅读(1064)  评论(0)    收藏  举报