Algebra Symboliczna
Wykład III

Andrzej Odrzywolek
Instytut Fizyki, Zakład Teorii Względnosci i Astrofizyki
05,11,2008, środa, 13:15

(* Solve[3 x^81+x+1==0,x] *)

No more memory available.
Mathematica kernel has shut down.
Try quitting other applications and then retry.

Dane kontaktowe

dr Andrzej Odrzywołek
pokój 447, IV pietro
E-mail: odrzywolek@th.if.uj.edu.pl
Wykład: środy 13.15-15.00, sala 128
Cwiczenia: piątki 10.30-12.00
Konsultacje: środy 11-13, czwartki 12-13
WWW: http://ribes.if.uj.edu.pl/alsymb/

Pewne uwagi na temat ,,rozwiązania'' zadania/problemu

Terminologia na przykładzie równanie a x2 + b x +c ==0 (1):
1. Rozwiązanie graficzne to wykres funkcji y[x_]:=a x2 + b x +c   w dowolnym przedziale dla ustalonych liczb a,b,c. Przecięcie wykresu z osią X oznacza rozwiązanie równania (1)
2. Rozwiazaniem numerycznym nazywam podanie nietrywialnej informacji gdzie znajduje sie rozwiazanie równania (1) dla pewnych ustalonych liczb a, b, c, np: dla
a = 1, b = 0 i c = −4, 1 < x < 3, lub x=0.123 z dokładnością 0.001.
3. Rozwiazaniem symbolicznym nazywam wzory:

Solve[a x^2+b x+c==0,x]

Wszystkie przypadki 1-3 są rozwiązaniami równania (1) !

Właściwa kolejność rozwiązywania zadań

1. O ile jest to mozliwe i sensowne staramy znalezc graficzne rozwiazanie zadania, czyli odczytac przyblizone wartosci z wykresu lub/i animacji. Dotyczy to m.in :
a) rozwiazywania równan i układów równan
b) szukania wartosci maksymalnych
c) badania funkcji
d) obliczania granic

2. Szukamy rozwiazania numerycznego/wartosci numerycznej

3. Szukamy symbolicznego rozwiazania zadania

Na kartce/ tablicy robimy to zwykle w dokładnie odwrotnej kolejnosci! Jest to możliwe tylko dla specjalnie spreparowanych zadań oraz niewielkiego ułamka realnych problemów !

Poprawna metodologia rozwiazywania zadan 1: 
Rozwiązanie graficzne

Narysowanie badanej funkcji w celu sprawdzenia czy np. posiada maksimum lub przecina os X daje nam przynajmniej 3 cenne informacje:
1. Ogólne pojecie o stopniu trudnosci problemu; niejednokrotnie wykres funkcji zapisanej przy pomocy niezwykle skomplikowanej formuły okazuje sie byc niemal linia prosta, lub wrecz przeciwnie
2. Istnienie oraz ilość potencjalnych rozwiązań
3. Przybliżone rozwiązanie zadania, czesto o wystarczajacej dokładnosci – jeżeli wymagana jest większa dokładność można je użyc jako punkt startowy dla metod numerycznych np. FindRoot

Przykład 1: rozwiąż Exp[1/x]=Log[x]

Plot[{Exp[1/x],Log[x]},{x,0,10}] (* ręcznie *)

Manipulate[Plot[{Exp[1/x],Log[x]},{x,x1,x2}],{x1,0,10,0.001},{{x2,10},0,10,0.001}]

Poprawna metodologia rozwiazywania zadan: 2
Rozwiazanie numeryczne

1. Wiekszosc typowych zadan mozna rozwiazac numerycznie, na ogół łatwiej i szybciej niz symbolicznie. 
2. W przypadku pojedynczych problemów bez symbolicznych
parametrów rzecz sprowadza sie do wywołania odpowiedniej funkcji numerycznej: FindRoot, NIntegrate, NDSolve,Det[N[A]].
3. Manipulowanie rozwiazaniami numerycznymi z parametrami jest skuteczne dzieki ogromnej mocy obliczeniowej współczesnych komputerów PC, które w locie generuja setki tysięcy rozwiazan przebiegajacych wszystkie możliwe wartości parametrów

Przykład 1: rozwiąż Exp[a/x]=Log[x]

Manipulate[Plot[{Exp[a/x],Log[x]},{x,0,10}],{a,-10,10,0.1}]

explog = Table[{a,x/.FindRoot[Exp[a/x]==Log[x],{x,2}]},{a,-10,10,0.1}] //Interpolation

Plot[explog''[t],{t,-10,10},PlotRange->All] (* wykres drugiej pochodnej)

