Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Немедленное и задержанное присваивание

Читайте также:
  1. I.2 Операторы цикла с присваиванием.
  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 и т.д. В программе используется оператор задержанного присваивания. Если вместо этого использовать операцию немедленного присваивания, возникнет ошибка: невозможно вычислить сумму с неопределенным числом слагаемых.

Итак, подытожим сказанное. В тех случаях, когда перед подстановкой численных значений необходимо сначала произвести аналитические преобразования, например, при вычислении производных, следует использовать оператор немедленного присваивания. При этом во избежание возможных ошибок следует непосредственно перед присваиванием очистить все идентификаторы, используемые в качестве аргументов функции. Если немедленное присваивание невозможно, например, не определено количество членов формулы, следует использовать операцию задержанного присваивания.


Дата добавления: 2015-07-08; просмотров: 236 | Нарушение авторских прав


Читайте в этой же книге: Точные и приближенные вычисления. Численные и аналитические операции | Рабочий документ и ячейки. Основные команды | Правила написания. Основные встроенные функции | Функции комплексного аргумента | Прерывание вычислений | Матричные функции | Массивы | Двумерные графики | Изображения трехмерных объектов | Анимация |
<== предыдущая страница | следующая страница ==>
Цикл Do| Составление программ. Глобальные и локальные переменные

mybiblioteka.su - 2015-2024 год. (0.01 сек.)