【问题标题】:How-to apply Newton-Raphson method to find roots of a quintic function如何应用 Newton-Raphson 方法找到五次函数的根
【发布时间】:2013-12-23 19:16:41
【问题描述】:

说明

我开发了一种算法,实现了 Newton-Raphson 方法来查找五次函数的根。我必须反映的结果是303.6。但是,我的实现无法达到要求。

数据

参数

g = 9.81; 
Ds = 0.198; 
uj = 805.9; 
W = 0.0557;

方程

0.024*((gDs/uj^2)^(1/3))(Y^(5/3)) + 0.2*(Y^(2/3)) - ((2.85/W)^(2/3)) = 0

Y 的导数:

(0.04*d^(1/3)⋅g(1/3)⋅y^(2/3)) / u(2/3) + 2/15*y^(1/3)

解决Y的根

代码

    import java.lang.*;
    public class InvokeNewton {
    public static void main(String argv[]) {
    double del = 1e-5,
    double xx = 0 ;
    double dx =0, 
    double x= Math.PI/2;
    int k = 0;
    while (Math.abs(xx-x) > del && k<10 && f(x)!=0) {
      dx = f(x)/d(x);
      xx=x;
      x =x - dx;
      k++;

    System.out.println("Iteration number: " + k);
    System.out.println("Root obtained: " + x);
    System.out.println("Estimated error: " + Math.abs(xx-x));
    }
  }

    // Method to provide function f(x)

      public static double f(double x) {
        return 0.024*(Math.pow(g * Ds / Math.pow(uj, 2.0),(1.0/3.0)) *                       (Math.pow(Y,5.0/3.0))+ 0.2*(Math.pow(Y,2.0/3.0)) - (Math.pow((2.85/W)(2.0/3.0))));
      }

    // Method to provide the derivative f'(x).

      public static double d(double x) {
        return (0.04*Math.pow(Ds,1.0/3.0)*Math.pow(Y,2.0/3.0)) / Math.pow*uj,2.0/3.0) + 2 /    15*Math.pow(Y,1.0/3.0);
      }

}

输出

    Iteration number: 1
Root obtained: 3.65373153496716
Estimated error: 2.0829352081722634
Iteration number: 2
Root obtained: 5.2246000232674215
Estimated error: 1.5708684883002615
Iteration number: 3
Root obtained: 6.618389759316356
Estimated error: 1.3937897360489346
Iteration number: 4
Root obtained: 7.906164279270034
Estimated error: 1.287774519953678
Iteration number: 5
Root obtained: 9.119558352547333
Estimated error: 1.213394073277299
Iteration number: 6
Root obtained: 10.27633029334909
Estimated error: 1.1567719408017574
Iteration number: 7
Root obtained: 11.387769167896339
Estimated error: 1.1114388745472485
Iteration number: 8
Root obtained: 12.461641418739712
Estimated error: 1.0738722508433725
Iteration number: 9
Root obtained: 13.503592201954325
Estimated error: 1.041950783214613
Iteration number: 10
Root obtained: 14.517895007865569
Estimated error: 1.0143028059112442

方程和导数已经过检查和双重检查,但是我仍然没有得到想要的输出

参考

Newton Method

【问题讨论】:

  • 你得到了什么结果?这可能会有所帮助。
  • 不需要import java.lang.*; 行。默认情况下,java.lang 中的所有内容都是导入的。
  • 在函数 d 中将 2 / 15 更改为 2.0/15.0 有帮助吗?
  • @doctorlove 我已经尝试过了,但没有任何区别,但感谢您注意到这一点。
  • 那么我认为你需要的迭代次数比 10 多得多。尝试数百次迭代,看看输出是否接近预期结果。

标签: java math derivative newtons-method


【解决方案1】:

代码已作相应修改。该代码提供了 cmets 以简化对您的特定案例的修改。

    public class RootFinder {

    // Method to be called to calculate the root 

    public void InvokeNewton(){
        double del = 1e-10;                                  // Delta or precision; 
        double xx = 0 ;                                      // Storage for previous root

        double dx = 0;                                       // Storage to hold a derivative of a pre-defined function;
        double x= Math.sqrt(beta/alpha);                     // Initial guess;

        while (Math.abs(xx-x) >= del &&  f(x)!= 0.0) {       // Math.abs(xx-x) - Estimated error;
            dx = f(x)/d(x);                                  // Derivative
            xx=x;                                            // New xx value set to previous root for compersion;
            x = x - dx;                                      // Root obtained;
        }
    }// Method to provide function f(x)
                          // !!! Provide your function bellow !!!
    public double f(double x) {
        return (alpha * (Math.pow(x,5.0/3.0)) + 0.2*(Math.pow(x,2.0/3.0)) - beta);
    }

    // Method to provide the derivative f'(x).
                          // !!!Provide the prime derivative of your function bellow!!!
    public double d(double x) {
        return (0.04*Math.pow(jf.getSourceDiameter(),1.0/3.0)*Math.pow(x,2.0/3.0)) / Math.pow(jf.getJetVelocity(),2.0/3.0) + 2.0 /  15.0*Math.pow(x,1.0/3.0);
    }
}

