Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Методы прогноза и коррекции (итерационные методы) Метод Эйлера и Метод Милна теория и примеры реализации на Си

Лекция



Привет, сегодня поговорим про методы прогноза, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое методы прогноза, коррекции итерационные методы метод эйлера , метод милна , настоятельно рекомендую прочитать все из категории Моделирование и Моделирование систем.

Изученные нами ранее методы обладали одной важной особенностью — каждому методу соответствует обычно определенный класс точности, который мы обозначали как Oi. Например, метод Эйлера обладал первым классом точности O1. Это означало, что с уменьшением шага в 10 раз (на порядок) точность результата повышается тоже в 10 раз (на один порядок). Метод Рунге-Кутты обладает 4 порядком точности — O4, при уменьшении шага в 10 раз, результат улучшается в 10 000 раз. Поскольку этот метод по сравнению с методом Эйлера использует всего в 4 раза больше вычислений, то использование его более выгодно. На сегодняшний день известны методы до 8 порядка точности (например, метод Prince Dortmund), хотя одновременно стоит иметь в виду, что написание алгоритмов для них — задача достаточно трудная. Достоинством всех этих алгоритмов является то, что объем вычислений для них заранее известен.

Если требуется достичь ЛЮБОЙ точности на шаге, то следует использовать методы прогноза и коррекции. Этот подход состоит в том, что расчет траектории, задаваемой уравнением, на каждом шаге происходит многократно. А именно, сначала происходит расчет приближенного значения функции на конце шага какой-либо простой формулой (например, методом Эйлера), далее в этой точке вычисляется производная, и расчет происходит снова из начальной точки на шаге, но с уточненным значением производной. Последняя операция — уточнения производной и значения функции на конце шага — происходит МНОГОКРАТНО НА КАЖДОМ ШАГЕ, то есть до тех пор, пока вычисленные значения (функции и производной в конце шага) не перестанут меняться или будут меняться уже незначительно, меньше чем задаваемая заранее величина ε. Только тогда можно сказать, что точность εдостигнута.

Итак, за счет итерационной процедуры на каждом отдельном шаге можно достичь любой, наперед заданной точности ε. За такое достоинство метода приходится платить: к сожалению, невозможно сказать заранее, сколько итераций потребуется для достижения на шаге заданной точности ε. Поэтому такие методы нельзя, например, использовать в системах реального времени.

Рассмотрим для примера два метода из этого класса. Как и ранее задача состоит в нахождении функции y(t) из дифференциального уравнения dy/dt = f(y, x, t) или множества функций из системы таких уравнений.

Метод Эйлера с итерациями

1) Предсказывающая формула вычисляет (прогнозирует) значение функции на правом конце шага: yk + 1 = yk + fk · Δt.

2) Расчитывается производная в точке k + 1 подстановкой y в исходное уравнение в k + 1 точке:fk + 1 = f(t + Δt, yk + 1).

3) Уточняющая формула, используя старое значение производной (с шага 1) и уточненное с шага 2, дает уточненное значение yk + 1: yk + 1 = yk + (fk + fk + 1) · Δt/2. Здесь же производится подсчет итераций счетчиком i: i := i + 1.

4) Проверка точности: |yk + 1i-я итерацияyk + 1(i + 1)-я итерация| ≤ ε. Если условие выполнено и точность ε достигнута, то переходим на следующий шаг 5), иначе осуществляется переход на шаг 2) и процесс уточнения повторяется с новыми значениями y и f, причем их старое значение берется с предыдущей итерации.

5) Подготовка к новому шагу: изменение счетчика времени t на величину Δt и изменение номера шага k:
t := t + Δt
k := k + 1.

6) Проверка окончания расчета: tT. Если условие выполняется, расчет продолжается для следующей точки, переход на 1), иначе — конец.

пример реализации Метод Эйлера

public double tryEulerMethod(int segments) //Метод Эйлера
{
double step;
xArray = new double[segments];
yArray = new double[segments];
step = (endX - startX) / segments;
xArray = startX;
yArray = startY;
xArray[segments - 1] = endX;
for (int i = 1; i < segments - 1; i++)
{
xArray[i] = xArray[i - 1] + step;
}
for (int i = 1; i < segments; i++)
{
yArray[i] = yArray[i - 1] + step * formFunction(xArray[i - 1], yArray[i - 1]);
}
return yArray[segments - 1];

метод милна

1) По предсказывающей формуле вычисляется грубое значение y на правом конце интервала:yk + 1: yk + 1 = yk – 3 + 4/3 · (2 · fkfk – 1 + 2 · fk – 2) · Δt.

2) Рассчитывается производная в k + 1 точке: fk + 1 = f(t + Δt, yk + 1).

3) Снова рассчитывается yk + 1 по уточненной формуле, используя уже новое значение производной в точке k + 1: yk + 1 = yk – 1 + 1/3 · (fk + 1 + 4 · fk + fk – 1) · Δt.

4) Рассчитывается производная в k + 1 точке с учетом вновь вычисленного более точного значения yk + 1: fk + 1 = f(t + Δt, yk + 1). Об этом говорит сайт https://intellect.icu . Здесь же производится подсчет итераций счетчиком i: i := i + 1.

5) Проверка точности: |yk + 1i-я итерацияyk + 1(i + 1)-я итерация| ≤ ε. Если условие выполнено, и точность ε достигнута, то переходим на следующий шаг 6, иначе осуществляется переход на шаг 3 и процесс уточнения повторяется с новыми значениями y и f, причем их старое значение берется с предыдущей итерации.

6) Подготовка к новому шагу: изменение счетчика времени t, изменение номера шага k:
t := t + Δt
k := k + 1.

