matlab/octave – wprowadzenieif.pw.edu.pl/~sobiech/matlab2.pdf · matlab/octave matlab/octave –...

14
Matlab/Octave Matlab/Octave – wprowadzenie Tomasz Sobiech, Politechnika Warszawska, Wydzial Fizyki 2 marca 2015 S krypt ten ma na celu zapoznanie państwa z dzialaniem i podstawową pracą z Matlab/Octave, czyli obliczeniach na macierzach i wizualizacji wyników. Dzialania tablicowe omówione zostaly już w poprzedniej części, jednak ze względu na ich duże znaczenie i problemy w ich stosowaniu przez po- czątkujących, wracamy do nich raz jeszcze. W skrypcie wprowadzone zostalo ważne pojęcie (bardzo ważne) wektoryzacji, pomimo początkowych trudności, musi zostać przyswojone przez każdego użytkow- nika wszystkich języków skryptowych Matlab/Octave, Python, Julia itd. 1 Operatory (raz jeszcze) 1.1 Operator zakresu Skladnia operatora : wygląda następująco start : krok : nie większe niż . Przyklad: >> a = 3:0.7:7 a= 3.0000 3.7000 4.4000 5.1000 5.8000 6.5000 Domyślna wartość kroku to jeden, skladnia upraszcza się wtedy do postaci: >> a = 3:7 a= 34567 W kontekście macierzy operator ten może przybrać jeszcze jedną formę: Strona 1 z 14

Upload: buikhuong

Post on 28-Feb-2019

286 views

Category:

Documents


0 download

TRANSCRIPT

Matlab/Octave

Matlab/Octave –wprowadzenieTomasz Sobiech, Politechnika Warszawska, Wydział Fizyki

2 marca 2015

Skrypt ten ma na celu zapoznanie państwa z działaniem i podstawową pracą z Matlab/Octave, czyliobliczeniach na macierzach i wizualizacji wyników. Działania tablicowe omówione zostały już wpoprzedniej części, jednak ze względu na ich duże znaczenie i problemy w ich stosowaniu przez po-

czątkujących, wracamy do nich raz jeszcze. W skrypcie wprowadzone zostało ważne pojęcie (bardzoważne) wektoryzacji, pomimo początkowych trudności, musi zostać przyswojone przez każdego użytkow-nika wszystkich języków skryptowych Matlab/Octave, Python, Julia itd.

1 Operatory (raz jeszcze)

1.1 Operator zakresuSkładnia operatora : wygląda następująco start : krok : nie większe niż . Przykład:

>> a = 3:0.7:7a =

3.0000 3.7000 4.4000 5.1000 5.8000 6.5000

Domyślna wartość kroku to jeden, składnia upraszcza się wtedy do postaci:

>> a = 3:7a =

3 4 5 6 7

W kontekście macierzy operator ten może przybrać jeszcze jedną formę:

Strona 1 z 14

Matlab/Octave

>> A = zeros(3,4);>> A(:,2) = 1

A =

0 1 0 00 1 0 00 1 0 0

Zapis A(:,2) weź wszystkie wartości z kolumny 2. Operatora zakresu możemy też używać z typem danych char:

>> s = ’a’:’f’

s =

abcdef

1.2 Działania arytmetyczne1.2.1 Operatory macierzowe

Możliwość wykonywania działań macierzowych jest absolutnie niezbędna dla programisty-fizyka, środowiskoMatlab/Octave pozwala na wykonywanie takich obliczeń w szybki sposób przez zdefiniowane operatory (tab. 1), bezpisania zbędnych pętli for.

Tablica 1: Operatory macierzowe

Operacja OperatorDodawanie +Odejmowanie -Mnożenie *Potęgowanie ^Lewostronne dzielenie \Prawostronne dzielenie /

Jeszcze słowo komentarza á propos dzielenia, oprócz dzielenia prawostronnego (/) mamy do dyspozycji dzielenielewostronne (\). Dzielenie takie stosowane jest w równaniach macierzowych. W szczególności polecenie x = A\b rozwiązujerównanie Ax = b. Jest ono odpowiednikiem inv(A)*b, ale działa szybciej i numerycznie stabilniej.

1.2.2 Operatory tablicowe

