Metody numeryczne Laboratorium 2 1. Tworzenie i uruchamianie skryptów Środowisko MATLAB/GNU Octave daje nam możliwość tworzenia skryptów czyli zapisywania grup poleceń czy funkcji w osobnym pliku i uruchamiania ich wszystkich z jednym momencie przez uruchomienie skryptu. Pliki skryptu mają rozszerzenie .m, np.: mnozenie.m. Plik taki uruchamiamy podając jego nazwę w linii komend bez rozszerzenia, np. mnozenie. W skryptach mogą znajdować się komentarze zaczynające się od znaku %. Wyświetlanie napisów Przydatne jest wyświetlanie różnych informacji, nie tylko wartości zmiennych. Funkcja disp() Przykłady: imie = 'Tomasz'; wiek = 25; disp('Jakiś napis...'); disp(k) k disp(imie); disp(A); % wyświetla napis: „Jakiś napis...” % wyświetla wartość zmiennej k % również wyświetla wartość zmiennej k ale inaczej % wyświetla wartość zmiennej znakowej % wyświetla macierz A, jeśli taka istnieje Funkcja fprintf() Szablon wyświetlanej treści zawiera pola do uzupełnienia. Pole zaczyna się znakiem % i znaku pola. Najważniejsze typy pól: %d, %i – liczba całkowita ze znakiem w formacie dziesiętnym (pi: 3) %x, %X – liczby całkowite bez znaku, format szesnastkowy %u – liczba całkowita bez znaku w formacie dziesiętnym %e, %E – liczba zmiennoprzecinkowa w zapisie naukowym (pi: 3.14e0) %g, %G – liczba zmiennoprzecinkowa z automatycznie dobieranym formatem dziesiętnym %f – liczba zmiennoprzecinkowa w zapisie dziesiętnym (pi: 3.14) %s – łańcuch tekstowy %c – znak tekstowy, bajt Inne znaki specjalne: \n – przejście do nowej linii \t – tabulacja fprintf("Liczba pi: %i\n", pi); % wyświetla: „Liczba pi: 3” % W miejsce %i oczekiwana jest wartość liczby całkowitej podanej jako drugi parametr fprintf("Liczba pi: %f\n", pi); % wyświetla: „Liczba pi: 3.141593” fprintf("Liczba pi: %e\n", pi); % wyświetla: „Liczba pi: 3.141593e+00” fprintf("Liczba pi: %.33f\n", pi); % wyświetla: 33 cyfry po przecinku dla liczby pi fprintf('%d+%d=%d\n', 2, 3, 2+3); % wyświetla wyrażenie z dodawaniem dwóch liczb fprintf('%s ma %d lat.\n',imie,wiek); % wyświetla informację o osobie i jej wieku x=65:126; fprintf('%c', x); % wyświetla zakres kodów ASCII od znaku 65 do 126 Ćwiczenia 1.1. Napisać skrypt test.m, w którym utworzymy macierz A=[1 2 3; 4 7 0]. Do zmiennej rozA przypiszemy jej rozmiar (funkcja size()). Po uruchomieniu skrypt powinien wyświetlić: Macierz A 1 2 3 4 7 0 Rozmiar macierzy A 2 3 2. Proste konstrukcje programistyczne – instrukcje warunkowe Instrukcja warunkowa pozwala wykonać jakąś operację tylko, jeśli wystąpią określone warunki. Trzy rodzaje składni: % najprostsza składnia, tylko if if (warunek) instrukcje wykonywane gdy warunek jest spełniony end % zwyczajna składnia, jest warunek (if) i blok alternatywy (else) if (warunek) instrukcje wykonywane gdy warunek jest spełniony else instrukcje wykonywane gdy warunek nie jest spełniony end % pełna składnia, wiele różnych warunków (if, elseif), jedna alternatywa (else) if (warunek1) instrukcje wykonywane gdy warunek1 jest spełniony elseif(warunek2) instrukcje wykonywane gdy warunek2 jest spełniony elseif(warunek3) instrukcje wykonywane gdy warunek3 jest spełniony …... else instrukcje wykonywane gdy żaden wcześniejszy warunek nie jest spełniony end Przykłady: if( max(x)>100 ) disp('Wektor x ma wartość większą od 100.'); x = x/10; % dzielimy wartości w x przez 10 else x = x + 3; % zwiększamy elementy wektora x o 3 end if( size(A,2)==3 ) disp('Macierz A ma 3 kolumny.'); end if( (a+b>c) && (a+c>b) && (b+c>a) ) disp('Boki a, b i c pozwalają na zbudowanie trojkata.') if( a^2+b^2==c^2 ) disp('Trojkat jest prostokatny'); end else disp('Boki a, b i c NIE pozwalają na zbudowanie trojkata.') end if (a>0) disp('a jest dodatnie'); elseif(a<0) disp('a jest ujemne'); elseif(a==0) disp('a jest równe 0'); else disp('Chyba coś tutaj nie gra ...'); end 3. Proste konstrukcje programistyczne – pętle Mamy do wyboru dwa rodzaje pętli: pętla for i pętla while. Pętla for wykonuje zawarte w niej instrukcje n razy, za każdym razem dla innej wartości przyjmowanej przez indeks. Pętla while wykonuje się dopóki spełniony jest warunek określony przez wyrażenie. for indeks = wartości wykonywane instrukcje end while wyrażenie wykonywane instrukcje end Przykłady: for k=1:10 % wyświetli liczby od 1 do 10 disp(k); end for k=[1, -4.3, 5, 12, pi] fprintf('%f\t', k); end % wyświetli 5 liczb w zapisie zmiennoprzecinkowym % oddzielonych tabulacją (\t) disp('Wartości funkcji sinus:'); % wyświetli ładny opis :) for a=0:0.1:2*pi % pętla zaczyna od wartości 0 i kończy na 2*pi % wyświetlane jest nazwa funkcji sin, wartość argumentu i wartość funkcji printf('sin(%f)=%f\n', a, sin(a) ); end A= [1 2 3; 4 5 6; 0 8 1; -2 8 4]; for a=A disp(a); % wyświetli macierz kolumna po kolumnie disp(''); % po wyświetleniu jednej kolumny wyświetlenie pustej linii end A= [1 2 3; 4 5 6; 0 8 1]; N=size(A,1); % liczba wierszy M=size(A,2); % liczba kolumn for i = 1:N % i to indeks wiersza for j=1:M % j to indeks kolumny % mnożymy każdy element macierzy przez liczbę 5 A(i,j) = A(i,j) * 5; end A % wyświetlamy całą macierz A po wymnożeniu każdego wiersza end %dane A=[1,4; -3,0]; B=[-1,1; 4,-2]; %macierz wynikowa - zdefiniowanie rozmiaru C=[2,2]; disp("Wynik oczekiwany"); disp(A*B); %mnożenie macierzy A*B -> wynik zapisany w macierzy C for i=1:2 for j=1:2 C(i,j)=A(i,1)*B(1,j)+A(i,2)*B(2,j); end; end; a=8; while a>0 disp(a); a= a - 1; end % pętla wyświetla liczby: 8, 7, 6, 5, …, 1 % warunek zakończenia, bardzo ważne % wyświetlanie aktualnej wartości zmiennej a % zmniejszanie a o 1 Ćwiczenia 3.1. Korzystając z pętli for wyświetlić 20 razy napis 'n. Będę się pilnie uczył.' gdzie zamiast n powinien być numer wyświetlanej linii (od 1 do 20). [ ] 1 8 −3 A= 2 1 0 Ćwiczenia wykonać w skrypcie macierz.m. 9 0 8 3.2. Korzystając z pętli for utworzyć macierz B zwiększając każdy element macierzy A o 3. Porównaj macierz B wynikiem operacji A+3. 3.3. Korzystając z pętli for utworzyć macierz C podnosząc do potęgi 2 wszystkie elementy leżące na głównej przekątnej (taki sam indeks wiersza i kolumny). Sprawdzić wynik. 3.4. Korzystając z pętli for utworzyć macierz D równą sumie macierzy B i C. Porównać macierz B z wynikiem operacji B+C. 3.5. Mnożenie macierzy. Korzystając z potrójnej pętli for wyznaczyć macierz E będącą iloczynem macierzy B i C. Porównać macierz E z wynikiem operacji B*C. 4. Definiowanie własnych funkcji W plikach ze skryptami możemy tworzyć sobie własne funkcje. Pierwsza funkcja w pliku musi mieć taką samą nazwę jak plik! Utworzoną funkcję wywołujemy tak samo jak te zdefiniowane. Ogólny schemat definicji funkcji: function [y1, …, yN] = mojaFunkcja(x1, …, xN) wykonywane instrukcje end % funkcja bez zwracanej wartości, bez parametrów function mojaFunkcja() wykonywane instrukcje end % funkcja z dwoma parametrami, która jednak nic nie zwraca function mojaFunkcja(x1, x2) wykonywane instrukcje end % funkcja z jednym parametrem (argumentem), zwracająca trzy wartości function [y1, y2, y3] = mojaFunkcja(x1) wykonywane instrukcje end Przykłady: function asdf() disp('ASDF - asdf'); end % funkcja tylko wyświetla podany, ustalony napis % Funkcja wyświetla napis 'Uwielbiam …' z odpowiednią wartością zmiennej a. % Jeśli parametr x jest wektorem kolumnowym, to wyświetla napis tyle razy, % ile elementów ma wektor x. function uwielbiam(x) for a=x disp(['Uwielbiam metody numeryczne po raz ', num2str(a)]); end end % funkcja wylicza średnią i ją zwraca, przyjmuje jeden parametr, % który powinien być wektorem kolumnowym function wyn = srednia(x) % określenie wartości zwracanej wyn = 0; for k=x wyn = wyn +k; % liczenie sumy elementów wektora end wyn = wyn / length(x); % policzenie i średniej end % funkcja ma dwa parametry i dwie wartości zwracane function [suma, iloczyn] = operacje(x1, x2) suma=x1+x2; % liczymy sumę dwóch liczb iloczyn=x1*x2; % liczymy iloczyn tych samych liczb end function inna() % funkcja wywołuje inne nasze funkcje zm=magic(3); % utworznie macierzy 3x3 uwielbiam(zm(1,:)); % wywołanie funkcji uwielbiam() dla 3-elem. wektora aa = srednia([1 2 3 4]); disp(aa); % wywołanie funkcji srednia() % wyświetlenie zwróconej wartości [s, il] = operacje(3, 5); % wywołanie funkcji operacje() dla liczb 3 i 5 printf('suma: %d, iloczyn: %d\n', s, il); % wyświetlenie dwóch zmiennych end Ćwiczenia 4.1. Utworzyć plik hello.m. W pliku utworzyć funkcję hello(), która wyświetli napis: 'Witaj roku akademicki!'. Przetestować działanie. 4.2. W tym samym pliku poniżej utworzyć funkcję suma() z jednym parametrem będącym macierzą 3x3, która policzy sumę wszystkich elementów macierzy i zwróci ją. Funkcję dla macierzy magic(3) wywołać w funkcji hello() i wyświetlić zwróconą wartość. 4.3. Napisać funkcję o nazwie wyznacznik2(), która policzy wyznacznik dowolnej macierzy o rozmiarze 2x2 i zwróci wynik. Funkcję uruchomić i przetestować dla przykładowej macierzy PM w funkcji hello(). Porównać wynik z wynikiem operacji det(PM). 4.4. Napisać funkcję o nazwie wyznacznik3(), która policzy wyznacznik dowolnej macierzy o rozmiarze 3x3 i zwróci wynik. Funkcję uruchomić, przetestować, porównać z det(PM). Ćwiczenia inne Inne ciekawe pomysły na funkcje: 2.1. W skrypcie trojkat2.m utworzyć trzy zmienne (a, b, c) mające dowolne długości, reprezentujące boki trójkąta. Wykorzystać instrukcję warunkową do sprawdzenia czy z boków o podanych długościach można zbudować trójkąt. Dla obu możliwych rozwiązań wyświetlić właściwą informację. 2.2. W odniesieniu do zadania 2.1.: jeśli można utworzyć trójkąt, to proszę go narysować. 3.6. Korzystając z pętli, instrukcji warunkowej i funkcji isprime() sprawdzającej czy podana liczbą jest liczbą pierwszą, wyświetlić wszystkie liczby pierwsze mniejsze od 100. Zadanie rozwiązać na dwa sposoby, za pomocą pętli for i pętli while. Porównaj wynik z poleceniem: primes(100). 3.7. Korzystając z pętli for i funkcji fprintf() wyświetlić tabliczkę mnożenia, mniej więcej taką: 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100 3.8. Utworzyć macierz F o rozmiarze 5x5 zawierającą kolejne 25 pierwszych liczb pierwszych. 4.5. Utworzyć funkcję transponuj(), która przyjmuje jeden parametr będący macierzą i zwraca macierz transponowaną. Oczywiście trzeba używać pętli for, nie można użyć samego operatora transponowania czyli ' . http://www.naukowiec.org/wiedza/matematyka/macierz-odwrotna_607.html 4.6. Utworzyć funkcję odwrotna2(), która policzy macierz odwrotną dla macierzy 2x2. 4.7. Utworzyć funkcję odwrotna3(), która policzy macierz odwrotną dla macierzy 3x3.