MATEMAATTISET OHJELMISTOT Syksy 2012 Matlab-luennot, 1. osa Sisältö 1 Johdanto 1 2 Käyttöliittymä 3 3 Käytön perusteita 4 4 Matriiseista 7 4.1 Muodostaminen.............................. 7 4.2 Valmismatriisit.............................. 8 4.3 Indeksointi................................. 11 4.4 Laskutoimitukset............................. 15 4.5 Alkioittaiset operaatiot.......................... 18 5 Hieman lineaarialgebraa 19 1 Johdanto Matlab on interaktiivinen numeerisen laskennan ohjelmisto. Se on tehokas, monipuolinen ja laajalti käytössä teollisuudessa, yliopistoissa ja muissa tutkimuslaitoksissa. Matlabissa yhdistyvät laskentatehokkuus, ohjelmoitavuus ja visualisointi. Matlabin ensimmäisen version kirjoitti Fortran-ohjelmointikielellä Cleve Moler 1970-luvun lopulla. Ohjelman saavutettua suosiota sekä opetus- että tutkimuskäytössä se kirjoitettiin uudelleen C-ohjelmointikielellä. Ensimmäinen kaupallinen versio, Matlab 1.0, julkaistiin vuonna 1984. Alunperin Matlab kehitettiin matriisilaskennan ohjelmistoksi (MATrix LABoratory), mutta nykyään se on laajentunut hyvin monelle sovellusalueelle. Matlabille on tehty suuri joukko ns. toolboxeja, joilla on laajennettu Matlabin toiminnallisuutta uusille alueille. Toolboxit on kirjoitettu Matlabin omalla ohjelmointikielellä ja niitä on tarjolla signaalin- ja kuvankäsittelyyn, optimointiin, sumeaan logiikkaan, neuroverkkoihin, osittaisdifferentiaaliyhtälöiden ratkaisemiseen ym. Tällä kurssilla ei kuitenkaan käytetä mitään Matlabin toolboxeista, koska niiden saatavuus voi vaihdella suuresti. 1
Matlabilla on useita etuja perinteisiin numeerisen laskennan työkaluihin (esim. Fortran- ja C-ohjelmointi) verrattuna: Ohjelmointi Matlabin korkean tason kielellä on nopeaa ja kohtalaisen helppoa. Tietorakenteisiin ei tarvitse kiinnittää samassa määrin huomiota kuin perinteisillä ohjelmointikielillä. Erityisesti taulukoita (matriiseja) ei tarvitse esitellä ennen käyttöä. Interaktiivinen käyttöliittymä mahdollistaa erilaiset nopeat kokeilut (ns. prototyypitys). Korkeatasoisen grafiikan ja visualisoinnin teko on helppoa. Matlabilla tehdyt m-tiedostot ovat täysin siirrettäviä eri tietokonealustojen välillä. Ohjelmistoa voidaan laajentaa toolboxeilla. Edelleen Matlab on moderni ohjelmointikieli ja ongelmanratkaisuympäristö. Siinä on kehittyneet tietorakenteet, se sisältää editorin ja virheentarkistus-työkalut (ns. debuggaus). Se tukee nykyään myös oliosuuntautunutta ohjelmointia. Matlab on tulkattava kieli, joten se kärsii pienestä tehohäviöstä käännettäviin kieliin verrattuna. Uusimmat versiot sisältävät kuitenkin erilaisia sisäänrakennettuja kiihdytysmenetelmiä. Matlabia voi käyttää interaktiivisesti sen oman käyttöliittymän avulla tai voidaan ajaa Matlabin ohjelmointikielellä itse kirjoitettuja Matlab-ohjelmia. Matlab-ohjelmia voidaan myös integroida Matlab-ympäristön ulkopuolisiin sovelluksiin, jotka on tehty käännettävillä ohjelmointikielillä (esim. C, C++, Fortran tai Java). Siis voidaan esimerkiksi käyttää Matlabista käsin ko. kielillä tehtyjä ohjelmia. Edelleen on mahdollista kääntää Matlab-ohjelmia C- tai C++ -kielelle tehokkaampaa suoritusta varten. Matlab koostuu viidestä pääosasta: Kehitysympäristö. Matlabin interaktiivinen käyttöliittymä, jolla voidaan käyttää Matlabin valmiita komentoja tai funktioita. Kehitysympäristö sisältää myös työkalut, joiden avulla voidaan tehdä omia Matlab-ohjelmia. Matlabin matemaattisten funktioiden kirjasto sisältää Matlabin laskenta-algoritmit erilaisille matemaattisille funktioille, aina alkeisfunktioista erikoisfunktioihin ja erilaisiin matriisioperaatioihin sekä muunnoksiin. Matlabin ohjelmointikieli. Grafiikkaosa sisältää Matlabin grafiikkaominaisuudet. Matlab API (Application Program Interface). Matlabin ulkoisten kielien (ohjelmien) liittymä, jonka avulla voidaan kirjoittaa C- ja Fortran- ohjelmia, jotka vuorovaikuttavat Matlabin kanssa. Siis voidaan kutsua esim. Fortranohjelmia Matlabista tai Matlabia voidaan käyttää Fortran-ohjelmasta. 2
2 Käyttöliittymä Ikkunointia käyttävissä käyttöjärjestelmissä Matlab käynnistyy Kuvan 1 kaltaiseen käyttöliittymään, Matlabin työpöytään (Matlab Desktop). Työpöytä sisältää työkalut tiedostojen, muuttujien ja Matlabiin liitettyjen sovellusten hallintaan. Työpöydän ulkoasua voidaan muuttaa (esim. View-valikosta) työkalujen ikkunoita avaamalla, sulkemalla, siirtämällä ja niiden kokoa muuttamalla. Kuva 1: Matlabin graafinen käyttöliittymä (R2012b) Keskellä on komentoikkuna (Command Window), johon Matlabin komennot syötetään. Oikealla alhaalla on komentohistoriaikkuna (Command History), joka tallettaa kaikki komentoikkunaan syötetyt komennot. Historiaikkunasta voidaan esim. valita aiemmin suoritettuja komentoja uudelleen suoritettavaksi. Historiaikkunan yläpuolella on työtilaikkuna (Workspace). Työtilaikkunasta nähdään sillä hetkellä käytössä olevat muuttujat ja mm. niiden koko. Kaksoisnäpäyttämällä muuttujaa työtilaikkunassa avautuu Variable Editor, jolla voidaan mm. muokata muuttujan arvoa. Työtila voidaan tallettaa myöhempää käyttöä varten MAT-tiedostoksi File valikon Save Workspace As komennolla. Vasemmalla on hakemistoikkuna (Current Folder). Siitä nähdään sen hetkinen työhakemisto, jota voidaan muuttaa Current Folder Browserin (keskellä ylhäällä) avulla. Matlab käyttää ns. hakupolkua (search path) etsiessään M-tiedostoja ja muita Matlab-tiedostoja. Niinpä on usein syytä omien, varsinkin isompien, pro- 3
jektien yhteydessä määritellä oma työhakemisto Matlabin hakupolkuun. Tämä tapahtuu esimerkiksi File valikon Set Path komennolla. Käyttöliittymään voidaan kiinnittää (dock) muita ikkunoita, esimerkiksi kuvaajia, tai käyttöliittymän ikkunoita voidaan irrottaa (undock) omiksi ikkunoikseen. Tämä tapahtuu joko Desktop valikosta tai kussakin ikkunassa olevasta dock/undock napista. Edelleen käyttöliittymään kuuluu Matlabin oma editori/debuggeri, mutta tähän palaamme, kun alamme kirjoittamaan omia Matlabohjelmia. Lisäksi Help valikon alta löytyy Matlabin dokumentaatio eli eräs työpöydän käytetyimmistä osista. Edelleen vasemman alanurkan Start napilla pääsee helposti käsiksi Matlabin työkaluihin, demoihin ja dokumentaatioon. Matlabia voi käyttää myös tekstipohjaisella käyttöliittymällä (komentorivi), jolloin näkyvissä on pelkkä komentokehote >> 1+2+3 3 Käytön perusteita Matlab komennot syötetään komentoikkunaan ja päätetään tuttuun tapaan painamalla ENTER. Matlabissa ei ole erityistä rivin lopetusmerkkiä, mutta jos ei haluta tulosta näytölle, lopetetaan rivi puolipisteeseen. Tämän lisäksi seuraavat asiat on hyvä pitää mielessä: Matlab on case sensitive eli isoilla ja pienillä kirjaimilla on eri merkitys. Kirjoittamalla muuttujan nimi nähdään muuttujan arvo. Matlabissa käytetään kaarisulkeita ( ), hakasulkeita [ ] ja aaltosulkeita { }. Niillä kaikilla on eri merkitys ja käyttötarkoitus. Ylös- ja alas-nuolinäppäimillä voidaan selata aiemmin annettuja komentoja. Vanhaa komentoa voidaan myös hakea kirjoittamalla pari ensimmäistä merkkiä ja painamalla ylös-nuolinäppäintä. Komennolla help aihe saadaan lyhyt avuste komennosta, funktiosta tai symbolista aihe. Huomaa, että Matlab käyttää myös hyperlinkkejä, joita klikkaamalla pääsee avusteisiin. Kattavampi avuste avautuu komennolla doc aihe. Jos painetaan sarkainnäppäintä (TAB, tabulaattori) sen jälkeen, kun funktion tai muuttujan nimi on osittain syötetty, saadaan näkyviin lista mahdollisista kokonaisista funktion tai muuttujan nimistä. Kirjoittamalla exit tai quit lopetetaan Matlabin käyttö. Matlabia voi käyttää tutusti laskimen tapaan: >>sin(pi/2) + sqrt(4)*i 1.0000 + 2.0000i 4
Matlabissa luku π on siis pi ja imaginääriyksikkö on i tai j. Kompleksiluvut esitetään tutusti muodossa a + bi. Piin ja imaginääriyksikön lisäksi Matlabissa on muutamia muita vakioita: >>eps, realmin, realmax, Inf, NaN 2.2204e-016 2.2251e-308 1.7977e+308 Inf NaN Matlab sijoittaa komennon tuloksen muuttujaan ans, jos käyttäjä ei itse sijoita tulosta johonkin muuhun muuttujaan. Matlabissa sijoitusoperaattorina toimii =. Muuttujia voidaan siten määritellä yksinkertaisesti sijoituskäskyllä eli muodossa muuttuja = lauseke. Matlabin muuttujat eivät vaadi erityistä tyypin tai dimension määrittelyä. Matlabin havaittua uuden muuttujan nimen, se luo ko. muuttujan ja varaa sille tarvittavan tilan. Jos muuttuja on jo aiemmin määritelty, Matlab korvaa sen sisällön uudella sisällöllä, sekä varaa tarvittaessa lisää tilaa. Muuttujan nimi muodostuu kirjaimesta, jota seuraa mikä tahansa määrä kirjaimia, numeroita tai alaviivoja. Matlab huomioi kuitenkin vain muuttujan nimen 63 ensimmäistä merkkiä. Edelleen Matlab erottaa isot ja pienet kirjaimet eli muuttuja ja Muuttuja ovat eri muuttujia. Muuttujan arvo nähdään syöttämällä muuttujan nimi. Esim. >>a = 56; b = 3 b = 3 >>c = a*b; >>c c = 168 Komennolla who nähdään sillä hetkellä Matlabissa määritellyt muuttujat. Edelleen komennolla whos nähdään tarkempaa tietoa määritellyistä muuttujista, mm. niiden viemä muistitila. Nämä tiedot ovat näkyvillä myös Matlabtyöpöydän työtilaikkunassa. 5
>>who Your variables are: a ans b c >> whos Name Size Bytes Class Attributes a 1x1 8 double b 1x1 8 double c 1x1 8 double Muuttujan voi poistaa komennolla clear muuttuja. Komento clear poistaa kaikki muuttujat. Komento clc tyhjentää komentoikkunan näkymän (ei kuitenkaan muuttujia). Matlabissa on sisäänrakennettuina useimmat alkeisfunktiot sekä lukuisia erikoisfunktioita. Esim. >>[abs(3 + 2*i), angle(3 + 2i), atanh(pi/4), log(exp(1)), gamma(2.5)] 3.6056 0.5880 1.0593 1.0000 1.3293 Tulostuksen muotoa, ei sitä millä tarkkuudella Matlab laskee, voidaan säätää format-komennolla. Oletuksena on format short, jolloin tulostuksessa on neljä desimaalia (vrt. yllä). Muita vaihtoehtoja: >>format long, ans Columns 1 through 3 3.60555127546399 0.58800260354757 1.05930617082324 Columns 4 through 5 1.00000000000000 1.32934038817914 >>format rat, ans 4936/1369 892/1517 1679/1585 1 222/167 >>format short % palautetaan oletusmuoto Katso lisää tietoa komennolla help format. Matlabissa prosenttimerkki % on kommenttimerkki. Jos komennot eivät mahdu yhdelle riville, käytetään Matlabissa jatkomerkkinä kolmea pistettä (... ). Yhdellä rivillä voi syöttää useampia komentoja pilkuilla erotettuna. Komentorivillä voi liikkua nuolinäppäimillä oikealle ja vasemmalle, ja aiemmin syötettyjä komentoja voi selata nuolinäppäimillä ylös ja alas. 6
4 Matriiseista Matlabin peruselementti on matriisi. Skalaaria voidaan Matlab-ympäristössä ajatella 1 1-matriisina. Vastaavasti n-alkioista vektoria voidaan pitää joko 1 n- (vaakavektori) tai n 1-matriisina (pystyvektori). 4.1 Muodostaminen Matriisi voidaan muodostaa mm. syöttämällä alkiot hakasulkujen sisään. Esim. komennolla >>[1 2 3; 4 5 6] muodostetaan 2 3-matriisi 1 2 3 4 5 6 Syötettäessä matriisia, rivit erotetaan puolipisteellä ja sarakkeet pilkulla tai välilyönnillä. Siis vaakavektori ja pystyvektori muodostetaan seuraavasti: >>[1 2 3 4 5 6], [1, 2, 3, 4, 5, 6], [1; 2; 3; 4; 5; 6] 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 Matriisin transpoosia varten on kaksi operaattoria, ja.. Näistä ensimmäinen muodostaa kompleksiarvoisille matriiseille konjugoidun transpoosin, kun taas jälkimmäinen ei (normaali transpoosi). Esim. >> [1 2 3] 1 2 3 7
>> [1 2 3+i] 1.0000 2.0000 3.0000-1.0000i >> [1 2 3+i]. 1.0000 2.0000 3.0000 + 1.0000i Matlabissa hyvin tärkeä kaksoispisteoperaattori : helpottaa yllä olevan kaltaisten vektorien ja matriisien muodostamista. Esimerkiksi seuraavassa muodostetaan vaakavektori kokonaisluvuista yhdestä kymmeneen, sekä 3 3-matriisi luvuista yhdestä yhdeksään: >>a = 1:10, A = [1:3; 4:6; 7:9] a = A = 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 Oletusaskel on ykkösen suuruinen, mutta sen voi määritellä myös itse: >>0: pi/2 : 2*pi 0 1.5708 3.1416 4.7124 6.2832 >>20 : -0.2 : 19 20.0000 19.8000 19.6000 19.4000 19.2000 19.0000 4.2 Valmismatriisit Matriisi voidaan muodostaa myös käyttämällä Matlabissa olevia valmiita komentoja tietyille erikoismatriiseille: 8
>>zeros(2,3), ones(3) % 2x3-matriisi nollista, 3x3-matriisi ykkösistä 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 >>eye(3), diag(1:2:8) % yksikkömatriisi ja diagonaalimatriisi 1 0 0 0 1 0 0 0 1 1 0 0 0 0 3 0 0 0 0 5 0 0 0 0 7 Komennolla rand saadaan matriisi, jonka alkiot ovat tasanjakautuneita satunnaislukuja väliltä (0, 1). Komennolla randn saadaan puolestaan satunnaislukuja normaalijakaumasta N(0, 1) sisältävä matriisi. >>s1 = rand(3) s1 = 0.4103 0.3529 0.1389 0.8936 0.8132 0.2028 0.0579 0.0099 0.1987 >>s2 = randn(1, 6) s2 = 0.1139 1.0668 0.0593-0.0956-0.8323 0.2944 Matlabissa on myös hieman erikoisempia valmismatriiseja. Esimerkiksi ns. maaginen matriisi, jonka rivien, sarakkeiden ja diagonaalien summa on sama luku. >>help magic MAGIC Magic square. MAGIC(N) is an N-by-N matrix constructed from the integers 9
1 through Nˆ2 with equal row, column, and diagonal sums. Produces valid magic squares for all N > 0 except N = 2. >>M = magic(4) M = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1 Hilbertin matriisi, Vandermonden matriisi ja Pascalin matriisi (symmetrinen, positiivisesti definiitti matriisi, jonka alkiot on poimittu Pascalin kolmiosta): >>Hile = hilb(3), Vand = vander(1:3), Pasc = pascal(4) Hile = 1.0000 0.5000 0.3333 0.5000 0.3333 0.2500 0.3333 0.2500 0.2000 Vand = 1 1 1 4 2 1 9 3 1 Pasc = 1 1 1 1 1 2 3 4 1 3 6 10 1 4 10 20 Edelleen on mahdollista muodostaa matriiseja lataamalla matriisi jostain datatiedostosta load-funktiolla. Tiedosto voi olla binääritiedosto (.mat-tiedosto), johon on talletettu aiemmassa Matlab-istunnossa määriteltyjä matriiseja tai tekstitiedosto. Tarkempaa tietoa saa komennolla help load. Lisäksi matriiseja voi tallettaa ja lukea M-tiedostoihin, jotka ovat Matlab-koodia sisältäviä tekstitiedostoja. M-tiedostoja voi tallettaa ja muokata millä tahansa tekstieditorilla tai Matlabin omalla editorilla. M-tiedostot talletetaan.m-päätteellä ja niitä voidaan kutsua Matlab-istunnosta kirjoittamalla tiedoston nimi ilman.m-päätettä tai sen kanssa. Lisäksi matriiseja voi muodostaa yhdistämällä matriiseja toisiinsa. Matlabin yhdistämisoperaattori on hakasulut eli [ ]. Itse asiassa, kun edellä teimme ensimmäisen matriisimme, yhdistimme vain sen yksittäiset alkiot tällä yhdistämisoperaattorilla. >>yhdistys = [Pasc M; Pasc+ones(4) M+eye(4)] yhdistys = 10
1 1 1 1 16 2 3 13 1 2 3 4 5 11 10 8 1 3 6 10 9 7 6 12 1 4 10 20 4 14 15 1 2 2 2 2 17 2 3 13 2 3 4 5 5 12 10 8 2 4 7 11 9 7 7 12 2 5 11 21 4 14 15 2 Matriisien täytyy olla tietenkin dimensioiltaan yhteensopivia: >>yhdistys2 = [Pasc; Hile]??? Error using ==> vertcat CAT arguments dimensions are not consistent. Matriisin koko selviää helposti komennolla size: >>size(yhdistys) 8 8 4.3 Indeksointi Matriisin alkioita voidaan valita laittamalla nimen perään sulkuihin alkion rivija sarakeindeksi, siis >>M(2,3) 10 Indeksointi alkaa luvusta 1. Voidaan käyttää myös yhtä indeksiä, jolloin matriisin voi ajatella yhdeksi suureksi pystyvektoriksi, jossa on alkuperäisen matriisin alkiot asetettuna sarakkeittain peräkkäin, siis >>M(10) 10 Kerralla voidaan valita useampia alkioita käyttämällä kaksoispisteoperaattoria. Matriisin M kolmannen rivin toinen ja kolmas alkio: >>M(3, 2:3) 7 6 11
Koko rivi tai sarake voidaan valita pelkällä kaksoispisteellä, minkä lisäksi on käytössä varattu sana end viimeiselle riville ja sarakkeelle: >>M(end, :) 4 14 15 1 >>M(:, end) 13 8 12 1 >>M(end, end) 1 Alkioita voidaan valita myös sillä perusteella, toteuttavatko ne jonkin loogisen ehdon: >>M( isprime(m)) = 0 % kaikki ei-alkuluvut nolliksi matriisissa M M = 0 2 3 13 5 11 0 0 0 7 0 0 0 0 0 0 >>M = M( M>0 ) % Poimitaan matriisin M positiiviset alkiot M = 5 2 11 7 3 13 >>M = magic(4); Huomaa, että edellä käytettiin operaattoria, joka muodostaa matriisin transpoosin (kompleksiarvoisille matriiseille konjugoidun transpoosin). Matlabin find-funktiolla voidaan etsiä tietyn ehdon täyttävät alkiot: >>k = find(isprime(m)) k = 2 5 6 7 9 13 Tässä find palautti ehdon täyttävien alkioiden yksiulotteiset indeksit vektoriin k. Matriisista voidaan tämän jälkeen poimia ehdon täyttävät alkiot käyttämällä saatua indeksivektoria k: 12
>>M(k) 5 2 11 7 3 13 Jos koetetaan viitata alkioon matriisin indeksirajojen ulkopuolelta, saadaan virheilmoitus >>m = M(5,1)??? Index exceeds matrix dimensions. Kuitenkin, jos sijoitetaan arvo sellaiselle matriisin alkiolle, jota ei ole vielä olemassa, niin matriisi laajenee sellaiseksi, että lisätty alkio tai alkiot mahtuvat mukaan >>X = M; >>X(5,:) = zeros X = 16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1 0 0 0 0 Matriisin kokonaisia rivejä tai sarakkeita voidaan tuhota käyttämällä tyhjää yhdistämisoperaattoria []. >>X(:,3) = [] X = 16 2 13 5 11 8 9 7 12 4 14 1 0 0 0 Erityisesti yksiulotteisen vektorin alkioita voidaan poistaa: >>Y=1:5, Y(2:3)=[] Y = Y = 1 2 3 4 5 1 4 5 Kuitenkin: 13
>>X(2,2) = []??? Subscripted assignment dimension mismatch. Jos matriisista tuhoaa yhden elementin, ei tulos enää ole matriisi, joten edellisen kaltainen komento ei toimi. Käyttämällä yhtä indeksiä eli käsittelemällä koko matriisia yhtenä sarakevektorina, voidaan yksittäinen alkio tai alkioita poistaa. Tällöin matriisin jäljelle jääneistä alkioista tulee vaakavektori: >>X(6 : 2 : 13) = [] X = 16 5 9 4 0 11 14 13 12 1 0 Indeksejä käyttämällä voidaan muodostaa aritmeettisia operaatioita eli esimerkiksi matriisin M kolmannen sarakkeen alkioiden summa >>M(1,3) + M(2,3) + M(3,3) + M(4,3) 34 Tällaisiä usein tarvittuja operaatioita varten on Matlabissa valmiita funktioita, siis kolmannen sarakkeen alkioiden summa matriisissa M on: >>sum(m(:,3)) 34 Yleisemmin, sum-komento laskee oletuksena matriisin alkioiden summan sarakkeittain: >>sum(yhdistys) 12 24 44 74 69 69 69 69 Jos halutaan laskea summa riveittäin, niin se voidaan tehdä käyttämällä samaa sum-komentoa matriisin transpoosille. Matriisin yhdistys rivisumma: >>sum(yhdistys ) % konjugointi ei haittaa 38 44 54 69 43 49 59 74 Lasketaan maagisen matriisin M rivi-, sarake- ja diagonaalisummat. Huomaa, että diag poimii matriisin diagonaalin vektoriksi, kun sille annetaan argumentiksi matriisi. 14
>>sum(m), sum(m ), sum(diag(m)) 34 34 34 34 34 34 34 34 34 Matriisi on siis maaginen. 4.4 Laskutoimitukset Koska matriisi on Matlabin peruselementti, niin peruslaskutoimitukset voidaan tehdä matriiseille ilman mitään erityistoimenpiteitä: >>A = [1 2 3; 4 5 6] A = 1 2 3 4 5 6 >>B = [3 1 5; 2 0-3] B = 3 1 5 2 0-3 >>C = [3 4; 5 6; 7 8] C = 3 4 5 6 7 8 >>A + B 4 3 8 6 5 3 >>A + 5 % matriisin jokaiseen alkioon lisätään skalaari 5 6 7 8 9 10 11 15
>>5*A % skalaari*matriisi 5 10 15 20 25 30 >>A*C % matriisi*matriisi 34 40 79 94 Matriisien dimensioiden on tietenkin oltava yhteensopivat: >>A + C % voidaan lisätä vain samankokoinen matriisi tai skalaari??? Error using ==> plus Matrix dimensions must agree. >>A*B??? Error using ==> mtimes Inner matrix dimensions must agree. >>nelio = A*B % huomaa B:n transpoosi nelio = 20-7 47-10 >>nelioˆ3 % matriisi potenssiin 3-1870 203-1363 -1000 >>Aˆ2 % on oltava neliömatriisi??? Error using ==> mpower Inputs must be a scalar and a square matrix. Otetaan käyttöön vektorit u ja v : >>u = [2 4 6]; v = [1; 3; 5]; Nyt >>A*v 16
22 49 >>u*c 68 80 >>u*v % skalaaritulo eli pistetulo eli sisätulo 44 >>v *v 35 >>dot(v, v) 35 >>cross(u, v) % vektoritulo eli ristitulo 2-4 2 >>v*u % ulkotulo, tuloksena matriisi 2 4 6 6 12 18 10 20 30 Itseasiassa kyseessä on ns. Kroneckerin tulo eli tensoritulo >>kron(u,v) 2 4 6 6 12 18 10 20 30 Matriiseille: >>tens = kron(a, B) 17
tens = 3 1 5 6 2 10 9 3 15 2 0-3 4 0-6 6 0-9 12 4 20 15 5 25 18 6 30 8 0-12 10 0-15 12 0-18 Jos A on m n-matriisi ja B p q-matriisi, niin Kroneckerin tulo kron(a,b) on mp nq-matriisi, jossa on on kaikki mahdolliset tulot, kun kukin matriisin A alkio kerrotaan matriisilla B. 4.5 Alkioittaiset operaatiot Usein on tarve tehdä jokin operaatio vektorille tai matriisille alkioittain. Matlabissa on tätä varten kerto- ja jakolaskusta sekä potenssiinkorotuksesta alkioittaiset versiot.*,./ ja.ˆ. Nämä ovat ns. taulukko-operaatioita (array operators). Yhteen- ja vähennyslaskun tapauksessa taulukko-operaatiot ovat samat kuin matriiseille, joten operaattoreita.+ ja.- ei ole erikseen määritelty. Taulukkooperaatioita voidaan käyttää myös moniulotteisten taulukoiden käsittelyyn, mutta tällaisia taulukoita emme käsittele tässä yhteydessä. Esim. >>A.ˆ2 1 4 9 16 25 36 >>A.*B 3 2 15 8 0-18 >>B./A 3.0000 0.5000 1.6667 0.5000 0-0.5000 >>v./2 0.5000 1.5000 2.5000 Huomattakoon vielä, että useimmat alkeisfunktiot hyväksyvät argumenteikseen vektoreita ja matriiseja. Tällöin funktio operoi matriisiin alkioittain. 18
>>sin(z) % sinifunktio operoi suoraan vektoriin alkioittain 0.9093 0.2178-1.1634i -56.1623 +48.5025i >> x = 0:pi/2:2*pi x = 0 1.5708 3.1416 4.7124 6.2832 >> cos(x),exp(x) 1.0000 0.0000-1.0000-0.0000 1.0000 1.0000 4.8105 23.1407 111.3178 535.4917 5 Hieman lineaarialgebraa Matlabissa on kaksi eri jakolaskuoperaatiota / ja \. Näistä molemmista on myös alkioittaiset versiot eli./ ja.\. Jakolasku X=A\B on itseasiassa matriisiyhtälön AX = B ratkaisu (jaetaan vasemmalta, left divide). Vastaavasti, jakolasku X=B/A puolestaan määrää matriisiyhtälön XA = B ratkaisun (jakaa oikealta, right divide). Jakolasku A\B vaatii, että matriiseilla A ja B on yhtä monta riviä, ja jakolasku B/A vaatii, että sarakkeita on yhtä monta. Jakolaskua \ voidaan siis hyödyntää yhtälöryhmän ratkaisemisessa, esimerkiksi: >>A = [2-1 1; 3 2 2; 1-2 1] A = 2-1 1 3 2 2 1-2 1 >>b = [2; -2; 1] b = 2-2 1 >>x = A\b x = 19
2.0000-1.0000-3.0000 Samoin voidaan käyttää komentoa /, kun yhtälöryhmä on muotoa XA = B: >>B = [2-1 3] B = 2-1 3 >>X = B/A X = -2.2000 1.2000 2.8000 Matlab muodostaa käänteismatriisin, jos se on olemassa, komennolla inv: >>inv(a) 1.2000-0.2000-0.8000-0.2000 0.2000-0.2000-1.6000 0.6000 1.4000 Vaihtoehtoisesti voitaisiin tietenkin korottaa matriisi potenssiin 1: >>Aˆ(-1) 1.2000-0.2000-0.8000-0.2000 0.2000-0.2000-1.6000 0.6000 1.4000 tai ratkaista yhtälöryhmä AX = I >>A\eye(3) 1.2000-0.2000-0.8000-0.2000 0.2000-0.2000-1.6000 0.6000 1.4000 Todettakoon, että yhtälöryhmää ei tulisi ratkaista käänteismatriisilla kertomalla. Palaamme myöhemmissä luennoissa vielä hieman tarkemmin Matlabin käyttöön yhtälöryhmien ratkaisemisessa ja erilaisten matriisihajotelmien muodostamisessa. Todetaan kuitenkin vielä, että matriisi saadaan pelkistettyyn porrasmuotoon komennolla rref (reduced row echelon form). 20
>>rref(a) 1 0 0 0 1 0 0 0 1 >>rref([a b]) 1 0 0 2 0 1 0-1 0 0 1-3 >>rref([a eye(3)]) 1.0000 0 0 1.2000-0.2000-0.8000 0 1.0000 0-0.2000 0.2000-0.2000 0 0 1.0000-1.6000 0.6000 1.4000 Homogeeninen yhtälöryhmä Ax = 0 voidaan ratkaista komennolla null. >> null(ones(3)) 0 0.8165-0.7071-0.4082 0.7071-0.4082 Lopuksi vielä hieman lineaarialgebrasta tuttuja käsitteitä: >>rank(a) % matriisin aste 3 >>det(a) % determinantti 5 >>karak = poly(a) % karakteristisen polynomin kertoimet karak = 1.0000-5.0000 14.0000-5.0000 >>roots(karak) % ominaisarvot = karakteristisen polynomin juuret 21
2.2935 + 2.6164i 2.2935-2.6164i 0.4130 Matriisin ominaisarvojen ja -vektoreiden (eigenvalue, eigenvector) laskemiseksi on komento eig: >>lambda = eig(a) % ominaisarvot pystyvektorina lambda = 2.2935 + 2.6164i 2.2935-2.6164i 0.4130 Jos funktion eig paluuarvo ohjataan kahteen argumenttiin, on ensimmäisessä matriisissa ominaisvektorit sarakkeina ja toisessa ominaisarvot diagonaalina. Ominaisvektorit on skaalattu niin, että niiden euklidinen normi on yksi. >>[V, D] = eig(a) V = 0.1463 + 0.3540i 0.1463-0.3540i 0.5448 0.7780 0.7780 0.0264-0.1053 + 0.4867i -0.1053-0.4867i -0.8382 D = 2.2935 + 2.6164i 0 0 0 2.2935-2.6164i 0 0 0 0.4130 >>norm( V(:,1) ) 1.0000 >>[norm(v(:,1), 1) norm(v(:,1), inf)] % muita normeja 1.6590 0.7780 22
MATEMAATTISET OHJELMISTOT Syksy 2012 Matlab-luennot, 2. osa Sisältö 1 Grafiikkaa 1 1.1 Kaksiulotteista grafiikkaa........................ 2 1.2 Kolmiulotteista grafiikkaa........................ 8 1.3 Funktioiden kuvaajien piirtäminen................... 10 1.4 Kuvien muokkaus............................. 11 2 Matlab-ohjelmoinnista 14 2.1 Skriptit................................... 14 2.2 Funktiot.................................. 14 2.3 Funktion argumenteista......................... 17 2.4 Funktiokahvoista............................. 17 2.5 Operaattorit................................ 18 2.5.1 Vertailuoperaattorit........................ 19 2.5.2 Loogiset operaattorit....................... 19 2.6 Ohjausrakenteita............................. 20 2.6.1 Valintarakenteet.......................... 20 2.6.2 Toistorakenteet.......................... 21 2.7 Vektorointi ja allokointi.......................... 23 1 Grafiikkaa Matlabissa on hyvin tehokkaat ja monipuoliset grafiikkaominaisuudet. Seuraavassa käsitellään Matlabin kaksi- ja kolmeulotteisen grafiikan peruskomennot -ja työkalut. Vain ohimennen tullaan sivuamaan Matlabissa olevia erilaisia graafisella käyttöliittymällä varustettuja visualisointityökaluja, esim. plottools. Näihin voit tutustua itsenäisesti, vaikkapa piirtämällä visualisointityökaluja käyttäen tässä luennossa esimerkkeinä olevat kuvat. Kahvojen käyttöä grafiikassa (ns. Handle Graphics) käsitellään vain hyvin lyhyesti. 1
1.1 Kaksiulotteista grafiikkaa Matlabin peruspiirtokäsky 2D-kuville on plot. Yksinkertaisimmillaan käskyllä plot(y) voidaan piirtää vektorin y arvot niin, että x-akselilla on vektorin indeksit. Jos argumentteina on kaksi vektoria, piirtää komento plot(x,y) vektoreista x ja y pisteet (x(i), y(i)) ja yhdistää ne viivalla toisiinsa. Kuvassa 1 oleva murtoviiva saadaan seuraavasti: >> x = [1.5 2.2 3.1 4.6 5.7 6.3 9.4]; >> y = [2.3 3.9 4.3 7.2 4.5 6.1 1.1]; >> plot(x, y) 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 Kuva 1: Matlab piirtää kuvaajan erilliseen kuvaikkunaan (figure window). Jos nyt piirretään uusi kuvaaja esimerkiksi jostain toisesta funktiosta, tulee kuvaaja äsken avautuneeseen kuvaikkunaan vanhan kuvaajan tilalle. Samalla tavalla voidaan piirtää myös sileitä kuvaajia kunhan x-hilaa ensin tihennetään. Toisena esimerkkinä piirretään kosinifunktion kuvaaja välillä [0, 2π] (kts. Kuva 2): >>x = 0:pi/100:2*pi; >>y = cos(x); >>plot(x, y) Lisätään vielä akseleille nimet ja kuvalle otsikko. Näidenkin komentojen tulos tulee sillä hetkellä auki olevaan kuvaikkunaan. Huomaa, että Matlab osaa joukon TEX-komentoja kreikkalaisia aakkosia varten, kuten tässä \pi. >>xlabel( x = 0:2\pi ) >>ylabel( y = cos(x) ) >>title( Kosinin kuvaaja, Fontsize, 12) Samaan kuvaan voidaan piirtää useampia kuvaajia samalla plot-käskyllä. Tämä tapahtuu laittamalla plot-käskyyn pareittain piirrettäviä datoja vastaavat vektorit x ja y-koordinaattien arvoiksi. Seuraavassa piirretään kosinifunktion lisäksi sinifunktio ja sin(2x 1) samaan kuvaan. 2
1 Kosinin kuvaaja 0.8 0.6 0.4 0.2 y = cos(x) 0 0.2 0.4 0.6 0.8 1 0 1 2 3 4 5 6 7 x = 0:2π Kuva 2: 1 0.8 cos(x) sin(x) sin(2x 1) 0.6 0.4 0.2 0 0.2 0.4 0.6 0.8 1 0 1 2 3 4 5 6 7 Kuva 3: >>y2 = sin(x); >>y3 = sin(2*x-1); >>plot(x, y, x, y2, x, y3) Komennolla legend voidaan lisätä selitteet kullekin kuvaajalle (kts. Kuva 3): >>legend( cos(x), sin(x), sin(2x-1) ) Yleisemmin plot(x, y) voidaan korvata komennolla plot(x, y, merkkijono), missä merkkijono voi sisältää korkeintaan kolme merkkiä, jotka säätävät piirtoväriä, -merkkiä ja viivatyyliä. Nämä ns. optiot lisätään heittomerkeissä plotkäskyyn piirrettävien datojen jälkeen. Tarkempia tietoja optioista käskyllä help plot. Piirretään esimerkkinä edellinen kuva niin, että kosinifunktio piirretään yhtenäisellä viivalla -, sinifunktio pisteviivalla : ja funktiosta sin(2x 1) piirretään vain datapisteet tähdellä *. Edelleen kaikki kuvaajat piirretään mustalla värillä k. Tulos on Kuvassa 4. >>plot(x, y, k-, x, y2, k:, x, y3, k* ) >>legend( cos(x), sin(x), sin(2x-1) ) 3
1 0.8 cos(x) sin(x) sin(2x 1) 0.6 0.4 0.2 0 0.2 0.4 0.6 0.8 1 0 1 2 3 4 5 6 7 Kuva 4: Edellä olevat kuvat voitaisiin piirtää myös plottools-työkalua käyttäen niin, että muodostettaisiin ensin vektori x x-akselin arvoja varten. Tämän jälken komennettaisiin plottools ja ryhdyttäisiin Plot Browser-ikkunan avulla lisäämään dataa y-akselia varten. Voitaisiin myös muodostaa komentorivillä y-akselin data vektoriin y ja valita vektorit hiirellä Workspace-ikkunasta (CTRL + hiiren vasen nappi), jonka jälkeen hiiren oikeaa nappia painamalla saadaan näkyviin erilaisia piirtovaihtoehtoja. Edelleen, plot-komennolle voidaan antaa myös matriisiargumentteja. Jos x on m-vektori ja Y on m n-matriisi, niin plot(x, Y) piirtää samaan kuvaan jokaisen Y:n sarakkeen arvot, kun x-akselilla on x:n arvot. Vastaavasti, jos X ja Y ovat molemmat m n-matriiseja, niin plot(x, Y) piirtää samaan kuvaan X:n ja Y:n sarakkeista saatavat kuvat (kts. Kuva 5). Komento plot(y) taas piirtää Y:n sarakkeet niin, että x-akselilla on matriisin indeksit (kts. Kuva 6). >> X = [1:3; 4:6; 7:9]; >> Y = magic(3) Y = 8 1 6 3 5 7 4 9 2 >> plot(x, Y) >> plot(y) Jos piirrettävä data on kompleksista, niin Matlab ei huomioi imaginääriosaa, vaan se piirtää vain reaaliosat. Kuitenkin, jos plot-käskylle annetaan vain yksi argumentti, jonka sisältämä data on kompleksista, piirtää Matlab kuvaajan, jossa on reaaliosa x-akselilla ja imaginääriosa y-akselilla. Jos halutaan piirtää olemassaolevaan kuvaikkunaan niin, ettei siinä jo oleva kuvaaja tuhoudu, voidaan käyttää komentoa hold on. Pito saadaan pois päältä komennolla hold off. Esim. >> plot(sin(x)) >> hold on >> plot(cos(x)), hold off 4
9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 Kuva 5: 9 8 7 6 5 4 3 2 1 1 1.5 2 2.5 3 Kuva 6: 1 0.8 0.6 0.4 0.2 0 0.2 0.4 0.6 0.8 1 0 50 100 150 200 250 Kuva 7: 5
1 cos(x) 1 sin(x) 0.5 0.5 0 0 0.5 0.5 1 0 2 4 6 8 1 0 2 4 6 8 1 sin(2x 1) 1 cos(2x 1) 0.5 0.5 0 0 0.5 0.5 1 0 2 4 6 8 1 0 2 4 6 8 Kuva 8: piirtää sinin ja kosinin kuvaajat samaan kuvaikkunaan (kts. Kuva 7). Komennolla figure voidaan puolestaan avata uusi kuvaikkuna. Edelleen komennolla figure(n) voidaan määrätä, että piirtäminen tapahtuu kuvaikkunaan numero n (tämä saadaan aikaan myös klikkaamalla ko. kuvaikkunaa). Jos auki on useampia kuvaikkunoita, niin oletuksena Matlab piirtää siihen ikkunaan, johon on viimeksi piirretty tai jota on viimeisimmäksi klikattu. Komento clf tyhjentää sen hetkisen kuvaikkunan. Komennolla close suljetaan sen hetkinen kuvaikkuna ja close all sulkee kaikki kuvaikkunat. Samaan kuvaikkunaan voidaan piirtää useampia erillisä osakuvaajia komennolla subplot(m,n,p). Komento jakaa kuvaikkunan m n matriisiksi ja valitsee siitä akseliston p, johon kuva piirretään jollain piirtokomennolla (esim. plot). Osakuvat (akselistot) numeroidaan kuvan ylärivistä lähtien, vasemmalta oikealle. Esimerkkinä neljän eri trigonometrisen funktion kuvaajat on piirretty samaan kuvaikkunaan Kuvassa 8. >>y4 = cos(2*x-1); >>subplot(2,2,1); plot(x,y), title( cos(x) ) >>subplot(2,2,2); plot(x,y2), title( sin(x) ) >>subplot(2,2,3); plot(x,y3), title( sin(2x-1) ) >>subplot(2,2,4); plot(x,y4), title( cos(2x-1) ) Matlabin axis-komennolla voidaan muuttaa kuvan akseleiden skaalausta ja ulkonäköä. Esimerkiksi komennolla axis([xmin xmax ymin ymax]) muutetaan akseleiden rajat käyttäjän haluamaksi sen sijaan, että Matlab määräisi ne piirrettävän datan perusteella. Usein halutaan säilyttää akseleiden skaalaus samana, kun piirretään samaan kuvaan peräkkäin useampia kuvaajia. Komennolla axis manual voidaan pitää sen hetkinen akseleiden skaalaus käytössä, komennolla axis auto palautetaan automaattinen skaalaus käyttöön. axis tight asettaa skaalauksen tarkalleen piirrettävän datan määräämälle välille. Komennolla axis equal asetetaan puolestaan x- ja y-akseleiden askelväli samaksi ja axis square tekee akseleista yhtä pitkiä. Komento axis normal kumoaa komentojen axis square ja axis equal vaikutuksen. Edelleen axis off poistaa akselit kuvasta ja 6
8 x 105 7 6 5 4 3 2 1 0 0 0.5 1 1.5 2 2.5 3 Kuva 9: 50 45 40 35 30 25 20 15 10 5 0 0 0.5 1 1.5 2 2.5 3 Kuva 10: axis on palauttaa ne näkyviin. axis-komento laajenee luonnollisella tavalla 3Dkuviin, esimerkiksi axis([xmin xmax ymin ymax zmin zmax]). Yhden akselin skaalausta voidaan säädellä komennoilla xlim, ylim ja zlim. Muita komentoja kuvien muokkaamiseen ovat mm. grid on ja grid off, joilla saadaan kuvaan ruutuverkko näkyviin tai siitä pois. Piirretään seuraavassa funktion 1 f (x) = (x 1) + 3 2 (x 2), 0 x 3 2 kuvaaja, kts. Kuva 9: >> x = linspace(0, 3, 500); % luo 500 pisteen x-hilan välille [0,3] >> plot(x, 1./(x-1).ˆ2 + 3./(x-2).ˆ2) % Huomaa alkioittaisuus >> grid on Pisteissä x = 1 ja x = 2 olevien singulariteettien takia kuva ei anna juurikaan informaatiota funktiosta, mutta rajoittamalla lisäkomennolla ylim([0 50] y-akselin skaalausta saadaan huomattavasti mielenkiintoisempi kuvaaja, kts. Kuva 10. 7
Edellä olivat jo xlabel, ylabel, title ja legend, näiden lisäksi voidaan text-komennolla lisätä tekstiä mihin tahansa kohtaan kuvassa (kts. Kuva 11): >>x = 0:pi/100:2*pi; y = cos(x); plot(x, y) >>axis tight square >>grid on >>text(4, -0.8, Kosinin kuvaaja ) 1 0.8 0.6 0.4 0.2 0 0.2 0.4 0.6 0.8 Kosinin kuvaaja 1 0 1 2 3 4 5 6 Kuva 11: Yllä mainitut kuvan muokkaukset voidaan tehdä myös kuvaikkunassa käyttämällä esim. Edit-, Insert- ja Tools-valikoista löytyviä käskyjä. Jos kuvaa muokataan runsaasti kuvaikkunassa, niin valmiista tuloksesta voidaan generoida myöhempää käyttöä varten M-tiedosto File-valikon Generate M-File-komennolla. Tätä M-tiedostoa käyttäen voidaan myöhemmin piirtää asetuksiltaan samanlainen kuva eri datoilla. Edelleen, kuva voidaan tallettaa kuvatiedostoksi valitsemalla kuvaikkunan File-valikosta Save As.... Muita peruspiirtokomentoja ovat mm. loglog, semilogx, semilogy, joilla voidaan piirtää kuvaajia logaritmisilla akselistoilla, katso helpeistä lisätietoa. 1.2 Kolmiulotteista grafiikkaa Komennolla plot3 voidaan puolestaan piirtää kolmiulotteisia avaruuskäyriä, joten se on plot-komennon kolmiulotteinen vastine. Kuva 12 saadaan seuraavasti: >> t = -5 : 0.005 : 5; >> x = (1 + t.ˆ2).*sin(20*t); >> y = (1 + t.ˆ2).*cos(20*t); >> z = t; >> plot3(x, y, z) >> grid on >> xlabel( x(t) ), ylabel( y(t) ), zlabel( z(t) ) Kolmiulotteisten pintakuvien piirtämiseen Matlabissa on kaksi peruskomentoa: mesh ja surf. Molemmilla voidaan piirtää z-koordinaateilla määrätty pinta 8
5 z(t) 0 5 40 20 0 y(t) 20 40 40 20 x(t) 0 20 40 Kuva 12: x y -tasossa olevan hilan yläpuolelle. Komentojen ero on se, että mesh-komento piirtää datapisteiden lisäksi pisteitä yhdistävät viivat, joten tuloksena on rautalankakuva (wireframe) piirrettävästä pinnasta. surf näyttää rautalankakuvan lisäksi pisteitä yhdistettäessä syntyvät pinnat. Piirretään seuraavaksi funktion f (x, y) = 2 sin x cos y, x, y [0, 2π] pintakuva. Pintakuvien piirtämisessä on meshgrid-komento erittäin hyödyllinen, sillä voidaan helposti luoda piirtämisessä tarvittava hila: >>[x, y] = meshgrid(0:pi/20:2*pi); Tällä komennolla saatiin vektorista 0:pi/20:2*pi tehtyä matriisit x ja y, joita voidaan käyttää argumentteina komennoille mesh ja surf: >>z = 2.*sin(x).*cos(y); >>mesh(x, y, z) Näin saatiin kuvassa 13 oleva rautalankakuva. Kuvassa 14 oleva pintakuva saadaan puolestaan komennolla: >>surf(x, y, z) Pintakuviin voidaan lisätä akseleiden nimiä, otsikoita, tekstiä, selitteitä yms., samoilla komennoilla kuin 2D-kuviinkin. Lisäksi pintakuvien ominaisuuksia, esim. pinnan väritystä ja valaistusta, voidaan säätää omilla komennoillaan. Muokkaukset ja kuvien piirtämisen voi 3D-kuvissakin tehdä plottoolsilla ja kuvaikkunan valikoista löytyvillä komennoilla. Muokataan edellä piirrettyä pintakuvaa hieman erilaisilla asetuksilla (kts. Kuva 15): >>surf(x, y, z, FaceColor, green, EdgeColor, none ); >>camlight left; lighting phong, view(-40, 60) >>axis off 9
2 1 0 1 2 8 6 4 2 0 0 2 4 6 8 Kuva 13: 2 1 0 1 2 8 6 4 2 0 0 2 4 6 8 Kuva 14: 1.3 Funktioiden kuvaajien piirtäminen Edellä on piirretty kuvaajia käyttämällä Matlabin peruspiirtokomentoja. Peruspiirtokomennot ovat käteviä, kun piirretään jotain numeerista dataa, esimerkiksi mittaustuloksia. Funktioiden kuvaajien piirtämiseen Matlabissa on kuitenkin näppärämpiäkin tapoja kuin esimerkiksi plot-komento. Esimerkiksi komennolla ezplot(f, [a,b]) voidaan piirtää funktion f = f (x) arvot välillä a < x < b. Jos tätä piirtoväliä ei anneta käytetään oletusarvoisesti väliä 2π < x < 2π. Piirrettävä funktio annetaan lausekkeena (esim. ezplot( sin(x) )), määrittelemällä se inline-funktioksi (f = inline( sin(x) ); ezplot(f)) tai annetaan funktio funktiokahvana (function handle) ät-merkillä (ezplot(@sin)). Funktiokahvoista myöhemmin lisää. ezplot-komennolla voidaan helposti piirtää myös esim. implisiittisesti määriteltyjä kuvaajia ja parametrisoituja käyriä. Lisäksi Matlabissa on omat ez-komentonsa mm. napakoordinaatistossa piirrettäville kuvaajille (ezpolar) sekä pintakuville (ezsurf ja ezmesh) ja tasa-arvokäyrille (ezcontour). Lisätietoa mm. komennoilla help ezplot ja lookfor ez. Edelleen funktioiden piirtämiseen on komento fplot, ks. help fplot. Kuva 16 saadaan piirrettyä seuraavilla käskyillä: 10
Kuva 15: >>subplot(1,3,1); ezplot( sin(t), sin(t)*cos(t), [0,pi]) >>axis square >>subplot(1,3,2); ezpolar( cos(2*t) ) >>subplot(1,3,3); ezcontour( 2*sin(x)*cos(y), [0,2*pi]) >>axis tight square y x = sin(t), y = sin(t) cos(t) 0.5 0 0.5 0 0.5 1 x 90 1 120 60 150 0.5 30 180 0 210 330 240 300 270 r = cos(2 t) y 6 4 2 2 sin(x) cos(y) 0 0 5 x Kuva 16: 1.4 Kuvien muokkaus Palataan vielä ensimmäiseen esimerkkiimme eli Kuvaan 1. Joitakin kuvan ominaisuuksia, kuten viivanleveyttä ja piirtomerkin kokoa, voidaan piirtämisen yhteydessä muokata antamalla lisäargumentteja plot-komennolle ja useille muillekin komennoille (kts. esimerkiksi kuinka Kuvaa 15 muokattiin). Kasvatetaan seuraavaksi viivanleveyttä arvoon 3 pt (oletus 0.5 pt) ja piirtomerkin kokoa arvoon 5 pt (oletus 6 pt), missä pt (point, piste) on 1/72 tuumaa. Tulos on Kuvassa 17. >> x = [1.5 2.2 3.1 4.6 5.7 6.3 9.4]; 11
>> y = [2.3 3.9 4.3 7.2 4.5 6.1 1.1]; >> plot(x, y, m--ˆ, LineWidth, 3, MarkerSize, 5) 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 Kuva 17: Kuten edellä on nähty, kuvien ominaisuuksia voi Matlabissa muokata joko käyttämällä kuvaikkunan valikoita tai komentoriviltä käsin. Joskus on tarpeen muokata kuvaa piirtämisen jälkeen tai tehdä sellaisia kuvia, etteivät Matlabin peruskomennot riitä. Tällöin pitää yleensä muokata Matlabin grafiikkaobjekteja. Piirtokomentoja käytettäessä Matlab muodostaa kuvaajan käyttämällä erilaisia grafiikkaobjekteja, kuten viivoja, tekstiä, valoa ja pintoja. Kullakin objektilla on ominaisuuksia, joilla säädellään objektin ulkonäköä ja käyttäytymistä. Kun Matlab luo jonkin objektin, siihen liitetään tunnus (kutsutaan jälleen kahvaksi), jonka avulla voidaan objektin ominaisuuksiin päästä käsiksi. Puhutaan ns. Handle Graphicsista. Objektin jonkin ominaisuuden sen hetkisen arvon saa selville get-käskyllä ja arvoa voi muuttaa set-käskyllä. Objekteilla on keskinäinen hierarkiansa, esimerkiksi viivaobjekti on hierarkiassa akseliobjektin alapuolella, joten akseliston on oltava määritelty ennenkuin voidaan piirtää viiva. Seuraavassa piirretään sinifunktion kuvaaja ja saadaan muuttujaan kuva kahva kuvaan. Komennolla get nähdään LineWidth-ominaisuuden arvo ja setkomennolla muutetaan viivan paksuutta, tulos on Kuvassa 18. Objektin kaikki sen hetkiset ominaisuudet nähdään kirjoittamalla get(kuva). Objektin ominaisuuksia voidaan muuttaa myös piirtokäskyssä (ei kuitenkaan kaikissa piirtokäskyissä) eli nyt esimerkiksi käskyllä plot(x, y, LineWidth, 2.0) olisi saatu aikaan sama tulos. Erona näillä tavoilla on se, että get/set-menetelmällä voidaan kuvaa muokata sen piirtämisen jälkeen eli itse piirtämistä ei tarvitse toistaa uudestaan. >>x = 0:pi/100:2*pi; y = sin(x); >>kuva = plot(x,y); >>get(kuva, LineWidth ) 0.5000 12
>>set(kuva, LineWidth, 2.0) 1 0.8 0.6 0.4 0.2 0 0.2 0.4 0.6 0.8 1 0 1 2 3 4 5 6 7 Kuva 18: Muita objektien käsittelykomentoja ovat mm. copyobj, delete ja findobj. Näillä voidaan kopioida ja tuhota objekteja sekä etsiä kahva objekteihin, joilla on tietty arvo. Edelleen komennot gca, gcf ja gco palauttavat kahvat sen hetkiseen akselistoon, kuvaan ja objektiin. Esimerkkinä muutetaan Kuvassa 4 tähdet punaisiksi rasteiksi ja saadaan Kuva 19. >>x = 0:pi/100:2*pi; >>y = cos(x); y2 = sin(x); y3 = sin(2*x-1); >>plot(x, y, k-, x, y2, k:, x, y3, k* ) >>set(findobj( Type, line, Marker, * ), Marker, x,... Color, red ) 1 0.8 0.6 0.4 0.2 0 0.2 0.4 0.6 0.8 1 0 1 2 3 4 5 6 7 Kuva 19: 13
2 Matlab-ohjelmoinnista Seuraavaksi alamme tutustumaan Matlab-ohjelmoinnin perusteisiin. Matlabissa ohjelmat kirjoitetaan M-tiedostoiksi (M-files). M-tiedostot ovat MATLAB-koodia sisältäviä tekstitiedostoja, joiden tiedostopääte on.m. M-tiedosto suoritetaan kirjoittamalla komentoikkunaan tiedoston nimi. M-tiedostoa tiedosto.m voidaan siis ajatella Matlab-komentona, jonka nimi on tiedosto. M-tiedostoja on kahta tyyppiä: skriptejä ja funktioita. 2.1 Skriptit Skripti (script) on joukko Matlab-komentoja, jotka suoritetaan, kun kyseistä M- tiedostoa kutsutaan. Skriptillä ei ole lainkaan argumentteja ja se käyttää työtilassa (Workspace) olevia muuttujia. Skripti käyttää siis työtilassa oleva dataa ja skriptissä laskettu tai muodostettu data sekä muuttujat jäävät myös työtilaan. Esimerkiksi, voidaan kirjoittaa Matlab-skripti sini_kuva.m, joka piirtää sinin kuvaajan. Komennolla edit sini_kuva avataan tekstieditori (yleensä Matlabin oma editori), ja kirjoitetaan komennot: x = 0:pi/100:2*pi; y = sin(x); plot(x,y) legend( sin(x) ) Tiedoston tallettamisen jälkeen komennolla sini_kuva skripti suoritetaan ja Matlab piirtää kuvan. Skriptin suorittamisen jälkeen siinä määritellyt muuttujat ovat käytettävissä työtilassa (kts. whos). 2.2 Funktiot Skripteistä poiketen, funktiolle (function) voidaan sen sijaan antaa syötteenä argumentteja (input) ja se (yleensä) palauttaa jonkin arvon tai useita arvoja suorituksensa jälkeen (output). Funktion sisäiset muuttujat ovat oletusarvoltaan lokaaleja eli ne ovat käytettävissä vain funktion sisällä, eivät työtilassa kuten skriptin tapauksessa. Komennolla type voidaan komentoikkunassa tulostaa jonkin M-tiedoston sisältö, ja komennolla what nähdään luettelo sen hetkisen hakemiston M-tiedostoista. Tulostetaan Matlabin valmisfunktion trace sisältö: >>type trace function t = trace(a) %TRACE Sum of diagonal elements. % TRACE(A) is the sum of the diagonal elements of A, which is % also the sum of the eigenvalues of A. % % Class support for input A: % float: double, single 14
% Copyright 1984-2007 The MathWorks, Inc. % $Revision: 5.8.4.2 $ $Date: 2007/11/01 12:38:53 $ if (ndims(a)==2 && size(a,1)==size(a,2)) error( MATLAB:square, Matrix must be square. ); end t = sum(diag(a)); Tulostuksesta nähdään, että trace.m on funktiotyyppinen M-tiedosto. Funktion ensimmäinen rivi alkaa aina avainsanalla function, jonka jälkeen tulee funktion paluuarvojen määrittely (tässä t), funktion nimi, joka on sama kuin M-tiedoston nimi (nyt trace) sekä suluissa funktion argumentit (tässä A). Ensimmäiseltä riviltä nähdään myös funktion paluuarvojen ja argumenttien keskinäinen järjestys, jos niitä on useampia kuin yksi. Jos funktiolla on useampia paluuargumentteja, niin ne laitetaan hakasulkujen sisään pilkulla erotettuna. Jos funktiolla ei ole paluuarvoja, laitetaan joko tyhjät hakasulut tai jätetään paluuarvon määrittely pois, esim. function funktio(x) tai []=funktio(x). Ensimmäisen rivin jälkeen on yleensä yksi tai useampia kommenttirivejä ennen ensimmäistä suoritettavaa käskyä. Nämä kommenttirivit nähdään, kun help-käskyllä kysytään tietoa jostain komennosta. Ensimmäinen kommenttirivi on ns. H1-rivi, sen teksti nähdään, kun etsitään tietoa lookfor-komennolla tai käytetään help-käskyä johonkin hakemistoon, esim. help graph2d. Kommenttirivien jälkeen tulee varsinainen funktion runko, jossa on suoritettavat lauseet sekä mahdollisia kommenttirivejä. Ensimmäisen tyhjän rivin tai suoritettavan käskyn jälkeiset kommenttirivit eivät näy help-käskyllä. Yllä olevassa funktiossa paluuarvo määräytyy (virheentarkistusten jälkeen), kun muuttujaan t sijoitetaan arvo sum(diag(a)). Funktiossa määritellyt muuttujat ovat siis lokaaleja, joten nyt muuttujat t ja A eivät näy funktion ulkopuolella työtilassa, ainoastaan funktion omassa, sisäisessä työtilassa. Funktioissa määriteltyjä muuttujia koskevat samat säännöt ja rajoitukset kuin Matlabin komentorivikäytössä määriteltyjä muuttujia. Funktioissakaan ei tarvitse muuttujien kokoa tai tyyppiä määritellä. Kannattaa huomata, että ei ole syytä käyttää muuttujalle nimeä, joka on jo käytössä jonkin funktion nimenä. Tämä siitä syystä, että tällöin nimi viittaa muuttujaan eikä samannimiseen funktioon. Jotta funktiota voi taas käyttää, täytyy päällekkäinen muuttuja poistaa clear-käskyllä. Muuttujia voidaan määritellä globaaleiksi avainsanalla global. Tällöin kyseinen muuttuja on käytössä, sekä funktion työtilassa, että siellä missä muuttuja määritellään globaaliksi (esim. muut funktiot ja perustyötila). Tutkitaan klassista Lotka-Volterran peto-saalis -mallia. Olkoon y 1 =saalispopulaation tiheys ja y 2 =petopopulaation tiheys. Tällöin malliksi muodostuu yhtälöpari dy 1 = y 1 αy 1 y 2 dt dy 2 = y 2 + βy 1 y 2. dt Tehdään M-tiedosto lotka2.m, jossa on kyseiset differentiaaliyhtälöt. Globaaleiksi muuttujiksi asetetaan mallin vuorovaikutuskertoimet α ja β. 15
function yp = lotka2(t, y) % LOTKA Lotka-Volterran saalis-peto -malli global ALPHA BETA yp = [y(1) - ALPHA*y(1)*y(2); -y(2) + BETA*y(1)*y(2)]; Komentoikkunassa voidaan määritellä globaalit muuttujat arvoineen: >>global ALPHA BETA >>ALPHA = 0.01; >>BETA = 0.02; Nyt kertoimien α ja β arvot vaikuttavat myös funktioon lotka2.m. Ratkaistaan differentiaaliyhtälö komennolla ode23 numeerisesti yo. kertoimien arvoilla ja piirretään kuva. >>[t, y] = ode23( lotka2, [0 30], [1; 1]); >>plot(t,y(:,1), k-,t,y(:,2), k: ) >>legend( saalis, peto ), title( Lotka-Volterra ) 1000 900 800 Lotka Volterra saalis saalistaja 700 600 500 400 300 200 100 0 0 5 10 15 20 25 30 Kuva 20: Matlabissa voi määritellä myös pysyviä muuttujia (persistent variables) avainsanalla persistent. Pysyviä muuttujia voi määritellä ainoastaan funktioissa, eikä pysyvän muuttujan arvoa pyyhitä muistista funktiosta poistumisen jälkeen. Pysyvät muuttujat eroavat globaaleista muuttujista siinä, että muut funktiot tai työtila eivät voi niitä käyttää. Pysyville muuttujille on käyttöä lähinnä silloin, kun halutaan että jonkin muuttujan arvo säilyy funktion kutsukertojen välillä, mutta ei haluta määritellä sitä globaaliin työtilaan. Matlabissa voidaan myös tehdä anonyymejä funktioita. Anonyymien funktioiden avulla voidaan muodostaa helposti yksinkertaisia funktioita niin, ettei niistä tarvitse tehdä M-tiedostoa. Anonyymeja funktioita voi luoda joko komentorivillä, M-tiedostossa olevassa funktiossa tai skriptissä. Syntaksi anonyymin funktion muodostamiselle on funktio_kahva = @(argumenttilista) lauseke Esim. yksinkertainen lineaarinen kuvaus x 2x + 1 tehdään näin: 16
>>f = @(x)(2*x+1) f = @(x)(2*x+1) Sitä voi nyt kutsua tavallisen funktion tavoin, esim. >>f(2) 5 2.3 Funktion argumenteista Komennoilla nargin ja nargout voidaan selvittää monellako input- ja output-argumentilla funktiota on kutsuttu. Jos funktiolle halutaan antaa merkkijono argumentiksi, on se laitettava heittomerkkien sisään. Matlab-funktiolle voidaan antaa merkkijonoja argumentteina myös ilman, että ne ovat heittomerkkien sisällä. Esimerkiksi legend sin(x) cos(x) on sama komento kuin legend( sin(x), cos(x) ). Kun tätä muotoa käytetään, ei funktio voi palauttaa tulosargumenttia. Tässä on itse asiassa kyse ns. funktio/komento -dualiteetista eli siitä, että Matlabissa on kaksi eri kutsusyntaksia funktioille: funktiosyntaksi ja komentosyntaksi. Funktiosyntaksi on muotoa >>[tulos1, tulos2,..., tulosn] = funktio(arg1, arg2,..., argn) Komentosyntaksilla funktiokutsu on >>funktio arg1 arg2... argn On siis huomattava, ettei komentosyntaksilla kutsuttaessa voida funktion paluuarvoja sijoittaa muuttujiin. Funktiosyntaksi välittää argumentin arvon, kun taas komentosyntaksilla välitetään argumentti merkkijonona. 2.4 Funktiokahvoista Haluttaessa välittää funktiolle jokin toinen funktio argumentiksi, käytetään funktiokahvaa (function handle). Kun funktiokahva on välitetty funktiolle argumenttina, voidaan sen funktion, johon kahva viittaa, arvoja laskea feval-komennon avulla. Funktiokahva muodostetaan liittämällä @-merkki funktion nimen eteen. Tehdään kahva Matlabin valmisfunktioon humps >>fkahva = @humps; Tehdään funktio kahavan_piirto, jossa käytetään komentoa feval laskemaan funktion arvoja. Komento feval käytettäessä annetaan sille ensimmäiseksi argumentiksi funktiokahva ja loput argumentit ovat ne, jotka välitetään itse funktiolle. Tiedoston kahavan_piirto.m sisältö: 17
function kahavan_piirto(kahava, data) plot(data, feval(kahava, data)) Piirretään kuva tällä funktiolla ja etsitään funktion lokaali minimi Matlabin valmisfunktiolla fminsearch. Minimin etsinnässä alkuarvona on x = 0.5. Tässä on siis hyvä huomata, että useat Matlabin valmisfunktiotkin käyttävät kahvoja argumentteinaan. >>kahavan_piirto(fkahva, 0:0.001:1.5) >>minimi = fminsearch(fkahva, 0.5) minimi = 0.6370 100 80 60 40 20 0 20 0 0.5 1 1.5 Kuva 21: Etsitään vielä funktion humps nollakohta. Esimerkin vuoksi käytetään anonyymia funktiota. Kopioidaan tiedostosta humps.m funktion määrittely ja tehdään anonyymi funktio anon: >>anon = @(x) (1./ ((x-.3).ˆ2 +.01) + 1./ ((x-.9).ˆ2 +.04) -6); Anonyymi funktio on samalla funktiokahva, joten sitä voidaan käyttää argumenttina funktiolle fzero, jonka avulla etsitään yksi juuri lähtien liikkeelle pisteestä x = 1: >>fzero(anon, 1.0) 1.2995 2.5 Operaattorit Matlabin operaattorit jakaantuvat kolmeen luokkaan: aritmeettiset, vertailu- ja loogiset operaattorit. Aritmeettiset operaattorit on jo esitelty edellä. 18
2.5.1 Vertailuoperaattorit Vertailuoperaattoreita ovat <, <=, >, >=, == ja =, joista viimeinen tarkoittaa erisuuruutta. Matlabin vertailuoperaattorit tekevät vertailun alkioittain, ja molempien operandien on oltava samankokoisia ellei toinen ole skalaari. Esimerkiksi, jos halutaan testata, ovatko kaksi matriisia samat, on käytettävä funktiota isequal, sillä == palauttaa vain ne alkiot, joissa matriisien alkiot ovat yhtäsuuria. >>A = [ 1 2 3; 4 5 6;]; B = [1 2 4; 5 3 6]; >>A == B 1 1 0 0 0 1 >>isequal(a, B) 0 Huomaa, että yllä vertailuoperaattori == ja funktio isequal palauttavat tyyppiä logical olevan arvon, joka voi olla 0 tai 1. 2.5.2 Loogiset operaattorit Loogisia operaattoreita on Matlabissa itseasiassa kolmea tyyppiä, mutta esittelemme tässä niistä vain alkioittaiset loogiset operaattorit. Kaksi muuta tyyppiä ovat loogiset bittioperaattorit (esim. bitand) ja ns. oikosulkuoperaattorit (shortcircuit operators) && ja skalaarien vertailuun. Alkioittaisia loogisia operaattoreita ovat & ja tai ei, negaatio xor poissulkeva tai Näitä käytettäessä Matlab tekee loogiset operaatiot alkioittain ja jälleen on vaatimuksena (poikkeuksena ), että taulukot ovat saman kokoisia tai jompikumpi on skalaari. Huomaa, että myös loogiset operaattorit palauttavat tyyppiä logical olevan arvon. >>A = [0 1 1 0 1]; >>B = [1 1 0 0 1]; >>A & B 0 1 0 0 1 >>A B 1 1 1 0 1 >> A 19