Prawdopodobnie dużo częściej wykorzystywane są operatory tablicowe (tab. 2). Za ich pomocą możemy uzyskać takiestruktury jak v.*w = [v1w1, v2w2, ..., vnwn], czy v.^w = [vw1

1 , vw22 , ..., vwn

n ]. Te same zasady stosują się do macierzy. Dladwóch macierzy A i B polecenie C = A.*B, w wyniku daje macierz z elementami Cij = AijBij .

Strona 2 z 14

Matlab/Octave

Tablica 2: Działania tablicowe

Operacja OperatorDodawanie +Odejmowanie -Mnożenie .*Potęgowanie .^Lewostronne dzielenie .\Prawostronne dzielenie ./

1.3 Operatory relacjiDziałania z użyciem operatorów relacji dają wynik w postaci macierzy o tej samej wielkości co argumenty, gdzie 1

oznacza prawdziwość relacji, a 0 oznacza fałsz.

Tablica 3: Operatory relacji

Operacja OperatorMniejszy niż <Mniejszy lub równy <=Większy niż >Większy lub równy >=Równy ==Różny od =

Przykłady:

>> x = [1, 5, 3, 7];>> y = [0, 2, 8, 7];>> k = x<y

k =

0 0 1 0>> k = x>=y

k =

1 1 0 1>> k = x~=y

k =1 1 1 0

1.4 Operatory logiczneOperatory logicznie działają analogicznie do operatorów relacji, zwracają macierz o tej samej wielkości co argumenty:

Strona 3 z 14

Matlab/Octave

Tablica 4: Operatory logiczne

Operacja OperatorKoniunkcja &Alternatywa |Negacja ~Alternatywa wykluczająca xor

2 Praca z macierzami

2.1 Indeksowanie macierzyW środowisku Matlab/Octave istnieją dwa sposoby indeksowania tablic (patrz rys. 1) tzw. index oraz subscripts,

jak to działa sprawdzimy na prostym przykładzie:

>> A = rand(4, 5)

A =

0.6557 0.6787 0.6555 0.2769 0.69480.0357 0.7577 0.1712 0.0462 0.31710.8491 0.7431 0.7060 0.0971 0.95020.9340 0.3922 0.0318 0.8235 0.0344

>> A(4) %w notacji index

ans =

0.9340>> A(4,1) %to samo w notacji subscripts

ans =

0.9340

>> A(5) %w notacji index

ans =

0.6787

>> A(1, 2) %to samo w notacji subscripts

ans =

0.6787

Strona 4 z 14

Matlab/Octave

Rysunek 1: Dwa sposoby indeksowania macierzy

Oczywiście tyczy się to też macierzy o większej ilości wymiarów. Do konwersji pomiędzy tymi dwoma stylamiindeksowania macierzy można wykorzystać funkcję ind2sub oraz sub2ind. Przykład (Macierz A z poprzedniego przykładu):

>> idx = [sub2ind(size(A), 3, 2), sub2ind(size(A), 4, 4), sub2ind(size(A), 4, 5)] ...%tworzymy wektor 3 indeksów które chcemy wybrać z macierzy

idx =

7 16 20

>> A(idx) %wypisujemy podane elementy

ans =

0.7431 0.8235 0.0344>> A(idx) = 0; %nadpisujemy wartość podanych elementów

>> A

A =

0.6557 0.6787 0.6555 0.2769 0.69480.0357 0.7577 0.1712 0.0462 0.31710.8491 0 0.7060 0.0971 0.95020.9340 0.3922 0.0318 0 0

Możemy też podawać w obu konwencjach wektory. W konwencji index przykład jest już wyżej, z macierzy wybieranesą wszystkie elementy, których index jest podany w wektorze. Trochę więcej przykładów:

>> A([1, 3, 5, 6, 7])

ans =

0.6557 0.8491 0.6787 0.7577 0

>> A(1:2:20) %co drugi element

ans =

Strona 5 z 14

Matlab/Octave

Columns 1 through 9

0.6557 0.8491 0.6787 0 0.6555 0.7060 0.2769 0.0971 0.6948

Column 10

0.9502

>> i = 5:5:20 %co piąty indeks od piątego do dwudziestego

i =

5 10 15 20

>> A(i)

ans =

0.6787 0.1712 0.0971 0

W konwencji subscripts zwracany jest produkt kartezjański podanych indeksów:

>> A([1, 2], [1, 2]) %produkt kartezjański to elementy (1, 1), (1, 2), (2, 1), (2, 2)

ans =

0.6557 0.67870.0357 0.7577

>> A(1:3,1:3) %wykorzystując operator zakresu

ans =

