Примеры подготовки пакетов расширений
Пакет реализации метода Рунге-Кутта
Теперь рассмотрим, как выглядит пакет расширения, решающий систему дифференциальных уравнений хорошо известным численным методом Рунге-Кутта четвертого порядка. Ниже представлена распечатка данного пакета.
(
*
:Title: RungeKutta
*
)
(
*
iContext: ProgramminglnMathematica
'RungeKutta'
*
)
BeginPackage[
"ProgramminglnMathematica'RungeKutta'"
]
RKSolve::usage
=
"RKSolve[{el,e2,..}, {yl,y2,..}, {al,a2,..}, {tl, dt}]
numerically integrates the ei as functions of the yi with inital values ai.
The integration proceeds in steps of dt from 0 to t1.
RKSolve[{el, e2,..},{yl,y2,..},{al,a2,..},{t,t0,tl, dt} ]
integrates a time-dependent system from t0 to t1."
Begin[
"'Private'"
]
RKStep[f_, y_, y0_, dt_]:
=
Module [{ kl, k2, k3, k4 }, kl
=
dt N[ f
/
. Thread[y
>
y0] ];
k2
=
dt N[ f
/
. Thread[y
>
y0
+
kl
/
2
] ];
k3
=
dt N[ f
/
. Thread [y
>
y0
+
k2
/
2
] ];
k4
=
dt N[ f
/
. Thread [y
>
y0
+
k3] ];
y0
+
(kl
+
2
k2
+
2
k3
+
k4)
/
6
RKSolve[f_List, y_List, y0_List, {tl_, dt_}]:
=
NestList[ RKStepff, y, #, N[dt]]&, N[y0], Round [N [ tl
/
dt ]] ]
/
;
Length [f]
=
=
Length [y]
=
=
Length [y0]
RKSolve [f_List, y_List, y0_List, {t_, t0_, tl_, dt_}]:
=
Module f { res },
res
=
RKSolve [ Append[f,
1
], Append[y, t], Append[y0, t0], {tl
-
t0, dt} ];
Drop[#,
-
1
]&
/
@ res
/
;
Length [f]
=
=
Length [y]
=
=
Length [y0]
End[ ]
Protect [ RKSolve ]
EndPackage[ ]
Знающие реализацию этого метода обратят внимание на естественность записи общеизвестных математических операций. Пакет содержит определения двух функций: основной (RKSolve) и вспомогательной (RKStep). Последняя содержит вычисление решения на очередном шаге алгоритма по результатам вычислений на предшествующем шаге. Используется подстановка для переменной х и вычисление решения на очередном шаге по известной формуле Рунге- Кутта четвертого порядка точности.
Теперь рассмотрим, как можно использовать такой пакет, создать который можно в любом текстовом редакторе, например в редакторе NotePad, входящем в состав Windows 95/98. Для удобства работы можно поместить файл этого пакета rk4.m в папку Mypack, расположенную в папке со стандартными пакетами. В этом случае вызов пакета и проверка его загрузки осуществляются следующим образом:
<
<
mypack\rk4.m
?RKSolve
RKSolve [ {el, e2,..}, {yl,y2,..}, {al,a2,..}, {tl, dt}]
numerically integrates the ei as functions of the yi with inital values ai.
The integration proceeds in steps of dt from 0 to tl. RKSolve
[ {el, e2,..}, {yl,y2,..}, {al,a2,..}, {t, t0, tl, dt}]
integrates a time
-
dependent system from t0 to t1.
Итак, при обращении ?RKSolve выводится информация о формате применения функции RKSolve. Она задана на английском языке. Можно записать эту информации и на русском языке, однако при этом возможна нестыковка наборов шрифтов. Поэтому рекомендуется подобную информацию давать на английском языке. В нашем случае решается система дифференциальных уравнений первого порядка в форме Коши, заданная правыми частями {e1, е2,…} с переменными {y1, у2,…} и их начальными значениями {a1, а2,…} в интервале времени от 0 до.1 при фиксированном шаге dt. Во второй форме записи функции время t может меняться от t0 до tl с шагом dt.
Приведенный ниже пример демонстрирует, как этот пакет используется на практике для решения системы дифференциальных уравнений y' = t*y + z и z' = t + y*z при начальных значениях у = z = 1 и t, меняющемся от 1 до 1.5 с шагом 0.1:
RKSolve[{t
*
y
+
z, t
+
y
*
z}, {y, z}, {
1
,
1
}, {t,
1
,
1.5
,
0.1
}]
{{!.,
1
.}, {
1.22754
,
1.22844
), {
1.52241
,
1.53202
), {
1.90912
,
1.95373
}, {
2.42456
,
2.57444
), {
3.12741
,
3.55937
}}
Решение представлено списком значений {yi, zi}, определяющим зависимости y(t) и z(t). Этот пример хорошо иллюстрирует реализацию популярного численного метода для решения систем дифференциальных уравнений.