/*
         * Provides grid that is analysis of GTE for different number of grid cells
         * Analysis n from nStart to nFinish
         */
        public Grid GTEAnalysisGrid(int nStart, int nFinish)
        {
            // grid to fill in
            Grid grid = new Grid(nStart, nFinish);

            // enumerate ovel all n
            for (int n = nStart; n <= nFinish; n++)
            {
                // construct exact solution grid with given number of steps
                MyExactSolution myExactSolutionGrid = new MyExactSolution(n, x[0], y[0], x[N]);
                // compute numerical method approximation for the given n
                double[] yNumerical = ComputeValues(myExactSolutionGrid.x, y[0]);
                double[] yExact     = myExactSolutionGrid.y;
                // find maximum error in the grid
                grid.y[n - nStart] = Math.Abs(yNumerical[0] - yExact[0]);
                for (int i = 1; i <= n; i++)
                {
                    grid.y[n - nStart] = Math.Max(grid.y[n - nStart], Math.Abs(yNumerical[i] - yExact[i]));
                }
            }
            // return GTE analysis grid for plotting
            return(grid);
        }
        /*
         * Function to redraw charts based on the provided parameters by the user.
         * Triggers when button plot&analyze is clicked.
         */
        private void buttonIVPPlotClick(object sender, EventArgs e)
        {
            try
            {
                // collect data from text boxes on this tab
                double x0 = Double.Parse(textBoxx0.Text);       // x0 - initial value of x
                double y0 = Double.Parse(textBoxy0.Text);       // y0 - initial value of y
                double X  = Double.Parse(textBoxX.Text);        // X - right border of the interval
                int    N  = Int32.Parse(textBoxN.Text);         // N - number of grid cells
                                                                // data is collected
                int nStart  = Int32.Parse(textBoxnStart.Text);  // nStart - left border for GTEAnalysis
                int nFinish = Int32.Parse(textBoxnFinish.Text); // nFinish - right border for GTEAnalysis

                // Solve IVP for each method and bind data to the charts so it will be plotted

                // Euler Method solution grid
                EulerMethod EulerGrid = new EulerMethod(N, x0, y0, X, new MyFunction());
                chartIVP.Series["Euler"].Points.DataBindXY(EulerGrid.x, EulerGrid.y);

                // Improved Euler method solution grid
                ImprovedEulerMethod ImprovedEulerGrid =
                    new ImprovedEulerMethod(N, x0, y0, X, new MyFunction());
                chartIVP.Series["ImprovedEuler"].Points.DataBindXY(ImprovedEulerGrid.x, ImprovedEulerGrid.y);

                // Runge Kutta method solution grid
                RungeKuttaMethod RungeKuttaGrid =
                    new RungeKuttaMethod(N, x0, y0, X, new MyFunction());
                chartIVP.Series["RungeKutta"].Points.DataBindXY(RungeKuttaGrid.x, RungeKuttaGrid.y);

                // Exact solution grid
                MyExactSolution myExactSolutionGrid = new MyExactSolution(N, x0, y0, X);
                chartIVP.Series["Exact"].Points.DataBindXY(myExactSolutionGrid.x, myExactSolutionGrid.y);

                // set limits on x-axis for charts

                // Initial Value Problem chart
                chartIVP.ChartAreas[0].AxisX.Minimum = x0;
                chartIVP.ChartAreas[0].AxisX.Maximum = X;
                // LTE analysis chart
                chartLTE.ChartAreas[0].AxisX.Minimum = x0;
                chartLTE.ChartAreas[0].AxisX.Maximum = X;
                // GTE analysis chart
                chartEA.ChartAreas[0].AxisX.Minimum = nStart;
                chartEA.ChartAreas[0].AxisX.Maximum = nFinish;

                // Compute LTE for each method and bind data to the charts so it will be plotted

                // LTE for Euler method grid
                Grid LTEEuler = EulerGrid.LTEGrid(myExactSolutionGrid);
                chartLTE.Series["Euler"].Points.DataBindXY(LTEEuler.x, LTEEuler.y);

                // LTE for Improved Euler method grid
                Grid LTEImprovedEuler = ImprovedEulerGrid.LTEGrid(myExactSolutionGrid);
                chartLTE.Series["ImprovedEuler"].Points.DataBindXY(LTEImprovedEuler.x, LTEImprovedEuler.y);

                // LTE for Runge Kutta method grid
                Grid LTERungeKutta = RungeKuttaGrid.LTEGrid(myExactSolutionGrid);
                chartLTE.Series["RungeKutta"].Points.DataBindXY(LTERungeKutta.x, LTERungeKutta.y);

                // Compute GTE for each method and bind data to the charts so it will be plotted

                // GTE Euler method analysis grid
                Grid GTEEuler = EulerGrid.GTEAnalysisGrid(nStart, nFinish);
                chartEA.Series["Euler"].Points.DataBindXY(GTEEuler.x, GTEEuler.y);

                // GTE Improved Euler method analysis grid
                Grid GTEImprovedEuler = ImprovedEulerGrid.GTEAnalysisGrid(nStart, nFinish);
                chartEA.Series["ImprovedEuler"].Points.DataBindXY(GTEImprovedEuler.x, GTEImprovedEuler.y);
                // GTE Runge Kutta method analysis grid
                Grid GTERungeKutta = RungeKuttaGrid.GTEAnalysisGrid(nStart, nFinish);
                chartEA.Series["RungeKutta"].Points.DataBindXY(GTERungeKutta.x, GTERungeKutta.y);
            }
            catch
            {
            }
        }