0.6557 0.6787 0.65550.0357 0.7577 0.17120.8491 0 0.7060

>> A(1:2:3,1:3) %co drugi wiersz od pierwszego do trzeciego i od pierwszej kolumny do trzeciej

ans =

0.6557 0.6787 0.65550.8491 0 0.7060

Należy tu jeszcze wspomnieć o kolejnym ważnym elemencie dotyczącym indeksowania, mianowicie słowo kluczoweend. Standardowo słowo end kończy blok kodu po for, if itd., w tym kontekście indeksowania ma ono inne znaczenie, tj.oznacza ostatni element macierzy.

Strona 6 z 14

Matlab/Octave

>> A(end)

ans =

0

>> A(end-4:end) %ostatnie pięć elementów

ans =

0 0.6948 0.3171 0.9502 0

>> A(end-1:end, 1) %korzystając z subscripts: przedostatni i ostatni element pierwszej kolumny

ans =

0.84910.9340

>> A(2:end, 1:end-3)

ans =

0.0357 0.75770.8491 00.9340 0.3922

Typowe zastosowanie wybierania indeksów z którym na pewno się spotkacie:

>> x = 0:0.01:10*pi;>> y = sin(x);>> idx = find(abs(y) < 5e-3); ...%funkcja find zwraca indeksy elementów wektora równych 1 (działanie operatora relacji już znacie)

>> plot(x, y, ’b-’, x(idx), y(idx), ’ro’)

Na rysunku 2 przedstawiony jest wynik powyższych operacji.

2.2 WektoryzacjaPrzez wektoryzację rozumiemy nadanie obliczeniom takiej struktury, w której można zastosować zmienne wektorowe lub

tablicowe z operatorami tablicowymi zamiast seryjnych obliczeń skalarnych. Jako przykład rozważ aproksymację funkcjiwykładniczej za pomocą pierwszych dziesięciu wyrazów rozwinięcia w szereg

ex =∑k

xk−1

(k − 1)!

Można to liczyć w pętli, co jest czasochłonne, gdyż interpreter musi dziesięć razy wykonać tą czynność (interpreterjest wolny). W formie zwektoryzowanej interpreter parsuje jedną linijkę, reszta liczy się w wewnętrznych funkcjach

Strona 7 z 14

Matlab/Octave

Rysunek 2: Miejsca zerowe funkcji f(x) = sin(x)

Matlab/Octave napisanych w szybkich językach typu C/C++

>> x = 1;>> k=1:10;>> e = sum(x.^(k-1)./factorial(k-1))

e =

2.7183>>%lub w inny sposób po wykonaniu drobnych przekształceń w głowie>> format long>> sum(1./factorial(0:10))-exp(1)

ans =

-2.731266102173890e-08

>> sum(1./factorial(0:10))-exp(1) %policzmy błąd takiego przybliżenia

ans =

-2.731266102173890e-08

>> sum(1./factorial(0:20))-exp(1) %zwiększmy nieco ilość wyrazów szeregu

ans =

0

W ten oto prosty sposób policzyliśmy liczbę Nepera. Stosować wektoryzację należy zawsze (o ile to jest możliwe)! Innyprzykład, odtworzymy sobie działanie funkcji diff, i policzmy pochodną funkcji:

Strona 8 z 14

Matlab/Octave

>> plot(x, y, x, Dy)>> dx = 0.001;>> x = 0:dx:2*pi;>> y = sin(x);>> Dy = (y(2:end)-y(1:end-1))./dx; ...%diff => y(2:end)-y(1:end-1), dzieląc przez dx otrzymujemy pochodną>> Dy = [Dy, Dy(end)]; %powielenie ostatniego elementu, żeby zgadzały się długości wektorów>> plot(x, y, x, Dy)

Rysunek 3: Funkcja f(x) = sin(x) oraz jej pochodna f ′(x) = cos(x)

2.3 Trudniejsze przykładyRozwiążmy teraz typowy fizyczny problem tj. rozwiążemy dwuwymiarowe równanie Poissona

∇u(x, y) = f(x, y) ∀(x,y) ∈ 〈0, 100〉 × 〈0, 100〉 = Ω

u(x, y)∣∣∂Ω

= 0

gdzie

f(x, y) =

100 ∀(x,y) ∈ 〈49, 51〉 × 〈10, 90〉 = ω

0 ∀(x,y) ∈ Ω\ω

