MATHCAD 2000 - Rozwiązywanie równań, optymalizacja, wykresy

Transkrypt

MATHCAD 2000 - Rozwiązywanie równań, optymalizacja, wykresy
MATHCAD 2000 - Rozwiązywanie równań,
optymalizacja, wykresy 3D
Wprowadzenie
Jak zauważyliśmy w poprzednich ćwiczeniach Mathcad dysponuje dość silnym "solverem"
symbo- licznym. Tym niemniej przy rozwiązywaniu złozonych problemów, szczególnie przy
rozwiązywaniu równań przestępnych, musimy zastosować bardziej zaawansowane techniki
obliczeniowe. i umiejętnie podpowiadać Mathcadowi poprzez wybranie odpowiedniej do danej
klasy zagadnień metody. Wymaga to oczywiście pewnego doświadczenia w posługiwaniu się
Mathcadem jak również elementarnej wiedzy z metod numerycznych. Rozwiązania równań (lub
układów równań) przestępnych w ogólnym przypadku nie da się przedstawić w postaci zwartego
wzoru matematycznego i musimy zadowolić się wynikiem numerycznym.
W zależności od klasy problemu stosujemy różne metody rozwiazywania równań. Często też
stosujemy różne metody zamiennie lub równolegle co pozwala na weryfikację uzyskanego
rozwiązania. Poniżej przedstawiono możliwe startegie obliczeń:
1. Realizacja własnego algorytmu - warto wspomnieć o tym, gdyż jesli wiemy co i jak policzyć
to nie musimy polegać na zawiłych algorytmach wbudowanych w Mathcada, ponadto w
wyjątkowych sytuacjach może to być jedyna lub najskuteczniejsza metoda obliczeń.
2. Metoda graficzna - stosowana głównie jako weryfikator wyników i podpowiadacz tzw.
punktów startowych w metodach numerycznych. Stanowi ogromną pomoc i jest zawsze
zalecana.
3. Solver symboliczny (solve, x ->) - bardzo wygodny i prosty w użyciu, pozwalający na
uzyskanie rozwiązania w postaci parametrycznej (wzór a nie liczba), jednak nie zawsze
prowadzi do poszu- kiwanego rozwiązania. Tym niemniej jest to podstawowe narzędzie, od
którego zawsze możemy rozpocząć nasze poszukiwania i dopiero w razie niepowodzeń
zastosować inne metody.
4. Blok "Given" - to najbardziej wszechstronny sposób rozwiązywania równań, a przede
wszystkim układów równań nieliniowych z kilkoma niewiadomymi. Blok given stosuje się
również w rozwią- zywaniu równań różniczkowych (zwyczajnych lub cząstkowych) oraz
zagadnień optymalizacji.
5. Zastosowanie specjalizowanych procedur numerycznych - najbardziej efektywny sposób
rozwiązania, pod warunkiem zastosowania właściwej procedury do danej klasy problemu.
Solver symboliczny (solve, x ->) z p.3 poznaliśmy już na poprzednich ćwiczeniach. Nadaje się
przede wszystkim do rozwiązywania równań z jedną niewiadomą, ale można go również
wykorzystać w bardziej złożonych zagadnieniach i przy pewnych "sztuczkach" usprawnić proces
przetwarzania danych. Dzisiejsze zajęcia poświęcone jednak będą przede wszystkim metodom z
punktów 4 i 5.
Warto zauważyć, że z problematyką rozwiązywania równań zetknęliśmy się już w poprzednich
ćwiczeniach a pewne tematy zostaną tu powtórzone dla usystematyzowania wiedzy. Już od
pierwszych zajęć zaczynaliśmy rozwiązywać proste równania algebraiczne lub układy równań
liniowych i stosowaliśmy a) własne algorytmy, b) solver symboliczny lub c) specjalizowaną
procedurę lsolve(A,B). Teraz nadszedł własciwy moment aby to wszystko uporządkować.
Podzielimy tematykę na kategorie w zależności od rodzaju zagadnienia.
Równania z jedną niewiadomą
Równania algebraiczne, wielomiany
Tu wystarczająco skutecznym narzędziem jest solver symboliczny (solve, x->) ale dla
wielomianów mamy alternatywę w postaci specjalnej funkcji polyroots(v), szczególnie zalecana
dla wielomianów wyższego stopnia. Ponadto łatwiej przechować rozwiązanie do dalszych
przeliczeń.
n := 5
n
W ( x) :=
∏
i
świadomie wybieramy prosty wielomian, dla którego
znamy pierwiastki aby łatwiej przśledzić dalsze obliczenia
( x − i)
=1
W ( x) → ( x − 1) ⋅ ( x − 2) ⋅ ( x − 3) ⋅ ( x − 4) ⋅ ( x − 5)
5
4
3
2
W ( x) expand → x − 15⋅ x + 85⋅ x − 225⋅ x + 274⋅ x − 120
1 
2 
 