Series[explog[x],{x,0,3}] //Normal (*rozwinięcie w szereg potęgowy, wygląda jakby szereg zaczynał się od E+x *)

Plot[{explog[a],E+a},{a,-3,3},PlotRange->All]

Przykład funkcji interpolaujacej w zakresie 6 rzędów wielkości. Zwróć uwagę na skutek zmiany MaxIterations z 100 na 1000.

explog2 = Join[Table[{-10^n,x/.FindRoot[Exp[-10^n/x]==Log[x],{x,2},MaxIterations->100]},{n,3,-3,-0.01}] ,{{0,E}},Table[{10^n,x/.FindRoot[Exp[10^n/x]==Log[x],{x,2},MaxIterations->100]},{n,-3,3,0.01}] ]//Interpolation

LogLogPlot[{explog[t],explog2[t]},{t,0.001,500},PlotRange->Automatic,PlotStyle->{Red,Blue}]

Przykład 2: rozwiąż UKŁAD RÓWNAŃ:
 {cn(y|(1/3))+sn(x|(1/3)) == 0, (x^2)+(y^2) == π^2}

w1=ContourPlot[{JacobiSN[x,1/3]+JacobiCN[y,1/3]==0,x^2+y^2==Pi^2},{x,-5,5},{y,-5,5}]

p1={x,y}/.FindRoot[{JacobiSN[x,1/3]+JacobiCN[y,1/3]==0,x^2+y^2==Pi^2},{x,3},{y,1}]
p4={x,y}/.FindRoot[{JacobiSN[x,1/3]+JacobiCN[y,1/3]==0,x^2+y^2==Pi^2},{x,3},{y,-1}]
p2={x,y}/.FindRoot[{JacobiSN[x,1/3]+JacobiCN[y,1/3]==0,x^2+y^2==Pi^2},{x,-3},{y,1}]
p3={x,y}/.FindRoot[{JacobiSN[x,1/3]+JacobiCN[y,1/3]==0,x^2+y^2==Pi^2},{x,-3},{y,-1}]

w2=ListPlot[{p1,p2,p3,p4}]

Show[{w1,w2}]

Solve[{JacobiSN[x,1/3]+JacobiCN[y,1/3]==0,x^2+y^2==Pi^2},{x,y}]

Poprawna metodologia rozwiazywania zadan: 3
Rozwiązanie symboliczne

1. Skutecznosc systemu MATHEMATICA (i innych CAS) w znajdowaniu rozwiazan analitycznych łatwo prowadzi do złudzenia, ze wszytko mozna rozwiazac w taki sposób
2. W rzeczywistosci to problemy egzaminacyjne, zbiory zadan jak równiez uswiecone przez czas metody i przykłady sa specjalnym podzbiorem wszystkich zagadnien, dobranym tak aby mozna było znalezc wynik symboliczny!
3. Jezeli atakujemy istotnie nowy problem, szanse na wynik symboliczny sa niewielkie, ale istnieja, dlatego zalecam szukanie rozwiazania tego typu dopiero gdy mamy pewnosc ze rozwiazanie istnieje (metoda graficzna) oraz wiemy jak wyglada w przyblizeniu (metoda numeryczna)

Przykład: rozwiąż UKŁAD RÓWNAŃ:
{cos(y)+sin(x)==0,(x^2)+(y^2)==(π^2)}

Czy taka odpowiedź jak niżej kogokolwiek satysfakcjonuje?

Reduce[{Sin[x]+Cos[y]==0,x^2+y^2==Pi^2},{x,y}]

Postępujemy jak poprzednio, niezaleznie od tegu czy rozwiązanie analityczne istnieje czy też nie. Dzięki temu zrozumiemy problem i podamy satysfakcjonujące rozwiązanie.

w3=ContourPlot[{Sin[x]+Cos[y]==0,x^2+y^2==Pi^2},{x,-5,5},{y,-5,5}]

Ponieważ problem graficznie jest nieomal nieodróżnialny od przyładu 2 powyżej, uzywamy takiego samego sposobu

p1={x,y}/.FindRoot[{Sin[x]+Cos[y]==0,x^2+y^2==Pi^2},{x,3},{y,1}]
p2={x,y}/.FindRoot[{Sin[x]+Cos[y]==0,x^2+y^2==Pi^2},{x,-3},{y,1}]
p3={x,y}/.FindRoot[{Sin[x]+Cos[y]==0,x^2+y^2==Pi^2},{x,3},{y,-1}]
p4={x,y}/.FindRoot[{Sin[x]+Cos[y]==0,x^2+y^2==Pi^2},{x,-3},{y,-1}]