Przedstawione tu rozumowanie jest nieco uproszczone, więcej o rozwiązywaniu równań różniczkowych można dowiedzieć sięna wykładnie z Metod Numerycznych lub w internecie. Dyskretyzując równanie dla prostokątnej siatki otrzymujemy:

ui−1,j + ui,j−1 + ui+1,j + ui,j+1

4− ui,j = fi,j (1)

u0,j = u100,j = ui,0 = ui,100 = 0 (2)

Obliczenie tego wyrażenia w C wymagałoby iteracji po całej macierzy w dwóch pętlach for, możemy jednak tozwektoryzować. Graficznie pierwszy składnik tego równania można przedstawić jak poniżej:

Strona 9 z 14

Matlab/Octave

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

+

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

+

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

+

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

1 6 11 16 212 7 12 17 223 8 13 18 234 9 14 19 245 10 15 20 25

+

Tak powstałą nową macierz należy jeszcze podzielić przez cztery i odjąć od niej macierz początkową.

1 close all, clear all, clc %zamknij wszystkie wykresy, wyczysc zmienne, wyczysc linie komend2

3 %definicja geometrii4 N = 100;5 u = zeros(N, N);6 %rysuje prostokat7 %wybieramy podmacierz i przypisujemy ladunek8 %floor (podloga) zaokraglenie, aby miec pewnosc ze bedzie liczba calkowita9 w1 = floor((N/2))-1;

10 w2 = floor((N/2))+1;11 u(10:N-10, w1:w2) = 100;12

13 for i = 0:1e414 %liczymy laplasjan (to tu cala magia)15 nabla = zeros(N, N);16 nabla(1:end-1,:) = nabla(1:end-1,:) + u(2:end,:);17 nabla(2:end,:) = nabla(2:end,:) + u(1:end-1,:);18 nabla(:,1:end-1) = nabla(:,1:end-1) + u(:,2:end);19 nabla(:,2:end) = nabla(:,2:end) + u(:,1:end-1);20 nabla = nabla./4.0;21 nabla = nabla - u;22

23 u = u + nabla;24

25 %warunki brzegowe26 u(1,:) = zeros(1, N);27 u(end,:) = zeros(1, N);28 u(:,1) = zeros(1, N);29 u(:,end) = zeros(1, N);

Strona 10 z 14

Matlab/Octave

30

31 u(10:N-10, w1:w2) = 100;32 end33

34 contourf(u); hold on;35 rectangle('Position',[w1, 10, w2-w1, N-20],'FaceColor','k')

Rysunek 4: Rozwiązanie równania

Na koniec jeszcze przykład rozwiązania jednego z zadań z KADD.

Zadanie 1. Wygenerować macierz 3D zgodnie ze wzorem v = x ∗ sin(x2 − y2 − z2

)w przedziale [−2, 2] z krokiem 0.05.

Wyświetlić ją na ekranie.

1 close all, clear all, clc %zamknij wszystkie wykresy, wyczysc zmienne, wyczysc linie komend2

3 [X,Y,Z] = meshgrid(-2:0.05:2,-2:0.05:2,-2:2); %tworzymy 3 macierze 3D4 V = X.*sin(X.^2-Y.^2-Z.^2); %tworzymy nowa macierz 3D z wartosciami ze wzoru5

6 for i = 1:57 % conturf rysuje wykres w formie mapy8 [¬,h] = contourf(X(:,:,3), Y(:,:,3), V(:,:,3)); hold on;9

10 %tu troche magicznych funkcji w sumie nieistotne11 hh = get(h,'Children');12 set(hh, 'ZData', cellfun(@(x) (i-3)*ones(size(x)), get(hh,'XData'), 'UniformOutput',false))13 end

Uwaga 1. Rysowanie kilku map na jednym wykresie nie zadziała w Octave, przynajmniej nie w ten sposób. Jednak tonieduża strata bo ten sposób jest bardzo nie czytelny.

3 WizualizacjaW tym rozdziale przedstawione zostały różne przykłady wizualizacji danych w Matlab/Octave. Najbardziej użyteczną

funkcją generującą wykresy jest plot, jej składnia wygląda następująco:

plot(vec_x1, vec_y1, ’opcje stylu’, vec_x1, vec_y1, ’opcje stylu’, ...)

Strona 11 z 14

Matlab/Octave

Rysunek 5: Mapy kostki

Przykładowo:

