Главная страница

Математика. Настоящий учебник посвящен системе Mathematica прикладному пакету компьютерной алгебры, при помощи которого можно решать любые задачи, в которых в той или иной форме встречается математика


Скачать 4.43 Mb.
НазваниеНастоящий учебник посвящен системе Mathematica прикладному пакету компьютерной алгебры, при помощи которого можно решать любые задачи, в которых в той или иной форме встречается математика
АнкорМатематика
Дата11.05.2022
Размер4.43 Mb.
Формат файлаpdf
Имя файла106-108.pdf
ТипУчебник
#521834
страница15 из 38
1   ...   11   12   13   14   15   16   17   18   ...   38
m точкой с запятой;
Предостережение. Условный оператор If вызывается с двумя аргументами, вместо обычных трех или четырех . Мы можем позволить себе делать это только потому, что эта функция написана нами в чисто учебных целях, и мы собираемся использовать ее для небольших значений n, когда PrimeQ гарантировано дает достоверный ответ True или False. В следующем параграфе мы объясняем, почему во всех серьезных случаях для оператора If мало и трех аргументов.
Конструкцию With[
{x=a,y=b},body] можно воспринимать как совмест- ное ослабление конструкций
Module[
{x=a,y=b},body] и Block[{x=a,y=b},body].

206
Однако между ними имеется существенное различие, состоящее в том, что с случае конструкций Module и Block значения a и b рассматриваются как начальные значения переменных x и y в вычислении body. В дальней- шем в процессе вычисления body эти значения могут меняться на каж- дом шаге и в вычислении окончательного ответа участвуют уже какие-то совсем другие значения x и y. В то же время в случае конструкции With переменные x и y становятся внутри нее локальными константами a и
b и именно они используются на всех шагах вычислении body. Эта кон- струкция не создает новых переменных, а локализует только их значения:
Все имена переменных используемых конструкцией With являются гло- бальными. Однако присвоенные внутри нее значения этих переменных не влияют на их глобальные значения. Например, x=1; With[
{x=2},y=x^2];
x+y даст Вам 5, а не 6.
Если имена переменных входят в конфликт, то в соответствии с общим принципом last in, first out всегда используется самое глубокое значение переменной. Например, With[{x=a},With[{x=b},f[x]]] даст
Вам f[b].
Конструкция With полупрозрачна: значения тех переменных, имена которых не входят в конфликт, продолжают оставаться видимыми локаль- но. Например, With[
{x=a},With[{y=b},f[x,y]]] даст Вам f[a,b].
В то же время, команда Unique действует прямо противоположным об- разом. Она каждый раз явно порождает уникальную переменную. Эту команду можно использовать следующим образом:
Unique[] создает новый символ с именем формата $ModuleNumber,
Unique[x] создаст новый символ с именем формата x$ModuleNumber,
Unique["x"] создаст новый символ с именем формата xModuleNumber.
Следующие два диалога хорошо иллюстрируют, что происходит при при- менении этой команды.
In[24]:=Table[Unique[x],
{i,1,10}]
Out[24]=
{x$85,x$86,x$87,x$88,x$89,x$90,x$91,x$92,x$93,x$94}
In[25]:=Table[Unique["x"],
{i,1,10}]
Out[25]=
{x71,x72,x73,x74,x75,x76,x77,x78,x79,x80}
В этот момент Вы должны всерьез задуматься, действительно ли Вам нуж- но несколько сотен индивидуальных переменных, имена которых начи- наются с x или, все же в этом случае удобнее рассматривать совокупность этих переменных как массив значений функции x или как компоненты спис- ка x. Более того, и с точки зрения компьютера вычисления с функцией или списком значительно эффективнее!!!

207
§ 11. Равенство и тождество:
== Equal versus === Same
Равенство есть продукт непротивления сторон.
Математик
Сейчас мы объясним еще два значения, на которые символ = расщепля- ется в Computer Science, а именно, равенство == и тождество ===.
x==y
Equal[x,y]
равно x!=y
Unequal[x,y]
не равно x===y
SameQ[x,y]
тождественно x=!=y
UnsameQ[x,y]
нетождественно
В первом приближении разницу в использовании этих операторов мож- но объяснить так: сравнивая значения двух выражений, нужно писать lhs==rhs в то же время сравнивая форму этих выражений, следует писать lhs===rhs.
В частности, во всех командах , связанных с символьным или числен- ным решением уравнений, уравнение f (x) = g(x) должно записываться как f[x]==g[x]. Запись уравнения в форме f[x]=g[x] представляет собой грубейшую ошибку!!! Эта ошибка настолько очевидна, что даже обсуж- дать ее смешно, ведь запись с помощью Set представляет собой присваива- ние, т.е. попытку изменить текущее значение f (x) на g(x). В большинстве случаев, если f (x) имеет защищенный заголовок или когда f (x) уже яв- ляется сырым объектом, система просто не даст нам записать уравнение в такой форме!! Например, попытка написать a*x^2+b*x+c=0, приведет к сообщению об ошибке: Tag Plus in c+b*x+a*x^2 is Protected.
Однако хотя различие между == и === менее очевидно, смешение этих операторов приводит к столь же драматическим последствиям. Вот, на- пример, как Mathematica решает квадратные уравнения.
In[26]:=Solve[a*x^2+b*x+c==0,x]
Out[26]=
nn x->
-b-