w4=ListPlot[{p1,p2,p3,p4}]

Show[{w3,w4}]

Teraz wiemy że istnieją cztery rozwiązania rzeczywiste. Spróbujmy ponownie zaatakować problem symbolicznie:

sys={Sin[x]+Cos[y]==0,x^2+y^2==Pi^2}

sol=Reduce[sys,{x,y}]

sol/.C[1]->0

Refine[%,x∈Reals]

Reduce[%,{x,y}]

{ToRules[%]}

wynik={x,y}/.%

rozw=ListPlot[wynik]

Show[{w3,rozw}]

Arytmetyka dowolnej precyzji

UWAGA: istotna przewaga MATHEMATICI nad innymi rozwiązaniami pozwlającymi na obliczenia dowolnej precyzji tkwi w możliwości używania każdej funkcji i procedury np. funkcji specjalnych Gamma, FresnelS, obliczeniowych FindRoot, NIntegrate, NDSolve itp.

Przykład: obliczenie pierwiastka kwadratowego

Sqrt[2]

Każdy wynik symboliczny posiada nieskończenie dużą precyzję, dlatego jest bardzo cenny:

Precision[Sqrt[2]]

Precision[Pi]

Precision[Log[2]]

(1/2)^10000

N[%]

Precision[%]

(1/2.0)^10000

Precision[%]

(1/2.0)^10000.0

Precision[%]

Wprowadzenie liczby numerycznej 2 zawierającej 100 zer po przecinku:

Sqrt[2.0``100] //Precision

N[Sqrt[2]]

Pierwiastek z 2 obliczony z dokładnością 100 miejsc po przecinku:

N[Sqrt[2],100]//Precision

Utrata precyzji numerycznej:

Nest[Tan,2.0``100,100]

Precision[%]