plot(y) %tworzy domyślny wykres na osi x odłożone są ideksy wektora yplot(x,y,’--’) %zamiast linii ciągłej jest przerywanaplot(x,y,’ro’) %rysuje czerwone kółka

Tablica 5: Opcje stylów

Opcje koloru Opcje stylu linii Opcje stylu znacznikay żółty - linia ciągła + symbol plusam purpurowy – linia przerywana o kółkoc granatowy : linia kropkowana * gwiazdkar czerwony -. linia kreskowo-kropkowa x znak xg zielony . kropkab niebieski ^ daszekw biały s kwadratk czarny d rąb

3.1 Etykiety, tytuły, legendy i inneWykresy można opisywać za pomocą poleceń:

xlabel(’napis x’) % tytuł osi xylabel(’napis y’) % tytuł osi ytitle(’tytul’) % tytuł wykresutext(x, y, ’napis’) % umieszcza na wykresie napis w pozycji (x,,y)

Legendę można utworzyć, jak nie trudno się zgadnąć, za pomocą funkcji legend

legend(’linia 1’, ’linia 2’, ...) % tworzy legendę zawierającą etykiety ’linia 1’, ...legend(’StylLinii1’, ’linia 1’, ...) % przypisuje każdej etykiecie styl liniilegend(..., pos) % pos = 1 (lub inna wartość) ustawia pozycję legendylegend off % wyłącza legendę

Strona 12 z 14

Matlab/Octave

Ustawiać zakresy osi możemy za pomocą polecenia axis

axis([x_min, x_max]) % ustawia zakres osi xaxis([x_min, x_max, y_min, y_max]) % ustawia zakres osi x i yaxis(’equal’) % ustawia jednakową skalę na obu osiachitd.

3.2 Wykresy nakładaneIstnieje kilka sposobów narysowania wielu linii na jednym wykresie, oto przykład:

1 t = linspace(0, 2*pi, 100);2 y1 = sin(t);3 y2 = t;4 y3 = t - (t.^3)/6 + (t.^5)/120;5

6 %rysuje y1 jako ciagla linie (domyslnie)7 plot(t,y1)8 % %dodaje y2 jako linie przerywana9 line(t,y2, 'linestyle', '--')

10 % %dodaje y3 jako serie kolek11 line(t,y3, 'linestyle', 'o')12

13 %inaczej ale robi to samo14 plot(t,y1)15 hold on16 plot(t,y2, 'linestyle', '--')17 plot(t,y3, 'linestyle', 'o')18 hold off19

20 %w ten sposob podobnie ale dodatkowo automatycznie zmienia kolory linii21 plot(t,y1,t,y2, '--',t,y3, 'o')22

23 axis([0 5 -1 5]) %nowe zakresy osi24 xlabel('t')25 ylabel('aproksymacja sin(t)')26 title('Wykresy nakladane')27 legend('sin(t)', 'aproksymacja liniowa', 'aproksymacja piatego rzedu')

3.3 Tworzenie wykresow rownoległych przy uzyciu subplot

Do rysowania kilku wykresów w jednym oknie służy polecenie subplot. Funkcja ta dzieli okno na siatkę (n, m)podwykresów, na przykład:

subplot(3,2,1) % trzeci argument oznacza na którym wykresie aktualnie rysujemyplot(x)subplot(3,2,2)plot(y)...

1 t = linspace(0, 8*pi, 200);2 y = t.*sin(t);3

4 figure(1) %tworzy okno5 subplot(1, 2, 1)% dzieli okno na macierz (1,2) wykresow rysuje na 16 area(t, y);7 subplot(1, 2, 2)% teraz rysuje na 28 t = linspace(0, 2*pi, 200);9 y = sqrt(abs(2.*sin(5.*t)));

Strona 13 z 14

Matlab/Octave

10 polar(t, y)11

12 figure(2) %tworzy drugie okno13 subplot(1, 2, 1)14 hist(randn(1, 1000));15 subplot(1, 2, 2)16 t = linspace(0, 2*pi, 500);17 r = sqrt(abs(2.*sin(5.*t)));18 x = r.*cos(t);19 y = r.*sin(t);20 fill(x, y, 'r')

ciąg dalszy nastąpi

Literatura

[Paratap] Rudra Paratap Matlab 7 dla naukowców i inżynierów Wydawnictwo Na-ukowe PWN, 2009.

[Krzy2012] Piotr Krzyżanowski Matematyka stosowana – Obliczenia naukowe Uni-wersytet Warszawski, 2012.

Strona 14 z 14