📜  牛顿拉夫森法程序

📅  最后修改于: 2021-05-04 11:17:17             🧑  作者: Mango

给定浮点数x的函数f(x)和根的初始猜测,请在区间中找到函数的根。在此,f(x)表示代数或先验方程。
为简单起见,我们假设函数的导数也作为输入提供。
例子:

Input: A function of x (for example x3 – x2 + 2),
       derivative function of x (3x2 – 2x for above example)
       and an initial guess x0 = -20
Output: The value of root is : -1.00
        OR any other value close to root.

我们已经讨论了以下在集合1和集合2中查找根的方法
设置1:平分法
第二组:错误位置的方法
与以上两种方法比较:

  1. 在以前的方法中,我们得到了一个间隔。在这里,我们需要root的初始猜测值。
  2. 保证前两种方法可以收敛,在某些情况下,牛顿·拉赫森可能不会收敛。
  3. 牛顿拉夫森法需要导数。某些功能可能难以执行
    无法区分。
  4. 对于许多问题,Newton Raphson方法的收敛速度高于上述两种方法。
  5. 而且,它可以识别重复的根,因为它不会显式查找f(x)的符号的变化。

公式:
从初始猜测x 1开始,Newton Raphson方法使用以下公式查找x的下一个值,即从前一个值x n获得x n + 1

牛顿公式

算法:
输入:初始x,func(x),derivFunc(x)
输出:Func()的根

  1. 针对给定的初始x计算func(x)和derivFunc(x)的值
  2. 计算h:h = func(x)/ derivFunc(x)
  3. 当h大于允许误差ε
    1. h = func(x)/ derivFunc(x)
    2. x = x – h

下面是上述算法的实现。

C++
// C++ program for implementation of Newton Raphson Method for
// solving equations
#include
#define EPSILON 0.001
using namespace std;
 
// An example function whose solution is determined using
// Bisection Method. The function is x^3 - x^2  + 2
double func(double x)
{
    return x*x*x - x*x + 2;
}
 
// Derivative of the above function which is 3*x^x - 2*x
double derivFunc(double x)
{
    return 3*x*x - 2*x;
}
 
// Function to find the root
void newtonRaphson(double x)
{
    double h = func(x) / derivFunc(x);
    while (abs(h) >= EPSILON)
    {
        h = func(x)/derivFunc(x);
  
        // x(i+1) = x(i) - f(x) / f'(x) 
        x = x - h;
    }
 
    cout << "The value of the root is : " << x;
}
 
// Driver program to test above
int main()
{
    double x0 = -20; // Initial values assumed
    newtonRaphson(x0);
    return 0;
}


Java
// Java program for implementation of
// Newton Raphson Method for solving
// equations
class GFG {
     
    static final double EPSILON = 0.001;
     
    // An example function whose solution
    // is determined using Bisection Method.
    // The function is x^3 - x^2 + 2
    static double func(double x)
    {
        return x * x * x - x * x + 2;
    }
     
    // Derivative of the above function
    // which is 3*x^x - 2*x
    static double derivFunc(double x)
    {
        return 3 * x * x - 2 * x;
    }
     
    // Function to find the root
    static void newtonRaphson(double x)
    {
        double h = func(x) / derivFunc(x);
        while (Math.abs(h) >= EPSILON)
        {
            h = func(x) / derivFunc(x);
     
            // x(i+1) = x(i) - f(x) / f'(x)
            x = x - h;
        }
     
        System.out.print("The value of the"
                + " root is : "
                + Math.round(x * 100.0) / 100.0);
    }
     
    // Driver code
    public static void main (String[] args)
    {
         
        // Initial values assumed
        double x0 = -20;
        newtonRaphson(x0);
    }
}
 
// This code is contributed by Anant Agarwal.


Python3
# Python3 code for implementation of Newton
# Raphson Method for solving equations
 
# An example function whose solution
# is determined using Bisection Method.
# The function is x^3 - x^2 + 2
def func( x ):
    return x * x * x - x * x + 2
 