7) Проверка окончания расчета: tT. Если условие выполняется, то расчет продолжается для следующей точки, и осуществляется переход на шаг 1, иначе — конец.

пример реализации Метода Милна

Предиктор и Корректор(Для Милна)
Милн с заменой метода SolveMiln


public static DifferentialFunctionContent SolvePredict (this DifferentialFunctionContent content)
{
bool isNext = true;
while (isNext)
{
content.SolveRungeKutt(3);
int count = content.X.Length;
double predict;
double step = Math.Abs((content.X - content.X[count - 1])) / (count - 1);
for (int i = 3; i < count - 1; i++)
{
predict = content.Y[i - 3] + (4 / 3) * step *
(2 * content.function(content.X[i - 2], content.Y[i - 2]) -
content.function(content.X[i - 1], content.Y[i - 1]) +
2 * content.function(content.X[i], content.Y[i]));
content.Y[i + 1] = content.Y[i - 1] + (step / 3) *
(content.function(content.X[i - 1], content.Y[i - 1]) +
4 * content.function(content.X[i], content.Y[i]) +
content.function(content.X[i + 1], predict));
if (CheckPrecision(content.Y[i], predict, content.precision, CoefficientRunge.Miln))
{
if (content.countSplits >= limit)
isNext = true;
break;
}
isNext = false;
}
}
return content;
}


Реализация метода Милна


public interface IFunctionContent
{
double[] X { get; set; } // табличные значения
double[] Y { get; set; } // табличные значения
}
public static class DifferentialOperation
{

public static DifferentialFunctionContent SolveMiln(this DifferentialFunctionContent content)
{
bool isNext = true;
while (isNext)
{
content.SolveRungeKutt(3);
int count = content.X.Length;
double previousPredict = content.Y ;
double predict;
double step = Math.Abs((content.X - content.X[count - 1])) / (count - 1);
double managerController;
isNext = false;
for (int i = 3; i < count - 1; i++)
{
predict = content.Y[i - 3] + (4 / 3) * step *
(2 * content.function(content.X[i - 2], content.Y[i - 2]) -
content.function(content.X[i - 1], content.Y[i - 1]) +
2 * content.function(content.X[i], content.Y[i]));
managerController = predict +
(28 / 29) * (content.Y[i] - previousPredict);
content.Y[i + 1] = content.Y[i - 1] + (step / 3) *
(content.function(content.X[i - 1], content.Y[i - 1]) +
4 * content.function(content.X[i], content.Y[i]) +
content.function(content.X[i + 1], managerController));
if (CheckPrecision(content.Y[i], predict, content.precision, content.countSplits, CoefficientRunge.Miln))
{
isNext = true;
break;
}
}
}
return content;
}
public static DifferentialFunctionContent SolveRungeKutt(this DifferentialFunctionContent content, int countValue)
{
bool isNext = true;
double[] previousY = new double[countValue];
content.Y = new double[countValue];
for (int i = 0; i < countValue; i++)
content.Y[i] = 0;
while (isNext)
{
countSplits *= 2;
for (int i = 0; i < countValue; i++)
previousY[i] = content.Y[i];
content.X = new double[countSplits + 1];
content.Y = new double[countSplits + 1];
content.X = content.xStart;
content.Y = content.yStart;
content.X[countSplits] = content.xEnd;
double step = Math.Abs((content.X[countSplits] - content.X )) / countSplits;
for (int i = 0; i < countSplits - 1; i++)
content.X[i + 1] = content.X[i] + step;
double coefficient1;
double coefficient2;
double coefficient3;
double coefficient4;
double deltaY;
isNext = false;
for (int i = 0; i < countValue; i++)
{
coefficient1 = content.function(content.X[i], content.Y[i]);
coefficient2 = content.function(content.X[i] + step / 2,
content.Y[i] + step * coefficient1 / 2);
coefficient3 = content.function(content.X[i] + step / 2,
content.Y[i] + step * coefficient2 / 2);
coefficient4 = content.function(content.X[i] + step,
content.Y[i] + step * coefficient3);
deltaY = step / 6 * (coefficient1 + 2 * coefficient2 + 2 * coefficient3 + coefficient4);
content.Y[i + 1] = content.Y[i] + deltaY;
if (CheckPrecision(content.Y[i + 1], previousY[i], content.precision, content.countSplits, CoefficientRunge.RungeKutt))
{
isNext = true;
break;
}
}
}
return content;
}
private static bool CheckPrecision(double currentValue, double previousValue, double precision, int countSplits, CoefficientRunge coefficient)
{
int order;
switch (coefficient)
{
case CoefficientRunge.RungeKutt: { order = 15; break; }
case CoefficientRunge.Miln: { order = 29; break; }
default: { return false; }
}
double discrepancy = Math.Abs(currentValue - previousValue) / order;
if (discrepancy > precision)
return true;
if (countSplits >= limit)
throw new FunctionException("Невозможно достигнуть указанной точности");
return false;
}
}

Вау!! 😲 Ты еще не читал? Это зря!

Надеюсь, эта статья об увлекательном мире методы прогноза, была вам интересна и не так сложна для восприятия как могло показаться. Желаю вам бесконечной удачи в ваших начинаниях, будьте свободными от ограничений восприятия и позвольте себе делать больше активности в изученном направлени . Надеюсь, что теперь ты понял что такое методы прогноза, коррекции итерационные методы метод эйлера , метод милна и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Моделирование и Моделирование систем

создано: 2015-12-19
обновлено: 2021-05-11
132516



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Моделирование и Моделирование систем

Термины: Моделирование и Моделирование систем