=
→
,
W ( x) 0 solve x
3 
4 
 
5 
Solver bez problemu znajduje rozwiązanie.
Ale jak przechować je do dalszych obliczeń?
(dla krótkich jednorazowych obliczen możemy ratować
się skopiowaniem wyniku poprzez schowek Windows ale
na dłuższą metę jest to niewygodne, bo przy każdej
zmianie wyniku musimy od nowa kopiować!!!)
Możemy zastosować następującą sztuczkę: przed wpisaniem równania definiujemy zmienną, w
której przechowamy rozwiązanie (tu będzie to wektor p). Potem już łatwo możemy wyciągać
poszczególne pierwiastki do dalszych obliczeń.
1 
2 
 
p := ( W ( x) = 0) solve , x →  3 
4 
 
5 
p1 = 2
W ( p1 ) = 0
1 
2 
 
p = 3 
4 
 
5 
tu ORIGIN=0 dlatego p1 to drugi element wektora
Aby zastosować funkcję polyroots(v) musimy mieć wektor współczynników wielomianu możemy go oczywiście policzyć odpowiednim algorytmem, ale na razie aby nie zaciemniać
istoty tematu wpiszemy go ręcznie.
T
v := ( −120 274 −225 85 −15 1 )
n
Y ( x) :=
∑
i
i
vi⋅ x
wielomianu nie trzeba nawet wcale definiować
tu robimy to tylko dla sprawdzenia
=0
5
4
wektor wierszowy zajmuje mniej miejsca
3
2
Y ( x) → x − 15⋅ x + 85⋅ x − 225⋅ x + 274⋅ x − 120
p := polyroots ( v)
1 
2 
 
p = 3 
4 
 