# Derivative of the above function
# which is 3*x^x - 2*x
def derivFunc( x ):
    return 3 * x * x - 2 * x
 
# Function to find the root
def newtonRaphson( x ):
    h = func(x) / derivFunc(x)
    while abs(h) >= 0.0001:
        h = func(x)/derivFunc(x)
         
        # x(i+1) = x(i) - f(x) / f'(x)
        x = x - h
     
    print("The value of the root is : ",
                             "%.4f"% x)
 
# Driver program to test above
x0 = -20 # Initial values assumed
newtonRaphson(x0)
 
# This code is contributed by "Sharad_Bhardwaj"


C#
// C# program for implementation of
// Newton Raphson Method for solving
// equations
using System;
class GFG {
     
    static double EPSILON = 0.001;
     
    // An example function whose solution
    // is determined using Bisection Method.
    // The function is x^3 - x^2 + 2
    static double func(double x)
    {
        return x * x * x - x * x + 2;
    }
     
    // Derivative of the above function
    // which is 3*x^x - 2*x
    static double derivFunc(double x)
    {
        return 3 * x * x - 2 * x;
    }
     
    // Function to find the root
    static void newtonRaphson(double x)
    {
        double h = func(x) / derivFunc(x);
        while (Math.Abs(h) >= EPSILON)
        {
            h = func(x) / derivFunc(x);
     
            // x(i+1) = x(i) - f(x) / f'(x)
            x = x - h;
        }
     
        Console.Write("The value of the"
                    + " root is : "
                    + Math.Round(x * 100.0) / 100.0);
    }
     
    // Driver code
    public static void Main ()
    {
         
        // Initial values assumed
        double x0 = -20;
        newtonRaphson(x0);
    }
}
 
// This code is contributed by nitin mittal


PHP
= $EPSILON)
    {
        $h = func($x) / derivFunc($x);
 
        // x(i+1) = x(i) -
        // f(x) / f'(x)
        $x = $x - $h;
    }
 
    echo "The value of the ".
           "root is : " , $x;
}
 
// Driver Code
$x0 = -20; // Initial values assumed
newtonRaphson($x0);
 
// This code is contributed by ajit
?>


Javascript


输出:

The value of root is : -1.00 

这是如何运作的?
这个想法是在点x 1处画一条与f(x)相切的线。切线与x轴相交的点应比x 1更好地估计根。将此点称为x 2 。计算f(x 2 ),并在x 2处绘制切线。

牛顿拉夫森法

我们知道线的从(X 1,F(X 1))到(x 2,0)为f的是斜率‘(×1))其中,f’表示导函数f的。

f'(x1) = (0 - f(x1)) / (x2 - x1) 

f'(x1) *  (x2 - x1) =  - f(x1)

x2 =  x1 - f(x1) / f'(x1) 

By finding this point 'x2', we move closer towards the root.
We have to keep on repeating the above step till we get really close to 
the root or we find it.

In general, 
xn+1 =  xn - f(xn) / f'(xn) 

使用泰勒级数的替代解释:

Let x1 be the initial guess. 

We can write x2 as below:
  xn+1  = xn + h ------- (1)
Here h would be a small value that can be positive or negative.

According to Taylor's Series, 
ƒ(x) that is infinitely differentiable can be written as below
f(xn+1) = f(xn  + h) 
       = f(xn) + h*f'(xn) + ((h*h)/2!)*(f''(xn)) + ...

Since we are looking for root of function, f(xn+1) = 0

f(xn) + h*f'(xn) + ((h*h)/2!)*(f''(xn)) + ... = 0

Now since h is small, h*h would be very small. 
So if we ignore higher order terms, we get

f(xn) + h*f'(xn) = 0

Substituting this value of h = xn+1 - xn from equation (1) we get, 
f(xn) + (xn+1  - xn)*f'(xn) = 0

xn+1 =  xn - f(xn) / f'(xn)  

笔记:

  1. 我们通常使用这种方法来改善通过二等分法或错误位置方法获得的结果。
  2. 巴比伦方根法是从牛顿-拉夫森法推导而来的。