如何应用Newton-Raphson方法来查找五次函数的根

时间:2013-12-06 12:25:07

标签: java math derivative newtons-method

描述

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

数据

参数

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

公式

  

0.024 *((g Ds / 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

2 个答案:

答案 0 :(得分:2)

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

一般来说,首先用X = 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

答案 1 :(得分:0)

代码已相应修改。该代码提供了注释,以简化对特定案例的修改。

    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);
    }
}