Утилитами в Derive называют наборы процедур, подобранных на заданную тему вычислений, которую можно загрузить в память текущей сессии не выводя их на видимое поле алгебры. При этом все операторы загруженной утилиты могут вызываться по своим именам, как функции с формальными параметрами. Для каждой утилиты имена их функций с описанием типа каждого параметра можно найти в меню помощи.
Пример подстановки векторного аргумента в оператор ITERATES(*) с использованием операторов из утилит покажем на примере интегрирования системы линейных дифференциальных уравнений первого порядка методом Рунге-Кутта. Процедура Рунге-Кутта расположена в утилите с именем ODE_APPR.mth - численное решение обыкновенных дифференциальных уравнений. Загрузка утилит осуществляется из главного меню File Load <имя утилиты>.
Формат оператора, вызывающего процедуру Рунге-Кутта, имеет следующий вид: RK(u, v, v0, h, k). Формальные параметры процедуры включают:
- n-мерный вектор системы уравнений u, элементами которого являются правые части уравнений системы;
- (n+1)-мерный вектор имен искомых переменных v, первым элементом которого является имя независимой переменной;
- (n+1)-мерный вектор начальных значений переменных v0;
- h - шаг по независимой переменной;
- k - число шагов.
В описываемом ниже примере текста программы численного интегрирования системы дифференциальных уравнений заложено решение в течение половины секунды следующей системы уравнений:
.
Аналитическим решением этой системы являются функции и . Численный метод Рунге-Кутта имеет погрешность, пропорциональную четвертой степени шага по независимой переменной. При шаге h=0.1 ошибка будет иметь порядок . Чтобы повысить точность результата решения на порядок необходимо уменьшить шаг в 10 раз. При этом для просмотра всего заданного интервала в одну секунду придется выводить в 10 раз больше векторов решения, так как число точек на оси времени возрастет в те же 10 раз, особого смысла в которых нет.
Идея вывода нужного числа векторов решения в нужные моменты времени, например, через интервалы, равные десятикратно увеличенному шагу, необходимо после каждых k=10 циклов выполнения процедуры RK(*) вывести последний вектор на печать, его значение присвоить вектору начальных условий v0 и снова 10 раз выполнить процедуру RK(*). Эти действия для охвата заданного интервала решения в 0,5 с необходимо повторить m=5 раз.
Таким образом, в тексте программы, кроме задания системы уравнений, вектора решения и его начального значения, должен присутствовать оператор с двумя вложенными циклами. Один (внутренний), соответствующий собственно процедуре Рунге-Кутта, повторяющийся k раз, и внешний, итерационный – для повторной подстановки m раз очередного вектора начальных значений и вывода промежуточных подстановок начальных векторов.
Текст программы с последовательностью операторов, записанных в текстовом формате командной строки, включает 5 строчек:
- [CaseMode := Sensitive, InputMode := Word, TimesOperator := Asterisk]
- [u := [2*p*x2, - 2*p*x1], v := [t, x1, x2], v0 := [0, 1, 0]]
- Frk(h, k, m) := ITERATES((RK(u, v, in, h, k))(k + 1), in, v0, m)
- F(h, k, m) := APPEND([v], Frk(h, k, m))
- F(0.01, 10, 5)
Вектор первой строки устанавливает чувствительность к регистру клавиатуры, к виду идентификаторов переменных и к виду символа операции умножения.
Вторая строка присваивает векторам u, v, v0 соответственно значения правых частей системы уравнений, имена независимой и зависимых переменных и их начальные значения.
Третья строка определяет функцию построения таблицы векторов решения для заданных точек Frk(h, k, m), а четвертая - располагает над таблицей имена переменных.
Исполнение функции F(h, k, m) с фактическими значениями параметров для шага h=0.01, кратности пропускаемых шагов k=10 и количестве выводимых значений m=5 выдаст следующий результат.
.
По последней строке видно, что результат вычисления имеет погрешность порядка 10-7. Точное значение равно нулю.