关于java的牛顿方法示例的解释

时间:2012-01-23 12:32:20

标签: java newtons-method

http://introcs.cs.princeton.edu/java/13flow/Sqrt.java.html

public class Sqrt { 
    public static void main(String[] args) { 

        // read in the command-line argument
        double c = Double.parseDouble(args[0]);
        double epsilon = 1e-15;    // relative error tolerance
        double t = c;              // estimate of the square root of c

        // repeatedly apply Newton update step until desired precision is achieved
        while (Math.abs(t - c/t) > epsilon*t) {
            t = (c/t + t) / 2.0;
        }

        // print out the estimate of the square root of c
        System.out.println(t);
    }

}

事情就是......我完全理解程序是如何运作的。我遇到的问题是方程式f(x)= x ^ 2 - c以及它与上述代码的关系。比如,为什么要用x除以x(x-c / x)?对于这些例子中的一些,似乎缺少数学解释。换句话说,我正在寻找一个简单的数学观点的解释,而不是编码那么多。

4 个答案:

答案 0 :(得分:4)

您获得c并且想要解决

t = sqrt(c)

或等效,

c = t^2

或者再一次,

c - t^2 = 0.

我将调用上面的等式f(t) = 0(不提及c,因为它是给定的常量)。 牛顿方法迭代t的试用值,我将其标记为t_i, t_{i+1}, ...

泰勒扩展到第一顺序是:

f(t_i + dt_i) = f(t_i) + dt_i * f'(t_i) + ...

因此,如果您没有f(t_i) = 0,则添加dt_i以便

f(t_i + dt_i) nearly = 0 = f(t_i) + dt_i * f'(t_i) + ...

所以dt_i = -f(t_i) / f'(t_i),即f(t_i + -f(t_i) / f'(t_i))f(t_i)更接近于零。

如果您为f(t) = c - t^2执行导数,您会发现代码t_{i+1} = (c / t_i + t_i) / 2中的等式只是迭代公式t_{i+1} = t_i + dt_i,其中dt_i估算在上面。

这是迭代方法,因此它没有提供精确的解决方案。您需要决定何时停止(足够的精度),否则算法将永远持续下去。这就是您检查f(t_i) < threshold而不是真f(t_i) = 0的原因。在他们的案例中,他们选择了threshold = epsilon * t^2;我认为使用t^2的乘法因为如果你使用固定常数作为阈值,你可能会遇到数值精度问题(即如果你正在玩万亿,你永远不会得到{{1的固定精度由于浮点表示的有限精度。)

答案 1 :(得分:1)

基于code,已经在Javadoc评论中解释了以下内容:

 *  Computes the square root of a nonnegative number c using
 *  Newton's method:
 *     - initialize t = c
 *     - replace t with the average of c/t and t
 *     - repeat until desired accuracy reached

答案 2 :(得分:1)

好的,我会给它一个bash(参见内联评论):

public class Sqrt { 
    public static void main(String[] args) { 

        // read in the command-line argument (i.e. this is the value that we want
        // square root from.)
        double c = Double.parseDouble(args[0]); 

        // Since the the square root of non-squares are irrational, we need some
        // error tolerance.  In other words, if the answer is less than epsilon wrong
        // we'll take it.  
        double epsilon = 1e-15;    // relative error tolerance

        // t is our first guess (c / 2.0 works well too - in fact it tends to be
        // better.)
        double t = c;              // estimate of the square root of c

        // repeatedly apply Newton update step until desired precision is achieved
        // The condition here is rather elegant and optimized... to see why it works,
        // simply break it up.  The absolute is there to cater for negative values, but
        // for c >= 0:
        //   | c - c/t | > epsilon * t
        //   t * ( t - c / t ) > epsilon
        //   tt - c = > epsilon)
        while (Math.abs(t - c/t) > epsilon*t) {
            // Improve the guess by applying Newton's genius :-)
            // Take the original number, divide by the guess add t and take the
            // average.
            t = ( c / t + t) / 2.0;
        }

    // print out the estimate of the square root of c
    System.out.println(t);
}

}

答案 3 :(得分:0)

ejlab.net jelmar

我相信上面提到的代码来自R.Sedgewick的书“Java编程简介”,第62页。他在本书中试图说明你可以使用f(x)=x^2-c作为一个特例来查找任何正数的平方根。它是如何工作的:

牛顿的方法陈述X(n+1)=X(n)-(F(X(n))/F'(X(n)))。假设在F(X)=X^2-CC=2,因为我们正在寻找2的平方根(如果你想找到36的平方根,那么C=36等)。然后函数F(X)的一阶导数是F'(X)=2X。应用牛顿方法得到

X(n+1)=X(n)-((X^2-C)/(2X))

我们得到X(0)=2

n=1, X(1)=2-(2^2-2)/(2*2)&gt; X(1)=1.5; n=2 X(2)=1.5 -(1.5^2-2)/(2*1.5)&gt; X(2)=1.41666667 等等...