Predictor-Corrector or Modified-Euler method for solving Differential equation

For a given differential equation \frac{dy}{dx}=f(x, y) with initial condition y(x_0)=y_0
find the approximate solution using Predictor-Corrector method.

Predictor-Corrector Method :
The predictor-corrector method is also known as Modified-Euler method.
In the Euler method, the tangent is drawn at a point and slope is calculated for a given step size. Thus this method works best with linear functions, but for other cases, there remains a truncation error. To solve this problem the Modified Euler method is introduced. In this method instead of a point, the arithmetic average of the slope over an interval (x_t, x_{t+1}) is used.

Thus in the Predictor-Corrector method for each step the predicted value of y_{t+1}is calculated first using Euler’s method and then the slopes at the points (x_t, y_t) and (x_{t+1}, y_{t+1}) is calculated and the arithmetic average of these slopes are added to y_t to calculate the corrected value of y_{t+1}.



So,

  • Step – 1 : First the value is predicted for a step(here t+1) : y_{t+1, p} = y_t + h*f(x_t, y_t),
    here h is step size for each increment
  • Step – 2 : Then the predicted value is corrected : y_{t+1, c} = y_t + h*\frac{f(x_t, y_t)+f(x_{t+1}, y_{t+1, p})}{2}
  • Step – 3 : The incrementation is done : x_{t+1}=x_t+h, t=t+1
  • Step – 4 : Check for continuation, if x_{t}<x_{n} then go to step – 1.
  • Step – 5 : Terminate the process.
  • As, in this method, the average slope is used, so the error is reduced significantly. Also, we can repeat the process of correction for convergence. Thus at every step, we are reducing the error thus by improving the value of y.

    Examples:

    Input : eq = \frac {dy}{dx} = y-2x^2+1, y(0) = 0.5, step size(h) = 0.2
    To find: y(1)
    Output: y(1) = 2.18147

    Explanation:
    \begin{tabular}{|l|l|l|l|l|} \hline x_t & y_t    & x_{t+1} & y_{t+1, p}  & y_{t+1, c}  \\ \hline 0    & 0.5     & 0.2  & 0.8     & 0.82444 \\ \hline 0.2  & 0.82444 & 0.4  & 1.17333 & 1.18543 \\ \hline 0.4  & 1.18543 & 0.6  & 1.55852 & 1.55553 \\ \hline 0.6  & 1.55553 & 0.8  & 1.92263 & 1.9012  \\ \hline 0.8  & 1.9012  & 1    & 2.22544 & 2.18147 \\ \hline \end{tabular}

    The final value of y at x = 1 is y=2.18147

    Implementation: Here we are considering the differential equation: \frac {dy}{dx} = y-2x^2+1

    C++

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ code for solving the differential equation
    // using Predictor-Corrector or Modified-Euler method
    // with the given conditions, y(0) = 0.5, step size(h) = 0.2
    // to find y(1)
      
    #include <bits/stdc++.h>
    using namespace std;
      
    // consider the differential equation
    // for a given x and y, return v
    double f(double x, double y)
    {
        double v = y - 2 * x * x + 1;
        return v;
    }
      
    // predicts the next value for a given (x, y)
    // and step size h using Euler method
    double predict(double x, double y, double h)
    {
        // value of next y(predicted) is returned
        double y1p = y + h * f(x, y);
        return y1p;
    }
      
    // corrects the predicted value
    // using Modified Euler method
    double correct(double x, double y,
                   double x1, double y1,
                   double h)
    {
        // (x, y) are of previous step
        // and x1 is the increased x for next step
        // and y1 is predicted y for next step
        double e = 0.00001;
        double y1c = y1;
      
        do {
            y1 = y1c;
            y1c = y + 0.5 * h * (f(x, y) + f(x1, y1));
        } while (fabs(y1c - y1) > e);
      
        // every iteration is correcting the value
        // of y using average slope
        return y1c;
    }
      
    void printFinalValues(double x, double xn,
                          double y, double h)
    {
      
        while (x < xn) {
            double x1 = x + h;
            double y1p = predict(x, y, h);
            double y1c = correct(x, y, x1, y1p, h);
            x = x1;
            y = y1c;
        }
      
        // at every iteration first the value
        // of for next step is first predicted
        // and then corrected.
        cout << "The final value of y at x = "
             << x << " is : " << y << endl;
    }
      
    int main()
    {
        // here x and y are the initial
        // given condition, so x=0 and y=0.5
        double x = 0, y = 0.5;
      
        // final value of x for which y is needed
        double xn = 1;
      
        // step size
        double h = 0.2;
      
        printFinalValues(x, xn, y, h);
      
        return 0;
    }

    chevron_right

    
    

    Java

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // Java code for solving the differential
    // equation using Predictor-Corrector
    // or Modified-Euler method with the 
    // given conditions, y(0) = 0.5, step
    // size(h) = 0.2 to find y(1)
    import java.text.*;
      
    class GFG
    {
          
    // consider the differential equation
    // for a given x and y, return v
    static double f(double x, double y)
    {
        double v = y - 2 * x * x + 1;
        return v;
    }
      
    // predicts the next value for a given (x, y)
    // and step size h using Euler method
    static double predict(double x, double y, double h)
    {
        // value of next y(predicted) is returned
        double y1p = y + h * f(x, y);
        return y1p;
    }
      
    // corrects the predicted value
    // using Modified Euler method
    static double correct(double x, double y,
                        double x1, double y1,
                        double h)
    {
        // (x, y) are of previous step
        // and x1 is the increased x for next step
        // and y1 is predicted y for next step
        double e = 0.00001;
        double y1c = y1;
      
        do
        {
            y1 = y1c;
            y1c = y + 0.5 * h * (f(x, y) + f(x1, y1));
        }
        while (Math.abs(y1c - y1) > e);
      
        // every iteration is correcting the value
        // of y using average slope
        return y1c;
    }
      
    static void printFinalValues(double x, double xn,
                        double y, double h)
    {
      
        while (x < xn) 
        {
            double x1 = x + h;
            double y1p = predict(x, y, h);
            double y1c = correct(x, y, x1, y1p, h);
            x = x1;
            y = y1c;
        }
      
        // at every iteration first the value
        // of for next step is first predicted
        // and then corrected.
        DecimalFormat df = new DecimalFormat("#.#####");
        System.out.println("The final value of y at x = "+
                            x + " is : "+df.format(y));
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        // here x and y are the initial
        // given condition, so x=0 and y=0.5
        double x = 0, y = 0.5;
      
        // final value of x for which y is needed
        double xn = 1;
      
        // step size
        double h = 0.2;
      
        printFinalValues(x, xn, y, h);
    }
    }
      
    // This code is contributed by mits

    chevron_right

    
    

    Python3

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    # Python3 code for solving the differential equation
    # using Predictor-Corrector or Modified-Euler method
    # with the given conditions, y(0) = 0.5, step size(h) = 0.2
    # to find y(1)
      
    # consider the differential equation
    # for a given x and y, return v
    def f(x, y):
        v = y - 2 * x * x + 1;
        return v;
      
    # predicts the next value for a given (x, y)
    # and step size h using Euler method
    def predict(x, y, h):
          
        # value of next y(predicted) is returned
        y1p = y + h * f(x, y);
        return y1p;
      
    # corrects the predicted value
    # using Modified Euler method
    def correct(x, y, x1, y1, h):
          
        # (x, y) are of previous step
        # and x1 is the increased x for next step
        # and y1 is predicted y for next step
        e = 0.00001;
        y1c = y1;
      
        while (abs(y1c - y1) > e + 1):
            y1 = y1c;
            y1c = y + 0.5 * h * (f(x, y) + f(x1, y1));
      
        # every iteration is correcting the value
        # of y using average slope
        return y1c;
      
    def printFinalValues(x, xn, y, h):
        while (x < xn):
            x1 = x + h;
            y1p = predict(x, y, h);
            y1c = correct(x, y, x1, y1p, h);
            x = x1;
            y = y1c;
      
        # at every iteration first the value
        # of for next step is first predicted
        # and then corrected.
        print("The final value of y at x =",
                         int(x), "is :", y);
      
    # Driver Code
    if __name__ == '__main__':
          
        # here x and y are the initial
        # given condition, so x=0 and y=0.5
        x = 0; y = 0.5;
      
        # final value of x for which y is needed
        xn = 1;
      
        # step size
        h = 0.2;
      
        printFinalValues(x, xn, y, h);
      
    # This code is contributed by Rajput-Ji

    chevron_right

    
    

    C#

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C# code for solving the differential
    // equation using Predictor-Corrector
    // or Modified-Euler method with the 
    // given conditions, y(0) = 0.5, step
    // size(h) = 0.2 to find y(1)
    using System;
      
    class GFG
    {
          
    // consider the differential equation
    // for a given x and y, return v
    static double f(double x, double y)
    {
        double v = y - 2 * x * x + 1;
        return v;
    }
      
    // predicts the next value for a given (x, y)
    // and step size h using Euler method
    static double predict(double x, double y, double h)
    {
        // value of next y(predicted) is returned
        double y1p = y + h * f(x, y);
        return y1p;
    }
      
    // corrects the predicted value
    // using Modified Euler method
    static double correct(double x, double y,
                double x1, double y1,
                double h)
    {
        // (x, y) are of previous step
        // and x1 is the increased x for next step
        // and y1 is predicted y for next step
        double e = 0.00001;
        double y1c = y1;
      
        do 
        {
            y1 = y1c;
            y1c = y + 0.5 * h * (f(x, y) + f(x1, y1));
        }
        while (Math.Abs(y1c - y1) > e);
      
        // every iteration is correcting the value
        // of y using average slope
        return y1c;
    }
      
    static void printFinalValues(double x, double xn,
                        double y, double h)
    {
      
        while (x < xn) 
        {
            double x1 = x + h;
            double y1p = predict(x, y, h);
            double y1c = correct(x, y, x1, y1p, h);
            x = x1;
            y = y1c;
        }
      
        // at every iteration first the value
        // of for next step is first predicted
        // and then corrected.
        Console.WriteLine("The final value of y at x = "+
                            x + " is : " + Math.Round(y, 5));
    }
      
    // Driver code
    static void Main()
    {
        // here x and y are the initial
        // given condition, so x=0 and y=0.5
        double x = 0, y = 0.5;
      
        // final value of x for which y is needed
        double xn = 1;
      
        // step size
        double h = 0.2;
      
        printFinalValues(x, xn, y, h);
    }
    }
      
    // This code is contributed by mits

    chevron_right

    
    

    PHP

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    <?php
    // PHP code for solving the differential equation
    // using Predictor-Corrector or Modified-Euler 
    // method with the given conditions, y(0) = 0.5, 
    // step size(h) = 0.2 to find y(1)
      
    // consider the differential equation
    // for a given x and y, return v
    function f($x, $y)
    {
        $v = $y - 2 * $x * $x + 1;
        return $v;
    }
      
    // predicts the next value for a given (x, y)
    // and step size h using Euler method
    function predict($x, $y, $h)
    {
        // value of next y(predicted) is returned
        $y1p = $y + $h * f($x, $y);
        return $y1p;
    }
      
    // corrects the predicted value
    // using Modified Euler method
    function correct($x, $y, $x1, $y1, $h)
    {
          
        // (x, y) are of previous step and 
        // x1 is the increased x for next step
        // and y1 is predicted y for next step
        $e = 0.00001;
        $y1c = $y1;
      
        do 
        {
            $y1 = $y1c;
            $y1c = $y + 0.5 * $h * (f($x, $y) + 
                                    f($x1, $y1));
        } while (abs($y1c - $y1) > $e);
      
        // every iteration is correcting the 
        // value of y using average slope
        return $y1c;
    }
      
    function printFinalValues($x, $xn, $y, $h)
    {
        while ($x < $xn
        {
            $x1 = $x + $h;
            $y1p = predict($x, $y, $h);
            $y1c = correct($x, $y, $x1, $y1p, $h);
            $x = $x1;
            $y = $y1c;
        }
      
        // at every iteration first the value
        // of for next step is first predicted
        // and then corrected.
        echo "The final value of y at x = " . $x
                   " is : " . round($y, 5) . "\n";
    }
      
        // here x and y are the initial
        // given condition, so x=0 and y=0.5
        $x = 0;
        $y = 0.5;
      
        // final value of x for which y is needed
        $xn = 1;
      
        // step size
        $h = 0.2;
      
        printFinalValues($x, $xn, $y, $h);
      
    // This code is contributed by mits
    ?>

    chevron_right

    
    

    Output:

    The final value of y at x = 1 is : 2.18147
    


    My Personal Notes arrow_drop_up

    Check out this Author's contributed articles.

    If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



    Improved By : Mithun Kumar, Rajput-Ji



    Article Tags :
    Practice Tags :


    Be the First to upvote.


    Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.