- •Пакет прикладных программ mathematica Инструкция пользователя
- •1. Общие сведения. Ядро и интерфейс пакета Математика
- •2. Точные и приближенные вычисления. Численные и аналитические операции
- •3. Рабочий документ и ячейки. Основные команды
- •4. Сеанс работы в системе Математика. Глобальный характер данных.
- •5. Правила написания. Основные встроенные функции.
- •Примеры выражений
- •Формы обращений к функциям
- •Нескольких аргументов
- •7. Циклические операции
- •Логические операторы
- •7.4. Функция If
- •7.5. Логические выражения
- •8. Функции пользователя. Составление программ
- •8.1. Функции пользователя. Описания типов аргументов
- •8.2. Немедленное и задержанное присваивание
- •8.3. Альтернативные определения функций
- •8.4. Составление программ. Глобальные и локальные переменные
- •8.5. Прерывание вычислений
- •9. Списки
- •9.1. Создание списков. Обращение к элементам списков
- •9.2. Преобразование списков
- •9.3. Матричные функции
- •10. Массивы
- •11. Основные типы графиков
- •11.1. Двумерные графики
- •Show[GraphicsArray[{g1, g2,…}], options]
- •11.3. Изображения трехмерных объектов
- •11.4. Анимация
- •12. Функция Manipulate
- •13. Аналитические операции. Интерполяция. Решение уравнений
- •13.1. Аналитические операции
- •13.2. Интерполяция
- •13.3. Решение алгебраических уравнений
- •13.4. Решение дифференциальных уравнений
- •14. Преобразование выражений
- •14.1. Стандартная форма выражений
- •Примеры выражений
- •14.2. Обращение к элементам выражений
- •14.3. Представление выражения в виде дерева
- •14.4. Операции преобразования выражений
- •14.5. Повторное выполнение операций
- •14.6. Анонимные функции
- •14.7. Функциональные операторы Outer и Inner
- •Вопросы
8.2. Немедленное и задержанное присваивание
Использование оператора простого присваивания L = R означает, что результат вычисления правой части R немедленно присваивается левой части L, где левая часть сама может быть любым выражением. После этого каждый раз, когда появляется L, оно заменяется на R. Присваивание в форме f[args] = R устанавливает привило преобразования связанное с символом f.
Простое присваивание будем называть также немедленным присваиванием.
Математика позволяет производить одновременное присваивание нескольким выражениям:
{l1, l2, …} = {r1, r2, …}.
Другой возможный способ присваивания – задержанное или отложенное присваивание (SetDelayed):
L := R
-
правая часть выражения вычисляется только тогда, когда происходит обращение к L. Разница между двумя операторами присваивания видна из следующих двух примеров:
x = Random[] и y := Random[]
Обе величины: x и y – являются случайными, но x при повторных обращениях сохраняет свое первоначальное значение, в то время как y при каждом обращении изменяется.
Пример 8.1.
Определим собственную функцию для вычисления факториала:
In[1] := fac[n_Integer/;n>=0] = If[n==0, 1, n*fac[n–1]]
В этом определении может быть использовано как простое, так и задержанное присваивание. Однако если при использовании оператора простого присваивания переменной n предварительно было присвоено какое-либо значение, возникает ошибка. Например, если переменной n предварительно присвоено значение 3, то мы получим функцию тождественно равную 6.
Замечание. Если в определении функции f(x) используется оператор немедленного присваивания, и аргументу x предварительно присвоено некоторое значение x=a, то определение дает функцию-константу . При использовании в определении функции немедленного присваивания для избежания возможных ошибок следует непосредственно перед присваиванием очистить все идентификаторы, используемые в качестве аргументов функции.
Пример 8.2.
Следующее определение функции f(x)=x2 реально порождает функцию-константу :
In[ ] := {x=3; f[x_]=x^2; Clear[x]; f[x], f[t], f[2]} Out[ ] = {9, 9, 9}
Проблемы с определением функции не возникает, если значение x предварительно очищено:
In[ ] := {Clear[x]; f[x_]=x^2; x=3, f[x], f[t], f[2]} Out[ ] = {3, 9, t2, 4}
Проблемы также не возникает, если используется задержанное присваивание:
In[ ] := {x=3, g[x_]:=x^2; g[x], g[t], g[2]} Out[ ] = {3, 9, t2, 4}
Рассмотрим пример еще одной ошибки.
Пример 8.3.
Определим двумя разными способами производную одной и той же функции:
f3[x_] = D[x^2, x] и f4[x_] := D[x^2, x]
Обращения f3[x] и f4[x] дают очевидный ответ: 2 x. Аналогично на вопрос f3[5] получаем правильный ответ: 10. В то же время попытка найти значение производной в фиксированной точке с помощью функции f4 приводит к ошибке. Например, на вопрос f4[5] получаем замечание, что 5 не является переменной и ответ: d525. Получается, что Математика здесь действует формально с учетом приоритета операций: сначала подставляет 5 вместо x, а после этого оказывается, что дифференцирование невозможно.
В рассматриваемом примере для исключения ошибки можно положить f4[x_]:=f3[x].
Аналогичная ошибка возникает, если отложенное присваивание используется для вычисления первообразной.
Пример 8.4.
Найдем значение экспоненты с помощью разложения в ряд Маклорена:
ex = 1 + x + x2/2! + x^3/3! + …
Для этого напишем простую программу:
ex[x_, n_] := ( For[ u=1; e=1; k=1, k<n, u=u*x/k; e=e+u; k++]; e )
Программа состоит из двух операторов, заключенных в объединяющие круглые скобки: оператора цикла и оператора, предписывающего вывести значение найденной суммы – значение переменной “e”. Члены ряда Маклорена вычисляются последовательно с помощью рекурсивной формулы:
uk = uk-1*x/k.
Число n задает количество суммируемых членов ряда. Если мы теперь напишем вопрос:
In[ ] := ex[x, 5], то получим ответ: Out[ ] = 1 + x + x2/2 + x3/6 + x4/24,
на вопрос In[ ] := ex[1, 9]//N получим ответ: Out[ ] = 2.71828 и т.д. В программе используется оператор задержанного присваивания. Если вместо этого использовать операцию немедленного присваивания, возникнет ошибка: невозможно вычислить сумму с неопределенным числом слагаемых.
Итак, подытожим сказанное. В тех случаях, когда перед подстановкой численных значений необходимо сначала произвести аналитические преобразования, например, при вычислении производных, следует использовать оператор немедленного присваивания. При этом во избежание возможных ошибок следует непосредственно перед присваиванием очистить все идентификаторы, используемые в качестве аргументов функции. Если немедленное присваивание невозможно, например, не определено количество членов формулы, следует использовать операцию задержанного присваивания.