ROMAN SALAMON MAREK S. MAKOWSKI MATLAB PODSTAWY I ZASTOSOWANIA

Podobne dokumenty
ROMAN SALAMON MATLAB PODSTAWY I ZASTOSOWANIA

Wprowadzenie do środowiska

AKADEMIA MORSKA W SZCZECINIE WI-ET / IIT / ZTT. Instrukcja do zajęc laboratoryjnych nr 1 AUTOMATYZACJA I ROBOTYZACJA PROCESÓW PRODUKCYJNYCH

Podstawowe operacje na macierzach

Akademia Górniczo-Hutnicza Wydział Elektrotechniki, Automatyki, Informatyki i Elektroniki

PODSTAWY AUTOMATYKI. MATLAB - komputerowe środowisko obliczeń naukowoinżynierskich - podstawowe operacje na liczbach i macierzach.

Obliczenia w programie MATLAB

Metody i analiza danych

Podstawy Automatyki ćwiczenia Cz.1. Środowisko Matlab

WYDZIAŁ ELEKTROTECHNIKI, AUTOMATYKI I INFORMATYKI INSTYTUT AUTOMATYKI I INFORMATYKI KIERUNEK AUTOMATYKA I ROBOTYKA STUDIA STACJONARNE I STOPNIA

Wprowadzenie do Scilab: macierze

LABORATORIUM 3 ALGORYTMY OBLICZENIOWE W ELEKTRONICE I TELEKOMUNIKACJI. Wprowadzenie do środowiska Matlab

MATLAB - laboratorium nr 1 wektory i macierze

do MATLABa podstawowe operacje na macierzach WYKŁAD Piotr Ciskowski

Programowanie w języku Matlab

Wykorzystanie programów komputerowych do obliczeń matematycznych

Mathcad c.d. - Macierze, wykresy 3D, rozwiązywanie równań, pochodne i całki, animacje

MATrix LABoratory. A C21 delta tvx444 omega_zero. hxx J23 aaa g4534 Fx_38

Ćwiczenie 1. Matlab podstawy (1) Matlab firmy MathWorks to uniwersalny pakiet do obliczeń naukowych i inżynierskich, analiz układów statycznych

Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania

Liczby zespolone. x + 2 = 0.

Ćwiczenie 3. MatLab: Algebra liniowa. Rozwiązywanie układów liniowych

Ćwiczenie 3: Wprowadzenie do programu Matlab

Matlab Składnia + podstawy programowania

Zakłócenia w układach elektroenergetycznych LABORATORIUM

Wprowadzenie do Mathcada 1

Algebra macierzy

MATLAB - podstawy użytkowania

SKRYPTY. Zadanie: Wyznaczyć wartość wyrażenia arytmetycznego

1 Podstawy c++ w pigułce.

Elementy metod numerycznych - zajęcia 9

Zanim zaczniemy GNU Octave

Wprowadzenie do programu Mathcad 15 cz. 1

Wstęp do Programowania Lista 1

Co to jest arkusz kalkulacyjny?

Informatyka Arkusz kalkulacyjny Excel 2010 dla WINDOWS cz.3

Wprowadzenie do Scilab: macierze

Podstawy MATLABA, cd.

Przykład 1 -->s="hello World!" s = Hello World! -->disp(s) Hello World!

; B = Wykonaj poniższe obliczenia: Mnożenia, transpozycje etc wykonuję programem i przepisuję wyniki. Mam nadzieję, że umiesz mnożyć macierze...

METODY KOMPUTEROWE W OBLICZENIACH INŻYNIERSKICH

Obliczenia Symboliczne

METODY KOMPUTEROWE W OBLICZENIACH INŻYNIERSKICH

WEKTORY I MACIERZE. Strona 1 z 11. Lekcja 7.

Próbny egzamin z matematyki dla uczniów klas II LO i III Technikum. w roku szkolnym 2012/2013

Instalacja Pakietu R

Edytor tekstu OpenOffice Writer Podstawy

Laboratorium Komputerowego Wspomagania Analizy i Projektowania

Obliczenia iteracyjne

Diary przydatne polecenie. Korzystanie z funkcji wbudowanych i systemu pomocy on-line. Najczęstsze typy plików. diary nazwa_pliku

EXCEL Prowadzący: dr hab. inż. Marek Jaszczur Poziom: początkujący

Cw.12 JAVAScript w dokumentach HTML

dr Mariusz Grządziel 15,29 kwietnia 2014 Przestrzeń R k R k = R R... R k razy Elementy R k wektory;

Macierze. Rozdział Działania na macierzach

ECDL/ICDL Przetwarzanie tekstów Moduł B3 Sylabus - wersja 5.0

Kolumna Zeszyt Komórka Wiersz Tabela arkusza Zakładki arkuszy

Wprowadzania liczb. Aby uniknąć wprowadzania ułamka jako daty, należy poprzedzać ułamki cyfrą 0 (zero); np.: wpisać 0 1/2

Sylabus Moduł 2: Przetwarzanie tekstów

GNU Octave (w skrócie Octave) to rozbudowany program do analizy numerycznej.

Zadanie Wstaw wykres i dokonaj jego edycji dla poniższych danych. 8a 3,54 8b 5,25 8c 4,21 8d 4,85

Politechnika Gdańska Wydział Elektrotechniki i Automatyki Katedra Inżynierii Systemów Sterowania

Ćwiczenia nr 2. Edycja tekstu (Microsoft Word)

JAVAScript w dokumentach HTML (1)

Rozdział 5. Macierze. a 11 a a 1m a 21 a a 2m... a n1 a n2... a nm


1 Programowanie w matlabie - skrypty i funkcje

WPROWADZENIE DO ŚRODOWISKA SCILAB

Wprowadzenie do Scilab: macierze

Wprowadzenie do Pakietu R dla kierunku Zootechnika. Dr Magda Mielczarek Katedra Genetyki Uniwersytet Przyrodniczy we Wrocławiu

Wprowadzenie do systemu Scilab

Instalacja

Tematy lekcji informatyki klasa 4a luty/marzec 2013

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Makropolecenia w Excelu

Podstawowe operacje na macierzach, operacje we/wy

WYRAŻENIA ALGEBRAICZNE

Metody Numeryczne. Laboratorium 1. Wstęp do programu Matlab

Zad. 3: Układ równań liniowych

3. Macierze i Układy Równań Liniowych

Ćwiczenie 1 - Arkusze kalkulacyjne

Celem ćwiczenia jest zapoznanie się z podstawowymi funkcjami i pojęciami związanymi ze środowiskiem AutoCAD 2012 w polskiej wersji językowej.

AKADEMIA MORSKA W SZCZECINIE WI-ET / IIT / ZTT. Instrukcja do zajęc laboratoryjnych nr 3 AUTOMATYKA

najlepszych trików Excelu

Algebra WYKŁAD 3 ALGEBRA 1

Uniwersytet Kazimierza Wielkiego w Bydgoszczy Zespół Szkół nr 5 Mistrzostwa Sportowego XV Liceum Ogólnokształcące w Bydgoszczy

Pracownia Informatyczna Instytut Technologii Mechanicznej Wydział Inżynierii Mechanicznej i Mechatroniki. Podstawy Informatyki i algorytmizacji

Dodawanie grafiki i obiektów

Technologie informacyjne: Arkusz kalkulacyjny

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

MATLAB tworzenie własnych funkcji

A A A A A A A A A n n

MACIERZE. Sobiesiak Łukasz Wilczyńska Małgorzata

Ćwiczenie 1. Wprowadzenie do programu Octave

FUNKCJE LICZBOWE. Na zbiorze X określona jest funkcja f : X Y gdy dowolnemu punktowi x X przyporządkowany jest punkt f(x) Y.

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Wykład 4. Matlab cz.3 Tablice i operacje na tablicach

1. Operacje logiczne A B A OR B

Wprowadzenie do środowiska MATLAB z zastosowaniami w modelowaniu i analizie danych

JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania.

ARKUSZ KALKULACYJNY MICROSOFT EXCEL cz.2 Formuły i funkcje macierzowe, obliczenia na liczbach zespolonych, wykonywanie i formatowanie wykresów.

Transkrypt:

ROMAN SALAMON MAREK S. MAKOWSKI MATLAB PODSTAWY I ZASTOSOWANIA SKRYPT DLA STUDENTÓW I ROKU KIERUNKU ELEKTRONIKA I TELEKOMUNIKACJA POLITECHNIKI GDAŃSKIEJ DO PRZEDMIOTU TECHNIKA OBLICZENIOWA I SYMULACYJNA POLITECHNIKA GDAŃSKA WYDZIAŁ ELEKTRONIKI, TELEKOMUNIKACJI I INFORMATYKI KATEDRA SYSTEMÓW ELEKTRONIKI MORSKIEJ GDAŃSK 2008 2016

2 Copyright Roman Salamon 2008 Copyright Marek S. Makowski 2016 Katedra Systemów Elektroniki Morskiej Politechniki Gdańskiej Skrypt objęty jest prawem autorskim. Prawa autorskiego nie narusza korzystanie z jego wersji elektronicznej oraz jednokrotny wydruk części lub całości skryptu do użytku prywatnego przez studentów Wydziału Elektroniki, Telekomunikacji i Informatyki Politechniki Gdańskiej. Pozostałe formy wykorzystania skryptu wymagają pisemnej zgody autora. Autorzy będą zobowiązani za przekazanie uwag dotyczących treści skryptu i dostrzeżonych błędów na adres: roman.salamon@eti.pg.gda.pl marek.makowski@eti.pg.gda.pl

3 SPIS TREŚCI 1. WPROWADZENIE... 5 CZĘŚĆ I. PODSTAWY UŻYTKOWANIA PROGRAMU MATLAB... 6 2. INFORMACJE WSTĘPNE... 7 2.1. PRZYGOTOWANIE PROGRAMU MATLAB DO PRACY... 7 2.2. CZĘSTO STOSOWANE POLECENIA... 10 3. PODSTAWY OBLICZEŃ NUMERYCZNYCH W PROGRAMIE MATLAB... 12 3.1. WARTOŚCI LICZBOWE... 12 3.1. Liczby rzeczywiste... 12 3.1.2. Liczby zespolone... 13 3.1.3. Zaokrąglenia liczb... 15 3.2. MACIERZE I WEKTORY... 15 3.2.1. Definiowanie macierzy i wektorów... 15 3.2.2. Podstawowe operacje macierzowe... 20 3.2.3. Macierze kwadratowe... 23 3.3. TABLICE... 24 3.3.1. Tablice numeryczne... 25 3.3.2. Łańcuchy... 26 3.4. FUNKCJE... 27 3.4.1. Funkcje standardowe... 27 3.4.2. Funkcje macierzowe... 29 3.4.3 Relacje i operacje logiczne... 32 3.4.4. Instrukcje warunkowe... 33 3.4.5. Definiowanie funkcji... 35 3.5.5. Pętle... 38 4. GRAFIKA... 45 4.1. GRAFIKA DWUWYMIAROWA... 45 4.1.1. Podstawowe funkcje graficzne... 45 4.1.2. Funkcje formatujące rysunek... 48 4.1.3. Tworzenie wielu rysunków... 49 4.1.4. Dobór parametrów rysunku bez użycia instrukcji graficznych... 52 4.2. GRAFIKA TRÓJWYMIAROWA... 55 4.2.1. Linie w przestrzeni trójwymiarowej... 55 4.2.2. Tworzenie obrazów funkcji dwóch zmiennych... 56 4.2.3. Dobór kolorów... 58 4.2.4. Ustawianie położenia układu współrzędnych... 61 4.2.5. Efekty oświetlania rysunków trójwymiarowych... 62 4.2.6. Inne metody formatowania rysunku... 63 4.2.7. Obrazy figur trójwymiarowych... 65 4.3. GRAFICZNY INTERFEJS UŻYTKOWNIKA... 66 4.3.1. Ogólna charakterystyka... 66 4.3.2. Projektowanie planszy GUI... 67 4.3.3. Podstawy programowania graficznego interfejsu użytkownika GUI... 70 4.3.4. Użycie przełącznika Toggle Button i okna edycyjnego Edit Text.... 73 4.3.5. Użycie przełącznika Radio Button i okna edycyjnego Edit Text.... 76 4.4.6. Użycie Popup Menu... 78 4.3.6. Użycie Listbox i Axes... 79

4 4.3.7. Zastosowanie suwaka Slider... 81 5. IMPORT I EKSPORT DANYCH... 84 5.1. WPROWADZENIE... 84 5.2. EKSPORT I IMPORT DANYCH W FORMACIE BINARNYM... 84 5.3. ZAPISYWANIE I CZYTANIE DANYCH W FORMACIE TEKSTOWYM... 85 5.4. EKSPORT I IMPORT PLIKÓW DŹWIĘKOWYCH... 86 CZĘŚĆ II. ZASTOSOWANIA PROGRAMU MATLAB... 88 6. METODY NUMERYCZNE W ZASTOSOWANIU DO FUNKCJI CIĄGŁYCH... 89 6.1. WIELOMIANY... 89 6.2. FUNKCJE WYMIERNE ZMIENNEJ ZESPOLONEJ... 90 6.3. MIEJSCA ZEROWE, MINIMA I MAKSIMA FUNKCJI... 93 6.4. CAŁKOWANIE NUMERYCZNE... 96 6.5. RÓWNANIA RÓŻNICZKOWE... 98 7. GENERACJA, ANALIZA I PRZETWARZANIE SYGNAŁÓW... 106 7.1. SYGNAŁY ANALOGOWE I DYSKRETNE... 106 7.2. GENERACJA SYGNAŁÓW IMPULSOWYCH... 107 7.3. DYSKRETNA REPREZENTACJA SYGNAŁÓW CIĄGŁYCH... 112 7.3.1. Sygnały deterministyczne... 112 7.3.2. Sygnały losowe... 115 7.4. DYSKRETNA TRANSFORMACJA FOURIERA... 119 7.4.1. Definicja i podstawowe własności... 119 8.4.2. Widmo dyskretne a widmo ciągłe... 121 7.4.3. Widma sygnałów o nieograniczonym czasie trwania... 125 7.5. FILTRACJA SYGNAŁÓW DYSKRETNYCH... 129 7.5.1. Filtracja w dziedzinie częstotliwości... 129 7.5.2. Filtracja w dziedzinie czasu... 131 7.6. SPLOT... 137 8. ANALIZA NUMERYCZNA OBWODÓW I UKŁADÓW ELEKTRYCZNYCH... 140 8.1. OBWODY PRĄDU STAŁEGO... 140 8.1.1. Metoda prądów oczkowych... 140 8.1.2. Metoda napięć węzłowych (m. potencjałów)... 142 8.1.3. Metoda prądów oczkowych: Obliczenia ręczne... 144 8.1.4. Metoda napięć węzłowych (m. potencjałów): Obliczenia ręczne... 144 8.1.5. Obliczenia ręczne vs MATLAB metody rozwiązania układu r-ń lin.... 145 8.2. ANALIZA OBWODÓW RLC PRZY POBUDZENIU SINUSOIDALNYM... 148 8.2.1. Obwód RL... 148 8.2.2. Szeregowy obwód rezonansowy... 149 8.2.3. Sprzężone równoległe obwody rezonansowe... 151 8.3. ANALIZA OBWODÓW RLC PRZY DOWOLNYM POBUDZENIU... 154 8.3.1. Analiza numeryczna w dziedzinie częstotliwości... 154 8.3.2. Analiza numeryczna w dziedzinie czasu... 157 8.4. PROJEKTOWANIE FILTRÓW ANALOGOWYCH... 159 8.4.1. Podstawy teoretyczne... 159 8.4.2. Wybór rozwiązania konstrukcyjnego... 162 8.4.3. Wyznaczanie wartości elementów obwodów... 165 INDEKS INSTRUKCJI I FUNKCJI... 170

5 1. WPROWADZENIE Program MATLAB, zwany również często środowiskiem MATLAB, przeznaczony jest do obliczeń inżynierskich i naukowych oraz do wizualizacji ich wyników. W środowisku MATLAB obowiązuje język, w którym komunikujemy się z programem polecając mu wykonywanie określonych zadań. Jest to język wysokiego poziomu, co w praktyce oznacza, że w formie prostej instrukcji można wyrazić polecenie wykonania bardzo złożonego zadania. Cechą charakterystyczną języka MATLAB jest to, że podstawową formą danych jest w nim macierz rzeczywista bądź zespolona. Dane i wyniki obliczeń są przechowywane w przestrzeni roboczej i istnieją w niej dopóki nie zostaną usunięte przez użytkownika, bądź przez zamknięcie programu. Zmienne nie są deklarowane. Środowisko MATLAB jest otwarte w tym sensie, że użytkownik ma dostęp do jego funkcji, poleceń i bibliotek oraz może tworzyć własne pliki i funkcje. Program daje także możliwość współpracy z innymi programami, np. Excel, C, Fortran. Program MATLAB może być instalowany na praktycznie dowolnym komputerze. Zmiana platformy sprzętowej nie wiąże się z utratą własnego oprogramowania. Oprócz podstawowego programu MATLAB istnieją tzw. Toolboxy, które są zawierają specjalistyczne oprogramowanie z kilkunastu dziedzin nauki i techniki. Podstawowy pakiet MATLAB można także uzupełnić interaktywnym programem SIMULINK, który służy do modelowania i symulacji systemów dynamicznych, a w tym systemów elektronicznych, telekomunikacyjnych i systemów automatyki. Niniejszy skrypt został pomyślany jako pomoc dydaktyczna do przedmiotu Technika Obliczeniowa i Symulacyjna, prowadzonego na Wydziale Elektroniki, Telekomunikacji i Informatyki Politechniki Gdańskiej dla studentów drugiego semestru kierunku Elektronika i Telekomunikacja. Składa się on z dwóch części; w pierwszej omówione są podstawy użytkowania programu MATLAB, zaś w drugiej praktyczne przykłady zastosowania programu w elektronice i telekomunikacji. Pisząc ten skrypt autor zakładał, że Czytelnik po raz pierwszy spotyka się z programem MATLAB oraz że Jego wiedza i umiejętności odpowiadają programowi pierwszego semestru studiów. Jedynie w drugiej części skryptu występują przykłady dotyczące treści przekazywanych na drugim lub wyższych latach studiów. Materiał zawarty w skrypcie wystarcza do wykonania projektu i ćwiczeń laboratoryjnych z przedmiotu Technika Obliczeniowa i Symulacyjna w zakresie związanym z użytkowaniem programu MATLAB. Dążąc do zmniejszenia objętości skryptu ograniczono przede wszystkim liczbę omówionych funkcji i instrukcji, rezygnując z rzadziej używanych i bardziej skomplikowanych. Dużą część praktycznych zadań można wykonać bez używania tych pominiętych funkcji i instrukcji, aczkolwiek ich stosowanie ułatwia niewątpliwie programowanie. Ponadto opis omawianych instrukcji i funkcji często nie jest kompletny. Pominięto z zasady te możliwości zawarte w instrukcjach i funkcjach, które znajdują względnie rzadko praktyczne zastosowanie. Funkcjonowanie prawie każdej instrukcji zilustrowano przykładem, co powinno ułatwić jej pełne zrozumienie, zapamiętanie i dalsze stosowanie we własnych programach. Autorzy wyrażają nadzieję, że skrypt ułatwi opanowanie przedmiotu i zachęci do głębszego poznania programu MATLAB, a w przyszłości do jego stosowania w czasie studiów i pracy zawodowej.

CZĘŚĆ I. PODSTAWY UŻYTKOWANIA PROGRAMU MATLAB 6

7 2. INFORMACJE WSTĘPNE 2.1. Przygotowanie programu MATLAB do pracy Na pulpicie monitora znajduje się ikona programu MATLAB, której przyciśnięcie lewym klawiszem myszy powoduje uruchomienie programu. Pojawia się najpierw na krótką chwilę logo programu MATLAB, a następnie okno programu. Okno to może zawierać różne wewnętrzne okna, w zależności od wcześniejszego ustawienia przez poprzedniego użytkownika. W naszej pracy z programem MATLAB używać będziemy dwóch okien, a mianowicie okna podstawowego okna Command Window oraz okna Workspace. W celu uaktywnienia tych okien wybieramy na górnym pasku View i na rozwiniętej liście zaznaczamy wyżej wymienione nazwy okien. Pożądany widok okna programu MATLAB zawiera po lewej stronie okna Workspace, a po prawej stronie okno Command Window. Przeciągając myszą prawe obramowanie pionowe lewego okna można mu nadać pożądaną szerokość około 1/3 szerokości prawego okna. Okno Command Window wykorzystujemy do wprowadzania wszystkich instrukcji, komend, danych itp. W oknie Workspace pojawiają się natomiast sukcesywnie informacje o wszystkich stałych i zmiennych używanych w pisanym przez nas programie. W kolumnie Name widoczne są użyte symbole stałych i zmiennych, a obok ich wymiar. Obserwując to okno unikamy niezamierzonego używania tych samych symboli w odniesieniu do innych zmiennych. Użyteczna jest również informacja o wymiarach zmiennych, która pozwala unikać błędów związanych z niezachowaniem reguł matematycznych obowiązujących w programie MATLAB. Widok obu okien pokazano na rys. 2.1. Rys. 2.1. Widok okien programu MATLAB przygotowanego do pracy.

8 Program MATLAB umożliwia dobranie kroju i wysokości czcionek do upodobań użytkownika. W razie takiej potrzeby wybieramy w pasku okna MATLAB etykietę File, a po rozwinięciu menu etykietę Preferences. W widocznym menu wybieramy najpierw General. Pokazuje się wtedy oddzielne okno, w którym można wybrać krój czcionki i jej wysokość, a także kolory czcionek, którymi będą pisane charakterystyczne elementy programu. Należy wybierać takie style czcionek, które zawierają polskie litery, co jest ważne w zapisie komentarzy (np. Ariel lub SansSerif 1 ). W oknach Command Window i Editor/Debugger najlepiej ustawić Use desktop font. Pozostałe ustawienia mają mniejsze znaczenie i nie należy ich zmieniać bez wyraźnej potrzeby. Wykorzystując okno Command Window można wykonywać proste obliczenia i wprowadzań komendy. Okno to jest jednak mało użyteczne do pisania większych programów. Do tego celu służą specjalne skrypty. Otwieranie takiego skryptu odbywa się przez przyciśnięcie ikony z białą, pustą kartką, umieszczone w lewym skraju paska w oknie programu MAT- LAB. Widok okna przedstawia rys.2.2. Rys. 2.2. Okno do pisania programu Po przyciśnięciu tej ikony pojawia się nowe okno o nazwie Untitled. W oknie tym będziemy wpisywać nasz program. Program ten po nadaniu mu nazwy będzie przechowywany w katalogu Work. W celach porządkowych, każdy użytkownik powinien utworzyć własny fol- 1 Popularny styl Times New Roman ma trudną do odróżnienia literę l i cyfrę 1, co może być przyczyną błędów w programie.

9 der w katalogu Work i w tym folderze umieszczać swoje skryptu. W tym celu należy wykonać kolejno następujące czynności: w pasku okna Untitled wybrać File z menu File wybrać Save As pojawia się okno, w którym na górnym pasku wybieramy ikonę Utwórz nowy folder w oknie pojawia się ramka, w której wpisujemy nazwę użytkownika i wciskamy Enter przyciskamy ikonę nowego folderu i wpisujemy w dolnej ramce nazwę naszego programu, która nie zawiera polskich liter w oknie nazwanym dotąd Untitled pojawia się tytuł C:\MATLAB\work\nazwa użytkownika\nazwa skryptu.m Sprawdzamy, czy ścieżka dostępu do naszego skryptu jest prawidłowa i dokonujemy ewentualnych poprawek opisaną wyżej metodą. Nazwa skryptu ma nadane automatycznie rozszerzenie.m. Nazwy skryptów z takim rozszerzeniem są traktowane w programie MA- TLAB jako zbiory instrukcji przeznaczonych do wykonania. W otwartym oknie o podanej wyżej nazwie tworzymy nasz program. Pracę rozpoczynamy od wpisania nagłówka, którym powinna być (dla porządku) nazwa naszego skryptu. Wpisujemy ją następująco: nazwa (bez kropki). Każdy tekst zawarty między apostrofami napisany jest kolorem czerwonym i jest widoczny po uruchomieniu naszego programu w oknie Command Window. Następnie wpisujemy kolejne instrukcje według zasad podanych w dalszej części skryptu. Po zakończeniu każdego etapu pracy można postępować w dwojaki sposób. Jeżeli chcemy zapisać skrypt bez sprawdzania jego poprawności wówczas, po ciśnięciu File, wybieramy w menu polecenie Save lub wciskamy ikonę Save. Jeżeli chcemy jednocześnie sprawdzić działanie naszego programu, wówczas wciskamy na pasku etykietę Debug i w widocznym menu wybieramy komendę Save and Run. Analogiczny efekt daje wciśnięcie klawisza F5. Nasz program zostanie zapisany i jednocześnie uruchomiony. Skutki uruchomienia programu i jego działanie omówimy w dalszej części skryptu. Po zapisaniu programu można zakończyć jego użytkowanie przez zamknięcie jego okna lub kontynuować pracę nad programem. Usilnie zaleca się okresowe zapisywanie programu, w celu uniknięcia jego utraty w wyniku niewłaściwych działań lub zawieszenia się wykonywania programu MATLAB. Zapisany i zamknięty skrypt można otworzyć w celu dalszej pracy nad nim lub w celu uruchomianie zawartego w nim programu. Należy w tym celu na pasku okna programu MA- TLAB przycisnąć ikonę Open File i z wybrać z katalogu Work folder z nazwą użytkownika, a w nim nazwę skryptu. Inny sposób otwarcia skryptu polega na wpisaniu w oknie Command Window polecenia 2 : >> open <nazwa skryptu> % znak >> to tzw. znak zachęty (ang. prompt), wszystkie polecenia wprowadzane są po znaku zachęty % po znaku % wpisujemy komentarz Jeżeli, przykładowo, nasz skrypt ma nazwę wykres, to odpowiednia komenda ma następujący zapis: >> open wykres 2 Symbole < > oznaczają tu i w dalszym tekście miejsce, w którym programista wpisuje ciągi znaków, których znaczenie wpisano między symbolami.

