//Простейшая формула трапеций public static double TrapezoidalRule(PostfixNotation func_notation, double left_bound, double right_bound, int subint_count) { //Вычисляем шаг разбиения double norm = (right_bound - left_bound) / subint_count; //Получаем, собственно, разбиение (мн-во точек) double[] x = GetPartition(left_bound, right_bound, subint_count); double sum = 0; //Проходим циклом по мн-ву точек //Замечание: число точек на единицу больше, чем число отрезков разбиения for (int i = 0; i <= subint_count; i++) { //На концах интервала if (i == 0 || i == subint_count) { //берем по половине значения ф-ции sum += func_notation.Calculate(x[i]) / 2; } //В остальных точках - целиком else { sum += func_notation.Calculate(x[i]); } } //Возвращаем полученную сумму, предварительно умножив на шаг разбиения return(norm * sum); }
//Формула средних прямоугольников public static double RectangleRule(PostfixNotation func_notation, double left_bound, double right_bound, int subint_count) { //Вычисляем шаг разбиения double norm = (right_bound - left_bound) / subint_count; //Получаем, собственно, разбиение (мн-во точек) double[] x = GetPartition(left_bound, right_bound, subint_count); double sum = 0; //Проходим циклом по мн-ву точек //Замечание: число точек на единицу больше, чем число отрезков разбиения for (int i = 0; i < subint_count; i++) { //На каждом шагу добавляем полусумму значений ф-ции в текущей и следующей точках sum += func_notation.Calculate((x[i] + x[i + 1]) / 2); } //Возвращаем полученную сумму, предварительно умножив на шаг разбиения return(norm * sum); }
private void IntegrateBtn_Click(object sender, RoutedEventArgs e) { try { //Получаем стоку, в которой записана ф-ция string func_input = FunctionInput.Text; PostfixNotation func_notation = new PostfixNotation(func_input); //Получаем границы интервала double left_bound = Convert.ToDouble(LeftBoundBox.Text); double right_bound = Convert.ToDouble(RightBoundBox.Text); //Получаем начальное/конечное значения и шаг для цикла вычислений int partition_start = Convert.ToInt32(PartStartBox.Text); int partition_finish = Convert.ToInt32(PartFinishBox.Text); int step = Convert.ToInt32(PartStepBox.Text); //Получаем код требуемого способа интегрирования string rule = (RuleBox.SelectedItem as ComboBoxItem).Name; //Считаем число итераций, которые требуется сделать int iterations_count = (int)Math.Floor((double)((partition_finish - partition_start) / step)) + 1; //Инициализируем массивы, в которых будут хранится данные для осей X/Y графика int[] partition_row = new int[iterations_count]; double[] results = new double[iterations_count]; //Запускаем цикл вычислений for (int i = 0; i < iterations_count; i++) { //Вычисляем число отрезков, на которые нужно разбить интервал на данной итерации int subint_count = partition_start + i * step; //Вычисляем интеграл соотв. формулой switch (rule) { case "Rect": results[i] = Integration.RectangleRule(func_notation, left_bound, right_bound, subint_count); break; case "Trap": results[i] = Integration.TrapezoidalRule(func_notation, left_bound, right_bound, subint_count); break; } //Записываем мелкость разбиения на данной итерации partition_row[i] = subint_count; } //Отображаем график в интерфейсе, если он был скрыт if (ChartContainer.Visibility == System.Windows.Visibility.Collapsed) { ChartContainer.Visibility = System.Windows.Visibility.Visible; } //Добавляем линию на график Series result_series = new Series(); result_series.ChartType = SeriesChartType.Line; result_series.Points.DataBindXY(partition_row, results); StatsChart.Series.Add(result_series); } catch (Exception ex) { MessageBox.Show(ex.Message); } }