private void DrawOriginBtn_Click(object sender, RoutedEventArgs e) { try { //Берем входную стоку, содержащую запись исходной функции.. string origin_input = OriginBox.Text; //.. и переводим ее в постфиксную нотацию PostfixNotation origin = new PostfixNotation(origin_input); //Получаем границы интервала и требуемый размер сетки double left_bound = Convert.ToDouble(LeftBoundBox.Text); double right_bound = Convert.ToDouble(RightBoundBox.Text); int points_count = Convert.ToInt32(PointsCountBox.Text); //Получаем разбиение точек и сетку значений функции double[] x = FunctionsHelper.GetPartition(left_bound, right_bound, points_count); double[] y = FunctionsHelper.CalculateValues(origin, x); //Рисуем функцию ChartHelper.Draw(ResultChart, x, y); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
public static double[] Solve(PostfixNotation f, double[] x, double y0, double h, int rank) { double[] y = new double[x.Length]; y[0] = y0; for (int i = 0; i < x.Length - 1; i++) { //Если треубемый порядок больше, чем пока что вычислено точек, if (rank > i + 1) { //рассчитываем следующую точку методом меньшего порядка y[i + 1] = Prediction(f, x, y, h, i, i + 1); y[i + 1] = Correction(f, x, y, h, i, i + 1); } //Иначе else { //считаем методом нужного порядка y[i + 1] = Prediction(f, x, y, h, i, rank); y[i + 1] = Correction(f, x, y, h, i, rank); } } return(y); }
//Получение сетки значений функции по ее постфиксной нотации и сетке иксов public static double[] CalculateValues(PostfixNotation f, double[] x) { //Очевидно, размер сетки значений функции такой же, как у сетки иксов double[] y = new double[x.Length]; //Для каждого x из сетки for (var i = 0; i < x.Length; i++) { //Находим значение функции y[i] = f.Calculate(x[i]); } return(y); }
private void SolveBtn_Click(object sender, RoutedEventArgs e) { try { //Берем входную стоку, содержащую запись правой части уравнения... string func_input = FunctionBox.Text; //.. и переводим ее в постфиксную нотацию PostfixNotation func = new PostfixNotation(func_input); //Получаем границы интервала и требуемый размер сетки double left_bound = Convert.ToDouble(LeftBoundBox.Text); double right_bound = Convert.ToDouble(RightBoundBox.Text); int points_count = Convert.ToInt32(PointsCountBox.Text); //Получаем сетку иксов и значение шага разбиения double[] x = FunctionsHelper.GetPartition(left_bound, right_bound, points_count); double norm = (right_bound - left_bound) / (points_count - 1); //Получаем начальное значение double y0 = Convert.ToDouble(InitValBox.Text); //Получаем требуемый порядок метода int rank = (int)MethodRankSlider.Value; //Вычисляем сетку значений искомой функции double[] y = PredCorScheme.Solve(func, x, y0, norm, rank); //Отображаем график в интерфейсе, если он был скрыт if (ChartContainer.Visibility == System.Windows.Visibility.Collapsed) { ChartContainer.Visibility = System.Windows.Visibility.Visible; } //Рисуем кривую на графике ChartHelper.Draw(ResultChart, x, y); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
//Вычисление корректора private static double Correction(PostfixNotation f, double[] x, double[] y, double h, int i, int rank) { switch (rank) { case 1: return(y[i] + h * f.Calculate(x[i + 1], y[i + 1])); case 2: return(y[i] + (h / 2) * (f.Calculate(x[i + 1], y[i + 1]) + f.Calculate(x[i], y[i]))); case 3: return(y[i] + (h / 12) * (5 * f.Calculate(x[i + 1], y[i + 1]) + 8 * f.Calculate(x[i], y[i]) - f.Calculate(x[i - 1], y[i - 1]))); case 4: return(y[i] + (h / 24) * (9 * f.Calculate(x[i + 1], y[i + 1]) + 19 * f.Calculate(x[i], y[i]) - 5 * f.Calculate(x[i - 1], y[i - 1]) + f.Calculate(x[i - 2], y[i - 2]))); case 5: return(y[i] + (h / 720) * (251 * f.Calculate(x[i + 1], y[i + 1]) + 646 * f.Calculate(x[i], y[i]) - 264 * f.Calculate(x[i - 1], y[i - 1]) + 106 * f.Calculate(x[i - 2], y[i - 2]) - 19 * f.Calculate(x[i - 3], y[i - 3]))); case 6: return(y[i] + (h / 1440) * (475 * f.Calculate(x[i + 1], y[i + 1]) + 1427 * f.Calculate(x[i], y[i]) - 798 * f.Calculate(x[i - 1], y[i - 1]) + 482 * f.Calculate(x[i - 2], y[i - 2]) - 173 * f.Calculate(x[i - 3], y[i - 3]) + 27 * f.Calculate(x[i - 4], y[i - 4]))); default: throw new Exception("Метод такого порядка не реализован"); } }
//Вычисление предиктора private static double Prediction(PostfixNotation f, double[] x, double[] y, double h, int i, int rank) { switch (rank) { case 1: return(y[i] + h * f.Calculate(x[i], y[i])); case 2: return(y[i] + (h / 2) * (3 * f.Calculate(x[i], y[i]) - f.Calculate(x[i - 1], y[i - 1]))); case 3: return(y[i] + (h / 12) * (23 * f.Calculate(x[i], y[i]) - 16 * f.Calculate(x[i - 1], y[i - 1]) + 5 * f.Calculate(x[i - 2], y[i - 2]))); case 4: return(y[i] + (h / 24) * (55 * f.Calculate(x[i], y[i]) - 59 * f.Calculate(x[i - 1], y[i - 1]) + 37 * f.Calculate(x[i - 2], y[i - 2]) - 9 * f.Calculate(x[i - 3], y[i - 3]))); case 5: return(y[i] + (h / 720) * (1901 * f.Calculate(x[i], y[i]) - 2774 * f.Calculate(x[i - 1], y[i - 1]) + 2616 * f.Calculate(x[i - 2], y[i - 2]) - 1274 * f.Calculate(x[i - 3], y[i - 3]) + 251 * f.Calculate(x[i - 4], y[i - 4]))); case 6: return(y[i] + (h / 1440) * (4277 * f.Calculate(x[i], y[i]) - 7923 * f.Calculate(x[i - 1], y[i - 1]) + 9982 * f.Calculate(x[i - 2], y[i - 2]) - 7298 * f.Calculate(x[i - 3], y[i - 3]) + 2877 * f.Calculate(x[i - 4], y[i - 4]) - 475 * f.Calculate(x[i - 5], y[i - 5]))); default: throw new Exception("Метод такого порядка не реализован"); } }