10 Polecenie jest wykonywane tylko wtedy, gdy w Current Directory wpisana jest właściwa ścieżka dostępu do naszego skryptu. Zwykle wpisany jest jedynie katalog Work i wtedy należy uzupełnić ścieżkę wciskając sąsiednią ikonę Browse for Folder i wybierając z niej nazwę folderu użytkownika. Po wykonaniu czynności opisanych w powyższej instrukcji można przystąpić do pisania programu. Aby jednak nasz program funkcjonował zgodnie z naszymi intencjami, konieczne jest poznanie podstawowych zasad obowiązujących w programie MATLAB. Przedstawimy je w następnym rozdziale. 2.2. Często stosowane polecenia Obsługa programu MATLAB wymaga znajomości pewnych podstawowych poleceń. Podamy i omówimy niżej najważniejsze z nich. Część poleceń będzie szerzej opisana w dalszej części skryptu. Tutaj sygnalizujemy ich istnienie i znaczenie w celu uniknięcia możliwych pomyłek np. w związku z poleceniami występującymi w poprzednim podrozdziale Polecenia dotyczące plików i rysunków open <nazwa pliku> Poleceni otwiera plik lub rysunek o wpisanej nazwie, jeżeli właściwa ścieżka dostępu podana jest w okienku CurrentDirectory. Jeżeli ścieżka dostępu do poszukiwanego pliku jest niewłaściwa, to można ją zamienić w okienku Current Directory lub podać w poleceniu open: open <work\student\wykres.m> Jeżeli plik o nazwie wykres.m znajduje się w podkatalogu student, to zostanie otwarty. Dotyczy to również rysunków o nazwach z rozszerzeniem.fig. W analogiczny sposób można otwierać pliki o innych rozszerzeniach. W zależności od rodzaju rozszerzenia otwierane są zmienne, rysunki itp. i umieszczane w odpowiednich oknach. save <nazwa pliku> Polecenie zapisuje na dysku wszystkie zmienne występujące w przestrzeni roboczej (widoczne w oknie Workspace) na dysku w pliku o podanej nazwie i rozszerzeniu.mat INFO (szczegóły nt. save w rozdziale Eksport i import danych, str. ). saveas(h, nazwa ) To polecenie zapisuje rysunek o uchwycie h w pliku o podanej nazwie. Polecenie używane jest programach dotyczących grafiki. INFO Czym jest uchwyt (ang. handle) patrz rozdział nt. GUI, strony 73 i 81 dir <nazwa katalogu> W oknie Command Window pojawia się lista plików znajdujących się w podanym katalogu lub nazwy podkatalogów. Jeżeli potrzebny plik znajduje się w pewnym podkatalogu to należy podać ścieżkę dostępu, np. dir <work\student> Do znalezienie ścieżki dostępu do poszukiwanej funkcji lub pliku z rozszerzeniem.m służy polecenie which <nazwa funkcji>

11 lub which <nazwa pliku.m> Program zwraca ścieżkę dostępu do danej funkcji, którą można wykorzystać do jej otwarcia. Niestety, w wypadku plików umieszczonych w podkatalogach katalogu Work, trzeba podać ścieżkę dostępu w Current Directory. what Powyższe polecenie powoduje pojawienie się wszystkich plików znajdujących się w bieżącym katalogu, do którego ścieżka podana jest w Current Directory. Niepotrzebne pliki i obiekty graficzne usuwamy poleceniem delete <nazwa pliku> Usunąć można pliki, do których dostęp podany jest w Current Directory. close Powyższe polecenie zamyka okno otwartego rysunku. Jeżeli chcemy zamknąć wszystkie rysunku, to dajemy polecenie close all Polecenia dotyczące przestrzeni roboczej clear Polecenie to usuwa z przestrzeni roboczej wszystkie zmienne. Polecenie uzupełnione o: clear x,y,z,... usuwa wymienione zmienne clear global usuwa zmienne globalne clear functions usuwa funkcje clear all usuwa zmienne lokalne, globalne i funkcje. Listę bieżących zmiennych występujących w przestrzeni roboczej otrzymujemy pisząc who Pełną informację o tych zmiennych daje polecenie whos Przypominamy, że lista zmiennych znajduje się również w oknie Workspace.

12 3. PODSTAWY OBLICZEŃ NUMERYCZNYCH W PROGRAMIE MATLAB 3.1. Wartości liczbowe 3.1. Liczby rzeczywiste Program MATLAB wykonuje obliczenia na liczbach 64-bitowych, skąd wynika, że minimalna liczba dodatnia ma wartość 1.7 10-307, zaś maksymalna liczba ma wartość 1.7 10 307. Przekroczenie w trakcie obliczeń maksymalnej wartości jest sygnalizowane jako Inf. Chociaż obliczenia wykonywane są z bardzo dużą dokładnością, to ich wyniki liczbowe pokazywane są w oknie Command Window za pomocą mniejszej liczby cyfr. I tak w podstawowym formacie short (domyślnym) liczby są zapisywane często przy użyciu pięciu cyfr i wykładnika potęgi 10. Oto charakterystyczne przykłady reprezentacji liczb w oknie Command Window. >> a=123 a = 123 >> a=123456 a = 123456 >> a=1234.5678 a = 1.2346e+003 Format ostatnio zapisanej liczba zawiera zaokrąglenie do pięciu cyfr znaczących wpisanej liczby oraz wykładnik potęgi 10. Liczba w tym zapisie jest równoważna: a=1.2346 10 +3 Należy podkreślić, że zaokrąglenie użyte jest wyłącznie przy prezentacji liczby w oknie Command Window, natomiast obliczenia, w których występuje ta liczba, są wykonywane z pełną dokładnością. Jeżeli krótki format liczby nie jest wystarczająco dokładny (co zdarza się bardzo rzad ko), to można zmienić go na długi: >> format long >> a=1234.5678 a = 1.234567800000000e+003 Podane wyżej instrukcje nadały zmiennej a określone wartości liczbowe. Wartości te są przechowywane w pamięci do czasu zamknięcia okna Command Window, lub usunięcia z pamięci wszystkich danych. Usuwamy je z pamięci komendą clear. Po wpisaniu tej komendy program reaguje następująco: >> clear >> a??? Undefined function or variable 'a'. Zauważmy, że po wpisaniu powyższych instrukcji, w oknie Workspace pojawia się litera a i obok jej wymiar 1x1. Wszystkie liczby mają taki wymiar, który oznacza w programie MATLAB macierz jednoelementową liczbę. Liczby mogą być zapisywane bezpośrednio w sposób pokazany wyżej, lub jako wynik operacji matematycznych. Oto kilka przykładów: >> a=1+2 a = 3

13 >> a=2*3 a = 6 >> a=2/3 a = 0.6667 >> a=2^3 a = 8 Liczby mogą być również wyrażone jako wartość funkcji: >> a=sin(2) a = 0.9093 >> a=log10(2) a = 0.3010 Zauważmy, że po wpisaniu wartości liczby, program MATLAB zwraca jej wartość w stosownym formacie. Bardzo często jest to niewygodne, zwłaszcza, gdy wyniki pośrednich obliczeń są liczne i nie interesują użytkownika. W celu uniknięcia tej niedogodności, instrukcję kończymy znakiem ; (średnikiem). Mamy wtedy: >> a=2^3; lecz wartość zmiennej a pozostaje w pamięci, co sprawdzamy pisząc >> a a = 8 3.1.2. Liczby zespolone Program MATLAB wykonuje obliczenia na liczbach rzeczywistych i zespolonych. Liczby zespolone zapisujemy w następujący sposób: >> a=2+i*3 lub >> a=2+3*i a = a = 2.0000 + 3.0000i 2.0000 + 3.0000i Podane wyżej sposoby zapisu liczb rzeczywistych odnoszą się w całości do liczb zespolonych. I tak przykładowo mamy: >> a=sin(2)+i*sin(3) 0.9093 + 0.1411i Liczbą zespolona może być zapisana w formie wykładniczej. Wyżej podaną liczbę a można mianowicie zapisać jako: >> a=abs(a)*exp(i*angle(a)) gdzie >> abs(a) ans = 0.9202 >> angle(a) ans = 0.1540 Wówczas dostajemy tę samą liczbę: a = 0.9093 + 0.1411i

14 Funkcja abs(a) zwraca wartość bezwzględną liczby zespolonej a, zaś funkcja angle wartość jej argumentu w radianach. Funkcja exp jest funkcją wykładniczą o podstawie e. Do zagadnienia funkcji w programie MATLAB powrócimy w dalszej części skryptu. Tutaj podamy jeszcze trzy funkcje związane z liczbami zespolonymi. Są to: funkcja real, zwracająca część rzeczywistą liczby zespolonej i funkcja imag, wyznaczająca część urojoną takiej liczby. oraz conj, która zmienia liczbę na sprzężoną. >> real(a) ans = 0.9093 >> imag(a) ans = 0.1411 >> conj(a) 0.9093-0.1411i W wypadku, kiedy próbujemy wykonać operację, której wynikiem nie jest określona liczba, program MATLAB daje ostrzeżenie lub sygnalizuje błąd. Przykładem jest dzielenie liczby przez zero: >> 1/0 Warning: Divide by zero. (Type "warning off MATLAB:divideByZero" to suppress this warning.) ans = Inf Wynikiem operacji jest nieskończoność zapisywana tu jako Inf. Inny przykład to dzielenie 0/0: >> 0/0 Warning: Divide by zero. (Type "warning off MATLAB:divideByZero" to suppress this warning.) ans = NaN Skrót NaN (od ang. Not a Number) oznacza, że wynik nie ma formy liczbowej. Problemów takich można uniknąć wykorzystując liczbę oznaczoną jako eps. Jest to bardzo mała liczba o wartości równej przedziałowi kwantyzacji liczb obwiązującemu w obliczeniach. Zastosowanie tej liczby ilustruje przykład wyznaczania wartości funkcji sinx/x w punkcie x=0. W punkcie tym występuje dzielenie 0/0, lecz funkcja jest ciągła i ma wartość 1 o czym przekonujemy się w obliczeniach ręcznych po zastosowania reguły d Hospitala. W programie MATLAB natomiast unikniemy problemu typu NaN zapisując zamiast: >> x=0; >> sin(x)/x Warning: Divide by zero. (Type "warning off MATLAB:divideByZero" to suppress this warning.) ans = NaN, następujące wyrażenie: >> x=0+eps; >> sin(x)/x ans = 1 W drugiej instrukcji do argumentu dodaliśmy eps, w wyniku czego otrzymaliśmy prawidłowy wynik. Wartość eps wynosi w tym wypadku >> eps ans = 2.2204e-016

15 3.1.3. Zaokrąglenia liczb Często w obliczeniach numerycznych pojawia się potrzeba zaokrąglenia wartości liczb do liczb całkowitych. Program MATLAB ma cztery funkcje, które dokonują zaokrągleń na cztery różne sposoby. I tak funkcja round zaokrągla liczbę do najbliższej liczby całkowitej: >> round(2.7) ans = 3 Funkcja floor zaokrągla liczbę do najbliższej liczby całkowitej, najbliższej minus nieskończoności. >> floor(2.7) ans = 2 Funkcja ceil zaokrągla liczbę do najbliższej liczby całkowitej, najbliższej nieskończoności. >> ceil (-2.7) ans = -2 Funkcja fix zaokrągla liczbę do najbliższej liczby całkowitej, najbliższej zeru. >> fix(2.7) ans = 2 Jakkolwiek wyniki zaokrąglenia przy użyciu różnych funkcji bywają jednakowe, to każda z nich może być przydatna. Każda z wymienionych funkcji może mieć argument zespolony, a wówczas sposób uśredniania odnosi się oddzielnie do części rzeczywistej i urojonej liczby. Przykładowo: >> floor(2.7-i*2.7) ans = 2.0000-3.0000i 3.2. Macierze i wektory Charakterystyczną cechą programu MATLAB jest traktowanie każdej zmiennej liczbowej jako macierzy lub wektora, który też jest szczególną formą macierzy. Zauważyliśmy to już, kiedy wymiar liczby zapisany został w oknie Workspace jako 1x1, czyli jako macierz jednoelementowa. Wynikają stąd w początkowym okresie posługiwania się programem pewne utrudnienia i ograniczenia, które związane są z rachunkiem macierzowym. MATLAB traktując każdą zamienną jako macierz akceptuje wyłącznie i konsekwentnie te operacje matematyczne, które odnoszą się do macierzy i spełniają odpowiednie kryteria. Omówimy te zagadnienia szczegółowo. 3.2.1. Definiowanie macierzy i wektorów Jak wiadomo, macierz składa się z elementów uszeregowanych w wierszach i kolumnach. Jeżeli chcemy wprowadzić do programu pewną macierz, to używamy do tego celu następującego zapisu: >> X=[1 2 3 4;5 6 7 8;9 10 11 12] X = 1 2 3 4 5 6 7 8 9 10 11 12

16 Zapisana w ten sposób macierz ma dwa wiersze i cztery kolumny, co znalazło odbicie w oknie Workspace, w kolumnie Space, jako 2x4. Zauważmy, że elementy macierzy oddzielone są spacjami (lub przecinkami), zaś wiersze średnikami. W ten sposób można definiować macierze o praktycznie dowolnej liczbie wierszy i kolumn. Elementami macierzy mogą być liczby rzeczywiste i zespolone. Szczególnym rodzajem macierzy są wektory: wierszowe i kolumnowe. Wektor wierszowy zapisujemy jako: >> x=[1 2 3 4 5] x = 1 2 3 4 5 zaś wektor kolumnowy jako: >> x=[1;2;3] x = 1 2 3 bądź wykorzystując transponowanie (patrz niżej) Bardzo często zachodzi potrzeba zapisu wektora wierszowego, którego elementami są liczby tworzące ciąg rosnący lub malejący o stałej różnicy między sąsiednimi liczbami. Ciąg taki zapisujemy następująco: >> x=1:2:15 % komentarz: ciąg liczb od 1 do 15 co 2 x = 1 3 5 7 9 11 13 15 Jeżeli w zapisie pominiemy drugą liczbę to domyślnie przyjmowana jest jej wartość jako 1, a mianowicie: >> x=0:9 x = 0 1 2 3 4 5 6 7 8 9 Ciąg malejący tworzy się następująco: >> x=2:-0.5:-3 % ciąg malejący liczb od 2 do -3 co.5 x = Columns 1 through 6 2.0000 1.5000 1.0000 0.5000 0-0.5000 Columns 7 through 11-1.0000-1.5000-2.0000-2.5000-3.0000 Prostym zapisem można dokonać w macierzy zamiany wierszy na kolumny (utworzyć macierz transponowaną). W przypadku zamiany macierzy wierszowej na macierz kolumnową mamy przykładowo: >> x=(1:4)' % transpozycja wektora wierszowego na kolumnowy x = 1 2 3 4 Zapis w nawiasach daje macierz wierszową, zaś apostrof ' zamienia wiersz na kolumnę. W przypadku transpozycji macierzy mamy: >> X=[1 2 3; 4 5 6] X = 1 2 3 4 5 6

17 >> Y=X Y = 1 4 2 5 3 6 Jeżeli elementami macierzy są liczby zespolone, to przy zamianie wierszy w kolumny (lub na odwrót) liczby zamieniają się na sprzężone (sprzężenie hermitowskie macierzy): >> X=[1+i*2 2-i*3 3+i*4; 4-i*5 5+i*6 6-i*7] % lub prościej X=[1+2i 2-3i 3+4i; 4-5i 5+6i 6-7i] X = 1.0000 + 2.0000i 2.0000-3.0000i 3.0000 + 4.0000i 4.0000-5.0000i 5.0000 + 6.0000i 6.0000-7.0000i >> Y=X' Y = 1.0000-2.0000i 4.0000 + 5.0000i 2.0000 + 3.0000i 5.0000-6.0000i 3.0000-4.0000i 6.0000 + 7.0000i Jeżeli chcemy dokonać transpozycji macierzy bez zmiany znaków części urojonych, wówczas stosujemy zapis Y=X.' (apostrof poprzedzamy kropką). Każdy element macierzy jest opisany przez podanie numeru jego wiersza i kolumny. Przykładowo, jeżeli chcemy zapisać wartość elementu macierzy Y zaznaczonej wyżej pogrubioną czcionką, wówczas piszemy: >> y=y(3,2) % wyświetla element macierzy Y o współrzędnych 3,2 y = 6.0000 + 7.0000i gdyż zaznaczony element leży w trzecim wierszu i drugiej kolumnie. Wykorzystując tę zasadę możemy zmienić wartość określonego elementu macierzy. Jeżeli w macierzy Y w miejsce y chcemy wstawić np. 5, to piszemy: >> Y(3,2)=5; % zamiana wartości elementu macierzy o współrzędnych 3,2 >> Y Y = 1.0000-2.0000i 4.0000 + 5.0000i 2.0000 + 3.0000i 5.0000-6.0000i 3.0000-4.0000i 5.0000 W napisanym programie często chcemy wprowadzać pewne zmiany wartości przed kolejnym jego uruchomieniem. Jeżeli zmiana taka polega na zmianie wartości liczbowej wówczas posługujemy się instrukcją input. Sposób jej wykorzystania ilustrują dwa przykłady. Jeżeli chamy wprowadzić lub zmienić wartość stałej (parametru) a, wtedy piszemy: >> a=input('nowa wartość=') nowa wartość=2 % wstawiliśmy z konsoli liczbę 2 po znaku = a = 2 Jeżeli w programie wystąpi instrukcja zapisana w pierwszym wierszu, wówczas w oknie Command Window pojawi się ciąg znaków ujętych w apostrofy (tu nowa wartość= ). Program czeka, aż użytkownik wpisze wartość stałej a. Po wpisaniu program zwraca jej wartość. W analogiczny sposób można zmienić wartość dowolnego elementu macierzy. Jeżeli w zdefiniowanej wyżej macierzy Y chcemy zmienić wartość elementu w drugim wierszu i pierwszej kolumnie, to piszemy: >> Y(2,1)=input( Y(2,1)= ) >> Y(2,1)= 0 % wstawiliśmy z konsoli liczbę 0 po znaku =

18 Y = 1.0000-2.0000i 4.0000 + 5.0000i 0 5.0000-6.0000i 3.0000-4.0000i 5.0000 Program MATLAB zwraca wybrany wektor z macierzy, gdy użyjemy dwukropka. Weźmy jako przykład następującą macierz: A = 1 2 3 4 5 6 7 8 9 10 11 12 Zaznaczony grubą czcionką wektor otrzymujemy dzięki następującemu zapisowi: >> a=a(:,3) % oznacza: wszystkie wiersze, 3-cia kolumna a = 3 7 11 Jak widać dwukropek oznacza tu wszystkie wiersze Jeżeli chcemy utworzyć wektor tylko z dwóch wierszy znajdujących się w trzeciej kolumnie, to piszemy: >> a=a(2:3,3) % wiersze od 2-go i 3-go, w 3-ciej kolumnie a = 7 11 W powyższym zapisie dwukropek oznacza do. Dzięki podanemu niżej zapisowi tworzymy macierz z pożądanych wierszy i kolumn. >> B=A(2:3,1:3) B= 5 6 7 9 10 11 Program MATLAB generuje kilka prostych i użytecznych macierzy, a mianowicie macierz zerową, jedynkową i jednostkową: >> A=zeros(3,5) % podajemy wymiary macierzy (3,5) A = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 >> A=ones(4,3) % podajemy wymiary macierzy (4,3) A = 1 1 1 1 1 1 1 1 1 1 1 1 >> A=eye(3,4) % podajemy wymiary macierzy (3,4) A = 1 0 0 0 0 1 0 0 0 0 1 0 Ostatnia z podanych macierzy jest szczególnie użyteczna jako macierz kwadratowa.

19 Ponadto program MATLAB generuje macierze zawierające wartości losowe o rozkładzie jednostajnym i normalnym, bardzo użyteczne w obliczeniach inżynierskich. Macierz o rozkładzie jednostajnym zawiera liczby z przedziału <0,1>, a jej przykładowa postać jest następująca: >> A=rand(2,5) A = 0.9501 0.6068 0.8913 0.4565 0.8214 0.2311 0.4860 0.7621 0.0185 0.4447 Liczby zawarte w macierzy o rozkładzie normalnym mają wartość średnią zmierzającą do zera i odchylenie standardowe zmierzające do jedności. >> A=randn(2,5) A = -0.4326 0.1253-1.1465 1.1892 0.3273-1.6656 0.2877 1.1909-0.0376 0.1746 Szczegóły dotyczące praktycznego wykorzystania tych macierzy podamy w dalszej części skryptu. Na zakończenie omawiania sposobów definiowania macierzy pokażemy jeszcze jedną użyteczną metodę. Polega ona na sklejaniu macierzy o tej samie liczbie wierszy lub kolumn. Metodę te pokazują następujące przykłady: >> A=zeros(3,4) A = 0 0 0 0 0 0 0 0 0 0 0 0 >> B=ones(3,3) B = 1 1 1 1 1 1 1 1 1 >> C=[A B A] C = 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 Ze zdefiniowanych macierzy A i B utworzona została macierz C o liczbie wierszy równej liczbie wierszy macierzy A i B i zwiększonej liczbie kolumn. Jeżeli macierze mają jednakową liczbę kolumn, to można z nich utworzyć macierz o zwiększonej liczbie wierszy: >> C=[A(:,1:3);B;A(:,1:3)] C = 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 W macierzy A zmniejszyliśmy liczbę kolumn do trzech stosując wcześniej podany zapis. Należy zwrócić uwagę, że macierze w instrukcji zostały rozdzielone średnikiem.

20 Dogodnym narzędziem wprowadzania zmian istniejącej macierzy jest Array Editor. Niech macierz A ma postać: >> A=[1+1i 2+2i 3+3i].' A = 1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i Wówczas Array Editor jest oknem, w którym edytowana jest macierz i w którym można zmieniać wartości elementów macierzy, liczbę wierszy i kolumn oraz wpisywać w nie nowe wartości. Okno to otwiera instrukcja openvar( A ) Można je także otworzyć zaznaczając w oknie Workspace odpowiednią macierz (wektor) i przyciskając ikonę Open. Obok ikony Open na pasku okna Workspace znajduje się ikona Delete, której przyciśnięcie usuwa zaznaczoną macierz (wektor). 3.2.2. Podstawowe operacje macierzowe Konsekwencją traktowania zmiennych w programie MATLAB jako macierzy jest akceptowanie tylko takich operacji na zmiennych, które są zgodne z zasadami rachunku macierzowego. INFO Przypomnimy dlatego pokrótce podstawowe operacje na macierzach i zilustrujemy je prostymi przykładami. Zdefiniujemy najpierw dwie macierze, którymi będziemy się posługiwać w przykładach: >> A=[1 4-2; 3-5 6] A = 1 4-2 3-5 6 >> B=[2 4-4; 6 7-3] B = 2 4-4 6 7-3 Suma macierzy A i B jest równa: >> C=A+B C = 3 8-6 9 2 3

21 Sumować można wyłącznie macierze posiadające jednakowy wymiar, czyli tę samą liczbę wierszy i kolumn. Sumowanie polega na sumowaniu korespondujących ze sobą (o odpowiednich współrzędnych) wyrazów macierzy czyli na następujących operacjach: C(m,n)=A(m,n)+B(m,n) dla m=1:m, n=1:n gdzie M jest liczbą wierszy macierzy A i B, a N liczbą kolumn tych macierzy. Jeżeli macierze mają różny wymiar, wtedy program MATLAB nie wykonuje źle zapisanej operacji i podaje tego przyczynę. Przykładowo zapiszemy: >> C=B(:,1:2) C = 1 4 6 7 >> D=A+C??? Error using ==> + Matrix dimensions must agree. Program wykrył błąd w zapisie sumy i wskazał na jego przyczynę: Wymiary macierzy muszą być zgodne. Macierz C ma bowiem tylko dwie kolumny, zaś macierz A trzy. Odejmowanie macierzy B od macierzy A o tych samych wymiarach daje macierz C, o następujących elementach: >> C=A-B C = -1 0 2-3 -12 9 Mnożenie macierzy A(m,n) o wymiarach MxN przez macierz B(n,k) o wymiarach NxK daje macierz C(m,k) o następujących elementach: C(m,k) N n1 A(m,n)B(n,k) dla m=1:m i k=1:k; % m-ty wiersz macierzy A mnożony przez k-tą kolumnę macierzy B Zdefiniowane wyżej macierze A i B nie mogą być mnożone, bo liczba kolumn macierzy A nie jest równa liczbie wierszy macierzy B. Rzeczywiście mamy: >> C=A*B??? Error using ==> * Inner matrix dimensions must agree. Można natomiast wykonać mnożenia macierzy A przez macierz transponowaną B. >> B' ans = 2 6 4 7-4 -3 >> C=A*B' C = 26 40-38 -35 Użyteczną operacją w obliczeniach jest mnożenie wektora kolumnowego przez wektor wierszowy. Mamy bowiem wtedy: N C(m,k) n 1 A(m, 1)B( 1,k) A(m, 1)B( 1,k) dla m=1:m i k=1:k; % A(M wierszy, 1 kolumna)

