Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Инстр_Mathem_v8.doc
Скачиваний:
5
Добавлен:
16.11.2019
Размер:
1.91 Mб
Скачать

7.4. Функция If

Общий формат функции: If[test, then, else, unknown]. Максимальное количество аргументов – четыре, но применимы также более короткие форматы: If[test, then, else] и If[test, then]. Если условие test выполнено, то вычисляется выражение then, иначе вычисляется else. Предусмотрен также случай, когда логическое значение условия test не может быть определено. Например, значение высказывания x<5 не определено, если не известно значение x. Более общая форма функции If учитывает эту возможность: если истинность условия test не определена, то вычисляется выражение unknown. Каждый из аргументов: then, else и unknown – может включать несколько операторов, отделенных друг от друга точкой с запятой. Функция If допускает вложения.

7.5. Логические выражения

Язык пакета Математика содержит достаточное количество логических операторов, необходимых для составления условных выражений. Часть таких операторов приведена в таблице 7.1.

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

Значение высказывания во второй строчке таблицы определяется тем, что прибавляемое к единице число в левой части равенства меньше машинного эпсилон.

Значение высказывания в четвертой строке связано с тем, что в пакете Математика вводится особый формат чисел – Rational. В этом формате числа представляются точно, поэтому даже ничтожная прибавка к единице делает сумму отличной от единицы.

8. Функции пользователя. Составление программ

8.1. Функции пользователя. Описания типов аргументов

Для того чтобы ввести новую функцию, например, функцию возведения в квадрат, достаточно написать выражение:

f

Таблица 8.1. Применение

функции f[x_] = x^2

Входное

выражение

Выходное

выражение

f[t]

t2

f[3]

9

f[f[3]]

81

f[a+b]//Expand

a2 + 2 a b + b2

f["длина "]

длина2

[x_] = x^2

В этом выражении “=” – оператор простого присваивания (Set), “x” – аргумент функции. После имени аргумента в качестве обязательного элемента следует описание его типа. В данном случае таким описанием является знак подчеркивания, описывающий самый общий тип: в качестве x может использоваться любой объект, даже строковая переменная. Примеры применения введенной функции даны в таблице 8.1. Команда Expand в четвертой строке таблицы предписывает раскрыть скобки в формуле (a+b)2.

Другие возможные описания типов аргументов:

_Integer – любое целое число,

_Real – любое действительное число,

x_/; x>0 – любое положительное число.

Последнее описание включает условное выражение: знак ”/;” (condition) означает “при условии”.

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

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