Precyzja procesora (rachunek numeryczny ,,hardware'owy'')

$MachinePrecision

Rozwiązanie o dowolnej precyzji na ogół nie jest możliwe, jeżeli dane wejściowe mają precyzję niższą niż  żądamy tego od wyniku:

wynik1= x/. FindRoot[x^2==4.15,{x,1},PrecisionGoal->100,WorkingPrecision->100]

Rozwiązanie to podanie liczby z wymaganą dokładnością:

wynik2 = x/. FindRoot[x^2==4.15``100,{x,1},PrecisionGoal->100,WorkingPrecision->100]

Lub przekształcenie na liczbę wymierną:

4.15 //Rationalize

wynik3 =  x/. FindRoot[x^2==83/20,{x,1},PrecisionGoal->100,WorkingPrecision->100]

Na koniec rozwiązanie analityczne:

wynik4 =N[x /.(Reduce[x^2==83/20&&x>0,x] //ToRules),100]

Porównanie 4 wyników:

TableForm[{wynik1,wynik2,wynik3,wynik4}]

Przykład z manuala:

N[(Sqrt[2])+(Sqrt[3])-(Sqrt[5+2 (Sqrt[6])])]

N[(Sqrt[2])+(Sqrt[3])-(Sqrt[5+2 (Sqrt[6])]),100]

Simplify[(Sqrt[2])+(Sqrt[3])-(Sqrt[5+2 (Sqrt[6])])]

FullSimplify[(Sqrt[2])+(Sqrt[3])-(Sqrt[5+2 (Sqrt[6])])]

Operator nakazujacy zastosowanie polecenia do wyrazenia obliczonego przed nim (Postfix)

Przykład: ile wynosi wartosc numeryczna wyrazenia (e^π)-(π^e) lub (i^i) ?

E^Pi-Pi^E // N

I^I //N //Chop

I^I //ComplexExpand

Kilka przykładów:

(x^2-x-1)^7 //Expand

% //Simplify

Poniższe komendy robią to samo:

-1 //Sqrt //N

N[Sqrt[-1]]

Operator // używamy zwykle w pracy interaktywnej, gdy np. w ostatniej chwili przypominamy sobie że potrzebujemy wyrażenia w postaci numerycznej a nie symbolicznej. Dodajemy wtedy na końcu linijki  //N

Zmienne i wyrazenia

Dowolne wyrazenie (wielomian, funkcje, równanie, wykres,
macierz) mozna przypisac do pewnej zmiennej operatorem =

f=Sin[Sin[x]]

w=(x+1)^5

rownanie=x^2==-1

napis="algebra symboliczna"

n=100

t=12.7

Znak równosci (w równaniach) to podwójne == ! Uzycie w tym
momencie operatora przypisania = to najczesciej popełniany bład.

Zmienne wbudowane i już przypisane kolorowane są na czarno, pozostałe na niebiesko

Funkcje

Najprostsza definicja funkcji f:x->(2^x)

f[x_]:=2^x

f[2]

f[2.0]

f[a]

Składniki definicji funckji: f - nazwa, x - argument, _ - typ argumentu (pusty w tym przypadku), :=  - operator ,,oblicz dopiero po wywołaniu funkcji f''

Czysta funkcja (pure function) bez argumentu

Sin' (* pochodna sinusa *)

g=2^#& (* definicja funcji  g:x->(2^x) w postaci czystej funkcji *)

g[2]

Jak w wyrażeniu poniżej zamienić sinus na inną funkcję?

s=Sum[Sin[x]^n,{n,1,10}]

Bardzo prosto można to zrobić jeżeli funkcja ma nazwę:

s /. Sin->Log

Ale jak podstawić funkcję y=1/x ?

Sposób 1: zdefiniowanie funkcji wykonujacej operację 1/x

odwrotnosc[x_]:=1/x

s/. Sin -> odwrotnosc

Sposób 2 : użycie , , czystej funkcji''

s /. Sin ->(1/#&)

Funkcja wielu zmiennych

u[x_,y_,z_]:=Log[x^y^z]

u[1,a,a]

u[1,2,3]

u[2.0,2.0,2.0]

Operator podkreślenia ?, /; (porównywanie ze wzorcem)

f[t_]:=N[t]

g[t_?NumericQ]:=N[t]

h[t_?NumberQ]:=N[t]

f[Pi]

g[Pi]

h[Pi]

f[a]

g[a]

h[a]

i[i_?IntegerQ]:=i!

i[6]

i[6.0]

i[1.5]

i[-1]

Podobne  notacje

f1[n_?IntegerQ]:=n! (* n całkowite *)

f2[n_/;IntegerQ[n]&&n>0]:=n! (* n całkowite i większe od zera *)

f3[n_?IntegerQ]:=n! /;n>0 (* n całkowite i większe od zera *)

Listy

Lista może składać się z dowolnych elementów (w tym innych list) i wygląda następująco:

lista={x,1,Pi,Sin[x],{0,1},"abc",x+y}

Podstawowe operacje na elementach listy:

lista[[1]] (* pierwszy element listy *)

First[lista]  (* pierwszy element listy, inna notacja *)

lista[[4]] (* czwarty element listy *)

lista[[-1]] (* ostatni, czyli pierwszy od końca element listy *)

lista[[0]] (* elementy numerujemy od 1, zero wskazuje na nagłówek, patrz niżej *)

lista //FullForm

Dimensions[lista] (* rozmiar listy *)

Select[lista, #>0&] (* wybierz z listy elementy wieksze od zera, notacja za pomocą czystej funkcji*)

Select[lista, IntegerQ] (* wybierz z listy liczby całkowite *)

Select[lista, StringQ] (* wybierz z listy elementy tekstowe *)

,,Spłaszczenie listy''

lista //Flatten

Podstawy rysowania funkcji

Wykres funkcji danej w postaci jawnej:

Plot[Exp[x],{x,-3,3}]

Krzywa płaska (2 D) w postaci parametrycznej :

ParametricPlot[{3 Sin[t], 2 Cos[t]},{t,0, 2 Pi}]

Krzywa płaska w postaci uwikłanej:

ContourPlot[x^2/4+y^2/9==1,{x,-5,5},{y,-5,5}]

Kilka funkcji równocześnie na osobnych rysunkach:

Table[Plot[Sin[ω t],{t,-10,10},PlotLabel->"ω="<>ToString[ω]],{ω,1,10}]

Prosta animacja (opcja PlotRange jest konieczna w przypadku animacji):

Animate[Plot[Sin[ω t]/ω,{t,-10,10},PlotLabel->"ω="<>ToString[ω],PlotRange->{{-10,10},{-1,1}}],{ω,1,4,0.01}]

Kilka wykresów równocześnie:

Plot[Table[(Sin[x])^n,{n,2,16,2}],{x,-2 π, 2π}]

Table[Plot[(Sin[x])^n,{x,-2 π, 2π}],{n,2,16,2}]

Show[%]

Wykresy z tooltipami (najedź kursorem myszy na wykres! ):

ContourPlot[Evaluate[Table[x^n+y^n==3,{n,2,16,1}]],{x,-2, 2},{y,-2,2}]

Wykres funkcji danej w postaci tabeli liczb:

punkty=Table[{x,x^2 Exp[-x]Sin[x]},{x,0,10,0.5}]

ListPlot[punkty]

ListPlot[punkty, Joined->True]

ListPlot[punkty, Joined->True, InterpolationOrder->0]

ListPlot[punkty, Joined->True, InterpolationOrder->1]

ListPlot[punkty, Joined->True, InterpolationOrder->3]

Table[Tooltip[{Re[Exp[I ϕ]],Im[Exp[I ϕ]]},Exp[I ϕ]],{ϕ,0, 2 Pi,Pi/6}]

ListPlot[%,AspectRatio->1]

Najczesciej wykonywane symbolicznie zadania

Całka oznaczona, np: (∫_0^π)Sin[x]dx

Integrate[Sin[x],{x,0,Pi}]

Rozwiązanie równania, np: (x^4)=4

Solve[x^4==4,x]

Reduce[x^4==4,x]

FindInstance[x^4==4,x] (* czy równanie ma jakiekolwiek rozwiązanie *)

Upraszczanie/przekształcanie wyrazeń

TrigExpand[Sin[4 x]]

ExpToTrig[Exp[x]]

TrigToExp[Cos[x]]

PowerExpand[Log[(x /y)^m]]

Simplify[a^2+ 2a b + b^2]

Factor[x^4+x^2 + 1]

Simplify[Gamma[n+1],Assumptions->n∈Integers&&n>0]

FullSimplify[Gamma[n+1],Assumptions->n∈Integers&&n>0]

Expand[(1+x)^6]

Pochodna funkcji

D[Tan[x],x] (* pochodna Tan[x] po x *)

D[Sin[a x],{x,25}] (* 25-ta pochodna po x funkcji Sin[a x] *)

D[Exp[x^2+y^2],x,y] (* druga pochodna cząstkowa wyrażenia *)

Integrate[f'[x],{x,x1,x2}] (* podstawowy wzór rachunku całkowego *)

Granice

Limit[Sin[x]/x,x->0]

Limit[Exp[-1/x],x->0]

Limit[FresnelS[x],x->Infinity]

Czy MATHEMATICA obliczyła poniższe granice czy nie?

Limit[(FresnelS[x]-1/2)/Exp[-x],x->Infinity]

Limit[(FresnelS[x]-1/2)/Log[1+1/x],x->Infinity]

Najczęściej wykonywane numerycznie zadania

Całka oznaczona np: (∫_0^π)Sin[x]dx

NIntegrate[Sin[x],{x,0,Pi}]

Manipulate[NIntegrate[If[x^n+y^n<1,1,0],{x,0,Infinity},{y,0,Infinity}],{n,2,10,1}]

Numeryczne rozwiązanie równania

FindRoot[Exp[x]==Sin[x],{x,1}] (* punkt startowy x=-1 *)

Rzeczywiste rozwiazania układu równań x^2 + y^2 == 4, Log[x] + Log[y] == -1:

ContourPlot[{x^2+y^2==4, Log[x]+Log[y]==-1},{x,0,3},{y,0,3}]

Z wykresu odczytujemy wartości startowe:

FindRoot[{x^2+y^2==4, Log[x]+Log[y]==-1},{{x,2},{y,0.2}}]

FindRoot[{x^2+y^2==4, Log[x]+Log[y]==-1},{{x,0.2},{y,2}}]

Interpolacja wyników w celu zdefiniowania własnej funkcji:

sin={{0,0},{Pi/6,1/2},{Pi/4,Sqrt[2]/2},{Pi/3,Sqrt[3]/2},{Pi/2,1}}//Interpolation

Plot[{sin[x],Sin[x]},{x,0,Pi/2}]

Powody implementacji i używania metod numerycznych w CAS

Obliczenia numeryczne czesto prowadza do wyniku szybciej, np. obliczenie całki oznaczonej z funkcji o „banalnym’' przebiegu

Wiekszosc problemów nie posiada rozwiazania analitycznego

Zwykle ostatecznym celem jest uzyskanie wyniku liczbowego

Stosuje się algorytmy o ustabilizowanej reputacji. Algorytmy „niepewne” nie sa używane.

Dysponujemy metodami graficznymi  pozwalajacymi na relatywnie łatwe testowanie wyników pod katem poprawnosci

Gigantyczna i ciagle rosnaca moc obliczeniowa komputerów pozwala na obliczenia numeryczne w czasie rzeczywistym, w sposób nieomal nieodróżnialny od obliczeń analitycznych

Obliczenia symboliczne vs numeryczne

Pi1=3.141592653589793

Pi2 = 3141592653589793/10^15

3.141592653589793`

BaseForm[0.1,2]

0.00011001100110011001101

Nest[10 #^2&,0.1,100]

Nest[10 #^2&,0.1``50,100]

Nest[10 #^2&,1/10,100]