heady |
Отправлено: 04.04.2005, 16:13 |
|
Не зарегистрирован
|
Hi, All! может кто-нить писал метод Рунге-Кутта на cpp? Очень нужно. Зарание благодарен. |
|
exp |
Отправлено: 06.04.2005, 12:24 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
метод Рунге-Кутты (пока для обыкновенного дифура):
пусть есть дифур и его начальные условия:
CODE |
dy
------- = f(t,y), y(t0) = y0
dt
|
Надо его решить на отрезке [a; b]
Метод Рунге-Кутты (как правило второго порядка) предполагает вычисление 4-х поправок: n1, n2, n3, n4. Как? А вот так:
пусть разность между двумя рядом стоящими значениями аргумента
Пусть теперь мы находимся на i-том шаге вычислений и известны t[i] и y[i].
Твои действия:
CODE |
i = 0;
t[i] = a;
НАЧАЛО_ЦИКЛА(ПОКА_t[i]_МЕНЬШЕ_ЛИБО_РАВЕН_a )
1) считаешь n1 = f(t[i],y[i])
2) считаешь n2 = f(t[i]+h/2,y[i]+n1*h/2)
3) считаешь n3 = f(t[i]+h/2,y[i]+n2*h/2)
4) считаешь n4 = f(t[i]+h,y[i]+n3*h)
5) вычисляешь шаговую поправку Delta_y = (n1+2*n2+2*n3+n4)/6.0f
6) прибавляешь ее к y[i] и получаешь y[i+1]: y[i+1] = y[i]+Delta_y
7) увеличиваешь значение аргумента;
КОНЕЦ_ЦИКЛА;
|
Наше время в эфире подходит к концу. В следующем выпуске: решение систем дифуров. Не переключайте;
PS: Подробнее об этом смотри "Вычислительные методы" или "методы вычислений", или "Вычмат", или "Вычмслительная математика".
Я пользуюсь "Основы численных методов" Вержбицкий В. М.
Отредактировано exp — 06/04/2005, 12:26
|
|
heady |
Отправлено: 07.04.2005, 09:03 |
|
Не зарегистрирован
|
Спасибо! а как организовать проверку на неправильный интервал по x?
т.е. если текущий x для dy/dx недопустим... |
|
exp |
Отправлено: 09.04.2005, 09:59 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
Так и написать:
CODE |
if(x недопустим)
{
}
else
{
}
|
Прости за такой ответ, но все зависит от условий самой задачи.
|
|
exp |
Отправлено: 09.04.2005, 13:04 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
Продолжаем разговор о системах.
Допустим есть система
CODE | _
| dY1
| ------- = F1(t, Y1,..., Yn)
| dt
|
/ ......
\
| dYn
| ------- = Fn(t, Y1,..., Yn)
|_ dt
|
Тогда тебе придется решать все эти уравнения одновременно, считая, что для очередного уравнения у тебя уже данные есть.
Т. Е.:
Пусть на i-том шаге ты знаешь Y1[i], Y2[i],..., Yn[i]. Тогда ты можешь посчитать Y1[i+1], Y2[i+1], ..., Yn[i+1] твоим любимым и ставшим уже практически родным методом Рунге-Кутты (см. 2-е сообщение).
ЗЫ:
Можно адаптировать метод Зейделя для решения систем неалгебраических уравнений к нашей теме.
Делается это так: Считаешь по данным Y1[i], Y2[i],..., Yn[i] значение Y1[i+1]. После чего используешь это значение для вычисления Y2[i+1], подставляя его вместо Y1[i]. И так далее пока не вычислишь Yn[i+1].
После этого увеличивай значение аргумента и снова считай Y1[i+2] ...................... пока не устанешь
ЗЗЫ: Думаю понятно, что при решении первым методом тебе придется хранить значения Y1[i], Y2[i],..., Yn[i], вычисленные на i-той итерации для того, чтоб их использовать на (i+1)-й
ЗЗЗЫ: Будут вопросы — спрашивай.
|
|
|