22 Każdy element macierzy C jest iloczynem odpowiedniego elementu wektora kolumnowego i wierszowego. Przykładowo: >> a=[1 2 3]' a = 1 2 3 >> b=[4 5 6 7 8] b = 4 5 6 7 8 >> C=a*b C = 4 5 6 7 8 8 10 12 14 16 12 15 18 21 24 Wykorzystując wektory jednostkowe można generować macierze o jednakowych wierszach lub kolumnach. Przykładowo: >> a=ones(3,1) % wektor jednostkowy kolumnowy a = 1 1 1 >> A=[a 2*a 3*a] % macierz o jednakowych wierszach A = 1 2 3 1 2 3 1 2 3 Czwartą operację na macierzach, a mianowicie ich dzielenie omówimy w następnym punkcie poświęconym macierzom kwadratowym. Przypomnijmy, że na ogół operacja mnożenia macierzy nie jest przestawna, czyli A B B A, nawet jeżeli w obu wypadkach mnożenie jest wykonywalne. Ilustruje to następujący prosty przykład: >> A=[1 2; 4 5] A = 1 2 4 5 >> B=[3 4; 6 5] B = 3 4 6 5 >> C=A*B C = 15 14 42 41 >> D=B*A D = 19 26 26 37 Jak widać, przestawienie kolejności macierzy daje różna wyniki, gdyż C D.

23 3.2.3. Macierze kwadratowe Największe znaczenie w obliczeniach inżynierskich mają macierze kwadratowe, czyli macierze o tej samej liczbie wierszy i kolumn. Z macierzy kwadratowej można utworzyć macierz odwrotną, którą wykorzystuje się do m.in. do rozwiązywania układów równań liniowych. Pomijając procedurę wyznaczania macierzy odwrotnej, którą stosuje program MA- TLAB, przedstawimy jej podstawowe właściwości i zastosowania w rachunku macierzowym. Macierz odwrotną do macierzy A oznaczmy jako A -1, a wtedy związek między oby macierzami można zapisać jako: A A -1 =1 lub A -1 A=1 gdzie 1 oznacza macierz jednostkową. Jeżeli mamy równanie macierzowe: A x=b, gdzie x jest wektorem niewiadomych, a b wektorem danych, to mnożąc obustronnie powyższe równanie przez A -1 otrzymujemy: A -1 A x=a -1 b Wykorzystując podaną wyżej zależność między macierzą i macierzą do niej odwrotną mamy: 1 x=a -1 b, a stąd ostatecznie: x=a -1 b. Program MATLAB wyznacza macierz odwrotną do macierzy A, gdy zapiszemy następującą instrukcję: >> inv(a) lub >> A^-1 Sposób wykorzystania macierzy odwrotnej pokażemy na przykładzie rozwiązania podanego niżej układu czterech równań liniowych. 2x 4x 3x 2x 1 1 1 1 3x 4x 3x 2x 2 2 2 2 4x 8x 4x 3x 3 3 3 3 5x 2x 2x 5x 4 4 4 4 28 4 7 13 Układ ten zapisany w formie macierzowej ma następującą postać: 2 3 4 5 x1 28 4 4 8 2 x 2 4 3 3 4 2 x 3 7 2 2 3 5 x 4 13 Poniżej przedstawiono program służący do rozwiązania tego układu równań. >> A=[2-3 4 5;4 4-8 2;3-3 -4 2;2-2 3-5]; >> b=[28-4 -7-13]'; >> x=inv(a)*b % dostajemy cały wektor rozwiązań x = 1.0000 2.0000 3.0000 4.0000

24 >> x1=x(1) % dostajemy niewiadomą x1 czyli pierwszy wiersz kolumnowego wektora x x1 = 1.0000 >> x2=x(2) x2 = 2.0000 >> x3=x(3) x3 = 3.0000 >> x4=x(4) x4 = 4.0000 Należy zwrócić uwagę na apostrof przy zapisie wektora b, który zamienia wektor wierszowy na kolumnowy. W przedstawionym programie nie jest potrzebna użytkownikowi jawna postać macierzy odwrotnej. Podamy ją jednak dla porządku w celu ewentualnego sprawdzenia poprawności obliczeń. >> inv(a) ans = 0.1200 0.1400-0.0400 0.1600 0.0428 0.1303-0.2097 0.0110 0.1048 0.0131-0.1269 0.0593 0.0938 0.0117-0.0083-0.1048 Instrukcja x=inv(a)*b jest równoważna lewostronnemu dzieleniu macierzy, które zapisuje się jako: >> x=a\b % alternatywny zapis instrukcji x=inv(a)*b x = 1.0000 2.0000 3.0000 4.0000 co jest łatwiejsze do zapamiętania. Prawostronne dzielnie macierzy definiowane jest jako: >> B/A=B*inv(A) przy czym B musi mieć taką samą liczbę kolumn, jaką liczbę wierzy ma macierz inv(a). Operacja ta jest rzadko stosowana w praktyce. W niektórych obliczeniach potrzeby jest wyznacznik macierzy (ang. determinant). Dla podanej wyżej macierzy A, program MATLAB wyznacza go następująco: >> det(a) ans = 1450 3.3. Tablice Program MATLAB operuje nie tylko na macierzach, lecz również na tablicach (ang. arrays). Tablicą (dwuwymiarową) jest uporządkowany w wiersze i kolumny zbiór liczb lub znaków. W tym sensie macierz jest specyficzną tablicą numeryczną, której dotyczą operacje macierzowe. Specyficzną formą tablic zawierających znaki (ang. charakter arrays) są również łańcuchy (ang. strings). W skrypcie zajmiemy się wyłącznie tablicami numerycznymi i łańcuchami, które mają duże znaczenie z punktu widzenia obliczeń inżynierskich.

25 3.3.1. Tablice numeryczne Jedno i dwuwymiarowe tablice numeryczne definiowane są identycznie jak wektory i macierze. Różnice pojawiają się wtedy, gdy chcemy wykonać na nich określone operacje. Charakterystyczną cechą tablic jest to, że operacje na nich wykonywane są na ich elementach metodą element po elemencie. Domyślnie każda tablica numeryczna traktowania jest w programie MATLAB jako macierz. Jeżeli chcemy wykonać na niej operacje odnoszące się do tablic, musimy to wyróżnić specjalnym operatorem. Potrzeba taka nie zachodzi tylko w przypadku dodawania i odejmowania, gdyż operacje te są jednakowe dla tablic i macierzy. INFO Omówimy teraz pokrótce podstawowe operacje na tablicach. Mnożenie tablic A i B zapisujemy jako: >> C=A.*B % mnożenie tablicowe, czyli z kropką Znak mnożenia został poprzedzony kropką, co sygnalizuje, że A i B są tablicami i mnożenie ma być wykonane w sposób dla nich właściwy. Mnożenie tablic polega na następujących operacjach: C(m,n)=A(m,n) B(m,n) dla m=1:m i n=1:n. Oto prosty przykład: >> A=[ 1 2 3; 3 2 1; 4 5 6] A = 1 2 3 3 2 1 4 5 6 >> B=[2 3 4; 4 3 2; 1 2 3] B = 2 3 4 4 3 2 1 2 3 >> C=A.*B C = 2 6 12 12 6 2 4 10 18 W analogiczny sposób zapisujemy operację dzielenia tablic: C(m,n)=A(m,n)/B(m,n) dla m=1:m i n=1:m. W programie MATLAB odpowiednia instrukcja ma następującą postać: >> C=A./B % znak./ oznacza dzielenie przez siebie korespondujących elementów C = 0.5000 0.6667 0.7500 0.7500 0.6667 0.5000 4.0000 2.5000 2.0000 Operację potęgowania tablicy zapisujemy jako: >> C=A.^3 C = 1 8 27 27 8 1 64 125 216 Ze względu na sposób wykonywania operacji na tablicach nie są wykonywane niektóre operacje odnoszące się do macierzy. Przykładowo porównajmy dwie operacje, w których występuje wcześniej zdefiniowana macierz A:

26 >> B=[1 2 3]' B = 1 2 3 >> C=A*B C = 14 10 32 >> C=A.*B??? Error using ==>.* Matrix dimensions must agree. Pierwsza operacja odnosi się do macierzy i jest poprawna. Druga operacje dotyczy tablic i jest błędna, gdyż obie tablice muszą mieć jednakowy wymiar. Podane wyżej przykłady dotyczyły tablic kwadratowych. Obowiązują one również dla tablic prostokątnych, a w tym jednowymiarowych, odpowiadających wektorom. Pokazuje to następujący przykład: >> a=1:10 a = 1 2 3 4 5 6 7 8 9 10 >> b=a.^2 b = 1 4 9 16 25 36 49 64 81 100 Zauważmy, że operacja potęgowania jest równoważna mnożeniu. Jeżeli zapiszemy: >> b=a^2??? Error using ==> ^ Matrix must be square. program MATLAB zgłosi błąd i wskaże na jego przyczynę, która wynika z reguł mnożenia macierzy (przy mnożeniu a a=a 2 macierz a musi być prostokątna). W programie MATLAB można posługiwać się tablicami wielowymiarowymi (ang. multidimesional arrays). Sposób definiowania takich tablic i posługiwania się nimi pokażemy w dalszej części skryptu. 3.3.2. Łańcuchy Łańcuchy wykorzystywane są w prostych obliczeniach inżynierskich głównie do opisywania danych i rysunków. Łańcuch znaków tworzymy ujmując je w apostrofy. Program MATLAB sygnalizuje pojawienie się początku łańcucha standardowo kolorem niebieskim, a jego zakończenie zmianą koloru na czerwony. Łańcuchy wyróżniają się zatem wyraźnie w pisanym przez użytkownika programie. Każdy znak łańcucha traktowany jest jako element tablicy, co umożliwia wykonywanie na nich określonych operacji. Kilka prostych operacji ilustruje poniższy przykład. >> a='dom' a = dom >> a(3) ans = m >> a(2)='y' a = dym

27 W pierwszym wierszu poleceń zdefiniowany został łańcuch, w drugim wywołano trzeci element tego łańcuch, a w trzecim zmieniono znak o na znak y. Łańcuchy można rozszerzać analogicznie jak macierze. Ilustruje to poniższy przykład >> b='ek' b = ek >> c=[a b] c = dymek Rozdzielnie łańcuchów znakiem średnika powoduje utworzenie tablicy pod warunkiem, że oba łańcuch mają jednakową liczbę znaków: ale uwaga: >> d='ogień' d = ogień >> e=[c;d] e = dymek ogień >> e=[a;d]??? Error using ==> vertcat CAT arguments dimensions are not consistent. 3.4. Funkcje Program MATLAB dysponuje wielką liczbą funkcji, z których niewielka część jest znana z ogólnej matematyki, a pozostała została zdefiniowana w programie w celu rozwiązywania rozmaitych problemów numerycznych i tworzenia grafiki. Nawet pobieżna prezentacja funkcji występujących w programie MATLAB zdecydowanie przekracza ramy tego skryptu. Ograniczymy się zatem do podania ogólnych zasad posługiwania się funkcjami i omówimy najczęściej stosowane. Dla potrzeb tego skryptu wygodnie jest podzielić funkcje na kilka charakterystycznych typów i omówić je oddzielnie. 3.4.1. Funkcje standardowe Do tej klasy funkcji zaliczymy ogólnie znane funkcje matematyczne. Są to funkcje potęgowe, wykładnicze, logarytmiczne i trygonometryczne. Zapis tych funkcji nie różni się od stosowanego w matematyce. Program MATLAB wyznacza wartości tych funkcji dla dyskretnych wartości argumentu, którym jest wektor lub macierz. Ogólny zapis standardowych funkcji ma następującą postać: >> Y=f(X) gdzie X jest macierzą argumentów, Y macierzą wartości funkcji, a w miejsce symbolu f wpisuje się nazwę funkcji. Przykładowo wartości funkcji sinus wyznacza się następującą instrukcją: >> y=sin(x) Praktyczny sposób wykorzystanie tej instrukcji pokazuje następujący przykład: >> x=2*pi*(0:0.1:1)

28 x = Columns 1 through 7 0 0.6283 1.2566 1.8850 2.5133 3.1416 3.7699 Columns 8 through 11 4.3982 5.0265 5.6549 6.2832 >> y=sin(x) y = Columns 1 through 7 0 0.5878 0.9511 0.9511 0.5878 0.0000-0.5878 Columns 8 through 11-0.9511-0.9511-0.5878-0.0000 Powyższy program wyznacza wartości funkcji sinus w przedziale <0,2> w punktach stanowiących kolejne elementy wektora x. Wartości te podano w celach edukacyjnych; w praktyce należy po pierwszej instrukcji wstawić średnik, dzięki czemu unikniemy niepotrzebnego wypisywania wartości argumentu. Posługując się funkcjami standardowymi i operatorami można tworzyć własne funkcje. Pozostając przy zdefiniowanej wyżej funkcji sinusoidalnej można przykładowo utworzyć niestandardową funkcję sin 2 (x) i wyznaczyć jej wartości. W tym celu zapisujemy następujące instrukcje: >> x=2*pi*(0:0.1:1); >> y=sin(x).^2 % uwaga: potęgowanie tablicowe, z kropką y = Columns 1 through 7 0 0.3455 0.9045 0.9045 0.3455 0.0000 0.3455 Columns 8 through 11 0.9045 0.9045 0.3455 0.0000 Kropka przed znakiem potęgi jest niezbędna, gdyż powoduje, że potęgowanie dotyczy każdego elementu wektora sinx. Przy braku kropki program zgłasza błąd. W zmieszczonej niżej tablicy podano najczęściej używane funkcje standardowe. matematyczny MATLAB sin sin cos cos tg tan arcsin asin arccos acos artg atan log log10 ln log sqrt e(.) exp sinh sinh cosh cosh tgh tanh (.) a (.)^a

29 Argumenty funkcji w programie MATLAB mają szersze dziedziny niż podawane w matematyce elementarnej, gdyż program operuje na liczbach zespolonych. Przykładowo: lub >> log10(-2) ans = 0.3010 + 1.3644i >> sin(2+i*3) ans = 9.1545-4.1689i Jak już wspomniano, dziedziną funkcji standardowych są nie tylko wektory, lecz także macierze. Jeżeli w argumencie funkcji występuje macierz, wówczas program zwraca wartości funkcji dla każdego elementu macierzy i zapisuje je w formie macierzy. Położenia (współrzędne) każdej wartości funkcji w tej nowej macierzy są takie same jak argumentów w macierzy stanowiącej dziedzinę funkcji. Oto prosty przykład funkcji sinus, której argumentem jest macierz: >> X=[0 pi/2 pi 3*pi/2 2*pi; 0 pi/4 pi/2 3*pi/4 pi] X = 0 1.5708 3.1416 4.7124 6.2832 0 0.7854 1.5708 2.3562 3.1416 >> Y=sin(X) Y = 0 1.0000 0.0000-1.0000-0.0000 0 0.7071 1.0000 0.7071 0.0000 3.4.2. Funkcje macierzowe Program MATLAB dysponuje bardzo dużą liczbą funkcji, których dziedziną są macierze i wektory. Omówimy tutaj część tych funkcji, które są najczęściej używane w obliczeniach inżynierskich. Niektóre z tych funkcji już poznaliśmy wcześniej i przypomnimy je w celu podkreślenia, że dotyczą one macierzy jako argumentów. det(a) inv(a) abs(a) real(a) zwraca wyznacznik macierzy prostokątnej wyznacza macierz odwrotną do macierzy prostokątnej zwraca macierz zawierającą wartości bezwzględne elementów macierzy A zwraca macierz zawierającą wartości rzeczywiste elementów macierzy A imag(a) zwraca macierz zawierającą wartości urojone elementów macierzy A angle(a) zwraca macierz zawierającą wartości argumentów elementów macierzy A conj(a) zwraca macierz, której elementy są sprzężone względem elementów macierzy A round(a), floor(a), ceil(a), fix(a) zwracają macierze, których elementami są liczby zaokrąglone według reguł opisanych dla liczb (patrz str. 15) Omówione niżej funkcje wykorzystuje się m.in. do analizy przebiegu funkcji jedno i dwuwymiarowych zapisywanych numerycznie w formie wektorów lub macierzy. Funkcja sum dokonuje sumowania liczb, po wierszach, oddzielnie w każdej kolumnie macierzy i tworzy wektor wierszowy, w którym elementami są wyniki sumowania w odpowiednich kolumnach. Ilustruje to następujący przykład: >> A=[ 1 2 3; -1 3 4; -5 0 1]

30 A = 1 2 3-1 3 4-5 0 1 >> a=sum(a) a = -5 5 8 Jeżeli argumentem funkcji sum jest wektor, to zwraca ona sumę elementów tego wektora. Tak więc sumę wszystkich elementów macierzy A wyznaczamy jako: >> as=sum(a) as = 8 lub bezpośrednio jako: >> as=sum(sum(a)) as = 8 Bardzo użyteczną funkcją jest cumsum, która jest w obliczeniach numerycznych odpowiednikiem całki t y (t) x( )d. 0 Funkcja ta wyznacza macierz, w której wierszach znajdują się bieżące sumy wyznaczane oddzielnie w każdej kolumnie według następującego wzoru: m B (m,n) A(m,n). n1 Dla rozpatrywanej macierzy A mamy więc: >> B=cumsum(A) B = 1 2 3 0 5 7 % suma cząstkowa wierszy 1 i 2 macierzy A -5 5 8 % suma wszystkich wierszy czyli sum(a) Odpowiednikiem różniczkowania w obliczeniach numerycznych jest funkcja diff. Realizuje ona następującą operację: m C(m,n) n 1 A(m 1,n) A(m,n) Dla macierzy A funkcja diff buduje macierz: >> C=diff(A) C = -2 1 1 % różnica cząstkowa wierszy 2 i 1 macierzy A -4-3 -3 % różnica cząstkowa wierszy 3 i 2 macierzy A Jak widać liczba wierszy w macierzy C jest o jeden mniejsza od liczby wierszy macierzy A. Funkcja max zwraca wektor wierszowy, w którym znajdują się maksymalne wartości występujące w odpowiednich kolumnach. Pokazuje to następujący przykład: >> a=max(a) a = 1 3 4

31 Jeżeli argument jest wektorem, to funkcja max wyznacza maksymalną wartość tego wektora: >> amax=max(a) amax = 4 Zauważmy, że w tym przykładzie liczba 4 jest wartością maksymalną występującą w macierzy A. W celu wyznaczenia wartości maksymalnej macierzy można użyć krótszej instrukcji: >> amax=max(max(a)) amax = 4 Funkcja min zwraca wektor wierszowy, w którym znajdują się minimalne wartości występujące w odpowiednich kolumnach. Oto przykład: >> a=min(a) a = -5 0 1 >> amin=min(a) amin = -5 Funkcja mean zwraca wektor wierszowy, w którym znajdują się średnie wartości liczb występujących w odpowiednich kolumnach. Dla rozpatrywanej to macierzy mamy: >> a=mean(a) a = -1.6667 1.6667 2.6667 >> amean=mean(a) amean = 0.8889 Ostatnia liczba jest średnią wartością elementów macierzy A. Funkcja std zwraca wektor wierszowy, w którym znajdują się odchylenia standardowe wartości w odpowiednich kolumnach. >> a=std(a) a = 3.0551 1.5275 1.5275 Funkcja var wyznacza wariancję według podanych wyżej reguł: >> a=var(a) a = 9.3333 2.3333 2.3333 Jak widać, wariancja jest równa kwadratowi odchylenia standardowego. W wypadku ostatnich funkcji nie podano odchylenia standardowego i wariancji wyznaczonego z wektorów, gdyż nie są te wielkości równe odpowiednim wielkościom dla całej macierzy. Funkcji mean, std i var używa się głównie do analizy procesów stochastycznych. Bardzo użyteczną funkcją jest funkcja size, która zwraca liczbę wierszy i kolumn macierzy: >> [M,N]=size(A) M = 3 N = 3

32 Na pierwszy rzut oka wydaje się ona zbędna, jednakże w bardziej złożonych programach wykorzystuje się ją bardzo często. Wymiary macierzy bywają bowiem zmienne, gdyż mogą być uzależnione od podawanych przez użytkownika parametrów. 3.4.3 Relacje i operacje logiczne Operacje logiczne polegają w ogólności na sprawdzaniu, czy zapisana relacja między macierzami jest prawdziwa. Wynikiem sprawdzenia jest decyzja binarna: prawda oznaczona cyfrą 1 lub fałsz, oznaczony cyfrą 0. Najczęściej używanymi relacjami są równość i nierówności. Najprostszy przykład dotyczy macierzy jednoelementowych, czyli liczb. Zapiszmy następującą relację >> p=3>2 p = 1 >> p=2>3 p = 0 Pierwszą instrukcję należy rozumieć następująco: Sprawdź, czy prawdą jest, że 3 jest większe od 2. Jeżeli jest to prawda to wstaw p=1, w przeciwnym wypadku wstaw p=0. Ponieważ pierwsza nierówność jest prawdziwa, program zwrócił wartość p=1. Druga nierówność jest fałszywa i stąd p=0. Ogólny zapis operacji logicznych dla macierzy ma następującą postać: >> C=A==B lub >> C=eq(A,B) A równe B >> C=A~=B lub >> C=ne(A,B) A nie równe B >> C=A<B lub >> C=lt(A,B) A mniejsze od B >> C=A<=B lub >> C=le(A,B) A mniejsze lub równe B >> C=A>B lub >> C=gt(A,B) A większe od B >> C=A>=B lub >> C=ge(A,B) A większe lub równe B W powyższych relacjach A i B są macierzami o takich samych wymiarach. Sprawdzanie poprawności zapisanych relacji odnosi się do wszystkich elementów macierzy o tym samym numerze wiersza i kolumny. W miejscach elementów dla których relacja jest prawdziwa w macierzy C figurują cyfry 1, a w pozostałych cyfry 0. Ilustrują to następujące przykłady dotyczące wcześniej zdefiniowanych macierzy A i B. A = 1 2 3-1 3 4-5 0 1 B = 3 2 1-6 3 0 0 0 1 >> C1=A==B C1 = 0 1 0 0 1 0 0 1 1

33 >> C2=A>B C2= 0 0 1 1 0 1 0 0 0 >> C3=A>=B C3 = 0 1 1 1 1 1 0 1 1 Jeżeli chcemy znać wartości elementów macierzy A lub B, dla których zapisana relacja jest prawdziwa możemy użyć mnożenia tablicowego (wyraz po wyrazie). Przykładowo relację równości spełniają w obu macierzach następujące elementy: >> D=A.*C1 D = 0 2 0 0 3 0 0 0 1 Opis rzadziej używanych operatorów logicznych (np. and lub or) można znaleźć w Help programu MATLAB. Wszystkie podane wyżej relacje dotyczą również wektorów o tej samej liczbie elementów. Można je wykorzystywać m.in. do analizy przebiegu funkcji, rozwiązywania równań nieliniowych itp. Przydatną funkcją, w której występują relacje jest funkcja find. Zwraca ona numery wierszy i kolumn w których dana relacja jest prawdziwa. Ilustruje to następujący przykład: >> [m,n]=find(d>1) m = 1 2 n = 2 2 Elementy macierzy D o wartościach większych od 1 to D(1,2) i D(2,2). 3.4.4. Instrukcje warunkowe Instrukcje warunkowe służą do uzależnienia wykonania instrukcji od spełnienia określonych relacji logicznych. Najprostsza struktura instrukcji warunkowej jest następująca: if <relacja logiczna> <instrukcja> end Instrukcja jest wykonywana tylko wtedy, gdy zapisana wyżej relacja logiczna jest prawdziwa. W przeciwnym wypadku program przechodzi do instrukcji znajdującej się za end. Oto prosty przykład: >> w=2; >> if w==2 y=2*w end y = 4