b^2-4*a*c
2*a o
,
n x->
-b+

b^2-4*a*c
2*a oo
Однако попытка предложить системе вычислить
Solve[a*x^2+b*x+c===0,x]
приведет к ответу
{}. Понятно, почему? В первый раз мы спросили, при каких x значение ax
2
+ bx + c равно 0. А во второй раз — при каких
x внутренняя форма выражения a*x^2+b*x+c текстуально совпадает с внутренней формой выражения 0. Да ни при каких!!!
Упражнение. Как Вы думаете, почему команда решения уравнения име- ет формат Solve[f[x]==g[x],x]? При чем тут x?
Решение. Ну это тоже понятно. Это мы знаем, что x обозначает неиз- вестную, но система об этом не должна догадываться. Ну в самом деле,

208
не предлагать же ей по умолчанию решать все уравнения относительно
x!! Предложение вычислить Solve[a*x^2+b*x+c==0,a] приведет к ответу a=(-c-bx)/x^2.
Так как решение уравнений встречается довольно часто, еще раз под- черкнем, что предикаты Equal[x,y] и SameQ[x,y] следует тщательней- шим образом различать:
Справедливость равенства x==y представляет собой математический вопрос, функция Equal[x,y] возвращает значение True, если x и y имеют равные значения и значение False, если x и y имеют различные значения.
Во многих случаях Mathematica на основе имеющихся у нее данных не в состоянии решить, равны x и y или нет!!! В этом случае она просто оставляет выражение Equal[x,y] неэвалюированным.
В то же время справедливость тождества x===y представляет собой алгоритмический вопрос. Функция SameQ[x,y] возвращает значение True,
только если x и y реализованы одинаковым образом —
имеют одинако- вую внутреннюю форму — и False во всех остальных случаях. Это значит, что Mathematica всегда может дать ответ на вопрос SameQ[x,y].
Эти ответы очень часто отличаются — две равные вещи не обя- зательно тождественны — как учили нас на уроках диалектического ма- териализма,
одинаковое одинаковому рознь! Чтобы сознательно ис- пользовать эти операторы, полезно постараться понять логику системы.
Например, 1==1. принимает значение True — ведь это равные числа — но,
конечно, 1===1. принимает значение False — хотя бы потому, что 1. не является целым числом!
Единственный случай, когда тождество x===y не требует текстуаль- ного совпадения внутренних представлений — это равенство приближен- ных вещественных или комплексных чисел. В этом случае система может решить, что два числа тождественны, если их разность меньше, чем точ- ность каждого из них.
Еще одной типичной ошибкой, которую мы систематически соверша- ли в начале 1990-х годов, было неосторожное использование == в условных операторах. По наивности мы исходили из того, что оператор If[x==y,u,v]
должен возвращать либо u, либо v. Но это совершенно не так, в тех слу- чаях, когда система не может решить, действительно ли x==y, она просто оставляет это выражение неэвалюированным, что часто приводит к бес- конечной рекурсии. После нескольких крайне неприятных эпизодов (в те годы ни в интерфейсе Mathematica ни в Mac OS не было предусмотрено прерывание вычисления и мы были вынуждены физически выключать ком- пьютер, теряя все предшествующие вычисления!!!) мы сделали три важных вывода:
better save than sorry;
в сомнительных случаях условные операторы необходимо задавать в виде If[x==y,u,v,w], явно предписывающим значение условного выраже-

