Математика. Настоящий учебник посвящен системе Mathematica прикладному пакету компьютерной алгебры, при помощи которого можно решать любые задачи, в которых в той или иной форме встречается математика
Скачать 4.43 Mb.
|
(теорема 267), но мы же слышали о логической эквивалентности? Из сказанного выше ясно, что в общем случае трансцендентные уравне- ния не решаются. У нас просто нет такого количества букв, чтобы при- своить индивидуальное имя каждому корню всех встречающихся в приро- де трансцендентных уравнений. Более того, в большинстве случаев очень трудно даже связать решения различных трансцендентных уравнений или вообще доказать какое-то индивидуальное суждение об этих решениях. Са- мый знаменитый пример, когда мы не в состоянии решить простейшее трансцендентное уравнение — это гипотеза Римана. При re(s) > 1 опре- делим дзета-функцию Римана сходящимся рядом ζ(s) = ∞ X n=1 1 n s . Эта функция допускает аналитическое продолжение на всю комплексную плоскость, с полюсом в s = 1 (гармонический ряд расходится!) Так вот, многие факты в теории чисел зависят от того, что все нули дзета-функции в критической полосе 0 < re(s) < 1 расположены на прямой re(s) = 1/2. Однако на протяжении полутора веков решение этой проблемы — кото- рую Давид Гильберт называл главной задачей не только математики, но и всей жизни! — ускользает от всех усилий специалистов. Иными слова- ми, мы не можем решить уравнение ζ(s) = 0 даже при дополнительных предположениях о локализации корней! • Решение трансцендентных уравнений. Команда Solve может служить и для решения трансцендентных уравнений, в тех случаях, ко- гда система может легко сделать это известными ей методами. Однако в действительности правильной командой для решения трансцендентных уравнений в подавляющем большинстве случаев является Reduce, а отнюдь не Solve!! Разумеется, так как мы не умеем решать трансцендентных урав- нений, то даже Reduce не может в общем случае дать правильного отве- та. Однако применение Reduce по крайней мере гарантирует от получения неправильного или неполного ответа. Сравним эти команды на конкретных примерах. Скажем, попытка провести вычисление In[41]:=Solve[Exp[2*x]+2*Exp[x]+1==x,x] приводит к следующему сообщению об ошибке: Solve: This system cannot be solved with the methods 28 Э.Ландау, Введение в дифференциальное и интегральное исчисление. — 1948, ИЛ, М., с.1–458. 67 available to Solve. В результате система просто оставляет наше исходное выражение неэва- люированным. К сожалению, в данном случае и применение Reduce не приводит к большому успеху, в ответ на попытку вычислить In[41]:=Reduce[Exp[2*x]+2*Exp[x]+1==x,x] мы получаем такое оптимистическое сообщение: Reduce: This system cannot be solved with the methods available to Reduce. Так что не нарисовав графики левой и правой части при помощи коман- ды Plot, Вы так и не сможете узнать, имеет это уравнение вещественные корни, или нет. С другой стороны при попытке вычислить In[41]:=Solve[Sqrt[Log[x]]==Log[Sqrt[x]],x] система выдает сообщение о возможной ошибке: Solve: Inverse functions are being used by Solve, so some solutions may not be found; use Reduce for complete solution information. Однако в данном случае, несмотря на свою озабоченность, система возвра- щает правильный ответ: Out[41]= {{x->1},{x->E^4}} Следует отметить, что встречаются примеры — и мы увидим их в Моду- ле 2, — когда система действительно находит лишь часть решений, а не все решения, так что обычно к подобному предупреждению следует отно- ситься с полной серьезностью. Вот еще один похожий пример, в котором мы игнорируем error message и в результате получаем лишь частичный ответ: In[42]:=Solve[Sin[x]==Cos[x],x] Out[42]= {{x->-3*Pi/4},{x->Pi/4}} Понятно, что это не совсем то, что мы хотели. В то же время применение здесь команды Reduce дает уже абсолютно осмысленный ответ: In[43]:=Reduce[Sin[x]==Cos[x],x] Out[43]=C[1] ∈Integers&&(x==-2*ArcTan[1+Sqrt[2]]+2*Pi*C[1]|| x==-2*ArcTan[1-Sqrt[2]]+2*Pi*C[1]) Дальнейшие примеры трансцендентных уравнений рассмотрены в § 5. • Численное решение уравнений. Основной командой для числен- ного решения алгебраических уравнений является команда NSolve. Дело в том, что точное решение алгебраических уравнений с последующим округ- лением может приводить к чрезвычайно забавным эффектам. В качестве типичного примера можно рассмотреть характеристическое уравнение ку- бической матрицы золотого сечения 1 − 5x + 6x 2 − x 3 = 0. Решая это уравнение при помощи формулы Кардано, мы получим точные корни: In[44]:=Solve[1-5*x+6*x^2-x^3==0,x] 68 Out[44]= {{x->2+7^(2/3)/(3/2*(9+I*Sqrt[3])^(1/3)+ (7/2*(9+I*Sqrt[3]))^(1/3)/3^(2/3) }, {x->2-(7/2)^(2/3)*(1+I*Sqrt[3])/(3*(9+I*Sqrt[3]))^(1/3) -(1-I*Sqrt[3])*(7/2*(9+I*Sqrt[3]))^(1/3)/2*3^(2/3) }, {x->2-(7/2)^(2/3)*(1-I*Sqrt[3])/(3*(9+I*Sqrt[3]))^(1/3) -(1+I*Sqrt[3])*(7/2*(9+I*Sqrt[3]))^(1/3)/2*3^(2/3) }, Как было известно итальянским математикам XVI века, все мнимости в этих формулах сокращаются, так что все три корня вещественные (Кар- дано назвал это явление casus irreducibilis). Однако попытка найти приближенные значения корней приводит к следующему удивительному ответу, еще раз иллюстрирующему полную абсурдность применения чис- ленных методов к задачам с точными условями: In[45]:=Map[N,Solve[1-5*x+6*x^2-x^3==0,x]] Out[45]= {{x->5.04892+2.77556*10^-17*I}, {x->0.307979+2.22045*10^-16*I}, {x->0.643104-2.22045*10^-16*I}} Понятно, что здесь происходит? Система находит значения 9 + i √ 3 и т.д. с машинной точностью (около 16 знаков после запятой), после чего начина- ет манипулировать с этими приближенными значениями. Но при прибли- женных вычислениях неизбежно возникают артефакты наподобие 2.77556, 2.22045 и т.д. В подобных случаях изначальная трактовка условий как приближенных приводит к лучшим результатам: In[46]:=NSolve[1-5*x+6*x^2-x^3==0,x,20] Out[46]= {{x->0.3079785283699041304}, {x->0.6431041321077905561},{x->5.048917339522305314}} 69 § 4. Системы уравнений и неравенств Nowadays we can do computer experiments using Mathematica, and even solve a system of 42 equations. This offers another route to knowledge, rather than mere ideas. John F. Nash, Jr. Конечно, преимущества системы Mathematica становятся полностью по- нятны только в тот момент, когда нам нужно решить систему 42 уравнений от 47 неизвестных. Для наглядности и из типографских соображений мы проиллюстрируем способности системы на чисто учебных примерах систем от трех неизвестных, но она сравнительно легко решает в реальном вре- мени системы от десятка неизвестных, а, если дать ей немного подумать — то и от нескольких десятков неизвестных В действительности в этом отношении Mathematica уступает только са- мым продвинутым специализированным системам полиномиальных вычис- лений, вроде Singular, которые, с другой стороны, не умеют делать абсо- лютно ничего, кроме полиномиальных преобразований и решения систем алгебраических уравнений. Решение систем алгебраических уравнений от нескольких сотен неизвестных сегодня все еще рассматривается как очень трудная задача для систем компьютерной алгебры. • Решение систем алгебраических уравнений. Для решения систе- мы алгебраических уравнений f 1 (x, y, z) = g 1 (x, y, z), . . . , f n (x, y, z) = g n (x, y, z) команда Solve вызывается в одном из следующих основных форматов: ◦ Как функция двух аргументов, первым из которых является список уравнений, а вторым — список тех неизвестных, относительно которых мы пытаемся решить систему: Solve[ {f1[x,y,z]==g1[x,y,z],...,fn[x,y,z]==gn[x,y,z]},{x,y}] остальные неизвестные при этом рассматриваются как параметры. ◦ Как функция двух аргументов, первым из которых является конъюнк- ция уравнений, а вторым — список тех неизвестных, относительно которых мы пытаемся решить систему: Solve[f1[x,y,z]==g1[x,y,z]&&...&&fn[x,y,z]==gn[x,y,z], {x,y}] ◦ Как функцию двух аргументов, первым из которых является вектор- ное уравнение, (f 1 (x, y, z), . . . , f n (x, y, z)) = (g 1 (x, y, z), . . . , g n (x, y, z)), а вторым — список тех неизвестных, относительно которых мы пытаемся решить систему: Solve[ {f1[x,y,z],...,fn[x,y,z]}=={g1[x,y,z],...,gn[x,y,z]}, {x,y}] 70 ◦ Как функция одного аргумента, который при этом оформляется либо как список, либо как конъюнкция уравнений, либо, наконец, как векторное уравнение: Solve[ {f1[x,y,z]==g1[x,y,z],...,fn[x,y,z]==gn[x,y,z]}] Solve[f1[x,y,z]==g1[x,y,z]&&...&&fn[x,y,z]==gn[x,y,z]] Solve[ {f1[x,y,z],...,fn[x,y,z]}=={g1[x,y,z],...,gn[x,y,z]}] В этом случае система изо всех сил пытается найти значения всех входя- щих в эти уравнения символов, что, вообще говоря, не всегда получается, если количество уравнений меньше, чем количество неизвестных и пара- метров. ◦ Как функция трех аргументов, первым из которых является система уравнений (представленная в любой из трех описанных выше эквивалент- ных форм), вторым — список тех неизвестных, относительно которых мы пытаемся решить систему, а третьим — та неизвестная или список тех неиз- вестных, которые мы при хотим при этом полностью элиминировать (= исключить) из ответа, как в качестве неизвестных, так и в качестве пара- метров: Solve[f1[x,y,...]==g1[x,y,...]&&...&&fn[x,y,...]==gn[x,y,...], {x,y},{u,v}] Поскольку понять (а тем более объяснить!!) не только все детали, но даже азы того, что происходит при вызове команды Solve с тремя аргументами, довольно трудно, мы настоятельно рекомендуем начинающему использо- вать команду Eliminate для исключения неизвестных, а потом уже решать получаюшуюся систему обычным образом. • Enough, or too little. Проиллюстрируем решение систем алгебра- ических уравнений на простейших примерах. Заметим, что в связи с ис- пользуемой процедурой элиминации неизвестных система может несколько раз порождать одно и то же решение, поэтому, если нас — в школьном ду- хе — интересует множество решений, для сокращения ответа мы обычно применяем поверх команды Solve команду Union. Мы уже видели, что уже в случае одного уравнения Mathematica не зна- ет, какие из входящих в него символов следует рассматривать как неизвест- ные, а какие как параметры. Для правильного решения систем уравнений эта проблема становится абсолютно критической. Как всегда, Mathematica может посчитать некоторые некоторые параметры неизвестными — но это сравнительно мелкая неприятность (или, на компьютерном языке, small beer). В действительности, здесь может произойти значительно более серьзное несчастье: Mathematica может решить, что некоторые неизвест- ные являются параметрами!!! А это, как правило, приводит к неверному ответу, причем получающиеся ошибки очень трудно отслеживаются (осо- бенно если решение уравнений бесконтрольно вызывается в составе другого вычисления). Например, если Вы постараетесь решить систему x − y = z 2 , x 3 = 1, y 3 = 1 71 относительно x и y посредством беззастенчивого In[47]:=Solve[ {x-y==z^2,x^3==1,y^3==1},{x,y}] то ответом будет оглушительное {}, хотя совершенно ясно, что эта система имеет решение, ну хотя бы (x, y, z) = (1, 1, 0). Ясно, что произошло? Дело в том, что у этой системы нет общих решений, в которых z могло бы вы- ступать в качестве параметра. Для любых допустимых значений x и y мы получаем явное уравнение на z. А попросив разрешить систему уравнений относительно x и y мы предложили Mathematica найти такие решения, в которых z выступает в качестве параметра!!! Это значит, что мы окажемся в гораздо лучшем положении, если попросим больше. И действительно, вычисление In[48]:=Union[Solve[ {x-y==z^2,x^3==1,y^3==1},{x,y,z}]] дает все 15 решений системы. Итак, решая систему уравнений, всегда зада- вайте себе вопрос, что Вас интересует: нахождение всех решений системы или нахождение общих решений, в которых какие-то неизвестные высту- пают в качестве параметров? Мораль: Чтобы избежать грубых ошибок, всегда просите у системы больше, чем хочется. • Примеры решения систем. Приведем несколько чисто учебных примеров решения систем алгебраических уравнений. ◦ В первом примере мы пытаемся решить систему 29 x 2 + y + z = 1, x + y 2 + z = 1, x + y + z 2 = 1 относительно всех входящих в нее неизвестных: In[49]:=Union[Solve[ {x^2+y+z==1,x+y^2+z==1,x+y+z^2==1}]] Out[49]= {{x->0,y->0,z->1},{x->0,y->1,z->0},{x->1,y->0,z->0}, {x->-1-Sqrt[2],y->-1-Sqrt[2],z->-1-Sqrt[2]}, {x->-1+Sqrt[2],y->-1+Sqrt[2],z->-1+Sqrt[2]}} ◦ Решение уже простейших систем, зависящих от параметров, представ- ляет собой довольно серьезную задачу. Дело в том, что при последователь- ном исключении неизвестных степень уравнений относительно остающихся неизвестных быстро растет. Например, исключая неизвестные y и z из си- стемы x 2 + y + z = a, x + y 2 + z = b, x + y + z 2 = c мы получаем уравнение степени 8 относительно x, коэффициенты которого довольно тягостным образом выражаются через a, b, c. Это значит, что по- пытавшись решить систему относительно уравнений x, y, z беззастенчивым In[50]:=Solve[ {x^2+y+z==a,x+y^2+z==b,x+y+z^2==c},{x,y,z}] 29 Д.Кокс, Дж.Литтл, Д.О'Ши, Идеалы, многообразия и алгоритмы. — Москва, Мир, 2000, с.1–687; стр.151–152. 72 Вы конечно, увидите на экране решение. Вот только что именно Вы соби- раетесь делать с таким решением, координаты которого выражены в тер- минах объектов типа Root от многочлена степени 8, каждый из коэффи- циентов которого в свою очередь является многочленом изрядной степени от a, b и c? Такой ответ легко может занять сотни или тысячи строк на экране. Поэтому в тех случаях, когда мы не знаем, что произойдет, мы часто вначале интересуемся не самим ответом, а длиной ответа, в данном случае количеством решений: In[51]:=Length[Union[Solve[ {x^2+y+z==a,x+y^2+z==b,x+y+z^2==c}, {x,y,z}]]] Ну в данном-то случае у нашей системы 8 решений. А если их несколько десятков или несколько сотен? В этом случае мы обычно смотрим на вид решений посредством команды Short: In[52]:=Short[Union[Solve[ {x^2+y+z==a,x+y^2+z==b,x+y+z^2==c}, {x,y,z}]],10] Вызванная в формате Short[expression,d] команда Short приводит к тому, что на экране отображается не все вы- ражение expression, которое может занимать несколько сотен страниц и форматирование которого может требовать весьма значительного времени, а только его часть, приблизительно d строчек. Приблизительно потому, что система все же пытается вывести осмысленную часть выражения, по которой можно составить хотя бы самое общее впечатление о виде всего остального. В общем случае (например, если количество уравнений меньше, чем ко- личество неизвестных) решить систему относительно всех неизвестных не удастся, в этом случае следует явно указывать те неизвестные, которые мы хотим выразить через остальные. ◦ В следующей задаче мы просим Mathematica выразить в системе x + y + z = 1, x 2 + y 2 + z 2 = 1, неизвестные x, y через неизвестную z, которая в этом случае трактуется как параметр: In[53]:=Solve[ {x+y+z==1,x^2+y^2+z^2==1},{x,y}] Out[53]= {{x->1/2*(1-z-Sqrt[1+2*z-3*z^2]), y->1/2*(1-z+Sqrt[1+2*z-3*z^2]) }, {x->1/2*(1-z+Sqrt[1+2*z-3*z^2]), y->1/2*(1-z-Sqrt[1+2*z-3*z^2]) }} Если попытаться решить систему относительно всех трех неизвестных, ска- жем, так: In[54]:=Solve[ {x+y+z==1,x^2+y^2+z^2==1},{x,y,z}] то результатом будет уже знакомое нам сообщение об ошибке: 73 Solve: Equations may not give solutions for all "solve" variables. Тем не менее, Mathematica снова вернет те же самые формулы, что и в предыдущем случае. Кстати, как Вы думаете, почему она и в этом слу- чае выражает x и y через z? Ну это, как раз, совершенно понятно. Она пытается решить систему в первую очередь относительно тех переменных, которые перечислены в списке первыми. В ответ на In[55]:=Solve[ {x+y+z==1,x^2+y^2+z^2==1},{z,y,x}] она выдаст то же сообщение об ошибке и выразит z и y (в таком порядке!) через x. • Исключение неизвестных. В тех случаях, когда уравнений недо- статочно, чтобы найти все неизвестные, часто полезно просто свести исход- ную систему уравнений к системе от меньшего количества неизвестных. В случае алгебраических уравнений основной командой для этого в языке Ma- thematica является Eliminate. Для исключения неизвестной z из системы алгебраических уравнений f 1 (x, y, z) = g 1 (x, y, z), . . . , f n (x, y, z) = g n (x, y, z) команда Eliminate вызывается в формате Eliminate[ {f1[x,y,z]==g1[x,y,z],...,fn[x,y,z]==gn[x,y,z]},z] функции двух аргументов, первым из которых является список уравнений, а вторым — исключаемая неизвестная (или список неизвестных, если их несколько). Для получения более симметричного ответа, как всегда, реко- мендуется применять поверх команды Eliminate команду Simplify. Вот пара простейших примеров: In[56]:=Simplify[Eliminate[ |