5 
UWAGA: wynik numeryczny szukamy zawsze z
pewnym dopuszczalnym (z góry ustalonym) błędem.
Tu również wektor p zawiera błedy, o czym przekonać
się można po wyświetleniu wyniku z 15 cyframi
znaczącymi.
Powstaje naturalne pytanie - po co używać polyroots() jeśli (solve, x) robi to dokładniej?
Owszem, ale dla wielomianów stopnia > 10 rozwiązanie symboliczne może zająć od kilku
sekund do nawet kilku minut na wolnym komputerze, podczas gdy obliczenia numeryczne z
użyciem polyroots trwaja zaledwie ułamek sekundy. Oczywiście fakt ten nabiera na znaczeniu
dopiero w większych projektach, szczególnie jeżeli duże wielomiany musimy wielokrotnie
rozwiązywać.
Podobna uwaga dotyczy zresztą i pozostałych procedur numerycznych omawianych poniżej.
- w skrócie - zyskujemy ogromną szybkość obliczeń kosztem minimalnych błędów
(w typowych zastosowaniach inżynierskich pomijalnie małych)
Równania przestępne
Wracamy do przykładu z poprzednich ćwiczeń: cos ( x) = 0.3x , Tu dla wygody przejdziemmy
do standardowej postaci f ( x) = 0 gdzie: f ( x) := cos ( x) − 0.3x . Jak pamietamy (solve, x)
potrafił znaleźć tyllko jedno rozwiązanie. Poniżej pokażemy jak mozna znaleźć pozostałe
pierwiestki. Jak zwykle bardzo przydatny będzie wykres badanej funkcji i ewentualnie technika
"zoomowania" do precyzyjniejszej lokalizacji pierwiastków.
a := 0.3
f ( x) := cos ( x) − a⋅ x
Pierwszy - zgrubny wykres
f ( x) = 0 solve , x → 1.2019131636661846248
Drugi wykres - zawężony do przedziału (-4,2)
1
f ( x)
10
0
10
f ( x)
4
2
0
2
1
x
x
Korzystając z techniki zoomowania można stwierdzić, że dwa pozostałe pierwiastki wynoszą
około:
x2 = -3.3 i x3 = -2.4. Dokładniejsze przybliżenia możemy znaleźć przy pomocy funkcji:
• root( f(x), x)
tu musimy wcześniej określić punkt startowy
• root( f(x), x, a, b)
tu zamiast punktu starowego podajemy przedział (a,b)
given
• lub za pomocą bloku
i funkcji find(x)
UWAGA: Omawiane funkcje - jako ogólniejsze - można również z powodzeniem stosować do
równań wielomianowych - "tylko po co wyciągać armatę do zabicia muchy".
f ( x) → cos ( x) − .3⋅ x
sprawdzamy wzór (czy wszystko OK?)
x2 := −3.3
definiujemy początkowe przybliżenie
root ( f ( x2) , x2) = −3.29451378182576
i rozwiazujemy
root ( f ( x3) , x3 , −2.5 , −2) = −2.35558457003311
tu podajemy przedział (a,b) tak aby na
jego końcach funkcja miała różne znaki
Drugi sposób jest bezpieczniejszy gdyż zmniejsza ryzyko rozbieżności procesu iteracyjnego.
Nie ma tu jednak miejsca na dokładniejsze omówienie tego problemu bo nie jest to kurs
matematyki czy metod numerycznych. Naszym celem jest zapoznanie sie z możliwościami
jakie oferuje Mathcad. Pokażemy więc poniżej jak otrzymać wszystkie trzy pierwiaski od razu
oraz jak kontrolować dokładność.
niszczymy starą definicje wektora p - to zabieg typowo kosmetyczny
p := 0
 −5 
a :=  −3 
0 
 
 −3 
b :=  −2 
2 
 
i := 0 .. 2
definiujemy początki i końce
przedziałów jako wektory, a nastepnie
poprzez zmienną zakresową wykonamy
kolejne obliczenia cyklicznie
pi := root ( f ( x) , x , ai , bi)
Wywietlimy wyniki i sprawdzimy ewentualne błędy podstawiając do oryginalnego równania
tu szczęśliwie udało się rozwiązać
 −3.29446115628298 
 0 
problem super dokładnie ale na ogół
powstają pewne błedy. Ich wielkość
p =  −2.35558457003311 
f ( p) =  0 
możemy konrolować poprzez globalne
 1.20191316366618 