209
ния и в том случае, когда система не в состоянии решить, равны x и y или,
все-таки, нет!
Часто система не может решить, равны ли два выражения, по чи- сто формальным причинам. Дело в том, что во многих ситуациях она не производит автоматических упрощений. Это значит, что сравнивая два выражения, всегда полезно применить к ним все возможные
54
упрощения!!! Если Вы хотите проверить, равны ли x и y, Ваши шансы на получение правильного ответа резко возрастут, если вместо x==y Вы напе- чатаете Simplify[x]==Simplify[y], FullSimplify[x]==FullSimplify[y],
или что-нибудь соответствующее ситуации: FunctionExpand, LogicalEx- pand, Refine, Reduce и тому подобное.
Другой народный способ состоит в том, чтобы задавать условные опе- раторы с использованием === но тогда, конечно, тем более вначале нужно либо упрощать сравниваемые выражения,
If[Simplify[x]===Simplify[y],u,v],
либо принудительно приводить их к одинаковой форме посредством Fac- tor, Expand и т.д.
Предостережение. Как и в языке C++ выражения ==, !=, ===, =!=, <=, >=
и т.д. представляют собой командные слова, а внутри слова пробел не ставится. Выражение, содержащее пробел внутри командного слова счита- ется синтаксически неправильным и приводит к сообщению об ошибке.
Предостережение. Mathematica исходит из того, что реляционные опера- торы транзитивны!!! Выражение x!=y!=z оценивается как истинное только если x, y, z попарно различны! В частности, 1!=0!=1, истинное с точки зре- ния математических традиций, будет оценено как False.
§ 12. Решение алгебраических уравнений
Как мы знаем, с точки зрения Mathematica выражение f[x]==g[x] пред- ставляет собой уравнение. В системе имплементировано несколько функ- ций для точного (когда это возможно) и приближенного (во всех остальных случаях) решения уравнений. Вот наиболее употребительные из них.
Roots[f==g,x]
решить полиномиальное уравнение f (x) = g(x)
Solve[f==g,x]
решить уравнение f (x) = g(x) относительно x
Reduce[f==g,x]
упростить уравнение f (x) = g(x)
Команды Roots, Solve и Reduce служат для точного решения урав- нений. В то же время команды NRoots, NSolve и FindRoot служат для приближенного вычисления корней. Поясним различие между ними.
Roots[f==g,x] является самой слабой командой, которая умеет ре- шать только полиномиальные уравнения в школьном духе. В случае неал-
54
всевозможные!