34 Ponieważ w =2, to program wykonał instrukcję y=2w i podał jej wynik. Inny przykład: >> w=2; >> if w>2 y=2*w end >> y=3*w y = 6 Warunkiem wykonania instrukcji y=2w jest to, że w>2; a ponieważ nie jest to prawda, więc program wykonał pierwszą instrukcję znajdującą się za end i podał jej wynik. Instrukcje warunkowe mogą być rozbudowane w celu zwiększenia liczby relacji logicznych, których prawdziwość warunkuje wykonanie większej liczby instrukcji. Struktura takich instrukcji warunkowych ma następującą postać: if <relacja logiczna 1> <instrukcja 1> eleseif <relacja logiczna 2> <instrukcja 2> else <instrukcja 3> end Polecenie elseif może powtarzać się wielokrotnie. Polecenie else może być użyte jednokrotnie lub być pominięte. Jeżeli relacja 1 zapisana za if jest prawdziwa, program wykonuje instrukcję 1 i po jej wykonaniu przechodzi do pierwszej instrukcji po end. W przeciwnym wypadku przechodzi do polecenia elseif i sprawdza zapisaną relację 2. Jeżeli jest ona prawdziwa, to wykonuje instrukcję 2 i po jej wykonaniu przechodzi do pierwszej instrukcji za end. Jeżeli relacja 2 nie jest prawdziwa, program wykonuje instrukcję 3 znajdującą się za poleceniem else i po jej wykonaniu przechodzi od instrukcji znajdującej się za end. Należy podkreślić, że instrukcje 1, 2 i 3 mogą składać się z całych, rozbudowanych fragmentów programu. Wykorzystując relację równości == można sprawdzać zgodność łańcuchów, pod warunkiem, że mają taką samą długość: a = kot if a=='kot' 'ssak' elseif a=='kos' 'ptak' end ans = ssak Poniżej podano przykład programu, który na żądanie użytkownika wyznacza wartości funkcji sin, cos, log, exp dla wektora x. Clear % usuwa wszystkie zmienne z przestrzeni roboczej x=1:5; 'Wpisz jedną z funkcji; sin, cos, log, exp.' % wyświetla napis ujęty w apostrofy f=input('f= '); % czeka na wpisanie funkcji if f=='sin' y=sin(x) elseif f=='cos' y=cos(x)

35 elseif f=='log' y=log10(x) else y=exp(x) end Po uruchomieniu programu mamy: ans = Wpisz jedną z funkcji; sin, cos, log, exp. f= 'sin' y = 0.8415 0.9093 0.1411-0.7568-0.9589 Należy zwrócić uwagę, że nazwy funkcji należy ująć w apostrofy. Po następnym uruchomieniu programu i wybraniu innej funkcji otrzymujemy: ans = Wpisz jedną z funkcji; sin, cos, log, exp. f= 'log' y = 0 0.3010 0.4771 0.6021 0.6990 3.4.5. Definiowanie funkcji Wszystkie funkcje występujące w programie MATLAB są zdefiniowane według reguł obowiązujących w tym programie. Część plików definiujących i realizujących funkcje można obejrzeć wpisując instrukcję: open <nazwa funkcji> Pliki te mają rozszerzenie.m. Pewna część funkcji, w tym np. wszystkie funkcje standardowe i podstawowe funkcje macierzowe, są funkcjami wbudowanymi i nie są dostępne dla użytkownika. Przykładowo pisząc komendę: open sin??? Error using ==> open Can't open the built-in function 'sin'. otrzymujemy powyższą informację. Programista może zdefiniować własną funkcję o nazwie nie występującej w zestawie funkcji programu MATLAB. Warto zadać sobie pytanie, czy i kiedy należy zdefiniować taką funkcję. Otóż należy najpierw stwierdzić wyraźnie, że każdy program można napisać bez konieczności definiowania własnych funkcji. Z kolei program można napisać tak, aby stanowił on określoną funkcję. Zwykle między tymi skrajnościami dokonujemy wyboru definiując fragmenty programu jako funkcję, a pozostawiając pozostałe części w formie zwykłego zbioru instrukcji. Ogólnie można powiedzieć, że funkcje tworzymy wówczas, gdy będziemy ich używać wielokrotnie w naszym programie lub chcemy je udostępnić dla innych programów. INFO Zasadnicza różnica między zwykłymi programami, a funkcjami polega na tym, że zmienne występujące w zwykłych programach są tzw. zmiennymi globalnymi, zaś występujące w funkcjach są zmiennymi lokalnymi. Zmienne globalne przechowywane są w pamięci dostępnej dla wszystkich uruchomionych programów. Jeżeli uruchomimy kolejno dwa programy, a w pierwszym z nich wystąpi

36 zmienna np. x, to w drugim programie można ją wykorzystać do obliczeń, zmienić jej wartość itp. Będzie ona dostępna dopóki programy nie zostaną zamknięte lub nie zostanie usunięta specjalną instrukcją. Przy długich programach może to być przyczyną błędów, gdyż można przypadkowo użyć tej samej nazwy do oznaczenia innych zmiennych. Często w jednym programie wykorzystuje się inne programy, które nie są zdefiniowane jako funkcje. Prawdopodobieństwo popełnienia opisanego błędu rośnie wtedy jeszcze bardziej. Zmienne lokalne występujące w funkcjach nie są widziane poza nimi. Można zatem używać w programie tych samych nazw zmiennych, które występują w pliku zawierającym funkcję. Jest to duże ułatwienie dla programisty. Aby funkcja nie była hermetycznie odcięta od innych programów, konieczne jest stworzenie mechanizmów wprowadzających dane do funkcji i umożliwiających pobieranie wyników. INFO Po tych ogólnych informacjach omówimy teraz podstawowe zasady tworzenia funkcji. Każdy plik definiujący funkcję musi na początku pierwszego wiersza zawierać deklarację function (program pisze ją automatycznie niebieskim kolorem), a następnie zapis funkcji. Oto prosty przykład definiowania funkcji liniowej y=ax+b: function u=prosta(v,m,n) u=m*v+n; Instrukcje te piszemy w nowym otwartym oknie skryptów (biała kartka na pasku narzędziowym). Następnie wciskamy przyciskamy File i wybieramy z listy poleceń Save As Do katalogu Work (lub własnego foldera w katalogu Work) wpisujemy nazwę pliku, która musi być identyczna jak nazwa funkcji. Plik zawierający funkcję prosta będzie zatem nosił nazwę: prosta.m. Zapiszmy teraz w oknie Command Window następujące dwie instrukcje: >> x=0:10; >> y=prosta(x,2,3) y = 3 5 7 9 11 13 15 17 19 21 23 Program zwrócił wartości funkcji y=2x+3. Zauważmy, że w powyższych instrukcjach użyto innych nazw zmiennych niż w definicji funkcji prosta. Nie ma to znaczenia, gdyż w zapisie funkcji liczą się wyłącznie pozycje zmiennych. Dla sprawdzenia czy zmienna v występująca w funkcji jest widoczna poza nią napiszmy: >> v??? Undefined function or variable 'v'. Widoczna jest natomiast zmienna globalna x: >> x x = 0 1 2 3 4 5 6 7 8 9 10 Można tworzyć funkcje, które mają kilka zmiennych, parametrów liczbowych lub łańcuchów. W podanym wyżej przykładzie mamy jedną zmienna i dwa parametry liczbowe. Funkcja może zwracać także pewną liczbę wyników zmiennych wyjściowych. Zapis funkcji jest wtedy bardziej złożony. Pokazuje to zamieszczony wyżej przykład funkcji liniowej, uzupełniony o wyznaczanie kąta nachylenia prostej. Funkcja realizująca te zadania ma następującą składnię: function [u,p]=prosta(v,m,n) u=m*v+n;

37 p=(180/pi)*atan(m) Jeżeli w oknie Command Window napiszmy następujące dwie instrukcje, to otrzymamy: >> x=0:10; >> [y,nachylenie]=prosta(x,2,3) y = 3 5 7 9 11 13 15 17 19 21 23 nachylenie = 63.4349 Nachylenie prostej wynosi 63.4 0. W podanych wyżej przykładach wpisywaliśmy w instrukcji używającej funkcji tę samą liczbę zmiennych, która występowała w definicji funkcji. W niektórych funkcjach nie ma nieraz potrzeby podawania wszystkich zmiennych występujących w instrukcji. Podobnie nie zachodzi także zawsze potrzeba zwracania wszystkich zmiennych wyjściowych. Wprowadzono dwie funkcje, które zwracają liczbę zmiennych wejściowych i wejściowych, co wykorzystuje się w programie funkcji. Liczbę zmiennych wejściowych podaje funkcja nargin, zaś liczbę zmiennych wyjściowych funkcja nargout. (od ang. number-arguments-out) Argumentami funkcji mogą być liczby, pojedyncze litery lub łańcuchy znaków. Jak to powiedziano wyżej użytkownik nie musi podawać wszystkich parametrów wejściowych i wymagać wszystkich wyników. W takich sytuacjach w zapisie definiowanej funkcji podajemy ogólne nazwy argumentów, a mianowicie varargin i varargout. Definicja funkcji ma wówczas następującą postać: function varargout=prosta(varargin) Częściej jednak stosuje się zapisy mieszane, np.: function [y,varargout]=prosta(x,varargin) Podane wyżej ogólne zapisy funkcji są używane przez zaawansowanych użytkowników Programu MATLAB. Dlatego ograniczamy się do zasygnalizowania ich istnienia, a zainteresowanych szczegółami odsyłamy do podanej literatury lub MATLAB Help. Jeżeli funkcja ma być dostępna tylko w tworzonym programie, można się posłużyć innym sposobem jej definiowania, a mianowicie funkcją inline. Instrukcja inline odnosi się wyłącznie do funkcji opisanych wyrażeniami matematycznymi zawierającymi operacje i funkcje istniejące w zbiorze programu MATLAB. Załóżmy, że chcemy zdefiniować funkcję f=xsinx. Funkcja ta nie występuje w zbiorze funkcji programu MATLAB, lecz zbudowana jest z funkcji standardowych. Definiujemy ją jako: >> f=inline('x.*sin(x)') f = Inline function: f(x) = x.*sin(x) Zauważmy, że formuła funkcji zapisana jest jako łańcuch. Zauważmy także, że w zapisie funkcji obowiązują reguły wynikające z traktowania zmiennych jako macierzy. Dlatego znak mnożenia poprzedzono kropką, gdyż bez niej znak mnożenia interpretowany byłby jako mnożenie macierzy. Jeżeli z góry zakładamy, że x będzie wyłącznie liczbą, znak kropki nie jest potrzebny. Po zdefiniowaniu funkcji f=f(x) możemy wyznaczać jej wartości dla dowolnej liczby x lub dla wektora x. Przykładowo:

38 >> f(pi/2) ans = 1.5708 >> x=[1 2 3 4]; >> f(x) ans = 0.8415 1.8186 0.4234-3.0272 Instrukcją inline można definiować funkcje wielu zmiennych, np. f=x 2 +y 2 Odpowiednia instrukcja ma następującą postać >> f=inline( x.^2+y.^2 ) Program zwraca zapis funkcji: f = Inline function: f(x,y) = x.^2+y.^2 Zapis ten nie jest edytowany, jeżeli po definicji wstawimy średnik. Może się wydawać, że nie ma różnicy między definiowaniem funkcji instrukcją inline, a bezpośrednim zapisem wyrażenia matematycznego. Są to jednak pozory, gdyż różnice są bardzo istotne. Pokażemy je na następującym przykładzie. Załóżmy, że w tej samej linii pewnego programu piszemy najpierw >> f=inline( x.^2+y.^2 ) f = Inline function: f(x,y) = x.^2+y.^2 Jak widać program zaakceptował tę instrukcję, mimo, że wartości x i y są nieokreślone. Napiszmy teraz >> f=x.^2+y.^2??? Undefined function or variable 'x'. Program odrzuca powyższą instrukcję i podaje tego przyczynę: nie jest określona wartość zmiennej x. Zapis funkcji byłby prawidłowy, gdyby został poprzedzony podaniem wartości x i y. Wynikiem byłaby liczba lub ciąg liczb, będących wartościami funkcji f dla podanych wcześniej wartości x i y. Wartości funkcji f zdefiniowanej instrukcją inline można wyznaczyć w dowolnej linii programu po definicji. 3.5.5. Pętle Pętle używane są do wielokrotnego powtarzania określonych obliczeń lub mówiąc ogólniej poleceń. Przykładowa, prosta pętla ma następującą formę: >> for n=1:10 y(n)=n^2; end Każda pętla rozpoczyna się poleceniem for i kończy poleceniem end. Dla wyróżnienia od innych poleceń program MATLAB zapisuje je kolorem niebieskim. Zapis pętli należy rozumieć następująco: dla każdej liczby naturalnej n od 1 do 10 wykonaj działanie zapisane wzorem umieszczonym niżej, przed poleceniem end. W naszym przykładzie polecenie polega na podniesieniu do kwadratu kolejnych liczb naturalnych i utworzeniu z nich wektora y. Wektor ten jest zapisany w pamięci i może być edytowany poza pętlą:

39 >> y y = 1 4 9 16 25 36 49 64 81 100 Jak wiemy, zapis n=1:10 generuje wektor liczb naturalnych. W pętlach można definiować inne wektory, których elementy tworzą ciągi monotoniczne. Zmienna n nie może być wtedy używana do wytwarzania wektorów lub macierzy, gdy ich elementy oznaczane są wyłącznie liczbami naturalnymi. Można temu zaradzić w sposób pokazany w następującym przykładzie: >> for x=-5:0.5:5 % elementy wektora x nie są liczbami naturalnymi n=2*x+11; % tworzone n jest liczbą naturalną y(n)=x^2; end >> y y = Columns 1 through 7 25.0000 20.2500 16.0000 12.2500 9.0000 6.2500 4.0000 Columns 8 through 14 2.2500 1.0000 0.2500 0 0.2500 1.0000 2.2500 Columns 15 through 21 4.0000 6.2500 9.0000 12.2500 16.0000 20.2500 25.0000 Alternatywnym rozwiązaniem są następujące instrukcje: >> for n=1:11 % tu n jest liczbą naturalną x=-5+(n-1)/2; % x jest wyrażone przez n aby wartości były zgodne z zapisem wyżej y(n)=x^2; end Zapisując pętlę należy zawsze pamiętać o stawianiu średników po każdej instrukcji. Skutki nie zastosowania się do tej rady pokazuje wykonanie obliczeń w pierwszej z podanych pętli, gdy pominiemy średnik: >> for n=1:10 y(n)=n^2 end y = 1 y = 1 4 y = 1 4 9 y = 1 4 9 16 y = 1 4 9 16 25 y = 1 4 9 16 25 36 y = 1 4 9 16 25 36 49 y = 1 4 9 16 25 36 49 64 y = 1 4 9 16 25 36 49 64 81 y = 1 4 9 16 25 36 49 64 81 100 Program zwraca kolejno budowane wektory, co jest nie tylko zbędne, lecz dodatkowo zajmuje wiele czasu.

40 Powyższy przykład ilustruje ponadto mechanizm obliczeń w pętli. W każdym cyklu tworzony jest nowy wektor o coraz to większej długości. Wymaga to wykonania szeregu operacji, które zajmują dużo czasu, nawet, gdy pośrednie wyniki nie są edytowane. Dlatego obliczenia w pętlach wykonywane są względnie długo. Jeżeli jest to tylko możliwe staramy się unikać obliczeń w pętlach i zastąpić je obliczeniami macierzowymi. Przykładowo ostatnią pętle można i należy zastąpić następującymi instrukcjami: >> n=1:10; >> y=n.^2 y = 1 4 9 16 25 36 49 64 81 100 Jeżeli zastosowania pętli nie można uniknąć wówczas przed pętlą należy zdefiniować najprostszą macierz lub wektor, w których będziemy zapisywać wyniki obliczeń w pętli. Wymiary macierzy bądź wektora muszą być zgodne z liczbą wyników w pętli. Rozpatrywany wyżej przykład powinien być zgodnie z tym zapisany jako: >> y=zeros(1,10); >> for n=1:10 y(n)=n^2; end Mechanizm działania programu jest wówczas odmienny, co ilustruje przykład wykonywania obliczeń w tej pętli (pominięto średnik). >> y=zeros(1,10); >> for n=1:10 y(n)=n^2 end y = 1 0 0 0 0 0 0 0 0 0 y = 1 4 0 0 0 0 0 0 0 0 y = 1 4 9 0 0 0 0 0 0 0 y = 1 4 9 16 0 0 0 0 0 0 y = 1 4 9 16 25 0 0 0 0 0 y = 1 4 9 16 25 36 0 0 0 0 y = 1 4 9 16 25 36 49 0 0 0 y = 1 4 9 16 25 36 49 64 0 0 y = 1 4 9 16 25 36 49 64 81 0 y = 1 4 9 16 25 36 49 64 81 100 Program wpisuje do istniejącego obszaru pamięci kolejne wyniki obliczeń, a nie tworzy coraz to nowe obszary, jak to miało miejsce w poprzedniej wersji pętli. Czas potrzebny na wpisywanie danych do określonego obszaru pamięci jest znacznie krótszy. Oczywiście różnice w czasie wykonywania obu wersji pętli przy tak małej liczbie operacji są niezauważalne. Cierpliwy Czytelnik może osobiście przekonać się o sensowności tych wskazówek zmieniając liczbę 10 na 10000 i pisząc różne wersje zamieszczonych wyżej programów. Odmianą opisanych pętli jest pętla rozpoczynająca się poleceniem while (dopóki). Struktura takiej pętli jest podobna do poprzedniej, a mianowicie:

41 >> while <relacja logiczna> <instrukcja> end Pętla ta nie ma określonej liczby cykli i instrukcja wykonuje się dopóki relacja logiczna jest spełniona. Oto przykład wyznaczania kolejnych liczb naturalnych: >> y=0; >> while y<3 y=y+1 end y = 1 y = 2 y = 3 W pierwszym wierszu zadeklarowana jest wartość początkowa. W drugim wierszu sprawdzana jest relacja logiczna y<3. Relacja ta jest prawdziwa, dla y=0,1,2. W trzecim wierszu zwiększana jest zmienna y o 1. W pierwszym cyklu mamy y=0+1=1, w drugim y=1+1=2 a w trzecim y=2+1=3. Pętla przestaje działać, gdyż y<3 nie jest prawdziwe. Poniżej podano przykład prostego programu do wyznaczania wartości x, przy której funkcja sinπx przyjmuje wartość maksymalną. Dokładność wyniku wynosi 0.00001. >> d=0; x=0; >> while d>=0 d=sin(pi*(x+0.00001))-sin(pi*x); x=x+0.00001; end >> x x = 0.5000 Takie samo zadanie może być wykonane przez inną pętlę z wykorzystaniem polecenia break. Polecenie to kończy obliczenia w pętli przed ich zakończeniem wskazanym w instrukcji obok for. Polecenie break powinno być poprzedzone instrukcją warunkową. >> for x=0:0.00001:1 d=sin(pi*(x+0.00001))-sin(pi*x); if d<=0 break end end >> x x = 0.5000 Pętle są używane do tworzenia wektorów, co już pokazano, a również do budowania macierzy i tablic wielowymiarowych. Takie pętle zawierają pętle zewnętrzne i wewnętrzne. Struktura takiej złożonej pętli jest następująca: for m=1:m <instrukcja> for n=1:n <instrukcja> end end

42 Instrukcja w zewnętrznej linii pętli jest opcjonalna. Prosty przykład pętli generującej macierz pokazuje następujący przykład: >> y=zeros(5,6); >> for m=1:5 x=m^2; for n=1:6 Y(m,n)=x*log10(n); end end >> Y Y = 0 0.3010 0.4771 0.6021 0.6990 0.7782 0 1.2041 1.9085 2.4082 2.7959 3.1126 0 2.7093 4.2941 5.4185 6.2907 7.0034 0 4.8165 7.6339 9.6330 11.1835 12.4504 0 7.5257 11.9280 15.0515 17.4743 19.4538 Program ten wyznacza macierz o elementach Y(m,n)=m 2 log(n). Zauważmy, że pętla została poprzedzona wytworzeniem macierzy zerowej o liczbie wierszy i kolumn, które są zgodne z liczbą cykli w pętli. Jak to podkreślano wcześniej, zapewnia to znaczne przyspieszenie obliczeń. Wątpliwości może budzić instrukcja w drugiej linii pętli. Na pierwszy rzut oka wydaje się ona zbędna, gdyż może być zastąpiona instrukcją w pętli wewnętrznej. Program dający te same wyniki miałby wtedy następujący zapis: >> for m=1:5 for n=1:6 Y(m,n)=m^2*log10(n); end end Z punktu widzenia liczby operacji, tą druga wersja jest jednak gorsza. W pierwszej wersji program wykonuje tylko 5 operacji podnoszenia liczby do potęgi 2, zaś w drugiej wersji 30 takich operacji. Przy tak małej liczbie operacji nie ma to oczywiście praktycznego znaczenia, lecz przy dużych wymiarach macierzy i złożonych operacjach różnica może być duża. Należy zatem budować pętle tak, aby minimalizować liczbę operacji. Jak już wspomniano należy unikać stosowania macierzy, gdyż program MATLAB jest zoptymalizowany pod katem obliczeń macierzowych. Przykładowo, pokazywana wyżej pętla może być zastąpiona następującymi obliczeniami macierzowymi: >> m=1:5; >> a=m.^2; >> n=1:6; >> b=log10(n); >> y=a *b 0 0.3010 0.4771 0.6021 0.6990 0.7782 0 1.2041 1.9085 2.4082 2.7959 3.1126 0 2.7093 4.2941 5.4185 6.2907 7.0034 0 4.8165 7.6339 9.6330 11.1835 12.4504 0 7.5257 11.9280 15.0515 17.4743 19.4538 Pętle mogą być wykorzystywane do budowania tablic wielowymiarowych. Przykład tworzenia tablicy trójwymiarowej ilustruje następujący przykład: >> zeros(4,5,3) >> for m=1:4 for n=1:5 for k=1:3 Y(m,n,k)=n+m+k; end

43 end end >> y Y(:,:,1) = 3 4 5 6 7 4 5 6 7 8 5 6 7 8 9 6 7 8 9 10 Y(:,:,2) = 4 5 6 7 8 5 6 7 8 9 6 7 8 9 10 7 8 9 10 11 Y(:,:,3) = 5 6 7 8 9 6 7 8 9 10 7 8 9 10 11 8 9 10 11 12 Tablica Y składa się z 3 macierzy o wymiarach 3x5. Wartość elementy tablicy jest sumą numeru wiersza, kolumny i macierzy, co widoczne jest w podanym wyżej wydruku tablicy. Z tablicy można utworzyć różne macierze po to, aby na nich wykonywać potrzebne operacje. Mamy np. >> A=Y(:,:,2) A = 4 5 6 7 8 5 6 7 8 9 6 7 8 9 10 7 8 9 10 11 Macierz A jest macierzą o wymiarach: >> size(a) ans = 4 5 Niestety utworzenie macierzy, w której występują wiersze lub kolumny ze wszystkich K tablic stwarza pewien problem. Pisząc bowiem: >> B=Y(2,:,:) B(:,:,1) = 4 5 6 7 8 B(:,:,2) = 5 6 7 8 9 B(:,:,3) = 6 7 8 9 10 otrzymujemy nadal tablicę o wymiarach size(b) ans = 1 5 3 Na tablicy B nie można wykonywać poznanych już operacji macierzowych. Zachodzi więc potrzeba przekształcenia takiej tablicy w macierz. Można to uczynić wykorzystując następującą pętlę: >> B=zeros(3,5); >> for m=1:3 for n=1:5 B(m,n)=y(2,n,m); end

44 end >> B B = 4 5 6 7 8 5 6 7 8 9 6 7 8 9 10 Rzeczywiście otrzymaliśmy macierz, gdyż >> size(b) ans = 3 5 Można do tego celu wykorzystać również funkcję reshape, która przekształca tablicę w macierz o odpowiednich wymiarach. Składnię tej funkcji pokazuje przykład: >> B=reshape(Y(2,:,:),3,5) B = 4 7 6 9 8 5 8 7 6 9 6 5 8 7 10 a sprawdzamy jej skuteczność pisząc: >> size(b) ans = 3 5

45 4. GRAFIKA 4.1. Grafika dwuwymiarowa 4.1.1. Podstawowe funkcje graficzne Z punktu widzenia obliczeń inżynierskich użyteczne jest szczególnie przedstawianie w formie graficznej funkcji, wyników obliczeń i symulacji. Na ogół wystarcza do tego celu posługiwanie się dwuwymiarowym układem współrzędny prostokątnych lub biegunowych. W układach tych mogą być przedstawiane funkcje typu y=f(x) oraz płaskie figury geometryczne. W programie MATLAB mają one zwykle formę dwóch wektorów o równej długości, z których jeden zawiera dyskretne wartości zmiennej niezależnej x, a drugi dyskretne wartości zmiennej zależnej y. Zajmiemy się najpierw graficzną reprezentacją tak rozumianych funkcji. Do wykonywania wykresów we współrzędnych prostokątnych służą funkcję graficzne, których podstawowy format jest następujący: funkcja_graficzna(x,y,<parametry>) Funkcja graficzna otwiera okno, w którym pojawi się wykres określony wektorem x, wektorem y oraz parametrami. Parametry są opcjonalne i przy ich braku wykres wykonywany jest przy parametrach domyślnych. Parametry umożliwiają wybór koloru wykresu, rodzaju linii lub znaczników, z których jest wykonany. Lista tych parametrów jest długa i można je znaleźć pisząc help plot. Przykładowy zapis funkcji graficznej wygląda następująco: plot(x,y, k*-- ); gdzie parametry oznaczają: k czarny kolor linii, * oznaczenie punktów wykresu gwiazdką, -- wykres wykonany linią kreskową. Format funkcji graficznych może być bardziej rozbudowany, ale ograniczymy się w tym miejscu do formatu podstawowego. Wektor wyznacza punkty na osi poziomej, którym przyporządkowane są elementy wektora y. Inaczej mówiąc element wektora x(n) określa współrzędną x, a element y(n) współrzędną y punktu, przez którą przechodzi wykres. Charakterystyczną cechą grafiki programu MATLAB jest to, że elementy wektora x nie muszą być rozmieszczone równomiernie, a nawet nie muszą stanowić ciągu monotonicznego (rosnącego lub malejącego). Pominięcie w zapisie funkcji graficznej wektora x powoduje, że skalą x będzie ciąg liczb naturalnych od 1 do N, gdzie N jest długością wektora y. Jeżeli nie użyjemy specjalnych, dodatkowych funkcji graficznych, to zakres osi X i Y program dobiera automatycznie. Program MATLAB oferuje następujące funkcje graficzne, których efektem jest wykonanie wykresu. Są to: plot wykonuje wykresy linią łamaną, przerywaną lub znacznikami, a linia ta przechodzi prze punkty wyznaczone przez wektory x i y stem wykonuje wykresy w formie próbek stairs wykonuje wykresy w formie schodkowej bar wykonuje wykresy w postaci słupków polar sporządza wykresy we współrzędnych biegunowych Ograniczymy się tu do opisu funkcji plot, stem i polar, gdyż pozostałe mają mniejsze znaczenie w zastosowaniach inżynierskich.

