// Update chart of LTEs.
 public void UpdateChartLTE(DifferentialEquation MyDifferentialEquation, Euler EulerApproximation, ImprovedEuler ImprovedEulerApproximation, RungeKutta RungeKuttaApproximation, double X0, double X)
 {
     // Set minimum and maximum values of Tab1ChartLTE.
     Tab1ChartLTE.ChartAreas[0].AxisX.Minimum = X0;
     Tab1ChartLTE.ChartAreas[0].AxisX.Maximum = X;
     // Plot the graphs of Local Truncation errors of numerical solutions.
     Tab1ChartLTE.Series[0].Points.DataBindXY(EulerApproximation.GetX(), EulerApproximation.ComputeLocalTruncationErrors(MyDifferentialEquation));
     Tab1ChartLTE.Series[1].Points.DataBindXY(ImprovedEulerApproximation.GetX(), ImprovedEulerApproximation.ComputeLocalTruncationErrors(MyDifferentialEquation));
     Tab1ChartLTE.Series[2].Points.DataBindXY(RungeKuttaApproximation.GetX(), RungeKuttaApproximation.ComputeLocalTruncationErrors(MyDifferentialEquation));
 }
 // Update chart of approximations.
 public void UpdateChartApproximation(DifferentialEquation MyDifferentialEquation, Euler EulerApproximation, ImprovedEuler ImprovedEulerApproximation, RungeKutta RungeKuttaApproximation, double X0, double X)
 {
     // Set minimum and maximum values of Tab1ChartApproximation.
     Tab1ChartApproximation.ChartAreas[0].AxisX.Minimum = X0;
     Tab1ChartApproximation.ChartAreas[0].AxisX.Maximum = X;
     // Plot the graphs of exact and numerical solutions.
     Tab1ChartApproximation.Series[0].Points.DataBindXY(MyDifferentialEquation.GetX(), MyDifferentialEquation.GetY());
     Tab1ChartApproximation.Series[1].Points.DataBindXY(EulerApproximation.GetX(), EulerApproximation.GetY());
     Tab1ChartApproximation.Series[2].Points.DataBindXY(ImprovedEulerApproximation.GetX(), ImprovedEulerApproximation.GetY());
     Tab1ChartApproximation.Series[3].Points.DataBindXY(RungeKuttaApproximation.GetX(), RungeKuttaApproximation.GetY());
 }
        /* Method calculating point-wise approximation. Implementation of the Runge-Kutta Method.
         * Returns an approximation at a point with given index i.
         */
        public override double ComputeForPoint(double[] x, double[] y, int i, DifferentialEquation MyDifferentialEquation)
        {
            // Initialize temporary variables.
            double h = GetStep(), K1, K2, K3, K4;

            // By default use RK4.
            K1 = MyDifferentialEquation.Derivative(x[i], y[i]);
            K2 = MyDifferentialEquation.Derivative(x[i] + h / 2, y[i] + h / 2 * K1);
            K3 = MyDifferentialEquation.Derivative(x[i] + h / 2, y[i] + h / 2 * K2);
            K4 = MyDifferentialEquation.Derivative(x[i] + h, y[i] + h * K3);
            return(y[i] + h / 6 * (K1 + 2 * K2 + 2 * K3 + K4));
        }
 /* Method computing Global Truncation Errors of Numerical Method.
  * Apply() should be called before utilizing this method.
  * Returns array of GTE's at every point of grid.
  */
 public double[] ComputeGlobalTruncationErrors(DifferentialEquation MyDifferentialEquation)
 {
     // Get exact values of y-coordinates.
     double[] y = GetY();
     // Initialize an array to store Global Truncation errors.
     double[] GTE = new double[GetN()];
     // Iteratively compute Global Truncation error for each grid step.
     for (int i = 0; i < GetN(); i++)
     {
         GTE[i] = Math.Abs(y[i] - MyDifferentialEquation.GetY()[i]);
     }
     return(GTE);
 }
 /* Method computing Local Truncation Errors of Numerical Method.
  * Apply() should be called before utilizing this method.
  * Returns array of LTE's at every point of grid.
  */
 public double[] ComputeLocalTruncationErrors(DifferentialEquation MyDifferentialEquation)
 {
     // Get values of x-coordinates.
     double[] x = GetX();
     // Get exact values of y-coordinates.
     double[] y = MyDifferentialEquation.GetY();
     // Initialize an array to store Local Truncation errors.
     double[] LTE = new double[GetN()];
     // Local Truncation error for a first point is 0 as it given by IVP.
     LTE[0] = 0;
     // Iteratively compute Local Truncation error for each grid step.
     for (int i = 1; i < GetN(); i++)
     {
         LTE[i] = Math.Abs(ComputeForPoint(x, y, i - 1, MyDifferentialEquation) - y[i]);
     }
     return(LTE);
 }
        /* Method solving given ordinary differential equation MyDifferentialEquation.
         * Returns y-coordinates of an solution approximation.
         */
        public double[] Apply(DifferentialEquation MyDifferentialEquation)
        {
            // Get number of grid steps.
            int N = GetN();

            // Get values of x-coordinates.
            double[] x = GetX();
            // Get values of y-coordinates.
            double[] y = GetY();
            // Iteratively compute an approximation for each grid step.
            for (int i = 1; i < N; i++)
            {
                y[i] = ComputeForPoint(x, y, i - 1, MyDifferentialEquation);
                // Debug information.
                // System.Diagnostics.Debug.WriteLine("y[i]={0:F} | x[i - 1]={1:F} y[i - 1]={2:F} h={3:F} Derivative={4:f}", y[i], x[i - 1], y[i - 1], GetStep(), MyDifferentialEquation.Derivative(x[i - 1], y[i - 1]));
            }
            // Set y-coordinates.
            SetY(y);
            return(y);
        }
 /* Method calculating point-wise approximation. Implementation of the Euler Method.
  * Returns an approximation at a point with given index i.
  */
 public override double ComputeForPoint(double[] x, double[] y, int i, DifferentialEquation MyDifferentialEquation) => y[i] + (GetStep() * MyDifferentialEquation.Derivative(x[i], y[i]));
 // Request replotting graphs on chart for GTEs.
 public void RequestUpdateChartGTE(DifferentialEquation MyDifferentialEquation,
                                   Euler EulerApproximation,
                                   ImprovedEuler ImprovedEulerApproximation,
                                   RungeKutta RungeKuttaApproximation,
                                   double X0,
                                   double X) => NewView.UpdateChartGTE(MyDifferentialEquation, EulerApproximation, ImprovedEulerApproximation, RungeKuttaApproximation, X0, X);
 /* Default implementation of a method calculating point-wise approximation.
  * Unique for each Numerical method.
  * Returns approximation at a point with given index i.
  */
 public virtual double ComputeForPoint(double[] x, double[] y, int i, DifferentialEquation MyDifferentialEquation) => 0;