210
гебраического уравнения или когда она не может найти корни алгебраи- ческого уравнения в духе школьной математики, она просто оставляет их неэвалюированными:
In[27]:=Roots[x^5-x-1==0,x]
Out[27]=x==Root[-1-#1+#1^5&,1] || x==Root[-1-#1+#1^5&,2] ||
x==Root[-1-#1+#1^5&,3] || x==Root[-1-#1+#1^5&,4] ||
x==Root[-1-#1+#1^5&,5]
По умолчанию Roots решает кубические уравнения и уравнения чет- вертой степени в радикалах, иными словами опции Cubics и Quartics поставлены на True.
Для того, чтобы решать уравнения совсем уж в школьном духе, нужно включить в тело функции замены Cubics->False и
Quartics->False.
Однако так как команда Roots использует только полиномиальные ал- горитмы, в некоторых случаях (например при вычислениях в конечных кольцах, полях алгебраических чисел и т.д.) она оказывается весьма по- лезной. Перечислим некоторые команды, связанные с командой Roots.
Roots[f==g,x]
корни полиномиального уравнения f (x) = g(x)
Root[f,n]
n-й корень полиномиального уравнения f = 0
RootReduce[y]
попытка свести выражение к одному Root
ToRadicals[y]
попытка выразить все Root в радикалах
ToRules[y]
преобразовать формат вывода Roots в формат Solve
Смысл этих команд ясен сам по себе. Обратите внимание, что в команде
Root нет указания на то, относительно какой переменной следует решать уравнение!! Это значит, что первый аргумент должен вводиться не как мно- гочлен, а в формате чистой функции, скажем, вместо x^2+ax+b следует печатать (#^2-a#+b)&.
В качестве универсальной команды, дающей — в тех случаях, когда это возможно в элементарных терминах!! — точные решения алгебраических уравнений или систем уравнений, но пытающаяся решить вообще любые числовые уравнения имеющие конечное число корней в том числе и транс- цендентные, начинающий должен рассматривать Solve[f==g,x]. Кроме чисто полиномиальных алгоритмов решения Solve использует другие ин- струменты, такие как обратные функции (опция InverseFunctions). Од- нако при этом в случае бесконечного количества решений Solve как прави- ло ограничивается одной ветвью обратной функции и указывает какие-то решения, а не все решения.
Команду Solve можно применять для решения системы уравнений относительно нескольких переменных.
При этом как уравнения, так и неизвестные, относительно которых эти уравнения решаются, можно за- давать в форме списка: Solve[
{f1==g1,...,fm==gm},{x1,...,xn}]. Урав- нения можно связывать также логическими связками, скажем, f1==g1 &&
f2==g2. В этом случае ответ тоже будет записан как список замен
{{x-
>a,y->b
},...}.

211
Команда Solve порождает только общие решения и игнорирует ре- шения, возникающие при специальных значениях параметров.
В таких случаях нужно применять команду Reduce.
Кроме того, под влиянием команды Solve система приходит в такой восторг, найдя какие-то реше- ния, что перестает искать остальные решения, в таких случаях также нуж- но использовать команду Reduce!!
Например, попытавшись вычислить
Solve[Cos[x]==2,x], Вы получите следующий эфемерный ответ
{{x->-ArcCos[2]},{x->ArcCos[2]}}
вместе с сообщением о возможной ошибке
Solve: Inverse functions are being used by Solve,
so some solutions may not be found и советом use Reduce for complete solution information.
С большим отрывом самой общей и самой мощной командой для ре- шения уравнения f (x) = g(x) является Reduce[f==g,x]. Дело в том, что команда Reduce[expr,x] пытается упростить любое выражение expr от x,
содержащее равенства, неравенства, включения, логические связки и кван- торы. В случае, когда это выражения состоит только из уравнений и нера- венств, команда Reduce пытается их решить, но делает это гораздо более изощренным образом, чем просто подстановка x в одну из ветвей обратной функции. Таким образом, в отличие от команды Solve, она может указать не какие-то, а все решения уравнения, даже если этих решений бесконечно много. Вот два типичных примера использования Reduce — напоминаем,
что в действительности Reduce умеет значительно больше, в частности,
решает неравенства и логические формулы!!!
Вычисление Reduce[Cos[x]==2,x] дает правильный ответ
C[1]
Integers&&(x==-ArcCos[2]+2*Pi*C[1]||x==ArcCos[2]+2*Pi*C[1])
Обратите внимание, что C
1
здесь — произвольная целочисленная посто- янная.
В других контекстах Reduce может порождать несколько таких постоянных, принадлежащих различным доменам.
В следующем вычислении мы пытаемся найти целочисленные решения системы уравнений x = y + 1, x
2
= y
3
+ 1:
Reduce[x^2==y^3+1&&x==y+1,
{x,y},Integers]
Она находит три таких решения:
x==0&&y==-1 || x==1&&y==0 || x==3&&y==2
Следующие команды являются приближенными вариантами обсуждав- шихся раньше точных команд.
NRoots[f==g,x]
численное решение полиномиального уравнения
NSolve[f==g,x]
численное решение уравнения f (x) = g(x)
FindRoot[f==g,x,x0]
корень уравнения f (x) = g(x) вблизи x
0

212
Мы не будем подробно обсуждать использование этих команд, так как оно ясно само по себе. Команды NRoots и NSolve являются численными ана- логами команд Roots и Solve, осуществляющими приближенное вычисле- ние корней полиномиального уравнения или, соответственно, произвольно- го уравнения, имеющего лишь конечное число корней (в случае, если су- ществует алгоритм для их вычисления). С другой стороны команда Find-
Root[f==g,x,x0] ищет корень уравнения f (x) = g(x) начиная итеративную процедуру со значения x
0
Глава 6. ФУНКЦИИ
Выше было указано, что функции должны определяться незави- симо от того, кому приписано их выполнение. Из перечисления функций можно было убедиться, что они должны определяться и независимо от того, как, каким способом они выполняются.
Это иногда затрудняет определение отдельных случаев, так как разные функции могут выполняться совершенно одинаково. По- видимому, здесь имеется влияние одних форм на другие.
Это явление может быть названо ассимиляцией способов исполнения функций.
В полном объеме это сложное явление здесь не может быть осве- щено. Оно может быть рассмотрено лишь постольку, поскольку это необходимо для последующих анализов.
В.Я.Пропп, Морфология волшебной сказки
Все на свете является функцией — с точки зрения компьютерной алгебры все, что делается, и все, что происходит, любое изменение значения или формы выражения, любая модификация состояния системы или спосо- ба ее работы называется функцией. Фактически и в предыдущих главах нам не встречалось ничего, кроме функций. В этой главе мы начинаем си- стематическое изучение этого понятия. Мы детально обсудим основные обозначения и понятия, связанные с функциями, и основные классы функ- ций языка Mathematica и чуть более подробно остановимся на арифмети- ческих операциях, числовых функциях и булевых функциях (предикаты и отношения). Это подготовит нас к тому, чтобы в следующей части под- ступить к самой сути языка Mathematica: определению новых функций и функциям работы со списками/применению функций к спискам.

213
1   ...   11   12   13   14   15   16   17   18   ...   38


написать администратору сайта