46 Funkcja plot jest używana głównie do prezentacji graficznej funkcji ciągłych, chociaż z konieczności są to w programie numerycznym funkcje dyskretne. Przykładowo, funkcja sinus jest funkcją ciągłą, lecz program MATLAB wyznacza jej wartości w skończonej liczbie punktów i na wykresie łączy je odcinkami linii prostej. Przy malej liczbie punktów wykres jest widoczny jako linia łamana, co fałszuje rzeczywisty przebieg funkcji. Zwiększając liczbę punktów i zagęszczając je uzyskujemy pożądany efekt ciągłości, czyli zbliżamy obraz graficznych do rzeczywistego przebiegu funkcji. Ilustruje to przykład pokazany na rys. 4.1. Rys. 4.1. Wykresy funkcji sinus przy rożnej gęstości punktów zmiennej niezależnej, sporządzony przez funkcję plot. Funkcji stem używamy do prezentacji graficznej funkcji dyskretnych, zwłaszcza wtedy gdy chcemy uwypuklić ich dyskretny charakter. Jeżeli przykładowo analizujemy lub symulujemy system cyfrowy wykorzystujący próbki sygnałów, to dobrze jest zaznaczyć graficznie, że wyniki mają postać dyskretną, a zatem są dostępne tylko w ograniczonej liczbie punktów zmiennej niezależnej (np. czasu). Przebieg funkcji sinus przedstawiony przy użyciu funkcji stem ma postać przedstawioną na rys. 4.2. Rys. 4.2. Wykres funkcji w formie próbek wykonany przy użyciu funkcji stem.

47 Funkcję polar stosujemy wtedy, gdy chcemy zaprezentować graficznie funkcję, której zmienną niezależną jest kąt. Na rys. 4.3. pokazano wykres funkcji sin(3x)/(3x), gdzie x jest kątem wyrażonym w radianach. Rys. 4.3. Wykres funkcji we współrzędnych biegunowych wykonany przez funkcję polar. Na jednym rysunku można zamieścić większa liczbę krzywych używając następującego formatu funkcji plot: plot(x,y,<parametry>,u,v,<parametry>, ) Zmienne (x,y), (u,v) i dalsze opisują parami kolejne krzywe umieszczone na wykresie. Za każdą parą zmiennych można wpisać (opcjonalnie) łańcuch znaków określających parametry danej krzywej, np. g+-, co oznacza krzywą narysowaną linią ciągłą w kolorze zielonym z punktami zaznaczonymi plusem. Jeżeli zmienna y jest zespolona, to zapis plot(y) powoduje rysowanie krzywej plot(real(y),imag(y)), czyli na osi poziomej umieszczane są współrzędne części rzeczywistej liczby zespolonej y, zaś na osi pionowej współrzędne części urojonej liczby zespolonej z. Jest to klasyczny sposób prezentacji graficznej liczb zespolonych. Każdy inny zapis funkcji plot, np. plot(x,y), gdzie y jest liczbą zespoloną powoduje pominięcie części urojonych i wykonywany jest wykres plot(x,real(y)). Wykonany rysunek chcemy najczęściej przechować w pamięci. W tym celu w oknie Figure No. 1 (lub o wyższym numerze) otwieramy menu File i wybieramy w nim Save As... Powoduje to otwarcie okna, które umożliwia zapisanie rysunku w pożądanym folderze i nadanie mu nazwy. Rysunek wykonany w programie MATLAB można skopiować do innego programu, np. do jednego programu z zestawu Microsoft Office. W tym celu w oknie rysunku wybieramy Edit i z wywołanego menu Copy Figure. Możliwe jest również wybranie sposobu kopiowania rysunku. W menu Edit wybieramy wówczas polecenie Copy Options, co powoduje rozwinięcie okna Preferenses. W oknie tym należy wybrać Figure Copy Template i w oknie Figure Copy Template Preferenses wybrać program, do którego będą kopiowane rysunki, a następnie ustawić pożądane parametry. Po rozwiniecie menu Figure Copy Template pojawi się menu Copy Options. W tym oknie wybieramy metodę kopiowania np. Bitmap oraz kolor tła rysunku, np. Force White Background. Czynności te kończymy wciskając przycisk Apply. Podaną wyżej procedurę wykonuje się jednokrotnie i powtarza tylko wtedy, gdy chcemy zmienić jakieś parametry rysowania i kopiowania.

48 Po instrukcji Copy Figure rysunek znajduje się w schowku i jest dostępny w innych programach. Np. programie Microsoft Word można go umieścić w dokumencie rozwijając menu Edycja, wybierając Wklej specjalnie... i przykładowo Mapa bitowa. (Nie należy przejmować się zbytnio informacją, że rysunek jako mapa bitowa zajmuje dużo miejsca w pamięci, gdy program Microsoft Word dokonuje samoczynnie kompresji danych potrzebnych do odtworzenia rysunku). Aktywne okno rysunku zamyka się poleceniem close. Wszystkie otwarte okna zamyka instrukcja close all. Instrukcje tę warto umieścić na początku programu aby rysunki nie pojawiały się we wcześniej otwartych oknach rysunkowych oraz żeby nie mnożyć otwartych okien rysunkowych przy kolejnych uruchomieniach programu. 4.1.2. Funkcje formatujące rysunek Ograniczenie się do napisania w programie samej podstawowej funkcji graficznej (np. plot) powoduje otwarcie okna z rysunkiem, lecz forma rysunku może odbiegać od naszych oczekiwań. Na rysunku ma bowiem naniesioną tylko skalę, a brakuje takich podstawowych danych jak nazwy zmiennych lub tytułu rysunku. Zakres zmiennych, który został dobrany automatycznie może nam również nie odpowiadać. Program MATLAB dysponuje szeregiem funkcji, które umożliwiają wprowadzenie wspomnianych danych i wykonanie różnorodnych manipulacji formatujących rysunek. Funkcje te są zapisywane w programie i realizują odpowiednie operacje graficzne po każdorazowym uruchomieniu programu. Jeżeli naszym celem jest jednorazowe wykonanie rysunku, to możemy odpowiednie operacje wykonać bez wpisywania instrukcji w program, lecz posługując się odpowiednimi oknami przeznaczonymi do wyboru funkcji i ich parametrów. Możliwe jest również stosowanie mieszanej techniki: ustawianie podstawowych parametrów rysunku za pomocą instrukcji i wprowadzanie dodatkowych zmian przy użyciu specjalnych okien. W pierwszej fazie poznawania program MATLAB preferowana jest technika mieszana, gdyż liczba i struktura wszystkich potrzebnych funkcji graficznych jest trudna do opanowania. Zważywszy na cel tego skryptu ograniczymy się do omówienia kilku najczęściej stosowanych funkcji oraz zaprezentujemy uproszczony sposób modyfikacji rysunków za pomocą okien. Rysunkowi nadajmy tytuł używając instrukcji: title( nazwa rysunku ) Instrukcję tę zamieszczamy za instrukcją plot, stem itp. Tekst ujęty w apostrofy pojawia się nad rysunkiem. Zakres osi poziomej X i osi pionowej Y dobieramy używając następującej instrukcji: axis([xmin Xmax Ymin Ymax]) gdzie Xmin jest liczbą określającą punkt przecięcia osi X z osią Y, Xmax jest maksymalną wartością na osi X, Ymin jest liczbą określającą punkt przecięcia osi Y z osią X, zaś Ymax jest maksymalną wartością na osi Y. Wpisując w oknie Command Window instrukcję help axis można znaleźć wykaz poleceń związanych z ustawieniem osi wykresu. Funkcja xlabel służy do opisu osi X. Ma ona następującą formę: xlabel( nazwa zmiennej ) W analogiczny sposób opisujemy oś Y: ylabel( nazwa zmiennej )

49 Jeżeli na rysunku znajduje się większa liczba krzywych narysowanych różnym rodzajem linii lub różnym kolorem, wówczas przydatna jest legenda opisująca poszczególne krzywe. Wykorzystuje się do tego celu następującą funkcję: legend( nazwa pierwszej krzywej, nazwa drugiej krzywej,,p) gdzie p jest liczbą od -1 do 4 określającą położenie legendy na rysunku (domyślnie ustawione jest 0, które umieszcza legendę w prawym górnym rogu). Do opisu krzywych służy instrukcja funkcja text, której argumentami są pozycja tekstu i łańcuch zawierający tekst: text(xt,yt, tekst ) Współrzędne xt,yt odnoszą się do skal występujących na rysunku. Kilkukrotne użycie funkcji text umożliwia naniesienie na rysunku w różnych miejscach dowolnych tekstów (najczęściej opisów krzywych). Przy dużym zakresie zmiennych wygodnie jest sporządzać wykresy w skali logarytmicznej. Służą do tego celu trzy funkcje, którymi zastępujemy funkcję plot zachowując w pełni jej format. Są to: loglog( ) obie osi w skali logarytmicznej o odstawie 10, semilogx( ) oś X w skali logarytmicznej, oś Y w skali liniowej semilogy( ) oś X w skali liniowej, oś Y w skali logarytmicznej. Polecenie grid powoduje pojawienie się na rysunku siatki. Linie siatki występują w punktach osi X i Y, które są opisane liczbami. Polecenie grid minor zagęszcza siatkę, a grid off powoduje jej zniknięcie. 4.1.3. Tworzenie wielu rysunków Wyniki obliczeń rzadko kiedy mogą być pokazane na jednym rysunku. Zachodzi zatem potrzeba przy pisaniu programu stosowania instrukcji umożliwiających tworzenie kilku rysunków. Możliwe są trze sytuacje: umieszczanie wykresów na oddzielnych rysunkach umieszczanie na wspólnym rysunku kilku wykresów z zachowaniem wspólnego układu współrzędnych umieszczanie na jednym rysunku kilku układów współrzędnych Pierwsza, najprostsza sytuacja, to tworzenie kilku oddzielnych rysunków. Nowy rysunek powstaje w nowym oknie po wpisaniu polecenia figure. Przykładowy ciąg instrukcji powodujących sporządzenie dwóch rysunków wygląda następująco: plot(x,y,<parametry>) title( pierwszy rysunek ); axis([...]); xlabel( X ); ylabel( Y ); <instrukcje> figure stem(u,v,<parametry>) title( drugi rysunek ); axis([...]); xlabel( U ); ylabel( V );

50 Funkcja plot otwiera pierwsze okno rysunkowe i łącznie z kolejnymi funkcjami powoduje wykonanie pożądanego wykresu. Polecenie figure otwiera drugie okno i w nim sporządzany jest rysunek według funkcji stem (lub innej) i dodatkowych, znajdujących się poniżej instrukcji. W ten sam sposób można otwierać kolejne okna rysunkowe, które otrzymują kolejne numery. Jeżeli funkcja plot, stem lub inne tego typu nie są poprzedzone poleceniem figure, to rysunek będzie wykonany w ostatnim otwartym oknie. Poprzedni rysunek będzie automatycznie usunięty. Kolejnym rysunkom należy przypisać nazwę, jeżeli chcemy je zapamiętać. Sposób zapamiętywania rysunków podano wyżej. Pierwszy sposób umieszczania na wspólnym rysunku kilku krzywych polega na omówionym wyżej wykorzystaniu funkcji plot z wieloma argumentami. Druga metoda wykorzystuje polecenie hold on. Umieszczenie tego polecenia w programie (lub w oknie Command Window) po pojawieniu się okna rysunkowego powoduje, że kolejne rysunki będą nakładane na istniejący. Oto przykład krótkiego programu rysującego dwie funkcje zmiennej zespolonej, a mianowicie y=exp(j2x) oraz z=xexp(j2x). x=0:0.001:1; y=exp(i*2*pi*x); plot(y,'k') axis square title('funkcje zmiennej zespolonej') xlabel('re');ylabel('im') set(gcf,'color','white') grid z=x.*y; hold on plot(z,'k:') legend('y','z') Po uruchomieniu programu otrzymujemy wykresy pokazane na rys. 4.4. Rys. 4.4. Wykresy funkcji zmiennej zespolonej. W przedstawionym wyżej programie występują dwie instrukcje, których dotąd nie omawialiśmy. Instrukcja axis square zamienia zwykły format rysunku na kwadratowy. W zwykłym formacie skale osi X i Y są różne, w wyniku czego figury geometryczne ulegają zniekształceniu. Aby tego uniknąć i pokazać, że funkcja exp(jx) ma kształt okręgu, wyrównano skale obu osi.

51 Funkcja set( ) zmieniła tło obrzeża rysunku na biały; domyślnie jest obrzeże ma kolor szary, co w tekście nie jest raczej korzystne. Funkcja set ma szerokie zastosowanie w grafice programy MATLAB i jej omówieniem zajmiemy się w dalszej części skryptu. W jednym rysunku można umieścić kilka układów współrzędnych i wykreślić w każdym z tych układów pewną liczbę krzywych. Służy do tego celu funkcja subplot, która w podstawowym formacie ma trzy parametry: subplot(m,n,p). Parametr m wskazuje, w ilu wierszach maja być utworzone rysunku, a parametr n w ilu kolumnach. Liczba pól przeznaczonych na rysunki wynosi zatem m n. Nie w każdym polu musi być zamieszczony rysunek. Parametr p wskazuje, w którym polu ma znajdować się określony rysunek. Rysunki są wykonywane według zasad obowiązujących dla pojedynczego rysunku. Wybierając liczbę rysunków należy pamiętać, że ze zwiększaniem tej liczby maleje powierzchnia przeznaczona na każdy z rysunków, co czyni je mniej czytelnymi. Poniżej przedstawiono program sporządzający trzy rysunki w jednym oknie figure. x=2*pi*(0:0.001:1); ys=sin(x); subplot(2,2,1); plot(x,ys) title('sinus');xlabel('x');ylabel('ys') axis([0 2*pi -1 1]) yc=cos(x); subplot(2,2,2); plot(x,yc) title('cosinus');xlabel('x');ylabel('yc'); axis([0 2*pi -1 1]) yt=tan(x); subplot(2,2,3); plot(x,yt) title('tangens');xlabel('x');ylabel('yt') axis([0 2*pi -10 10]) Powyższy programu sporządza rysunek pokazany na rys. 4.5. Rys. 4.5. Trzy wykresy funkcji umieszczone na jednym rysunku przy użyciu funkcji subplot.

52 Pola rysunkowe znajdują się w dwóch rzędach i dwóch kolumnach. Wykorzystano z nich trzy pola i umieszczono w nich trzy wykresy funkcji trygonometrycznych. Czwarty rysunek można umieścić pisząc następującą instrukcję: subplot(2,2,4);plot( ) 4.1.4. Dobór parametrów rysunku bez użycia instrukcji graficznych Wspomniano już, że parametry rysunku można dobierać używając instrukcji zapisanych programie, lub posługując się oknami rozwijanymi w wyniku wybraniu odpowiednich etykiet z paska narzędziowego rysunku. Powtórzmy, że to drugie rozwiązanie, chociaż prostsze, powinno być stosowane do formatowania pojedynczych, nie powtarzających się rysunków. Jeżeli w wyniku wykonania instrukcji plot, stem itp. pojawi się rysunek, którego wygląd nie jest zadawalający, wówczas z paska narzędziowego tego rysunku wybieramy Edit i pojawia się okno zawierające m.in. trzy ważne etykiety, a mianowicie: Figure Properties..., Axes Properties..., Current Object Properties... Po wybraniu Figure Properties pojawia się okno Property Editor- Figure. W pierwszym okienku Edit Properties for: widoczny jest tekst figure: 1 (lub inny numer otwartego rysunku). Znajdujące się niżej okienka służą do ustawienia parametrów odnoszących się do całego rysunku. Zazwyczaj ograniczamy się do zmiany koloru tła i nadania oknu nazwy. Nazwę wpisujemy w okno Window Name:. Nie będzie ona widoczna nigdzie poza oknem rysunkowym i paskiem zadań w programie Windows (wpisuje się ją wyłącznie dla wygody programisty). Kolor tła wybieramy po rozwinięciu okna Color (najczęściej wybieramy White). Po rozwinięciu okna Edit Properties for: pojawia się lista obiektów, z których zbudowany jest rysunek. Im bardziej skomplikowany jest rysunek, tym obiektów jest więcej. Co najmniej są to dwa obiekty: axes: i line:. Obiekt axes dotyczy osi współrzędnych, zaś obiekt line linii wykresu. Jeżeli na rysunku występuję większa liczba osi współrzędnych (co jest możliwe, lecz rzadko stosowane), lub większa liczba linii wykresów, to są one kolejno ponumerowane. Wybranie obiektu axes powoduje otwarcie okna z nagłówkiem Property Editor Axes. które pokazano na rys. 4.6. Takie samo okno pojawia się po wybraniu z menu Axes Properties Korzystając z tego okna można ustawić wszystkie pożądane parametry rysunku związane z układem współrzędnych. Wybierając kolejni X, Y, a w rysunkach trójwymiarowych również Z wpisuje my nazwę zmiennej x (Label:) i dobieramy w razie potrzeby właściwe parametry tego podpisu otwierając okno Properties... W oknie tym, posiadającym nagłówek Property Editor Text można zmienić wysokość czcionki, jej grubości, styl a także położenie oznaczenia osi X. Położenie zmieniamy w okienku Position: Domyślnie oznaczenie osi Y występuje w środku tej osi i jest napisane w kierunku pionowy. Można to zmienić wykorzystując okienko Rotation: i wybierając w nim 0.0 i następnie przesuwając oznaczenie do góry i ewentualnie w bok w okienku Position... W okienku Limits: po usunięciu oznaczenia Auto uzyskujemy możliwość wpisania zakresu osi X. Jest to równoważne instrukcji axis([xmin X max...]). W okienku Ticks: w trybie ręcznym można wpisywać położenie znaczników na osi X, zaś w okienku Labels: oznaczenia znaczników. W omawianym oknie można także ustawić pożądaną skalę wykresu, co odpowiada instrukcjom semilogx, loglog itp. Jeżeli w oknie Property Editor- Figure w górnym okienku wybierzemy line:, wówczas pojawia się okno Property Edition Line, pokazane na rys. 4.7.

53 Rys. 4.6. Okno do ustawiania parametrów osi rysunku. Rys. 4.7. Okno do ustawiania parametrów linii.

54 W oknie tym istotne znacznie ma rozwinięcie etykiety Style, widoczne na rysunku. Dobieramy w nim styl linii, jej grubość i kolor. Linie można uzupełnić znacznikami (Marker Properties), których lista znajduje się w okienku Style: Po wybraniu znacznika dobieramy jego rozmiar (Size:), kolor obramowania (Edge color:) oraz kolor wypełnienia (Face color:). Efekty wyboru pokazywane są automatycznie w okienku Example. Jeżeli na rysunku zaznaczymy lewym klawiszem myszy najpierw strzałkę w na pasku narzędziowym, a potem wybrany obiekt (np. linię wykresu) i wybierzemy z menu Edit polecenie Current Object Properties..., to otworzy się odpowiednie okno dotyczące tego obiektu. Są to te same okna, które omówiliśmy wyżej. Inny sposób zmieniania właściwości rysunku polega na użyciu myszki. Jeżeli po naprowadzeniu wskaźnika myszki wciśniemy jej lewy klawisz, to wybrany obiekt zostanie zaznaczony. Po wciśnięciu prawego klawisza pojawia się okienko z listą funkcji i parametrów właściwych dla danego obiektu. Wybranie Properties... powoduje otwarcie stosownego okna i dalsze postępowanie nie różni się od opisanego wyżej. Dodatkowo z okna można wybrać: Cut usuwa wszystkie elementy rysunku i przechowuje je w schowku, z którego mogą być odtworzone po wciśnięciu Paste Copy zachowuje element w schowku w celu jego ponownego użycia Paste umieszcza element znajdujący się w schowku na rysunku Clear usuwa zaznaczony obiekt z rysunku W zależności od rodzaju zaznaczonego obiektu w oknie pojawia się lista parametrów, których wartości można zmieniać z pominięciem okna otwieranego przez Properties. Np. w wypadku linii można zmieniać jej grubość, styl i kolor. W pasku narzędziowym znajduje się ikona oznaczona jako A, która służy do pisania tekstu na rysunku. Po wciśnięciu tej ikony (jej tło staje się białe) naprowadzamy wskaźnik myszy na miejsce, w którym ma być umieszczony tekst, a następnie przyciskamy lewy klawisz myszy. Na pojawiającym się wtedy szarym prostokącie wpisujemy tekst. Formatowanie tekstu odbywa się tak samo jak formatowanie innych elementów rysunku. Na pasku narzędziowym rysunku znajdują się także inne ikony, które służą do rysowania strzałek, linii prostych oraz do powiększania, zmniejszania i obracania wybranych fragmentów rysunku. Po przyciśnięciu ikony rysowania strzałki na polu rysunkowym pojawia się krzyżyk, który ustawiamy myszą w pozycji początku strzałki i po przyciśnięciu lewego klawisza przeciągamy krzyżyk do pozycji końcowej (grot strzałki). Analogicznie rysuje się linie proste. Po wciśnięciu ikony powiększenia (oznaczoną +) naprowadzamy kursor myszy na kraniec obszaru rysunku, który ma być powiększony. Przeciągając następnie kursor do drugiego krańca tego obszaru zaznaczamy pole rysunku ulegające powiększeniu. W momencie puszczenia klawisza myszy zaznaczony fragment rysunku zajmuje całą przestrzeń między osiami. Zmniejszenie powiększonego fragmentu rysunku uzyskuje się po wciśnięciu ikony oznaczonej jako, naprowadzeniu kursora myszy na pole rysunku i przyciskanie lewym klawiszem myszy do czasu uzyskania pożądanego rozmiaru rysunku. Obracanie rysunku jest wykorzystywane w grafice trójwymiarowej.

55 4.2. Grafika trójwymiarowa Program MATLAB dysponuje bardzo rozbudowanymi narzędziami do tworzenia obrazów trójwymiarowych (patrz Help 3-D Visualization). Nie sposób w skrypcie o rozsądnej objętości omówić wszystkie możliwości programu w tej dziedzinie. Szczęśliwie, do celów obliczeń inżynierskich wystarcza stosowanie podstawowych funkcji grafiki trójwymiarowej i te przedstawimy w tym podrozdziale. W celu uporządkowania prezentacji rozpatrzymy kolejno trzy przypadki, a mianowicie: wizualizację funkcji zapisanej trzema wektorami wizualizację funkcji zapisanej dwoma wektorami i macierzą wizualizację powierzchni zapisanej trzema macierzami Dwa pierwsze przypadki dotyczą funkcji dwóch zmiennych, które zgodnie z definicją przyporządkowują jednoznacznie zmiennym niezależnym jedną i tylko jedną wartość zmiennej zależnej. Trzeci przypadek dotyczy obok funkcji dwóch zmiennych także powierzchni, które nie są obrazami funkcji. Mogą to być figury geometryczne w rodzaju kuli, sześcianu itp. 4.2.1. Linie w przestrzeni trójwymiarowej Poznana wcześniej instrukcja plot ma wersję trójwymiarową plot3. Instrukcja ta umożliwia wyznaczanie obrazu linii w przestrzeni trójwymiarowej. Linia jest zapisana przy użyciu trzech wektorów x,y,z o tej samej długości. Ogólny zapis tej instrukcji ma następującą postać: plot3(x,y,z,...) Zmienne x,y,z opisują linię w układzie trzech współrzędnych prostokątnych. W miejsce kropek można wpisać parametry formatujące linię w ten sam sposób, jak w funkcji plot. Możliwe jest również zobrazowanie większej liczby krzywych, a wtedy instrukcja wygląda następująco: plot3(x1,y1,z1,...,x2,y2,z2,...,x3,y3,z3,...) W miejsce kropek wpisujemy parametry danej krzywej. Jako przykład wykorzystania instrukcji plot3 przedstawimy krótki program wyznaczający dwie spirale przestrzenne. t=0:pi/100:10*pi; x1=t.*cos(t); y1=t.*sin(t); z1=t; x2=t.*cos(2*t); y2=t.*sin(2*t); z2=t; plot3(x1,y1,z1,'g',x2,y2,z2) xlabel('x');ylabel('y');zlabel('z'); title('spirala') grid on %oznaczenia osi %tytuł %wstawienie siatki Wynikiem działania programu są wykresy pokazane na rys.4.8. Rysunek nieznacznie przeformatowano używając okien Figure Properties, Axes Properties.

