Опубликован: 18.05.2011 | Доступ: свободный | Студентов: 968 / 105 | Оценка: 4.40 / 4.20 | Длительность: 12:30:00
Лекция 17:

Обыкновенные дифференциальные уравнения

< Лекция 16 || Лекция 17: 123 || Лекция 18 >

Существует довольно много численных методов решения задачи Коши для дифференциальных уравнений. При этом многие методы были созданы еще в "до машинную эпоху". Такие методы часто ориентированы на ручной расчет и включают в себя использование аналитических выкладок, например, расчет производных от правой части. Наиболее часто используемым является метод Рунге-Кутта. Этот метод имеет весьма высокую точность, может иметь переменный шаг и может быть легко запрограммирован. Одним из самых простейших методов решения дифференциального уравнения является метод Эйлера. Мы подробно рассмотрим метод Эйлера и метод Рунге-Кутта 4 -го порядка.

Метод Эйлера применялся еще Л.Эйлером для доказательства существования решения задачи Коши. Он имеет интуитивно понятную форму, легко может быть запрограммирован, но имеет низкую точность. И так, рассмотрим уравнение 16.1. Производную в этом уравнении приближенно представим с помощью конечной разности:

y'(t)\approx\frac{y(t+h)-y(t)}{h},
где h>0 некоторое число. Используя это представление мы вместо дифференциального уравнения 16.1 получим разностное уравнение
\frac{y(t+h)-y(t)}{h}=f(y(t),t).
От сюда найдем
y(t+h)=y(t)+hf(y(t),t). ( 16.4)
Пусть мы хотим найти приближенное решение на отрезке [0,T]. Разобьем этот отрезок конечным числом точек необязательно равномерно
0=t_0<t_1<\dots<t_N=T.
Введем обозначения h_i=t_i-t_{i-1}, i=1,2,\dots,N. Для простоты будем предполагать, что функция f(x,t) определена во всем пространстве \Bbb{R}^{n+1}. Тогда мы можем построить набор \{y_i\}_{i=0}^N\subset\Bbb{R}^n по следующему правилу
y_0=y^0,
y_i=y_{i-1}+h_if(y_{i-1},t_{i-1}),\ i=1,2,\dots,N.
Обозначим h=\max\{h_i:i=1,2,\dots,N\}. Вектора y_i имеют смысл значений приближенного решения в точках t_i. Для нахождения приближенного решения внутри интервалов (t_{i-1},t_i) можно применять различные методы интерполяции, например, линейной. Функция y^N(t), построенная с помощью линейной интерполяции, называется ломанной Эйлера. Если для рассматриваемой задачи выполнены условия теоремы 16.2 и на отрезке [0,T] существует решение y(t), то приближенное решение y^N(t) сходится к точному решению равномерно имеет место оценка
\max\limits_{t\in[0,T]}|y(t)-y^N(t)|\le Ch.
Таким образов метод Эйлера имеет первый порядок точности.

Реализуем этот метод на C#. Сначала реализуем абстрактный класс, который будет использован для конструирования различных методов построения численных решений систем обыкновенных дифференциальных уравнений.

\begin{verbatim}
    abstract class TODE
    {
        public int N;
        protected double t; // текущее время
        // искомое решение Y[0] - само решение,
        // Y[i] - i-тая производная решения
        public double[] Y;
        protected double[] YY; // внутренние переменные

        public TODE(int N) // N - размерность системы
        {
            this.N = N;
            Y = new double[N]; // создать вектор решения
            YY = new double[N]; // и внутренних решений
        }

        // установить начальные условия.
        // t0 - начальное время, Y0 - начальное условие
        public void SetInit(double t0, double[] Y0)
        {
            t = t0;
            int i;
            for (i = 0; i < N; i++)
            {
                Y[i] = Y0[i];
            }
        }

        public double GetCurrent() // вернуть текущее время
        {
            return t;
        }

        abstract public void F(double t, double[] Y,
        ref double[] FY); // правые части системы.

        // следующий шаг, dt - шаг по времени
        abstract public void NextStep(double dt);
    }
\end{verbatim}

На основе этого класса построим класс, реализующий метод Эйлера.

\begin{verbatim}
    abstract class TEuler : TODE
    {
        public TEuler(int N) : base(N) {}
        public override void NextStep(double dt)
        {
            int i;

            F(t, Y, ref YY);

            for (i = 0; i < N; i++)
            {
                Y[i] = Y[i] + dt * YY[i];
            }

            t = t + dt;
        }
    }
\end{verbatim}

Прежде чем испытать наш метод Эйлера, мы рассмотрим и реализуем метод Рунге-Кутта 4 -го порядка. Метод Рунге-Кутта, также как и метод Эйлера, допускает перемену шага, но имеет значительно большую точность. Пусть t_i и y_i имеют тот же смысл, что и при рассмотрении метода Эйлера.

Правила построения точек y_i следующие

y_i=y_{i-1}+\frac{h_i}{6}(k_1+2k_2+2k_3+k_4),
где
k_1=f(y_{i-1},t_{i-1}),
k_2=f\left(y_{i-1}+\frac{h}{2}k_1,t_{i-1}+\frac{h}{2}\right),
k_3=f\left(y_{i-1}+\frac{h}{2}k_2,t_{i-1}+\frac{h}{2}\right),
k_4=f(y_{i-1}+hk_3,t_{i-1}+h).
Как мы видим, для расчета решения на следующем шаге необходимо вычислить правую часть четыре раза, зато точность этого метода имеет четвертый порядок, при условии гладкости правой части.

< Лекция 16 || Лекция 17: 123 || Лекция 18 >