0 


 
zmienne TOL i CTOL.
Zmienne TOL i CTOL używane są przede wszystkim przy rozwiązywaniu równań w bloku
Given.
• TOL okresla dopuszczalny błąd względny rozwiązania
• CTOL określa dopuszczalny błąd względny niespełnienia warunków ograniczających
Domyślnie wartości te ustawione są na 10-3 ale możemy je definiować wg własnych potrzeb.
Warto jednak pamiętać, że zmniejszając dopuszczalny błąd zmuszamy Mathcada do cięższej
pracy
Blok Given + funkcja find(x)
x0 := 1.5
0. przed użyciem bloku given należy podać punkt startow
Given
1. wpisujemy słowo kluczowe "Given"
2. następnie poniżej określamy równania
f ( x0) = 0
r := Find ( x0)
--------------------------------------------r = 1.20191307449865
−7
f ( r) = 1.09919555235649 × 10
p2 = 1.20191316366618
f ( p2 ) = 0
3. rozwiązujemy funkcją find(var1,var2,...)
jak widać rozwiązanie jest mniej dokładne niż z funkcji
root co wynika z zastosowania innego algorytmu
numerycznego. Możemy jadnak sterować dokładnością
obliczeń, a prawdziwe zalety bloku Given, będziemy
mogli docenić dopiero dla układów równań z kilkoma
niewiadomymi.
Powtórzymy teraz powyższe obliczenia przy zmniejszonej tolerancji na błędy
TOL = 1 × 10
−3
− 10
TOL := 10
−3
CTOL = 1 × 10
CTOL := 10
− 10
Given
f ( x0) = 0
tak było do tej pory
podajemy nowe wartości (10-10 to naprawdę
bardzo mały błąd) - przeważnie rozwiązanie
będzie i tak dokładniejsze o kilka rzędów
r := Find ( x0)
--------------------r = 1.20191316366618
f ( r) = 0
teraz jest OK
W bloku Given też możemy obliczyć wszystkie pierwiaski za jednym razem jeżeli za punkt
startowy podamy wektor a nie pojedynczą wartość
 −5 
z :=  −2 
1 
 
Given
f ( z) = 0
 −3.29446115628297 
Find ( z) =  −2.35558457003311 
 1.20191316366618 


Ćwiczenie 1:
1. Znajdź pierwiastki dowolnego wielomianu 4-go stopnia za pomocą funkcji polyroots() i
porównaj wyniki z rozwiązaniem symbolicznym.
x
2. Znajdź pierwiastki równania: 2 = 5x na różne sposoby opisane powyżej (obydwie
postacie funkcji root() i blok Given).
cos ( x) 
x
3. Dana jest macierz funkcyjna A ( x) := 
.
2
+
⋅
−
1
x
2
x
1