56 Rys.4.8. Przestrzenny wykres spiral. 4.2.2. Tworzenie obrazów funkcji dwóch zmiennych Obrazem funkcji dwóch zmiennych x,y jest powierzchnia, którą tworzą punkty x,y,z spełniające ogólną zależność z=f(x,y). W programie do obliczeń numerycznych jakim jest MATLAB, zmienne x,y i z są zmiennymi dyskretnymi, a zatem powierzchnia określona jest tylko w skończonej liczbie punktów. We współrzędnych prostokątnych zmienne x i y wyznaczają współrzędne punktu na płaszczyźnie X,Y, a z jest współrzędną wartości funkcji w tym punkcie, czyli wysokością punktu płaszczyzny względem płaszczyzny X,Y. W nomenklaturze programy MATLAB, zmienne x i y tworzą wektory, zaś zmienna z tworzy macierz Z. Wartości elementów tej macierzy są wyznaczają poszukiwaną powierzchnię, będącą graficzną reprezentacją dyskretnej funkcji z=f(x,y). Obraz graficzny funkcji dwóch zmiennych otrzymujemy wykorzystując instrukcje surf lub mesh. Instrukcja surf daje obraz powierzchni uzyskanej przy użyciu kolorów, których barwa jest uzależniona od wartości współrzędnej z dla danego punktu x,y. Dodatkowo na powierzchnię naniesiona jest siatka, która łączy wyznaczone punkty tej powierzchni. Instrukcja mesh tworzy obraz powierzchni za pomocą kolorowej siatki łączącej wyznaczone punkty tej powierzchni. Pola wewnątrz siatki są białe. Poza tym obie instrukcje funkcjonują podobnie, chociaż możliwości formatowania rysunku są znacznie większe w odniesieniu do instrukcji surf. Sytuacja jest najprostsza, gdy macierz Z(m,n) jest wyznaczona dla wektorów x(n) i y(m) tworzących równomierną siatkę na płaszczyźnie X,Y. Wówczas położenie punktów płaszczyzny jest tożsame z odpowiednimi wierszami i kolumnami macierzy Z. Reguła jest następująca: wartości w wierszach oznaczają współrzędną x(n), zaś wartości w kolumnach współrzędną y(m). Obraz funkcji Z(m,n) we współrzędnych prostokątnych otrzymamy pisząc następujące instrukcje:

57 surf(z) lub mesh(z) Poniżej pokażemy w surowej wersji obraz graficzny dwuwymiarowej funkcji Gaussa o następującej postaci: 1 Z(x, y) e 2 2 2 2 (x y / 4) / 2 Oto program wyznaczający obrazy graficzne tej funkcji: x=-4.8:0.2:5; fx=exp(-x.^2/2); fy=exp(-x.^2/8) ; Z=(fy*fx)/(4*pi); surf(z) axis([1 50 1 50 0 0.08]) figure mesh(z) axis([1 50 1 50 0 0.08]) Dwuwymiarową funkcję Gaussa przedstawiono w formie iloczynu dwóch wektorów fx i fy, przy czym wektor fy jest wektorem kolumnowym. Iloczyn takich dwóch wektorów jest macierzą, której elementami są iloczyny odpowiednich elementów wektorów. Uniknęliśmy w ten sposób stosowania obliczeń w pętlach. Rys. 4.9. Powierzchnie na obu rysunkach wytworzone zostały z 50 wierszy i kolumn macierzy Z. Na przedstawionych wykresach współrzędne x i y zostały zastąpione numerami wierszy i kolumn macierzy Z. Jeżeli skale wykresów chcemy pokazać w sposób jawny, wtedy używamy instrukcji: surf(x,y,z) lub mesh(x,y,z) Trójwymiarowy obraz funkcji Gaussa wykonany instrukcją surf.

58 Rys. 4.10. Trójwymiarowy obraz funkcji Gaussa wykonany instrukcją mesh. Na rysunkach można wprowadzić dodatkowe opisy używając instrukcji xlabel, ylabel, zlabel i title Zauważmy, że na obu wykresach najniższym wartościom funkcji przypisany jest kolor granatowy, następnie niebieski, zielony, żółty, aż po kolor ciemno czerwony, który jest przyporządkowany najwyższym wartościom funkcji. Jeżeli instrukcja jest zapisana w sposób podany w przykładach, to skala kolorów jest dobierana automatycznie. 4.2.3. Dobór kolorów Skalę kolorów można dobierać według własnych potrzeb wykorzystując instrukcje colormap i caxis. Sposób dobierania kolorów poprzedzimy krótkim opisem zasady tworzenia i zapisywania skali kolorów w programie MATLAB. Kolory używane na rysunku zapisywane są w formie macierzy zbudowanej z trzech kolumn i pewnej liczby wierszy. Domyślnie liczba wierszy wynosi 64 i każdemu wierszowi odpowiada jeden kolor. Barwa zależy od liczb umieszczonych w danym wierszu. Liczby te zawierają się w przedziale od 0 do 1 i opisują intensywność podstawowych trzech kolorów (RGB), których suma daje odpowiednią barwę. W pierwszej kolumnie zapisana jest intensywność koloru czerwonego, w drogiej zielonego, a w trzeciej niebieskiego. Na analogicznej zasadzie tworzone są np. kolory w telewizji. Wiersz zawierający 1 1 1 daje kolor biały, 0 0 0 czarny, 1 0 0 czerwony, 0 1 0 zielony, 0 0 1 niebieski. Wiersz zawierający np. 0.5 0.2 0.7 oznacza kolor składający się z 0.5R+0.2G+0.7B. Wpisanie instrukcji colormap zwraca opisaną wyżej macierz odnoszącą się do aktualnego rysunku. Jeżeli macierz ta jest potrzebna w programie, wówczas piszemy: Cm=colormap Macierz Cm jest zapamiętana i można dokonywać jej modyfikacji, których skutkiem są zmiany kolorów. Można przykładowo zmieniać liczbę wierszy, wycinać niektóre wiersze itp.

59 Jeżeli taką zmodyfikowaną macierz Cmm wstawimy jako argument funkcji colormap, to zmieni się skala kolorów: colormap(cmm) Można również w razie potrzeby skonstruować własną macierz Cm, zachowując wszakże jej strukturę, czyli liczbę kolumn równą 3. Efekty wprowadzonych zmian można zobrazować używając instrukcji colorbar. Na aktywnym rysunku (lub nowym, gdy nie ma rysunku) pojawia się pionowy słupek z naniesioną aktualną paletą barw. Program MATLAB dysponuje szeregiem standardowych palet barw, które mogą być użyte na rysunku. W celu wybrania odpowiedniej palety barw piszemy następujące instrukcje: colormap jet domyślna paleta barw używana na zamieszczonych wyżej rysunkach colormap hot ciepłe kolory od czarnego, poprzez czerwony do białego colormap cool zimne barwy od zielonego, poprzez niebieski do fioletowego colormap gray skala szarości colormap( default ) przywraca domyślną paletę barw Poza wymienionymi można użyć także: autumn, bone, colortube, cooper, flag, hsv, pink, prism, spring, summer i winter. Każda tak zapisana paleta zawiera 64 kolory. Liczbę kolorów można zmniejszyć lub zwiększyć w ramach danej palety pisząc np. jet(10) lub hot(100). Standardowa paleta zawiera teraz tylko 10 kolorów, a paleta hot - 100 kolorów. Powyższe instrukcje można zapisać również w zwartej formie, jak np.: colormap(hot(100)) Zmian palety kolorów można dokonywać ręcznie otwierając menu Edit, a w nim Colormap Otwiera się wtedy okno Colormap Editor, w którym można wybrać pożądaną paletę barw. Należy jednak pamiętać, że ustawienia palety uzyskane tą metodą odnoszą się wyłącznie do aktywnego rysunku. Preferowane jest ustawienie palet programowo, gdyż efekt jest wtedy powtarzalny. Pożyteczne jest wykorzystywania okna Colormap Editor do eksperymentalnego doboru palety. Pisząc po wybraniu palety w Command Window instrukcję Cm=colormap otrzymujemy macierz, którą można wykorzystać w programie. Paleta barw jest wykorzystywana w ten sposób, że program MATLAB automatycznie przypisuje najniższy kolor z palety barw do najmniejszej wartości macierzy Z, a najwyższy kolor do największej wartości tej macierzy. Można jednak tę zasadę zmienić używając instrukcji caxis. Jest ona podobna do instrukcji axis, która ustala zakres skali wykresu. Składnia tej funkcji ma postać: caxis([cmin cmax]) gdzie cmin oznacza najmniejszą wartość macierzy Z, do której przypisany jest najniższy kolor aktualnej palety barw zaś cmax najwyższą wartość, do której jest przypasany najwyższy kolor. Jeżeli zakres wartości macierzy Z zawarty jest w granicach cmin do cmax, to do wykonania wykresu użyta zostanie tylko odpowiednia część pełnej palety barw. W przeciwnym wypadku wartości macierzy Z mniejsze od cmin oznaczone zostaną kolorem odpowiadającym cmin, a przekraczające cmax kolorem przypisanym do cmax.

60 Aktualne wartości cmin i cmax można wyznaczyć następująco: [cmin,cmax]=caxis Instrukcja caxis auto cmin i cmax na granicach pełnej paletę barw, zaś instrukcja caxis manual zachowuje granice palety barw, gdy na jednym rysunku umieszcza się więcej wykresów, stosując polecenie hold on. Wykorzystując omówione instrukcje dokonamy modyfikacji wykresu przedstawionego na rys. 4. W tym celu zmienimy i uzupełnimy kod podany na wstępie tego punktu. x=-5:0.2:5; y=x; fx=exp(-x.^2/2); fy=exp(-y.^2/8)'; Z=(fy*fx)/(4*pi); surf(x,y,z) axis([-5 5-5 5 0 0.08]) colormap(cool(32)) caxis([0.01 0.1]) colorbar Zmin=min(min(Z)) Zmax=max(max(Z)) Program zwraca wartość minimalną i maksymalną macierzy Z Zmin = 1.3030e-008 Zmax = 0.0796 oraz sporządza wykres pokazany na rys. 4.11. Rys. 4.11. Trójwymiarowy obraz funkcji Gaussa wykonany przy użyciu instrukcji surf, colormap, caxis i colorbar. Na pionowym pasku widoczna jest pełna paleta barw w tonacji zimnej (cool). Składa się ona z 32 kolorów. Ponieważ Zmin<cmin, więc obszar powierzchni o wartościach mniejszych

61 od cmin=0.01 jest oznaczony najniższym kolorem z palety barw. Z drugiej strony Zmax<cmax, a zatem nie jest wykorzystana pełna paleta barw. 4.2.4. Ustawianie położenia układu współrzędnych Na rysunku widoczny jest rzut prostopadły układu współrzędnych, wyznaczonego w przestrzeni przez osie X,Y,Z na płaszczyznę rysunku. Kształt powierzchni przedstawianej funkcji zależy od samej funkcji, lecz także od usytuowania układu współrzędnych względem powierzchni rysunku. Nie zawsze usytuowanie to jest wygodne, gdyż część powierzchni funkcji jest przesłaniana przez inne jej fragmenty. W takiej sytuacji pożądana jest możliwość zmiany położenia układu współrzędnych względem płaszczyzny rysunku, lub inaczej mówiąc względem obserwatora. Oko obserwatora (ang. viewpoint), zgodnie z zasadami rzutu prostopadłego znajduje się (teoretycznie) na prostej prostopadłej do powierzchni rysunku i przechodzącej przez środek układu współrzędnych. Kąty między ową prostą, a osiami układu współrzędnych opisują położenie tego układu względem powierzchni rysunku. W programie MATLAB używa się kątów azymutu i elewacji, które pokazano na rys. 4.12. Z Y elewacja X azymut Rys. 4.12. Usytuowanie układu współrzędnych względem obserwatora. Standardowo, kąt azymutu wynosi 37.5 0, a kąt elewacji +30 0 i przy tak położonym układzie współrzędnych wykonane są wszystkie, zamieszczone wyżej, rysunki. Ustawienie układu współrzędnych zmienia instrukcja: view(az,el) lub view([az,el]) gdzie az oznacza kąt azymutu (w stopniach), a el kąt elewacji. Położenie prostej, na której leży punkt obserwacji można również ustawić podając współrzędne jednego z punktów prostej x,y,z: view([x,y,z]) Instrukcja view(2) ustawia obserwatora na osi Z i uzyskujemy dwuwymiarowy obraz przestrzeni, zaś instrukcja view(3) ustawia układ współrzędnych w standardowej pozycji.

62 Na pasku narzędziowym okna Figure znajduje się ikona w kształcie okręgu, która służy do ręcznej zmiany położenia układu współrzędnych. Po wciśnięciu przycisku z tą ikoną należy naprowadzić znacznik myszy na pole obrazu i - trzymając wciśnięty lewy klawisz przesuwać znacznik do momentu uzyskania pożądanego położenia układu współrzędnych. Położenie obserwatora przy istniejącym ustawieniu układu współrzędnych można wyznaczyć zapisując następującą funkcję: [az,el]=view Wartości te można wykorzystać w pisanym programie do pożądanego, niestandardowego ustawienia układu współrzędnych. Program MATLAB dysponuje bardzo rozbudowanym zestawem narzędzi służących do ustawiania położenia obserwatora względem układu współrzędnych, a także do ciągłej zmiany tego położenia. Efekty działania tych narzędzi są podobne do funkcjonowania kamery fotograficznej i filmowej. Nie ma tu miejsca na omawianie tych narzędzi, dlatego wspomnimy jedynie o jednej z licznych możliwości, a mianowicie o pasku narzędziowym Camera Toolbar, który rozwija się z menu View, znajdującym się w oknie Figure. Posługując się ikonami znajdującymi się na tym pasku, Czytelnik może samodzielnie sprawdzić i wykorzystać możliwości programu MATLAB w zakresie grafiki trójwymiarowej. 4.2.5. Efekty oświetlania rysunków trójwymiarowych Rysowanej powierzchni można nadać bardziej przestrzenny charakter stosując jej oświetlenie. Na powierzchni widoczne są wówczas jaśniejsze plamy i cienie. Program MA- TLAB umożliwia oświetlanie powierzchni z różnych źródeł światła oraz ustawienie źródła w dowolnej pozycji względem układu współrzędnych. Narzędzia do oświetlania rysunku znajdują się na pasku narzędziowym w menu View, Camera Toolbar, w menu Tool, Camera Motion, Orbit Scene Light, a także Edit, Figure Properties, Edit Properties for: surface. W ostatnim przypadku otwiera się okno, w którym można dobrać różne rysowanej parametry powierzchni, a w tym dotyczące oświetlenia. Do programowego ustawienia oświetlenia służy kilka instrukcji, które pokrótce omówimy. Instrukcja camlight służy do ustawienia źródła światła w określonym położeniu względem obserwatora (kamery). I tak camlight headlight ustawia źródło światła w pozycji kamery camlight right - ustawia źródło światła na prawo i nad kamerą camlight- jak wyżej camlight left - ustawia źródło światła na lewo i nad kamerą camlight(az,el) - ustawia źródło odchylone od kierunku kamerą o kąty az (azymutu) i el (elewacji), wyrażone w stopniach Komendy te można zapisywać w formie funkcji, np. camlight( right,...). W miejsce kropek można wpisać jeden z dwóch parametrów, a mianowicie local lub infinite. Parametr local ustawia źródło światła blisko układu współrzędnych i promienie światła tworzą wtedy wiązkę. Parametr infinite ustawia źródło światła w nieskończonej odległości od układu współrzędnych i wówczas promienie światła są równoległe. Instrukcja lightangle(az,el) ustawia źródło światła względem układu współrzędnych w ten sam sposób, jak view(az,el) odnosząca się do obserwatora.

63 Instrukcja lighting służy do wyboru algorytmu, który jest stosowany przez program MA- TLAB do uzyskania efektów oświetlenia. Mamy cztery możliwości do wyboru: lighting flat przypisuje odpowiedni kolor do każdej elementarnej płaszczyzny, z których utworzona jest rysowana powierzchnia lighting gouraud interpoluje kolory wewnątrz płaszczyzn, co daje lepszy efekt przy rysowaniu krzywych powierzchni lighting phong postępuje jak wyżej, przy czym interpolacja dotyczy każdego piksela, a więc rysowanie trwa dłużej. lighting none wyłącza źródło światła Instrukcja material pozwala dobrać materiał, z którego zbudowana jest oświetlana powierzchnia pod względem właściwości odbijających światło. Są to: material shiny materiał połyskliwy material dull materiał matowy material metal - metal material default domyślny, automatyczny dobór materiału 4.2.6. Inne metody formatowania rysunku Przedstawione wyżej instrukcje nie wyczerpują możliwości, które daje program MA- TLAB w zakresie grafiki trójwymiarowej. Możliwości te są opisane w Help w rozdziale 3-D Visualization. Wspomnimy tu jedynie o ustawieniu parametrów rysunku bezpośrednio w instrukcjach surf i mesh. Można mianowicie uzupełnić argumenty tych funkcji przez nazwy parametrów i ich wartości. Przykładowo instrukcja surf o rozszerzonym argumencie ma ogólną formę: surf(x,y,z, nazwa parametru,wartość parametru, nazwa parametru, wartość parametru,...) Listę wszystkich parametrów i ich wartości, którymi są z reguły ciągi znaków, można znaleźć w Help/Functions-Alphabetical List/Surface Properties. Inna metoda, której nie zalecamy początkującym użytkownikom programu MATLAB, używa do ustawiania parametrów rysunku funkcji set. Składnia tej funkcji jest następująca: set(h, nazwa parametru,wartość parametru, nazwa parametru, wartość parametru,...) Litera h oznacza identyfikator obiektu graficznego, którego dotyczyć będą podane parametry. Może to być liczba (np. numer rysunku) lub wektor, w którym poszczególne liczby identyfikują rysunek i jego elementy. Identyfikator jest ustalany przez program MATLAB. Można go znaleźć pisząc: h=findobj Jeżeli mamy zamiar wprowadzać parametry aktualnego rysunku, wtedy w miejsce identyfikatora wpisuje się gcf. Gdy chcemy zmienić parametry osi, wtedy w miejsce h wpisujemy gca. Nazwy parametrów i ich wartości dla aktualnego rysunku lub obiektu na rysunku otrzymujemy pisząc: V=get(h) gdzie h jest identyfikatorem rysunku lub obiektu graficznego.

64 Jeżeli chcemy znać wartości określonego parametru, wtedy wykorzystujemy następującą instrukcję: v=get(h, nazwa parametru ) Wykaz parametrów i ich wartości można znaleźć w Help/Functions-Alphabetical List/Surface Properties. Do wymienionych wyżej funkcji powrócimy jeszcze omawiając Graficzny Interfejs Użytkownika (GUI). Na zakończenie przedstawimy program rysujący wykres funkcji dwóch zmiennych, w którym zastosowano część omówionych wyżej instrukcji. Wyznaczymy mianowicie powierzchnię opisaną funkcją: Z=[sin(x)/x][sin(y)/y] Program wykreślający powierzchnię tej funkcji ma następującą postać: x=-2*pi:pi/50:2*pi; y=2*x'; fx=sin(x+eps)./(x+eps); fy=sin(y+eps)./(y+eps); Z=(fy*fx); surf(x,y,z,'linestyle','none') % Wektor wierszowy zmiennej x % Wektor kolumnowy zmiennej y % Wektor wierszowy funkcji zmiennej x % Wektor kolumnowy funkcji zmiennej y % Macierz funkcji dwóch zmiennych % Wykres powierzchni Z pozbawiony siatki axis([-2*pi 2*pi -4*pi 4*pi -0.5 1]) title('funkcja dwóch zmiennych') xlabel('x','position', [10.2-5 -1.05]) ylabel('y','position', [-5 15.5-0.72]) zlabel('z','position', [-5 15 1],'rotation',0) view(-45,40) colormap jet caxis([-0.5 1]) camlight(10,-5) lighting phong material shiny set(1,'color','white') % Ustawienie zakresu osi wykresu % Tytuł wykresu % Opis osi wykresu i ustawienie położenia napisu % Ustawienie kątów azymutu i elewacji obserwatora % Ustawienie palety barw % Ustawieni wartości zmiennej Z dla najniżej i najwyższej barwy % Ustawienie kątów azymutu i elewacji źródła światła % Określenie metody interpolacji barw % Określenie materiału powierzchni % Ustawienie koloru obrzeża rysunku Rys. 4.13. Wykres funkcji dwóch zmiennych.

65 4.2.7. Obrazy figur trójwymiarowych Dotychczas zajmowaliśmy się obrazami graficznymi funkcji dwóch zmiennych, w których zgodnie z definicją funkcji każdej parze zmiennych niezależnych x,y przyporządkowaną jest tylko jedna wartość zmiennej Z. Istnieją powierzchnie, których nie można opisać funkcją, np. powierzchnia sześcianu, kuli itp. W geometrii analitycznej opisane są one równaniami lub układami równań. Do wyznaczania obrazu takich powierzchni wykorzystuje się w programie MATLAB specjalne instrukcje, które teraz pokrótce zaprezentujemy. W odróżnieniu od wyżej omówionych argumentów funkcji surf i mesh, do rysowania powierzchni, które mogą lecz nie muszą być obrazem funkcji, używamy trzech argumentów będących macierzami. Zapis instrukcji ma teraz następującą postać: surf(x,y,z,...) lub mesh(x,y,z) Macierz X zbudowana jest w ten sposób, że każdy jej wiersz jest kopią wektora x. Liczba wierszy N jest równa długości wektora y. Macierz Y składa się z jednakowych kolumn, które są kopiami wektora y. Liczba kolumn N jest równa długości wektora x. Macierz Z ma wymiar [M,N]. Jeżeli zdefiniowane są wektory x i y, to macierze X i Y tworzy się używając instrukcji: [X,Y]=meshgrid(x,y) Oto prosty przykład: >> y=0:2:8; >> x=0:-1:-6; >> [X,Y]=meshgrid(x,y) X = Y = 0-1 -2-3 -4-5 -6 0-1 -2-3 -4-5 -6 0-1 -2-3 -4-5 -6 0-1 -2-3 -4-5 -6 0-1 -2-3 -4-5 -6 0 0 0 0 0 0 0 2 2 2 2 2 2 2 4 4 4 4 4 4 4 6 6 6 6 6 6 6 8 8 8 8 8 8 8 Zauważmy, że wartości w obu macierzach są współrzędnymi siatki prostokątnej utworzonej na płaszczyźnie Z=0. Każdemu punktowi tej siatki przyporządkowana jest odpowiednia wartość zmiennej niezależnej, którą jest macierz Z. Wartość ta jest wysokością punktu nad płaszczyzną Z=0. Ponieważ jednemu punktowi na płaszczyźnie Z=0 przyporządkowana jest tylko jedna wartość macierzy Z, a zatem Z jest funkcją. Mimo innego zapisu, omawiane tu instrukcje nie różnią się w istocie od podanych w poprzednich punktach. Macierzowy zapis argumentów funkcji surf i mesh otwiera jednak możliwości rysowania dowolnych powierzchni, nie tylko będących obrazem funkcji dwóch zmiennych. W tym celu należy zrezygnować z funkcji meshgrid i utworzyć inne macierze X,Y,Z. Macierze te powinny opisywać rzuty punktów na płaszczyzny i/lub osie układu współrzędnych. Wszystkie trzy macierze muszą mieć ten sam wymiar. Ten sam wymiar musi mieć także macierz C, która opisuje kolory na rysunku. Ponieważ macierze muszą mieć ten sam wymiar, więc

66 można je przedstawić jako funkcje dwóch parametrów, np. m,n : X(m,n),Y(m,n), Z(m,n), C(m,n). Parametry m,n mogą być kątami we współrzędnych sferycznych lub kątem i promieniem we współrzędnych cylindrycznych. Zamieszczony niżej krótki program ilustruje sposób tworzenia obrazu trójwymiarowego figury, która nie może być wyrażoną funkcją dwóch zmiennych. Jest to figura, która powstała w wyniku obrotu funkcji x=25+z2 wokół osi Z. Pokazano ją na rys. 4.14. theta=pi*(-20:20)/20; h=(-5:10)'; X=(25+h.^2)*sin(theta); Y=(25+h.^2)*cos(theta); Z=h*ones(1,41); colormap winter surf(x,y,z) Rys. 4.14. Trójwymiarowy obraz figury obrotowej. 4.3. Graficzny interfejs użytkownika 4.3.1. Ogólna charakterystyka Graficzny interfejs użytkownika jest narzędziem ułatwiającym wprowadzania zmian w programie i jednocześnie umożliwiającym wygodny dostęp do wyników obliczeń w formie graficznej i numerycznej. Używając programu MATLAB do obliczeń numerycznych lub do symulacji pracy układów bądź systemów piszemy skrypt zawierający wszystkie niezbędne instrukcje realizujące postawione zadanie. W takim skrypcie wszystkie dane, parametry, funkcje, operacje graficzne itp. są określone i nie ulegają zmianie przy każdorazowym uruchomieniu programu. Chcąc cokolwiek zmienić w napisanym skrypcie musimy wpisać inne instrukcje lub wykorzystać instrukcję input. Program natrafiając na tę instrukcję żąda od użytkownika wprowadzenia określonej danej, którą może być np. wartość parametru. Przy większej liczbie parametrów jest to kłopotliwe, gdyż wymaga każdorazowo wpisywania wszystkich, także powtarzających się