【讨论】:

    【解决方案2】:

    Y^(2/3) 的导数是 2/3*Y^(-1/3)。

    一般来说,首先替换 X=Y^(1/3) 会使算法更加稳定,这样你就有一个普通的多项式五次式,对 X 求解,然后将结果设置为 Y=X^3。

    A=0.024*(g*Ds/uj^2)^(1/3)), B=0.2, C= ((2.85/W)^(2/3))
    
    0=F(X)=A*X^5+B*X^2-C
    F'(X)=4A*X^4+2B*X
    

    对于 X 正值,这是一个从负值到正值的很好的凸函数。 X=0 是最小值,因此不是一个好的初始值。如果X=(C/A)^(1/5),则F(X)中的第一项和最后一项取消,第二项为正,表示一个好的起始值。

    public class InvokeNewton {
      // Define the given constants
      static double g = 9.81, Ds = 0.198, uj = 805.9, W = 0.0557;
      // Combine the constants into to coefficients of the polynomial
      // Executed during class creation
      static double A=0.024*Math.pow(g*Ds/(uj*uj), 1.0/3), B=0.2, C= Math.pow(2.85/W,2.0/3);
      /* The original problem asks for the solution of 
       * A*y^(5/3)+B*y^(2/3)-C, introduce x=y^(1/3) <=> y=x^3
       * The equation to solve now is f(x)=Ax^5+Bx^2-C=0, 
       * a polynomial with derivative f'(x)=5Ax^4+2Bx
       */
    
    
      public static void main(String argv[]) {
        // set the precision with some buffer to the full 1e-16
        double del = 1e-12;
        double xx = 0 ;
        double dx =0;
        /* -------------------
         * initial point obtained by solving Ax^5-C=0
         * Now f(0)<0, f(x)>0 and f is convex monotone increasing
         * for x>0, so Newtons method produces a decreasing 
         * sequence of points quadratically converging to
         * the root of the equation.
         */
        double x= Math.pow(C/A,1.0/5);
        int k = 0;
        while (Math.abs(xx-x) > del && k<20) {
          // Standard Newton method
          dx = f(x)/d(x);
          xx=x;
          x =x - dx;
          k++;
    
          System.out.println("Iteration number: " + k);
          System.out.print("Root obtained: " + x);
          // the number of interest is y=x^3
          System.out.println(" solution Y="+Math.pow(x,3));
          System.out.println("Estimated error: " + Math.abs(xx-x));
        }
      }
    
      // Method to provide function f(x)
    
      public static double f(double x) {
        return A*Math.pow(x,5)+B*Math.pow(x,2)-C;
      }
    
      // Method to provide the derivative f'(x).
    
      public static double d(double x) { 
        return 5*A*Math.pow(x,4)+2*B*x;
      }
    
    }
    

    有结果

     Iteration number: 1
     Root obtained: 7.127382504549578 solution Y=362.06804746760736
     Estimated error: 1.192264780096913
     Iteration number: 2
     Root obtained: 6.7530415629870015 solution Y=307.962806003808
     Estimated error: 0.37434094156257647
     Iteration number: 3
     Root obtained: 6.722154364534209 solution Y=303.75640454448063
     Estimated error: 0.030887198452792752
     Iteration number: 4
     Root obtained: 6.72196107618877 solution Y=303.73020272815836
     Estimated error: 1.932883454385248E-4
     Iteration number: 5
     Root obtained: 6.721961068677178 solution Y=303.7302017099299
     Estimated error: 7.511592237108289E-9
     Iteration number: 6
     Root obtained: 6.721961068677178 solution Y=303.7302017099299
     Estimated error: 0.0
    

    【讨论】:

    • 能否请您评论您的代码以更清晰?我将对其进行审查并对其进行评分。非常感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多