Znajdż takie x, dla których wyznacznik tej macierzy będzie równy 0.
Uwaga: do zadań z p. 2 i 3. sporządź odpowiednie wykresy.
Układy równań z wieloma niewiadomymi
Układy równań liniowych
Temat ten szczegółowo omówiliśmy w ćw. 2 (zajrzyj do pliku mcad_2.mcd). Przypomnijmy
jedynie, że obliczenia możemy przeprowadzić z zastosowaniem funkcji lsolve(A,B) lub poprzez
macierz odwrotną.
Nieliniowe układy równań
Rozwiązywanie nieliniowych układów równań jest skomplikowanym zagadnieniem.
Klasyczne podejście analityczne jest na ogół z góry skazane na niepowodzenie, gdyż
eliminacja kolejnych zmiennych (nawet gdy możliwa) jest czasochłonna i prowadzi na ogół
do skomplikowanego równania przestępnego. Mathcad pozwala w dość łatwy sposób
przezwyciężyć te trudności na drodze numerycznej. Najbardziej uniwersalne jest w tym
przypadku zastosowanie bloku Given, ale w niektórych szczególnych przypadkach możliwe
jest nawet uzyskanie rozwiązania symbolicznego (solve, vec(x,y,z) ->).Aby nie zagłębiać sie
dalej w zawiłosci teoretyczne przejdziemy od razu do przykładu.
Przykład: Wyznacz okrąg przecinający punkty (x,y) = (2,4), (-3,1), (5,5)
Zadanie to można łatwo rozwiązać wykonując proste obliczenia geometrii analitycznej. Na
wstępie należy wyznaczyć dwie proste prostopadłe do boków np. 12 i 23 i przechodzące przez
ich środki. Następnie z układu 2 równań liniowych (równań tych prostych) znaleźć można
środek okręgu (x0,y0) a na koniec wyznaczyć promień jako odległość (x0,y0) do np. (x1,y1).
Opisany tu algorytm wymaga jednak trochę "ręcznej" pracy aby wpisać odpowiednie wzory i
równania.
Czy nie możemy wykonać obliczen prościej? Spróbujmy zapisać w bezpośredniej postaci
odpowiedni układ równań i zlecić jego rozwiązanie Mathcadowi.
Poniżej podajemy różne sposoby zapisu i rozwiązania problemu.
=======================================================================
x1 := 2
y1 := −4
x2 := −3
y2 := 1
x3 := 5
y3 := 5
x0 := 0
y0 := 0
definiujemy parametry zadania (tu współrzędne punktów
r := 4
podajemy punkt startowy do rozwiązania
definiujemy blok Given
Given
2
2
2
2
2
2
2
2
2
( x1 − x0) + ( y1 − y0) = r
punkty muszą spełniać to samo równanie okręgu
( x2 − x0) + ( y2 − y0) = r
( x3 − x0) + ( y3 − y0) = r
 2 
Find ( x0 , y0 , r) =  1 
5 
 
otrzymaliśmy okrąg o promieniu 5 i środku (2,1)
=======================================================================
można znacznie skrócić zapis wykorzystując
 2 
 −4 
notację macierzową
xp :=  −3 
yp :=  1 
5 
 
5 
 
Given
2
2
2
( xp − x0) + ( yp − y0) = r
teraz trzy zwykłe równania możemy zapisać
jednym równaniem macierzowym
r>0
Przy okazji nowy element - w bloku given
możemy podawać nie tylko równości ale i
dodatkowe
ograniczenia w postaci
2
 
nierówności. W rozpatrywanym przypadku nie
Find ( x0 , y0 , r) =  1 
miało to znaczenia bo początkowa wartość r
5 
była
dodatnia i nawet bez tego ograniczenia
 
otrzymujemy r = 5
=======================================================================
Rozpatrywany układ równań jest na tyle prosty, że mozna go nawet rozwiązać symbolicznie
 ( x1 − xs) 2 + ( y1 − ys) 2 = rs2 
 xs 


2 1 5 
 ( x2 − xs) 2 + ( y2 − ys) 2 = rs2  solve ,  ys  → 

 2 1 −5 




2
2
2
 rs 
 ( x3 − xs) + ( y3 − ys) = rs 
Tu również możemy podać dodatkowe ograniczenia nierównościowe
 ( x1 − xs) 2 + ( y1 − ys) 2 = rs2 


 xs 
 ( x2 − xs) 2 + ( y2 − ys) 2 = rs2 

 solve ,  ys  → ( 2 1 5 )
2
2
2
 rs 
 ( x3 − xs) + ( y3 − ys) = rs 
 


rs > 0


=======================================================================
W bloku Given można również uzyskać rozwiązanie symboliczne (po funkcji find wciskamy
Ctrl+. ).
Given
2
2
2
2
2
2
2
2
2
( x1 − xx) + ( y1 − yy) = rr
( x2 − xx) + ( y2 − yy) = rr
( x3 − xx) + ( y3 − yy) = rr
 2 2 
Find ( xx , yy , rr) →  1 1 
 5 −5 


Ale z niewiadomych przyczyn nie można tu podać
ograniczeń typu rr > 0
2
5
Na zakończenie omawianego
przykładu
zilustrujemy rozwiązanie graficznie.
1. tworzymy parametryczny wykres
znalezionego okręgu
2. dodajemy serie punktów xp i yp
3. oraz pojedynczy punkt (2,1)
Aby uzyskać końcowy efekt jak na
wykresie obok musimy go jeszcze
odpowiednio sformatować.
5 sin( t ) + 1
1
yp
1
0
5
5
5 cos( t ) + 2 , xp , 2
Ćwiczenie 2
1. Okrąg o promieniu 2 i środku w punkcie (0,0) przecina
x
krzywa y ( x) := e − 1 . Sporządź wykresy tych krzywych
i oblicz punkty przecięcia z dokładnością co najmniej 5
cyfr znaczących.
2. Wykorzystując rozwiązanie z poprzedniego punktu oblicz
pole powierzchni "górnego-lewego" wycinka koła.
2
2
0
2
2
Wprowadzenie do optymalizacji
Tematyka optymalizacji jest na tyle bogata, że nie sposób tu podać nawet fragmentarycznych
wiadomości. Punkt niniejszy proszę więc traktować czysto technicznie - czyli jak znaleźć
opimum pewnej funkcji (tzw. funkcji celu) w Mathcadzie. Otóż rozwiązanie problemu
zapisujemy praktycznie zawsze w podobny do opisanego niżej algorytmu. Z formalnego punktu
widzenia nie jest istotne czy rozwiązujemy zadanie z jedną lub wieloma zmiennymi
decyzyjnymi, z ograniczeniami lub bez, oraz czy zadanie jest liniowe lub nieliniowe. Zapis w
Mathcadzie będzie zawsze podobny a solver sam będzie próbował sklasyfikować problem i
zastosować odpowiednią procedurę numeryczną. Podobnie jak wcześniej, przejdziemy do
konkretnego przykładu.
x
Przykład: Obliczyć odległość dwóch krzywych y = e i
2
y = x.
Dla ułatwienia parametryzujemy obydwie
krzywe - dla pierwszej krzywej przyjmujemy
parametr a= x, a dla drugiej b=y. Musimy teraz
zdefiniować funkcję odległości dla tych
parametrów i obliczyć kiedy osiągnie
minimalną wartość. Dla uproszczenia możemy
wziąć kwadrat odległości - unikniemy
pierwiastkowania i zmniejszymy stopień
nieliniowości naszej funkcji celu
(
) + (ea − b)2
2 2
f ( a , b) := a − b
2
e
t
t
2
0
2
2
t, t
2
definiujemy funkcję celu
f ( 0 , 0) = 1
to tylko dla sprawdzenia czy OK
a := 0
punkty startowe - musimy zawsze podać
b := 0
pusty blok given bo nie mamy ograniczeń
Given
tu ew. mogą być zapisane ograniczenia
r := Minimize ( f , a , b)
 −0.073562169275951 

 0.538167723515397 
r=
Ostatecznie odległość jest równa
obliczenie (a,b) => min f(a,b)
a := r0
L :=
f ( a , b)
b := r1
L = 0.533587574932908
Na koniec przedstawiamy wykres z zaznaczeniem znalezionych (najbliższych) punktów na
wykresie.
T
T
 −0.0735622 
 0.9290784 
2
a
:=
:=
rx
a b
ry
e b
rx = 
ry = 


 0.2896245 
 0.5381677 
(
)
(
)
1.5
1
e
t
0.5
t
ry
1
0.5
0
0.5
1
1.5
UWAGA: Aby prawidłowo pokazać
odległość musimy zadbać aby skale osi
x i y były takie same. W innym razie
wykres będzie zniekształcony i trudno
będzie ocenić czy rozwiazanie jest OK.
0.5
1
2
t , t , rx
Wykresy przestrzenne
UWAGA: Wykresy przestrzenne (powierzchniowe lub warsticowe) zostały umieszczone w
oddzielnym pliku, ze względu na niestabilną pracę Mathcada (częste zawieszanie aplikacji przy
obróbce i formatowaniu wykresów). Proszę zapisać i najlepiej zamknąć wszystkie otwarte pliki i
dopiero przejść do pliku Plot3D.mcd.
Ćwiczenie 3
Wyznacz maximum i minimum funkcji:
 x2 + y2  
  sin ( 2x) + cos  2y +
 −10  

1 

2 
1. Sporządź wstępne wykresy powierzchniowy i warstwicowy.
2. Zlokalizuj graficznie (oszacuj) maximum i minimum i sporządź w ich otoczeniu
odpowiednie wykresy warstwicowe.
3. Na podstawie wykonanych wykresów podaj odpowiednie punkty startowe do bloków
Given i znajdż min i max f(x,y).
4. Jak sprawdzić czy rozwiązanie jest OK?
f ( x , y) := exp 
UWAGA: ze względu na częste zawieszanie Mathcada przy pracy z wykresami 3D proszę
zadanie to wykonać w oddzielnym pliku (ew. pominąć punkty 1 i 2).