67 wartości. Tę niedogodność eliminuje graficzny interfejs użytkownika GUI (ang. Graphical User Interface). Narzędzie to tworzy rysunek w formie planszy, na której mogą znajdować się przyciski, klucze, suwaki, listy parametrów, pola wykresów itp. które obsługuje się myszą lub wpisuje dane z klawiatury. Skutkiem każdej zmiany nastaw jest wykonanie odpowiednich operacji i ekspozycja wyników w formie graficznej, numerycznej lub łańcuchów znaków. W sumie odpowiednio zaprojektowana plansza GUI przypomina płytę czołową przyrządu pomiarowego, np. oscyloskopu. Planszę graficznego interfejsu użytkownika projektuje się stosunkowo łatwo używając środowiska GUIDE (ang. GUI Design Environment). Wybiera się mianowicie myszą potrzebne elementy z menu znajdującego się na planszy projektowej i umieszcza na planszy GUI, która będzie obsługiwana po napisaniu programu przez użytkownika. Efektem tych operacji poza planszą z naniesionymi elementami jest specjalny program utworzony automatycznie przez GUIDE z rozszerzeniem.m oraz rysunek z rozszerzeniem.fig. Oba skrypty można umieścić w katalogu work lub utworzonym własnym folderze. Utworzony program z rozszerzeniem.m należy nazwać i zapamiętać, a nadana nazwa będzie jednocześnie nazwą funkcji i nazwą rysunku. Taki skrypt definiuje zatem nową funkcję, a konsekwencją tego jest to, że zmienne w ramach funkcji są zmiennymi lokalnymi (nie występują poza funkcją). Skrypt definiujący funkcję zawiera szereg instrukcji, które nie powinny być zmieniane przez programistę (definiują one planszę z jej elementami) oraz pewną liczbę instrukcji zapisanych wstępnie jako komentarze. Po usunięciu znaku % oraz po niezbędnych uzupełnieniach posłużą one do wykonania pożądanych operacji realizujących zadania programu. Nie wszystkie z tych instrukcji muszą być wykorzystane. Oczywiście, poza omawianymi instrukcjami zachodzi z reguły konieczność wprowadzenia innych, potrzebnych instrukcji. Omawiany tu program może współpracować z innymi programami zapisanymi jako oddzielne pliki z rozszerzeniem.m. Ponieważ program GUI jest funkcją, to występujące w nim zmienne nie są widoczne w innych programach i na odwrót. Przekazywanie zmiennych z programu GUI do innych programów i w kierunku odwrotnym odbywa się przez specjalną bazę danych, w której zawarte są wszystkie parametry obiektów znajdujących się na planszy użytkownika. Ogólne informacje o graficznym interfejsie użytkownika zakończymy uprzedzeniem, że przedstawione dalej omówienie obejmuje jedynie niewielki fragment jego możliwości. Może jednakże być pomocne w pokonaniu pierwszych kroków opanowania tego bardzo użytecznego narzędzia. 4.3.2. Projektowanie planszy GUI Proces projektowania planszy GUI rozpoczynamy od specyfikacji zadań, które ma ona spełniać w tworzonym programie. Do zadań tych dobieramy elementy planszy, których listę i realizowane funkcję podamy dalej. Elementy te rozmieszczamy na szkicu planszy, który wykonujemy odręcznie na kartce. Dysponując wstępnym szkicem planszy otwieramy narzędzie do projektowania GUI, pisząc: >>guide Otwiera się okno GUIDE Quick Start do uruchomienia narzędzia GUIDE. Pokazano je na rys. 4.15.

68 Rys. 4.15. Okno otwierające narzędzie GUIDE do projektowania planszy GUI Jeżeli rozpoczynamy tworzenie nowej planszy, wybieramy Create New Gui i Blank GUI. Jeżeli chcemy kontynuować prace z istniejącą planszą, wtedy wybieramy Open Existing GUI i w oknie zaznaczamy na liście poszukiwany program, po czym wciskamy przycisk Open. W jednym i drugim wypadku pojawia się okno do projektowania planszy, przy czym w pierwszym wypadku ma ono nazwę untitled.fig., zaś w drugim wcześniej nadaną nazwę i rozszerzenie.fig. Pustą planszę pokazano na rys. 4.16. Rys. 4.16. Okno do projektowania planszy graficznego interfejsu użytkownika.

69 W pliku z rozszerzeniem.fig znajduje się program, który rysuje plansze GUI. Program ten jest tworzony automatycznie przez narzędzie GUIDE. Każdorazowa zmiana naniesiona na planszy projektowej powoduje stosowaną zmianę tego programu. Z menu File wybieramy Save As... i wpisujemy nazwę pliku, która będzie jednocześnie nazwą programu (funkcji) z rozszerzeniem.m. Po wciśnięciu Zapisz, pojawia się plansza z nadaną właśnie nazwą i możemy przystąpić do umieszczania wybranych elementów na planszy. Są one widoczne w lewej kolumnie rysunku. Na górze kolumny znajduje się strzałka, która służy wyłącznie do oznaczania i wybierania elementów planszy. Pozostałe ikony przedstawiają kolejno: Push Button przycisk wciśnięcie myszą tego przycisku powoduje jednokrotną reakcję programu, np. uruchomienie określonej procedury, Toggle Button przełącznik dwustanowy w stanie wciśniętym (podświetlonym) realizuje pewną procedurę, a w stanie zwolnionym inną Radio Button przycisk dwustanowy działa jak Toggle Button, lecz jest zwykle używany w grupie i wtedy można spowodować, że włączenie jednego przycisku powoduje wyłączenie pozostałych Checkbox przycisk dwustanowy używany do wyboru pewnej akcji; zwykle stosuje się kilka takich przycisków do wyboru jednej lub kilku niezależnych akcji Edit Text okienko tekstowe służy do edycji tekstu emitowanego przez program lub do wpisywania tekstu przez użytkownika Static Text okienko tekstowe w oknie tym wpisuje się stałe teksty informacyjne; program nie reaguje na tekst Slider suwak przesuwanie musza manipulatora zmienia wartość przypisanej do suwaka zmiennej Frame ramka służy do obramowania zespołu elementów na planszy w celu zaznaczenia ich związku funkcjonalnego Listbox przycisk wielostanowy zawiera listę elementów (łańcuchów), z których można wybrać jeden lub kilka Popup Menu zestaw przełączników dwustanowych w formie listy funkcjonujących jak przełączniki Toggle Button; zastępuje zestaw przełączników Radio Button Axes osie wyznacza położenie i wielkość rysunku umieszczonego na planszy Położenie i wielkość każdego elementu można zmieniać myszą. Do zmian innych parametrów elementu służy Property Inspektor, który otwiera się przez oznaczenie elementu lewym klawiszem myszy i wciśnięciu prawego klawisza. Otwiera się wówczas okno z użytecznymi instrukcjami służącymi do usuwania, kopiowania, wklejania i wykonania innych operacji odnoszących się do zaznaczonego elementu. Na liście znajduje się również napis Property Inspector, którego wciśnięcie otwiera okno zawierające wszystkie parametry danego elementu. Najczęściej nie ma potrzeby dokonywania większych zmian owych parametrów. Ograniczamy się zwykle do zmiany nazwy elementu (String), zmiany nazwy zmiennej przypisanej do elementu (Tag), doboru koloru tła (BackgroundColor), koloru czcionki (ForegroundColor), wysokości czcionki (FontSize) i kroju czcionki (FontName). Wszystkie wprowadzone zmiany są automatycznie zapamiętane i obowiązują przy każdorazowym otwarciu rysunku.

70 Po umieszczeniu wszystkich elementów na planszy, nadaniu im pożądanego wyglądu i nazwy wybieramy z menu Tools polecenie Run. Pojawia się wtedy okno zawierające zaprojektowaną planszę. Można na nim zaobserwować wyniki naszego projektu i dokonać zauważonych poprawek (tylko w oknie do projektowania, oznaczonym jako...fig). W oknie przeznaczonym do projektowania planszy wciskamy teraz ikonę M-file Editor. Pokazuje się wtedy nowe okno zatytułowane tak jak plansza i posiadające rozszerzenie.m. Jest to wspomniany wcześniej szkic programu, który należy dostosować do naszych potrzeb i uzupełnić o wszystkie potrzebne instrukcje. 4.3.3. Podstawy programowania graficznego interfejsu użytkownika GUI Plik zawierający szkic programu GUI składa się z następujących ważnych części: W pierwszej linii widoczna jest instrukcja definiująca funkcję, którą definiuje omawiany plik. Ma ona nazwę przypisaną w czasie projektowania planszy. Szereg kolejnych linii zawiera krótkie informacje o funkcji. Są one edytowane jeżeli w oknie Command Window wpiszemy help <nazwa planszy GUI>. W kolejnych wierszach wpisane są instrukcje dotyczące każdego pliku GUI. Nie należy ich zmieniać, ani usuwać (z wyjątkiem komentarzy). Po tych instrukcjach występuje komentarz DO NOT EDIT. Następnie widoczne są wiersze zawierające standardowe funkcje dotyczące danych wejściowych i wyjściowych kończące się instrukcją varargout{1} = handles.output. Bez wyraźnej potrzeby nie należy dokonywać w nich zmian. Zawartość dalszych wierszy zależy od liczby i rodzajów elementów umieszczonych na planszy. Każdemu elementowi przypisana jest jedna lub dwie funkcje. Są to funkcje wewnętrzne, a więc komunikacja między nimi jest możliwa tylko w określony sposób, który omówimy dalej. Przypominamy, że zmienne w ramach funkcji są lokalne, a więc nie są widoczne poza nią. Definicji tych funkcji nie należy zmieniać. Funkcja poprzedzona jest komentarzem dotyczącym sposobu jej wykonywania. Za definicją funkcji występuje szereg wierszy zawierających wzory instrukcji, które może programista przekształcić w prawdziwe instrukcje usuwając znak % i je odpowiednio uzupełniając. Znajdują się tam również wskazówki dla programisty, które można usunąć po zapoznaniu się z ich treścią. Jeżeli wewnątrz funkcji znajdują się instrukcje (bez znaku %), to należy je pozostawić bez zmian. Podstawy programowania omówimy na prostym przykładzie polegającym na użyciu przycisku Push Button do włączenia programu prostych obliczeń. Przycisk ten nazwiemy START. Kolejne czynności są następujące: W oknie Command Window piszemy >> guide W oknie GUIDE Quick Start wybieramy Blank Gui (Default) W untitled1.fig wybieramy File, Save As... W oknie Save As... wpisujemy nazwę planszy (pliku) np. example1 Następuje zmiana nazwy okna do projektowania na example1.fig Oznaczamy myszą ikonę Push Button i przeciągamy ją na środek planszy Przyciskamy prawy klawisz myszy i z menu wybieramy Property Inspector

71 W BackgroundColor ustawiamy kolor tła wciskając kolorową ikonę, Definiuj kolory niestandardowe>> i suwakiem wybieramy kolor jasnoszary W wierszu FontSize wpisujemy 12 W wierszu String wpisujemy START W wierszu Tag wpisujemy start Myszą powiększmy przycisk do pożądanych rozmiarów W menu File wciskamy Save W menu Tools przyciskamy Run Pojawia się zaprojektowana plansza, której widok pokazano na rys. 4.17. Rys.4.17. Widok zaprojektowanej planszy GUI. Od tego momentu można przystąpić do pisania programu. W tym celu na pasku narzędziowym planszy projektowej wciskamy ikonę M-file Editor. Pojawia się wtedy okno, zatytułowane example1.m, a w oknie tym następujący program. function varargout = example1(varargin) % EXAMPLE1 M-file for example1.fig % EXAMPLE1, by itself, creates a new EXAMPLE1 or raises the existing % singleton*. % % H = EXAMPLE1 returns the handle to a new EXAMPLE1 or the handle to % the existing singleton*. % % EXAMPLE1('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in EXAMPLE1.M with the given input arguments. % % EXAMPLE1('Property','Value',...) creates a new EXAMPLE1 or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before example1_openingfunction gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to example1_openingfcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)".

72 % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help example1 % Last Modified by GUIDE v2.5 20-Jul-2007 12:53:13 % Begin initialization code - DO NOT EDIT gui_singleton = 0; gui_state = struct('gui_name', mfilename,... 'gui_singleton', gui_singleton,... 'gui_openingfcn', @example1_openingfcn,... 'gui_outputfcn', @example1_outputfcn,... 'gui_layoutfcn', [],... 'gui_callback', []); if nargin & isstr(varargin{1}) gui_state.gui_callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_state, varargin{:}); else gui_mainfcn(gui_state, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before example1 is made visible. function example1_openingfcn(hobject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hobject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to example1 (see VARARGIN) % Choose default command line output for example1 handles.output = hobject; % Update handles structure guidata(hobject, handles); % UIWAIT makes example1 wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = example1_outputfcn(hobject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hobject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on button press in start. function start_callback(hobject, eventdata, handles) % hobject handle to start (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) Przedstawiony wyżej program zawiera omówione wyżej elementy, z których większość to informacje i wskazówki. Niezbędne elementy tego programu przytoczone są poniżej.

73 function varargout = example1(varargin) gui_singleton = 0; gui_state = struct('gui_name', mfilename,... 'gui_singleton', gui_singleton,... 'gui_openingfcn', @example1_openingfcn,... 'gui_outputfcn', @example1_outputfcn,... 'gui_layoutfcn', [],... 'gui_callback', []); if nargin & isstr(varargin{1}) gui_state.gui_callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_state, varargin{:}); else gui_mainfcn(gui_state, varargin{:}); end function example1_openingfcn(hobject, eventdata, handles, varargin) handles.output = hobject; guidata(hobject, handles); function varargout = example1_outputfcn(hobject, eventdata, handles) varargout{1} = handles.output; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function start_callback(hobject, eventdata, handles) Wszystkie wiersze są niezbędne i nie należy ich zmieniać i usuwać. Ostatni wiersz zawiera funkcję start_callback, która reaguje na każdorazowe wciśnięcie przycisku START. Zauważmy, że nazwa tej funkcji zawiera tekst wpisany jako Tag w Property Inspector. Funkcje takie o nadanych im nazwach pojawią się w programie, w którym wystąpią także inne elementy na planszy GUI. Struktura funkcji jest stała i ma postać pokazaną w przykładzie. hobjet jest uchwytem (identyfikatorem) danego obiektu, eventdata jest zarezerwowane dla dalszego rozwoju GUI i nie jest obecnie używane, handles to zasób danych związanych z danym obiektem. W strukturze handles umieszcza się dane, które będą widoczne poza funkcją. W przypadku Push Button reakcją na wciśnięcie tego przycisku jest wykonywanie wszystkich instrukcji zapisanych za function start_callback(hobject, eventdata, handles). Przykładowo, jeżeli do powyższego programu dopiszemy x=1:10; figure stem(x) to każdorazowe wciśnięcie przycisku START spowoduje pojawienie się kolejno numerowanego rysunku zawierające dziesięć próbek o wartościach od 1 do 10. 4.3.4. Użycie przełącznika Toggle Button i okna edycyjnego Edit Text. Przełącznika użyjemy do pomiaru czasu stoperem, a wynik pokażemy w oknie edycyjnym. Postępując jak poprzednio umieszczamy na planszy przełącznik, który nazwiemy stoper oraz okno edycyjne i stałe napisy. Planszę tę zapisujemy pod nazwą example2.fig. Widok planszy pokazano na rys. 4.18. Poniżej zamieszczono część programu, z którego usunięto powtarzającą się część stałą oraz wszystkie komentarze i zbędne instrukcje. Stała część programu jest taka sama, jak w poprzednim przykładzie (z wyjątkiem nazwy funkcji). function stoper_callback(hobject, eventdata, handles)

74 function czas_createfcn(hobject, eventdata, handles) Instrukcja zapisana w pierwszym wierszu definiuje funkcję do zwracania efektów wciśnięcia lub zwolnienia przełącznika STOPER. Druga funkcja ustawia parametry okna edycyjnego, a w tym m.in. tekst, który powinien się pojawić w oknie. Ten krótki program należy uzupełnić o instrukcje, które zapewnią realizację pożądanych zadań, czyli w naszym przypadku pomiar czasu. Są to następujące instrukcje: Rys. 4.18. Plansza z przełącznikiem Toggle Button i oknem edycyjnym Edit Text. function stoper_callback(hobject, eventdata, handles) stan=get(hobject,'value'); if stan==1 tic t=0; elseif stan==0 t=toc; end ts=num2str(t); set(handles.czas,'string',ts) function czas_createfcn(hobject, eventdata, handles) Instrukcja zapisana w drugim wierszu zwraca aktualną wartość przełącznika. Parametr hobject identyfikuje aktualny obiekt, który jest nazwany w funkcji Callback jako hobject. Parametr value w przełączniku Toggle Button przyjmuje wartość 1, gdy przycisk jest wciśnięty i wartość 0, jeżeli jest on zwolniony. Zmienna stan przyjmuje zatem wartość 1 lub zero, w zależności od stanu przełącznika. W trzecim wierszu sprawdzamy, czy klucz jest włączony. Jeżeli jest to prawda, włączamy licznik czasu, który w programie MATLAB uruchamia się instrukcją tic. Zmienną t ustawiamy w momencie włączenia klawisza START na wartość 0. Tekst wyświetlany w oknie edycyjnym musi być koniecznie w formacie łańcucha znaków string. Konieczną jest zatem zamiana zmiennej liczbowej t na łańcuch. Operację tę wykonuje instrukcja num2str. W tym wypadku zwraca ona łańcuch ts= 0. Następna instrukcja umieszcza ten łańcuch w oknie edycyjnym. Parametrami funkcji set są handles.czas, który jest odwoła-

75 niem do funkcji czas zdefiniowanej w następnym wierszu, nazwa parametru string i wartość tego parametru ts. W momencie wciśnięcia przełącznika START w oknie edycyjnym pojawia się zatem 0. Od tego momentu program odlicza czas, aż do chwili zwolnienia przełącznika START. Wartość stan jest wtedy równa 0, a zatem realizowana jest instrukcja t=toc. Ta standardowa instrukcja programu MATLAB zatrzymuje zegar i zwraca jego wartość. Wartość ta jest wyświetlana w polu edycyjnym w wyniku działania omówionych wyżej instrukcji. Podany program ilustruje sposób wykorzystywania ważnych funkcji get i set. Pierwsza z nich służy do pozyskiwania parametrów, zaś druga do ich wprowadzania. Inny sposób ich użycia pokazuje następny przykład użycia okna edycyjnego. W jednym oknie będziemy wpisywać zmienną x, a w drugim podamy wartość funkcji y=log(x). Zaprojektowaną planszę pokazano na rys. 4.19. Rys.4.19. Plansza z oknami edycyjnymi Edit Text. Fragment programu realizującego opisane wyżej zadanie ma następującą postać: function x_createfcn(hobject, eventdata, handles) function x_callback(hobject, eventdata, handles) x=str2double(get(hobject,'string')); if x<=0 set(handles.y,'string','x musi być >0') else y=log10(x); ys=num2str(y); set(handles.y,'string',ys) end function y_createfcn(hobject, eventdata, handles) Instrukcje w pierwszym i ostatnim wierszu konfigurują dwa okna edycyjne. Funkcja w drugim wierszu definiuje funkcję, która w strukturze handles zawiera tekst wpisany do okna edycyjnego nazwanego x. Instrukcja w trzecim wierszy zwraca tekst wpisany w oknie edycyj-

76 nym (get(hobkect, string ) i zamienia go na wartość liczbowa (str2double). Następnie sprawdzamy, czy wartość x jest ujemna. Jeżeli tak, to wpisujemy do okna edycyjnego y tekst x musi być >0. W przeciwnym wypadku obliczamy wartość logarytmu, zamieniamy go na łańcuch i pisujemy do okna edycyjnego y. 4.3.5. Użycie przełącznika Radio Button i okna edycyjnego Edit Text. Sposób użycia przełącznika Radio Button zilustrujemy na przykładzie wyznaczania wartości czterech funkcji trygonometrycznych dla jednego kąta podawanego przez użytkownika. W tym celu, używając narzędzia GUIDE zaprojektujemy planszę pokazaną na rys. 4.20. Rys. 4.20. Przykład zastosowania przycisków Radio Button. Poniżej zamieszczono części programu wykonującego podane wyżej zadania. function x_createfcn(hobject, eventdata, handles) function x_callback(hobject, eventdata, handles) x=str2double(get(hobject,'string')) handles.x=x; guidata(hobject, handles); function fsin_callback(hobject, eventdata, handles) stan= get(hobject,'value'); if stan==1 set(handles.fcos,'value',0) set(handles.ftg,'value',0) set(handles.fctg,'value',0) x=handles.x; y=sin(pi*x/180); ys=num2str(y); set(handles.y,'string',ys) end function fcos_callback(hobject, eventdata, handles) stan=get(hobject,'value');

77 if stan==1 set(handles.fsin,'value',0) set(handles.ftg,'value',0) set(handles.fctg,'value',0) x=handles.x; y=cos(pi*x/180); ys=num2str(y); set(handles.y,'string',ys) end function ftg_callback(hobject, eventdata, handles) stan=get(hobject,'value') if stan==1 set(handles.fsin,'value',0) set(handles.fcos,'value',0) set(handles.fctg,'value',0) x=handles.x; y=tan(pi*x/180); ys=num2str(y); set(handles.y,'string',ys) end function fctg_callback(hobject, eventdata, handles) stan=get(hobject,'value') if stan==1 set(handles.fsin,'value',0) set(handles.fcos,'value',0) set(handles.ftg,'value',0) x=handles.x; y=1/tan(pi*x/180); ys=num2str(y); set(handles.y,'string',ys) end function y_createfcn(hobject, eventdata, handles) Pierwszy fragment programu służy do wprowadzania zmiennej x. W stosunku do poprzednich przykładów nowością są dwie instrukcje, a mianowicie handles.x=x oraz guidata(hobject, handles). Pierwsza z nich zapisuje zmienną x jako element struktury handles. zaś druga instrukcja zapamiętuje ten element w zbiorze handles. W ten sposób umożliwia dostęp do tej zmiennej wewnątrz innych funkcji. Cztery kolejne fragmenty o jednakowej składni służą do ustawiania przełączników Radio Button oraz do wykonania obliczeń i wpisania ich wyników w oknie edycyjnym y, zdefiniowanym ostatnią instrukcją. W każdym z fragmentów sprawdzamy najpierw stan przełącznika. Jeżeli jest on wciśnięty (stan==0), wtedy ustawiamy pozostałe przełączniki w stan wyłączenia ( value,0). Następnie pobieramy ze zbioru handles zmienną x (x=handles.x), wykonujemy obliczenie związane z danym przełącznikiem i wpisujemy wynik do okna edycyjnego y. Wzajemne uzależnienia stanu przełączników można zrealizować przy użyciu innych instrukcji, podanych w Help. W tym skrypcie staramy się ograniczyć liczbę instrukcji do niezbędnego minimum i dlatego posługujemy się znaną już funkcją set.

78 4.4.6. Użycie Popup Menu Zestaw przełączników Radio Button można zastąpić narzędziem Popup Menu. Aby pokazać różnice w oprogramowaniu zaprojektujemy planszę, w której w powyższym przykładzie zastąpimy tylko przełączniki Radio Button elementem Popup Menu. Projektując plansze, po umieszczeniu elementu Popup Menu, należy w oknie Property Inspector wybrać parametr String i wpisać w oknie w kolejnych wierszach tekst widoczny na rys. 4.21. Rys. 4.21. Plansza wykorzystująca Popup Menu (rozwinięte menu). Program używający Popup Menu jest nieco prostszy do poprzedniego. Wybór wiersza z listy przypisuje parametrowi value wartość, która jest równa numerowi wiersza. Sprawdzając zatem wartość stan=get(hobject, value ) możemy wykonać odpowiednie obliczenie i wpisać jego wynik do okna edycyjnego y. Wybór jednego wiersza wyklucza automatycznie możliwość wyboru pozostałych, co poprzednio wymagało napisania odpowiednich instrukcji. function x_createfcn(hobject, eventdata, handles) function x_callback(hobject, eventdata, handles) x=str2double(get(hobject,'string')) handles.x=x; guidata(hobject, handles); function popupmenu1_createfcn(hobject, eventdata, handles) function popupmenu1_callback(hobject, eventdata, handles) stan=get(hobject,'value'); if stan==1 x=handles.x; y=sin(pi*x/180); ys=num2str(y); set(handles.y,'string',ys) elseif stan==2 x=handles.x; y=cos(pi*x/180); ys=num2str(y);

79 set(handles.y,'string',ys) elseif stan==3 x=handles.x; y=tan(pi*x/180); ys=num2str(y); set(handles.y,'string',ys) else x=handles.x; y=1/tan(pi*x/180); ys=num2str(y); set(handles.y,'string',ys) end function y_createfcn(hobject, eventdata, handles) 4.3.6. Użycie Listbox i Axes Element Listbox służy do wyboru jednej lub kilku akcji (bądź parametrów) spośród wykazu umieszczonego przez programistę w okienku. Przykładowo, akcja może polegać na wykreśleniu jednej lub kilku funkcji sin(x), cos(x), sin(2x), cos(3x). Nazwy tych akcji wpisuje się w oknie String w Property Inspector, wywołanym po umieszczeniu elementu Listbox na planszy projektowej. Jeżeli chcemy dopuścić możliwość jednoczesnego uruchomienia kilku akcji, to w Property Inspector wpisujemy w Max liczbę naturalną większą od Min (np. Max=4, Min=0). Wyboru akcji dokonuje się myszą, a przy oznaczaniu większej liczby akcji myszą i klawiszami Shift i Ctrl. Na planszy pokazanej na rys. 4.22 zaznaczono w ten sposób sin(x) i cos(2x). Rys. 4.22. Zastosowanie Listbox do wykreślania wybranych funkcji. Jeżeli dopuszcza się wybór więcej niż jednej akcji, to należy bezwzględnie dodać przycisk Push Button, opisany na planszy jako RYSUJ. Wynika to ze sposobu reagowaniu Listbox na wybór akcji (parametru) umieszczonej na liście. Otóż funkcja Callback zmienia stan po każdorazowym wciśnięciu myszy. Jeżeli wybieramy najpierw sin(x), a potem (używając Ctrl) cos(2x), to najpierw stan informuje o włączeniu sin(x) i może to uruchomić niepotrzebnie od-

80 powiednią akcję. Wciśnięcie potem cos(2x) ponownie uruchamia obie akcje. Aby uniknąć tego niekorzystnego efektu, akcję uruchamiamy dopiero po ustawieniu całej listy. Element Axes umieszczony na planszy otwiera okno do rysowania wykresów. Można dobrać jego położenie i rozmiar w ten sam sposób, jak pozostałych elementów GUI. Element axes nie ma odzwierciedlenia w programie z rozszerzeniem.m. Wykonywanie wykresów polega na wpisaniu do tego programu instrukcji plot, stem, surf itp. Wszelkie napisy, skale itp. wykonują instrukcje zapisane za plot, stem, surf, mesh itp. Na planszy można umieścić kilka rysunków. Instrukcje plot, stem i inne muszą być wtedy poprzedzone adresem rysunku (osi). Jeżeli kolejne osi nazwane są automatycznie axes1, axes2,..., to program do umieszczania wykresów na kolejnych rysunkach ma następującą strukturę: axes(handles.axes1) plot(x,y) axes(handles.axes2) stem(x,y)... Program do wykreślania czterech funkcji zamieszczono poniżej. varargout{1} = handles.output; %Wyznaczanie funkcji x=2*pi*(0:0.01:1) y1=sin(x); y2=cos(x); y3=sin(2*x); y4=cos(2*x); Y=[y1;y2;y3;y4]; % Macierz zawierająca w czterech wierszach wartości funkcji handles.x=x; % Zapis zmiennej x w strukturze handles handles.y=y; % Zapis macierzy Y w strukturze handles guidata(hobject, handles); % Oprogramowanie Listbox function listbox1_createfcn(hobject, eventdata, handles) function listbox1_callback(hobject, eventdata, handles) stan=get(hobject,'value'); % Wektor z numerami funkcji handles.stan=stan; % Umieszczenie wektora stan w strukturze handles guidata(hobject, handles); % Oprogramowanie Push Button function start_callback(hobject, eventdata, handles) stan=handles.stan; % Odzyskiwane wektora stan ze struktury handels S=size(stan); % Wyznaczanie długości nd wektora stan nd=s(1,2); x=handles.x; % Odzyskiwane zmiennej x ze struktury handels Y=handles.Y; % Odzyskiwane macierz Y ze struktury handels reset(gca) % Usuwanie poprzedniego wykresu for n=1:n % Odczytywanie wartości w wektora stan w=stan(1,n); plot(x,y(w,:)) % Wykres wiersza w macierzy Y hold on % Zachowywanie wykresu end axis([0 2*pi -1 1]) % Zakres osi wykresu

81 xlabel('x') % Opis osi x Za ostatnią linią standardowej części programu GUI, którą zapisano dla przypomnienia w pierwszym wierszu, znajduje się szereg instrukcji wykonujących obliczenia wartości funkcji. Z wartości tych funkcji tworzymy macierz Y. Obliczeń dokonujemy w tym miejscu, aby były wykonane jednokrotnie, po uruchomieniu programu. Umieszczenie ich w ramach jakiejś funkcji spowodowałoby ich powtarzanie po każdej akcji związanej z tą funkcją. Wyniki obliczeń umieszczono w strukturze handles, aby były dostępne w obrębie innych funkcji. Zmienna stan w oprogramowaniu Listbox jest wektorem o długości równej liczbie wybranych funkcji. Elementami tego wektora są liczby od 1 do 4, odpowiadające położeniu funkcji na liści. Przy zaznaczeniu sin(x) i cos(2x) wektor stan = [1 4]. Wektor stan umieszczamy w strukturze handles, aby można z niego skorzystać w ramach funkcji Push Button, nazwanej tu start. W ramach funkcji Push Button (start) realizowany jest wybór wykresów i ich wykreślanie. Najpierw odczytujemy wektor stan, następnie znajdujemy jego długość, która jest potrzebna do ustalenia liczby operacji w pętli. W kolejnych dwóch wierszach pobieramy wartości zmiennej x i macierz Y ze struktury handles. Do umieszczania kilku wykresów na jednym rysunku służy zapisana dalej instrukcja hold on. Aby uniknąć nakładania nowych wykresów na umieszczone wcześniej zapisano instrukcję reset(gca), która usuwa zawartość aktualnego rysunku (osi). Funkcja gca (skrót ang. get current axes) zwraca uchwyt (adres) aktualnego rysunku (osi). W pętli odczytujemy kolejne wartości wektora stan i rysujemy wykres wiersza wektora Y o odczytanym numerze. Instrukcja hold on jak wspomniano wyżej powoduje rysowanie kolejnych wykresów na tym samym rysunku. Poza pętlą określamy zakres osi wykresów i oznaczamy oś poziomą jako x. 4.3.7. Zastosowanie suwaka Slider Suwak Slider służy do ciągłej, ręcznej zmiany pewnego parametru. Spośród rozmaitych jego zastosowań pokażemy przykład użycia go do realizacji funkcji zoom. Na jednym rysunku pokażemy funkcję: y(n) sin( n) cos( 10 n) n w przedziale -10n+10. n=0. Na drugim rysunku wykres ten będzie powiększany wokół środka wykresu, czyli wokół Wartość parametru Value funkcji slider_callback zależy od położenia suwaka. Standardowy zakres zmian wynosi od Min=0 (lewe położenie suwaka) do Max=1 (prawe położenie suwaka. Wartości te można zmienić w Property Inspektor w wierszach Min i Max. Zmiany położenia suwaka można dokonywać przyciskając strzałki lub przesuwając myszą suwak (zmiana precyzyjna) lub przyciskając myszą na puste pole (zmiana zgrubna). Standardowo zmiana strzałkami lub suwakiem dokonywana jest z krokiem 1% zakresu, z zmian zgrubna z krokiem 10% zakresu. Można to zmienić wpisując inne wartości x, y w SliderStep w Property Inspector. Położenie spoczynkowe suwaka wynosi standardowo 0 i można je zmienić wpisując inną wartość parametru Value. W naszym przykładzie użyliśmy ustawień domyślnych (standardo-

82 wych) z wyjątkiem wpisania Max=0.9 i zmiany tła suwaka. Po tych zabiegach plansza ma postać pokazaną na rys. 4.23. Rys.4.23. Użycie suwaka Slider do realizacji funkcji zoom. Fragment programu realizującego opisane wyżej zadanie przedstawia się następująco: % Obliczenia i wykonanie górnego rysunku n=-10:0.001:10; y=sin(pi*(n+eps)).*cos(10*pi*n)./(pi*(n+eps)); handles.y=y; guidata(hobject, handles); axes(handles.axes1) plot(n,y) axes(handles.axes2) %Odwołanie do dolnego rysunku plot(n,y) % Początkowa postać dolnego rysunku % Realizacja funkcji zoom na dolnym rysunku function slider1_createfcn(hobject, eventdata, handles) function slider1_callback(hobject, eventdata, handles) z=get(hobject,'value'); % Wynik położenia suwaka y=handles.y; nd=1+round(z*10000) ng=20001-round(z*10000) skala=-10.001+(nd:ng)/1000; axes(handles.axes2) % Odwołanie do dolnego rysunku plot(skala,y(nd:ng)); % Wykonanie dolnego rysunku nmin=min(skala); % Górna granica skali rysunku nmax=max(skala); % Górna granica skali rysunku axis([nmin nmax -1 1]) % Ustalenie skali na osi wykresu

Wartość zmiennej z opisuje położenie suwaka i zmienia się od 0 do 0.9. Po każdej zmianie położenia suwaka wykonują się zamieszczone niżej instrukcje. Od wartości z uzależniono dolny i górny zakres przedziału, z którego będą pobierane dane z wektora y do sporządzenia wykresu. Od wielkości tego przedziału zależy skala wykresu, która jest dostosowana do oznaczeń występujących na górnym rysunku. Znaczenie pozostałych instrukcji podano w komentarzach do programu. 83

84 5. IMPORT I EKSPORT DANYCH 5.1. Wprowadzenie Program MATLAB może działać autonomicznie wykonując obliczenia na danych generowanych wewnątrz programu i podając wyniki obliczeń w formie liczbowej lub graficznej. Dane do obliczeń mogą być również wprowadzane do programu przez użytkownika za pomocą klawiatury. Wiemy, że istnieje także możliwość kopiowania rysunków z program MA- TLAB do innych programów, np. MICROSOFT WORD. Kopiować można także teksty występujące w oknach programu MATLAB używając standardowych procedur środowiska WINDOWS. W niektórych sytuacjach możliwości te nie są jednak wystarczające z punktu widzenia użytkownika. Często zachodzi potrzeba użycia danych pomiarowych, sygnałów i innego rodzaju danych zgromadzonych w innych programach. Dane takie można przetwarzać w programie MATLAB symulując np. pracę pewnych układów lub systemów lub wykonując określone analizy. Przy dużej liczbie danych ich wprowadzanie do programu MATLAB z klawiatury byłoby czasochłonne lub wręcz niemożliwe. W takich sytuacjach program MA- TLAB oferuje specjalne procedury importu danych. Wynikiem obliczeń wykonywanych w programie mogą być również zbiory o dużej objętości, zawierające np. sygnały o długim czasie trwania. Sygnały te mogą być wykorzystywane w innych programach. Dobrym przykładem jest przetwarzanie sygnałów mowy, które efekty należy przekazać do programu umożliwiającego ich odsłuch. Realizują to procedury eksportu danych. W dalszej części rozdziału omówimy podstawowe metody importu i eksportu danych, które mogą być przydatne Czytelnikowi w trakcie samodzielnego rozwiązywania niezbyt trudnych zadań programistycznych. 5.2. Eksport i import danych w formacie binarnym W formacie binarnym zapisujemy i odczytujemy dane liczbowe w formie plików o rozszerzeniu.mat. Do zapisu danych liczbowych używana jest funkcja save: Instrukcja save nazwa_pliku zapisuje w pliku nazawa_pliku wartości liczbowe wszystkich zmiennych występujących w przestrzeni roboczej. Program C samoczynnie dodaje do nadanej nazwy pliku rozszerzeniem.mat. Oto przykład clear % Usuwa wszystkie zmienne z przestrzeni roboczej x=1:100; y=x.^2; save funkcja_kwadratowa; W katalogu Work pojawia się plik o nazwie funkcja_kwadratowa.mat zawierający wartości zmiennych x i y. Dane te można wprowadzić ponownie do przestrzeni roboczej używając funkcji load. W tym celu zapisujemy następujące instrukcje: clear who load funkcja_kwadratowa.mat who x y % Usuwa wszystkie zmienne z przestrzeni roboczej % Polecenie podaje zawartość przestrzeni roboczej (jest pusta) % Zapisuje zawartość pliku w przestrzeni roboczej % Polecenie sprawdzenia zawartości przestrzeni roboczej % W oknie Command Window ukazują się wartości x % W oknie Command Window ukazują się wartości x

85 Jeżeli po nazwie pliku umieści się wykaz zmiennych, to tylko te zmienne zostaną zapisane w pliku. clear x=1:4; y=x.^2; z= 1./x; save proba x z Poleceniem load proba ładujemy zmienne zapisane w pliku proba.mat do przestrzeni roboczej programu MATLAB. clear; load proba who Program zwraca: Your variables are: x y %Sprawdzanie aktualnej zawartości przestrzeni roboczej Zmienne są teraz dostępne w przestrzeni roboczej i mogą być odpowiednio przetwarzane. 5.3. Zapisywanie i czytanie danych w formacie tekstowym Zmienne z przestrzeni roboczej mogą być zapisane w pliku tekstowym, co umożliwia korzystanie z nich w innych programach. Dokonuje się tego poleceniem save nazwa_pliku symbole_zmiennych -ascii. clear x=1:100; y=x.^2; z= 1./x; save tekst x y -ascii Zmienne x i y zostają zapisane w pliku tekstowym o nazwie tekst. Do nazwy pliku można dołączyć rozszerzeni.txt. Plik znajduje się w katalogu Work. Można go umieścić w innym katalogu zmieniając ścieżkę w Current Directory. Załadowanie tego pliku do pamięci powoduje powstanie jednej zmiennej o nazwie tekst w postaci prostokątnej macierzy zawierającej w pierwszym wierszu zmienną x a w drugim zmienną y. Plik ten może być wczytany np. w programie EXCEL. Uzyskuje się wówczas zapis w postaci dwóch wierszy o wartościach x i y. Zawartość pliku tekst wpisujemy do przestrzeni roboczej programu MATLAB następującą instrukcją: load tekst Należy z naciskiem podkreślić że w przestrzeni roboczej nie występują teraz zmienne x i y, co sprawdzamy pisząc: clear load tekst x Undefined function or variable 'x'. Wartości zmiennej x lub y można wprowadzić do przestrzeni roboczej używając instrukcji x=tekst(1,:); y=tekst(2,:);

86 5.4. Eksport i import plików dźwiękowych W programie MATLAB można tworzyć pliki dźwiękowe i dokonywać ich zapisu w formacie wav. Plik dźwiękowy można stworzyć z dowolnego jednokolumnowego wektora. Dokonuje się tego poprzez zapisanie tego wektora poleceniem wavwrite. Wektor powinien zawierać liczby wyłącznie z przedziału < 1 1 >. Liczby wykraczające poza ten przedział zostaną przycięte na poziome odpowiednio 1 albo1. Dla przykładu podany zostanie sposób stworzenia dwusekundowego dźwięku o częstotliwości 800 Hz, próbkowanego z częstotliwością 44100 Hz. t=(1:2*44100)/44100; f=800; x=sin(2*pi*f*t) ; wavwrite(x,44100,16, ton ) Sygnał został zapisany w formacie 16-to bitowym. %Wektor momentów tworzenia próbek % Częstotliwość sygnału %Wektor kolumnowy sygnału %Zapis sygnału w pliku ton Jeżeli wektor x istnieje w przestrzeni roboczej, to można odsłuchać sygnał dźwiękowy poleceniem sound(x, 44100,16) Podanie w poleceniu tylko sound(x) spowoduje odtworzenie dźwięku przy częstotliwości próbkowania 8kHz i z dynamiką 16bitów. Do programu MATLAB można importować pliki dźwiękowe typu wav. Maja one postać wierszowego lub kolumnowego wektora. Aby po wczytaniu uzyskać pełną informację o wartościach próbek dźwięku, częstotliwości próbkowania oraz dynamice należy użyć następującej instrukcji: [x,a,b]=wavread(nazwa pliku,n) W rezultacie poszczególne zmienne będą zawierały: x b c N - wierszowy (kolumnowy) wektor próbek, - częstotliwość próbkowania, - dynamika próbek (w bitach). - liczba próbek (opcjonalna) Proces czytania plików można zaprogramować z możliwością wyboru myszą. Poniżej podano przykład takiego programu [FN,PN]=uigetfile('*.wav','Wybierz plik do obróbki'); if any(pn)==1 [x,fp,bits]=wavread(char([pn,fn])); end Pojawia się okno zatytułowane Wybierz plik do obróbki, w którym można myszą wybrać interesujący nas plik z rozszerzeniem.wav. Zawartość tego pliku zostanie wczytana do przestrzeni roboczej w formie wektora x. Program MATLAB ma obszerny zestaw funkcji i instrukcji związanych z importem i eksportem danych. W szczególności dotyczą one importu i eksportu funkcji, obiektów graficznych, Internetu, kompresji danych, plików dźwiękowych i plików wideo, formatowania, otwierania, zamykania i konwersji plików, obsługi portu szeregowego itp. Kompletny wykaz tych instrukcji można znaleźć pisząc: help iofun

87

CZĘŚĆ II. ZASTOSOWANIA PROGRAMU MATLAB 88

89 6. METODY NUMERYCZNE W ZASTOSOWANIU DO FUNKCJI CIĄGŁYCH Przedstawione dotychczas operacje matematyczne dotyczyły nieciągłych zbiorów liczbowych, którymi zajmuje się dział matematyki zwanej matematyką dyskretną. W innych działach matematyki, np. w analizie matematycznej, równaniach różniczkowych, geometrii analitycznej itp. rozpatruje się relacje na zbiorach ciągłych. Pojawiają się w nich zagadnienia, których rozwiązania analityczne są niemożliwe, lub ich uzyskanie jest bardzo skomplikowane. Stosuje się wtedy metody numeryczne, które dają przybliżone rozwiązania liczbowe. Program MATLAB dysponuje licznymi procedurami z zakresu metod numerycznych, których niewielką część przedstawimy w tym podrozdziale. Charakterystyczną cechą pokazanych dalej metod numerycznych jest to, że odnoszą się one do funkcji określonych na zbiorach ciągłych. Wymaga to z reguły zdefiniowania takiej funkcji nim zastosujemy do nie metody numeryczne. 6.1. Wielomiany Wielomian N-tego stopnia jest ciągłą funkcja jednej zmiennej o następującym zapisie: W (x,a) a(1)x N N a(2)x N 1... a(n)x Nn1... a(n)x a(n 1) Jak widać wielomian jest jednoznacznie zdefiniowany przez wartości współczynników a(n), które mogą być liczbami rzeczywistymi lub zespolonymi. Innym sposobem definiowania wielomianu jest podanie wartości jego pierwiastków. Wielomian N-tego stopnia ma N pierwiastków rzeczywistych bądź zespolonych, które oznaczymy jako r(n). Powyższy wielomian można wtedy zapisać jako: W(x,r) a(1)[x r(1)] [x r(2)]... [x r(n)]... [x r(n)] Jeżeli znane są pierwiastki wielomianu to funkcja a=poly(r) wyznacza wartości współczynników a(n) poczynając od a(1), kończąc na a(n+1). Pokażemy to na następującym przykładzie: >> r=[-1 0 1 2 ]; >> a=poly(r) a = 1-2 -1 2 0 Zdefiniowany w ten sposób wielomian ma postać: W(x,a) x Funkcja r=roots(a) 4 2x 3 x 2 2x wyznacza pierwiastki wielomianu. Dla podanego wyżej wielomianu, zdefiniowanego współczynnikami a(n) mamy: >> r=roots(a) r = 0-1.0000 2.0000 1.0000

90 Podany niżej wielomian ma pierwiastki zespolone. Funkcja roots podaje je w następującej formie: W(x,a) x 3 6x >> a=[1-6 21-26] >> r=roots(a) r = 2.0000 + 3.0000i 2.0000-3.0000i 2.0000 2 21x 26 Wartości wielomianu w punkcie x lub dla wektora bądź macierzy x wyznacza funkcja W=polyval(a,x) Przykładowo: >> W=polyval(a,[2+i*3 0]) W = 0-26 co jest oczywiste, gdyż pierwsza wartość zmiennej jest pierwiastkiem wielomianu, a druga daje współczynnik przy zerowej potędze. 6.2. Funkcje wymierne zmiennej zespolonej Funkcją wymierną nazywamy iloraz wielomianów B M (s,b) i A N (s,a): M BM(s,a) b(1)s A (s,b) a(1)s N N b(2)s a(2)s M1 N1... b(m)s... a(n)s Mm1 Nn1 b(m 1) a(n 1) Funkcje wymierne mają szerokie zastosowanie w analizie i syntezie obwodów i systemów, gdyż opisują m.in. transmitancję układów liniowych. Analiza transmitancji wymaga często znajomości zer i biegunów funkcji wymiernych. W celu ich wyznaczenia powyższą funkcję wymierną można zapisać w następującej postaci: BM(s,b) r(1) r(2) r(n)... K(s,k) A (s,a) s p(1) s p(2) s p(n) N gdzie r(n) są residuami, p(n) biegunami funkcji, a K(s,k) wielomianem stopnia M-N+1. Jeżeli M=N-1, to wielomian K(s,k) nie występuje. Jeżeli pewien n-ty biegun występuje U-krotnie, czyli p(n)=p(n+1)= =p(n+u-1), wówczas w powyższym wzorze mamy: BM(s,b) r(1) r(n) r(n 1)... A (s,a) s p(1) s p(n) [s p(n)] N 2 r(n U)... [s p(n)] U r(n U)... K(s,k) s p(n U) Program MATLAB dysponuje funkcją residue, która wyznacza residua r, bieguny p i współczynniki k, jeżeli funkcji wymiernej opisanej współczynnikami b i a. Zapis tej funkcji jest następujący: [R,P,K]=residue(B,A) Wektory B i A zawierają współczynniki b i a wielomianu w liczniku i mianowniku. Funkcja zwraca wektor R zawierający kolejne residua r, wektor P kolejne bieguny p, a wektor K kolejne współczynniki k wielomianu K(s,k). Weźmy jako przykład funkcję:

91 B2(s) A (s) s 3 3 6s 2 12s 46s 86 2 47s 60 Oto program wyznaczający residua i bieguny tej funkcji: >> B=[6-46 86]; >> A =[1-12 47-60]; >> [R,P,K]=residue(B,A) R = 3.0000 2.0000 1.0000 P = 5.0000 4.0000 3.0000 K = [] Zgodnie z przewidywaniami wektor K jest pusty, gdyż stopień wielomianu w liczniku jest o jeden mniejszy od stopnia mianownika. Można łatwo sprawdzić, że wyznaczone bieguny są zerami mianownika: >> P=roots(A) P = 5.0000 4.0000 3.0000 Dla tych wartości s rozpatrywana funkcja osiąga nieskończoność. W technice większe znaczenie mają funkcje wymierne o biegunach zespolonych. Wyznaczmy residua i bieguny takiej funkcji, np.: 3 B3(s) 6s 34s 80s 60 A (s) 4 3 2 s 8s 32s 48s 36 4 2 Definiujemy tą funkcję i wyznaczamy jej poszukiwane wartości: >> B =[6-34 80-60]; >> A =[1-8 32-48 36]; >> [R,P,K]=residue(B,A) R = 2.0000-0.0000i 2.0000 1.0000 + 0.0000i 1.0000-0.0000i P = 3.0000 + 3.0000i 3.0000-3.0000i 1.0000 + 1.0000i 1.0000-1.0000i K = [] Wszystkie bieguny są tu zespolone, a dodatkowo parami sprzężone. Zamieszczony niżej program sporządza trójwymiarowy wykres rozpatrywanej funkcji, który pokazano na rys. 6.1. % OBLICZENIA A= [1-8 32-48 36]; % wektor współczynników wielomianu mianownika

92 B=[6-34 80-60]; res=0:0.005:5; ims=-5:0.005:5; [X,Y]=meshgrid(res,ims); S=X+i*Y; L=polyval(B,S); M=polyval(A,S); W=abs(L./M); % wektor współczynników wielomianu mianownika % część rzeczywista zmiennej s % część urojona zmiennej s % część rzeczywista X i urojona S w formie macierzowej % macierz zmiennej s % wartości licznika %wartości mianownika % wartości bezwzględne funkcji wymiernej % GRAFIKA % Operacje ograniczenia wykresu do wartości 10 P=W<10; % Macierz pomocnicza wyznaczająca elementy spełniające nierówność WP=W.*P; % Macierz wartości spełniających nierówność R=W>=10; % Macierz pomocnicza wyznaczająca elementy spełniające nierówność WO=WP+R*10; % Macierz przeznaczona do reprezentacji graficznej % Wykres surf(res,ims,wo,'linestyle','none') xlabel('re(s)');ylabel('im(s)') camlight(10,-5) lighting phong Rys. 6.1. Wykres funkcji wymiernej zmiennej zespolonej s. Przy wykonaniu powyższego wykresu pojawiają się dwa problemy, które wymagają komentarza. Po pierwsze należy utworzyć macierz zmiennej zespolonej s tak, aby w kolumnach występowały kolejne wartości części rzeczywistej zmiennej s, a w wierszach części urojone. Wykorzystano do tego celu funkcję meshgrid, którą stosuje się w grafice trójwymiarowej. Działanie tej funkcji ilustruje prosty przykład: >> x=[1:4]; >> y=[-2:2]; >> [X,Y]=meshgrid(x,y)