Page 1. Whoops! There was a problem loading more pages. Retrying... MATLAB - Ohjelmointi.pdf. MATLAB - Ohjelmointi.pdf.
MATLAB Ohjelmointi Timo Mäkelä
MATLAB – Ohjelmointi
2
SISÄLTÖ: 1. YLEISTÄ....................................................................................................................................4 1.1 M-TIEDOSTOT.........................................................................................................................4 1.2 SYÖTTÖ JA TULOSTUS............................................................................................................5 2. FUNKTIOT................................................................................................................................9 2.1 FUNKTION RAKENNE..............................................................................................................9 2.2 ALIFUNKTIOT JA YKSITYISET FUNKTIOT..............................................................................12 2.3 FUNKTION MUUTTUJAT........................................................................................................12 2.4 ANONYYMI FUNKTIO............................................................................................................14 3. OHJAUSLAUSEET................................................................................................................16 3.1 TOISTOLAUSEET...................................................................................................................16 3.1.1 for-lause........................................................................................................................16 3.1.2 while-lause....................................................................................................................21 3.2 EHTOLAUSEET......................................................................................................................23 3.2.1 if-lause..........................................................................................................................23 3.2.2 switch-lause..................................................................................................................29 3.2.3 try-lause........................................................................................................................33 3.3 KESKEYTYSLAUSEET............................................................................................................34 4. DIFFERENSSIYHTÄLÖT.....................................................................................................36 4.1 TEORIAA...............................................................................................................................36 4.1.1 Differenssiyhtälö..........................................................................................................36 4.1.2 Differenssiyhtälöryhmä................................................................................................38 4.2 NUMEERINEN RATKAISEMINEN............................................................................................40 4.2.1 Differenssiyhtälö..........................................................................................................40 4.2.2 Differenssiyhtälöryhmä................................................................................................42 5. FUNKTION PARAMETREISTA..........................................................................................45 5.1 KAHVAT JA FUNKTIOPARAMETRIT.......................................................................................45 5.2 SOVELLUS – HAARUKOINTIMENETELMÄ..............................................................................45 5.3 VAIHTELEVA MÄÄRÄ ARGUMENTTEJA.................................................................................47 6. REKURSIIVINEN FUNKTIO...............................................................................................51 7. SOVELLUKSIA......................................................................................................................53 7.1 FUNKTION MAKSIMOINTI......................................................................................................53 7.2 FUNKTIOSARJOJEN PIIRTÄMINEN..........................................................................................55 7.3 TRIGONOMETRINEN FOURIER-SARJA....................................................................................59 7.4 LENTORATA HEITTOLIIKKEESSÄ...........................................................................................64 8. HIIREN KÄYTTÖ GRAFIIKKAIKKUNASSA..................................................................69 9. TIETOTYYPPEJÄ..................................................................................................................71 9.1 MERKKIJONOT......................................................................................................................71 9.1.1 Muunnoskomentoja.......................................................................................................71 9.1.2 Vertailukomentoja........................................................................................................74 9.1.3 Käsittely- ja testauskomentoja......................................................................................75
MATLAB – Ohjelmointi
3
9.1.4 Evaluointikomentoja.....................................................................................................78 9.1.5 Merkkijonon kirjoittaminen..........................................................................................79 9.1.6 Merkkijonosta lukeminen..............................................................................................81 9.2 SOLUTAULUKOT...................................................................................................................82 9.3 TIETUEET..............................................................................................................................86 10. TIEDOSTOT..........................................................................................................................90 10.1 TIEDOSTON AVAAMINEN....................................................................................................90 10.2 TIEDOSTON SULKEMINEN...................................................................................................91 10.3 BINÄÄRITIEDOSTON KÄSITTELY.........................................................................................91 10.4 TEKSTITIEDOSTON KÄSITTELY...........................................................................................94 10.5 KOMENTOIKKUNAN MUUTTUJIEN TALLENTAMINEN..........................................................96 10.6 EXCEL-TIEDOSTOJEN KÄSITTELY........................................................................................98
MATLAB – Ohjelmointi
4
1. YLEISTÄ 1.1
M-tiedostot
MATLABin tehokas käyttö on mahdollista vasta, kun osaa ohjelmoida MATLABilla. MATLABissa on korkean tason ohjelmointikieli, jolla ohjelmia tehdään. Ohjelmointi MATLABilla on helpompaa kuin varsinaisilla ohjelmointikielillä. Omat ohjelmat laajentavat MATLABin käskyjä. Usein toistuvat komentosarjat kannattaa tehdä ohjelmiksi. Seuraavassa esitellään MATLAB-ohjelmoinnin alkeita. Vaikka tässä lähdetäänkin perusteista, omaksumista helpottaa se, että lukija on hiukan perillä ohjelmoinnista. Ohjelmat ovat m-tiedostoja. Nimitys tulee siitä, että niiden tarkenteena on .m. M-tiedostot voivat olla skriptejä tai funktioita. Nämä eroavat seuraavasti: Skripti on vain jono komentoja, joita käytetään automatisoimaan laskentaa. Skriptin muuttujat ovat yleisiä komentoikkunan muuttujia. Skriptin komentojen tulos tulostuu komentoikkunaan, ellei komentoja päätetä puolipisteellä. Funktio on ohjelma, jonka liittyminen ulkomaailmaan tapahtuu sisäänmeno- ja ulostuloparametrien kautta1. Funktion muuttujat ovat funktion sisäisiä muuttujia, joten ne eivät sotkeudu komentoikkunan muuttujiin. Funktiota voidaan käyttää laajentamaan MATLABin ominaisuuksia. M-tiedostoja on käsitelty kirjassa Matematiikkaa MATLABilla luvussa 5. Tässä kirjassa keskitytään ohjelmien eli funktioiden tekemiseen. M-tiedostoja ajetaan komentorivillä aivan samoin kuin muitakin MATLABin komentoja. Skripti ajetaan kirjoittamalla m-tiedoston nimi ilman tarkennetta .m. Funktio ajetaan kirjoittamalla funktion nimi ja antamalla suluissa oleville kutsuparametreille arvot. M-tiedosto voidaan luoda editorilla. Editorin voi käynnistää komennolla edit (tai edit TiedostonNimi) tai HOME-valikoston painikkeilla
Editori tuntee MATLABin syntaksin. Editorissa voi olla auki useita tiedostoja. Jos useampi tiedosto on auki, on editori-ikkunan vasemmassa ylänurkassa välilehdet, josta voi klikkaamalla vaihtaa tiedostoa. M-tiedoston sisällön voi tulostaa komentoikkunaan komennolla type tiedoston_nimi. Tiedostonimen tarkenteen .m voi tiedoston nimestä jättää pois. Oletushakemistossa olevien tiedostojen nimet saa näytölle komennolla what. ESIMERKKI. Seuraavassa on toteutettu Lissajous’n käyrien piirto skriptinä ja funktiona. Tee ohjelmat editorilla ja tallenna tiedostoihin. Tyhjennä MATLABin työtila Workspace komennolla clear ennen skriptin ja funktion ajoa. Mitä eroa on työtilassa ajojen jälkeen?
1
Funktiossa voi tietenkin olla myös luku- ja tulostuskäskyjä.
MATLAB – Ohjelmointi
5
Skripti: Tallenna skripti tiedostoon lissajous.m. Voit ajaa skriptin käskyllä lissajous. Sulje ensin grafiikkaikkuna. Anna komento ja paina viisi kertaa Enteriä. Näytölle tulostuu viisi erilaista Lissajous’n käyrää. % Lissajous'n-käyriä t = 0:0.01:2*pi; for k = 1:5 plot(cos(k*t),sin((k+1)*t)) pause end
Funktio: Tallenna funktio tiedostoon lissa.m. Funktio voidaan ajaa esim. komennolla lissa(10,15). Kokeile tätä! Sulje ensin grafiikkaikkuna. Anna komento ja paina Enteriä, kunnes uusia kuvia ei tule. Näytölle tulostuu erilaisia Lissajous’n käyriä. Funktiossa on kaksi kutsuparametria, joille kutsussa annetaan arvot. Kokeile erilaisia arvoja. Huomaa, että tämä funktio ei palauta mitään arvoa. function lissa(m,n) % Lissajous'n-käyriä funktiona t = 0:0.01:2*pi; for k = m:n plot(cos(k*t),sin((k+1)*t)) pause end
Molemmissa m-tiedostoissa esiintyvää for-silmukkaa käsitellään tarkemmin myöhemmin. Komento pause aiheuttaa sen, että ohjelma jää odottamaan jonkin painikkeen painamista.
1.2
Syöttö ja tulostus
Normaalisti funktio välittää tietoa ympäristön kanssa parametrien välityksellä. MATLABissa on kuitenkin tavanomaisten ohjelmointikielten tyyppisiä syöttö- ja tulostuskäskyjä, joista joitakin esitetään seuraavassa. Kirjoittamalla muuttujan nimi tulostetaan näytölle muuttujan nimi ja arvo. Komennolla disp(A) tulostetaan pelkästään muuttujan A arvo. Jos on A on merkkijono1 tulostetaan merkkijonon sisältävä teksti. >> A = [1 2;3 4]; >> A A =
1 3
2 4
>> disp(A) 1
Merkkijono on yksinkertaisten lainausmerkkien sisällä oleva teksti.
MATLAB – Ohjelmointi 1 3
6
2 4
>> disp('Tässä on merkkijono') Tässä on merkkijono
Näppäimistöltä luetaan reaalilukuja ja matriiseja komennolla a = input(kehote), missä kehote on merkkijono. Tällöin näytölle tulostuu merkkijono kehote ja muuttujaan a tallennetaan käyttäjän syöttämä arvo. Jos käyttäjä ei syötä mitään, vaan painaa vain Enteriä, niin muuttujaan a tallentuu tyhjä matriisi. Jos komento päätetään puolipisteellä, ei tulosta esitetä näytöllä. Merkkijonoon kehote saadaan rivinvaihto aikaiseksi merkeillä \n. Syötetty arvo voi sisältää lausekkeita ja työtilassa olevia muuttujia. >> x = input('Anna x: ') Anna x: 1.7 x =
1.7000
>> x = input('Anna x: ') Anna x: 2*x+5 x =
8.4000
>> A = input('Anna uusi matriisi.\nMatriisi? ') Anna uusi matriisi. Matriisi? [1 3; 4 7] A =
1 4
3 7
>> mxn = input('Anna matriisin kertaluku: ') Anna matriisin kertaluku: size(A) mxn =
2
2
Silmukkarakenteessa syötön loppumista voi testata komennolla isempty: >> A=input('Anna matriisi:') Anna matriisi: A =
[]
>> isempty(A) ans = 1
Komennolla str = input(kehote, ’s’) luettu arvo tallennetaan muuttujaan str merkkijonona.
MATLAB – Ohjelmointi
7
>> valinta = input('Jatketaanko (y/n)? ','s') Jatketaanko (y/n)? y valinta = y
ESIMERKKI. Seuraavassa on yksinkertainen kyselevä ohjelma funktion kuvaajan piirtämiseksi. function plotfun disp('Piirretään funktion f(x) kuvaaja välillä [a,b]'); fun = input('Anna funktio :','s'); vali = input('Anna väli [a,b]: '); clf; ezplot(fun,vali);
Ohjelman ajo tapahtuu seuraavasti: >> plotfun Piirretään funktion f(x) kuvaaja välillä [a,b] Anna funktio :x*sin(1/x) Anna väli [a,b]: [-1,1]
Piirtoikkunaan tulee funktion kuvaaja.
TEHTÄVIÄ 1. Tee ohjelma, joka kysyy lämpötilaa Celsius-asteina ja tulostaa sen Fahrenheit-asteina. Käytä laskennassa kaavaa F =1,8⋅C32 . 2. Tee ohjelma, joka laskee katkaistun ympyräkartion tilavuuden V πh 2 V= (r 1 +r 2 r 2 +r 22 ) , 3
MATLAB – Ohjelmointi missä h on ympyräkartion korkeus r 1 on pohjaympyrän säde r 2 on kansiympyrän säde. Ohjelma kysyy syöttöarvot käyttäjältä ja tulostaa tilavuuden näytölle.
8
MATLAB – Ohjelmointi
9
2. FUNKTIOT 2.1
Funktion rakenne
Funktio koostuu seuraavista osista: 1. Funktion esittelyrivi. Tämä on ohjelman ensimmäinen rivi, joka kertoo MATLABille, että m-tiedosto sisältää funktion. Tällä rivillä esitellään funktion nimi sisäänmenoparametrit ulostuloparametrit Funktion esittelyrivi on muotoa function out_param = funktion_nimi(in_param), missä in_param sisältää funktion sisäänmeno- eli kutsuparametrit. Ne kirjoitetaan pilkulla erotettuna. Jos sisäänmenoparametreja ei ole voidaan sulut jättää pois. out_param ilmoittaa ulostuloparametrit. Niitä voi olla o ei yhtään: jätetään kokonaan pois tai kirjoitetaan [ ]. o yksi: kirjoitetaan ulostuloparametrin nimi o useampi: kirjoitetaan ulostuloparametrien nimet pilkulla erotettuna hakasulkuihin 2. H1-rivi. Tämä on kommenttirivi, joka on ohjelman toinen rivi. Rivi alkaa %-merkillä. MATLAB tulostaa H1-rivin, kun help-komento kohdistetaan hakemistoon. Tämän osan voi jättää pois. 3. Help-teksti. Nämä ovat kommenttirivejä, jotka alkavat riviltä kolme. Help-teksti päättyy tyhjään riviin tai komentoriviin. MATLAB tulostaa H1-rivin ja help-tekstin, kun help-komento kohdistetaan tiettyyn funktioon. Tämän osan voi jättää pois. 4. Funktion runko. Tämä osa sisältää funktion varsinaisen ohjelmakoodin antaa arvon mahdollisille ulostulo-parametreille. Funktiota muodostettaessa on käytettävä taulukko-operaatioita (.*, .^, ./), jos sisäänmenoparametri voi olla vektori tai matriisi. 5. Kommentit. Kommentit alkavat %-merkillä ja päättyvät rivin lopussa. Kommentteja voi sijoittaa minne tahansa ohjelmassa. Osat 1, 2, 3 ja 4 on oltava ohjelmassa tässä järjestyksessä. Osat 1 ja 4 ovat pakollisia. ESIMERKKEJÄ funktion esittelyrivistä: function lissa(m,n) function A = heron(a,b,c) function [x,y,x] = sphe2car(rho,theta,phi)
MATLAB – Ohjelmointi
10
ESIMERKKI. Määritellään funktio heron(a,b,c), jolla on kolme parametria: function A = heron(a,b,c) % HERON Kolmion pinta-ala % heron(a,b,c) laskee kolmion pinta-alan, kun kolmion sivujen % pituudet ovat a, b, c. p = (a+b+c)/2; % Kolmion piirin puolikas A = sqrt(p*(p-a)*(p-b)*(p-c));
Tallennetaan funktio hakemistoon work. Kohdistetaan help-komento nykyiseen hakemistoon: >> help work … HERON Kolmion pinta-ala …
Kohdistetaan help-komento funktioon: >> help heron HERON Kolmion pinta-ala heron(a,b,c) laskee kolmion pinta-alan, kun kolmion sivujen pituudet ovat a, b, c.
Funktioita käytetään seuraavasti: >> heron(3,4,5) ans = 6
Funktion nimen muodostaminen noudattaa samoja sääntöjä kuin muuttujan nimen muodostaminen: nimen on alettava kirjaimella ja se voi sisältää kirjaimia (ei kuitenkaan ääkkösiä), numeroita ja alaviivoja. Nimen 63 ensimmäistä merkkiä otetaan huomioon. Isot ja pienet kirjaimet ovat eri kirjaimia. Funktion nimenä ei voi olla MATLABin avainsana, kuten if tai end. Myöskään MATLABin funktioiden nimiä ei ole hyvä käyttää omien funktioiden niminä, sillä se voi johtaa yllättäviin virheisiin. Funktio on syytä tallentaa samannimiseen m-tiedostoon, muuten voi tulla vaikeasti havaittavia virheitä. Siis funktio fun tallennetaan tiedostoon fun.m. Funktio ajetaan kirjoittamalla funktion nimi ja sulkuihin funktion sisäänmenoparametrien arvot. Tarkemmin: funktion function [y1,y2, ...] = funktion_nimi(x1,x2,...) ajo komennolla funktion_nimi(a1,a2,...) palauttaa ensimmäisen ulostuloparametrin y1 arvon muuttujaan ans. b1 = funktion_nimi(a1,a2,...) palauttaa ensimmäisen ulostuloparametrin y1 arvon ja tallentaa sen muuttujaan b1.
MATLAB – Ohjelmointi
11
[b1,b2,...] = funktion_nimi(a1,a2,...) palauttaa ulostuloparametrien arvot ja tallentaa ne muuttujiin b1,b2,.... ESIMERKKI. Tehdään funktio, jonka sisäänmenoparametrina on vektori ja ulostuloparametreina vektorin suurin ja pienin arvo. Funktio: function [ymin,ymax,ymean] = minmax(vect) ymin = min(vect); ymax = max(vect); ymean = mean(vect);
Funktion ajo: >> v=rand(1,100); >> minmax(v) ans = 0.0046 >> [y1,y2]=minmax(v) y1 = 0.0046 y2 = 0.9961 >> [y1,y2,y3]=minmax(v) y1 = 0.0046 y2 = 0.9961 y3 = 0.4675
TEHTÄVIÄ 1. Tee ohjelma, jonka sisäänmenoparametrina on lämpötila Celsius-asteina ja ulostuloparametrina on lämpötila Fahrenheit-asteina. Käytä laskennassa kaavaa F =1,8⋅C +32 . 2. Tee ohjelma, jonka sisäänmenoparametreina on kaksi reaalilukua ja ulostuloparametreina reaalilukujen summa ja tulo. 3. Tee ohjelma, joka laskee ympyrän
A 1= α π r 2 360
•
sektorin pinta-alan
•
segmentin pinta-alan A2 =
missä • r on ympyrän säde •
a on keskuskulma asteina.
r2 α π−sin α 2 180
(
)
MATLAB – Ohjelmointi
12
Ohjelman sisäänmenoparametreina on luvut r ja ja ulostuloparametreina A1 ja A2 . 4. Tee ohjelma, joka tulostaa taulukon Celsius- ja Fahrenheit-asteiden vastaavuuksista. Syöttötietoina annetaan Celsiusasteiden alaraja, yläraja ja taulukointiväli. Käytä laskennassa kaavaa F =1,8⋅C +32 .
2.2
Alifunktiot ja yksityiset funktiot
M-tiedosto voi sisältä useita funktioita. Tiedoston ensimmäinen funktio on pääfunktio (primary function), muut funktiot ovat alifunktiota (subfunction). Vain pääfunktio ja muut samassa m-tiedostossa olevat alifunktiot voivat kutsua alifunktiota. Jokainen alifunktio alkaa määrittelyrivillä ja sisältää koodin normaaliin tapaan. Alifunktiot voivat olla missä järjestyksessä tahansa. Yksityinen funktio (private function) on funktio, joka sijaitsee alihakemistossa private. Vain private-hakemiston äiti-hakemistossa olevat funktiot voivat kutsua yksityistä funktiota. Alifunktioita ja yksityisiä funktioita käyttäen voidaan luoda tietystä ohjelmasta paikallinen versio. Tämä johtuu siitä, että MATLABissa funktion tai muuttujan nimen selvittäminen tehdään seuraavassa järjestyksessä: Tarkistetaan 1. onko kyseessä muuttuja. 2. onko kyseessä kutsuvan funktion alifunktio. 3. onko kyseessä onko kyseessä kutsuvaan funktioon liittyvä yksityinen funktio. 4. onko kyseessä jokin funktio MATLABin hakupolussa. Hakupolussa ensimmäinen kohdattu nimi valitaan. Jos on useita samannimisiä funktioita, valitaan yo. järjestyksessä ensimmäinen.
2.3
Funktion muuttujat
Funktion muuttujista voidaan todeta seuraavaa: Muuttujan nimi alkaa kirjaimella. Muuttujassa voi olla korkeintaan 63 merkkiä. Muuttujia ei tarvitse esitellä. Sijoituskäsky luo muuttujan tai muuttaa muuttujan arvon. Funktion muuttujat ovat lokaaleja eli funktion sisäisiä. Niitä ei voi käyttää funktion ulkopuolella. Poikkeuksena ovat globaalit muuttujat ja pysyvät muuttujat. Globaali muuttuja on sellainen muuttuja, jonka arvo on käytettävissä ja muutettavissa kaikissa niissä funktioissa, joissa muuttuja on määritelty globaaliksi. Jos globaalia muuttujaa halutaan käyttää komentoikkunassa, on se sielläkin määriteltävä globaaliksi. Globaalit muuttujat suositellaan määriteltäväksi funktion alussa ennen niiden käyttöä. Komennolla global x y z määritellään muuttujat x, y, z globaaleiksi. Pysyvä muuttuja on sellainen lokaali muuttuja, jonka arvo säilyy seuraavaan funktion kutsuun asti. Komennolla persistent x y z
MATLAB – Ohjelmointi
13
määritellään muuttujat x, y, z pysyviksi. Pysyvää muuttujaa voi käyttää vain funktion sisällä. Pysyvät muuttujat on määriteltävä funktion alussa ennen niiden käyttöä. ESIMERKKI. Tehdään funktio, joka tallennetaan tiedostoon herong.m. Huomaa, että funktiossa ei ole kutsuparametreja. function A = herong() % HERON Kolmion pinta-ala % HERON() laskee kolmion pinta-alan, kun kolmion sivujen % pituudet ovat a, b, c % muuttujat a, b, c ovat globaaleja. global a b c p = (a+b+c)/2; % Kolmion piirin puolikas A = sqrt(p*(p-a)*(p-b)*(p-c));
Annetaan komentoikkunassa globaalimäärittely >> global a b c
Annetaan muuttujille arvot >> a = 3; b = 4; c = 5;
Ajetaan funktio >> herong ans = 6
Muutetaan a:n arvo: >> a = 5 a = 5
Ajetaan funktio >> herong ans = 9.1652
Kuten yo. funktiosta nähdään, parametrien välitys globaalien muuttujien välityksellä ei ole kovinkaan havainnollista. Tämä saattaa johtaa vaikeasti havaittaviin virheisiin. Siksi globaalien muuttujien käyttö on syytä rajoittaa vain erikoistilanteisiin. Globaalit muuttujat suositellaan kirjoitettaviksi isoilla kirjaimilla. Tällöin virheellinen käyttö ehkä pienenee.
TEHTÄVIÄ
MATLAB – Ohjelmointi
14
1. Ketjupyörästön ketjun pituuden L määrittäminen. Syöttötietoina annetaan ketjupyörien säteet R ja r sekä ketjupyörien keskipisteiden etäisyys c. Ketjun pituus L lasketaan käyttäen seuraavia kaavoja L=2 t+ b1+ b2 , missä t=√ c 2−(R−r )2 (180+ 2 α) π R b1 = 180 (180−2 α)π r b 2= 180 Edellä kulman a yksikkö on aste ja se määräytyy ehdosta R−r sin α= . c Tee ohjelma, jolla voit määrittää ketjun pituuden.
2.4
Anonyymi funktio
Yksinkertainen funktio voidaan määritellä komentorivillä anonyyminä funktiona komennolla fkahva = @(arglist) lauseke Komennossa arglist sisältää funktion argumentit pilkulla erotettuina lauseke on funktion määräävä lauseke. Komento luo funktiokahvan (ks. seuraava luku) fkahva. Funktion kutsu on muotoa fkahva(arglist) ESIMERKKI. Toteutetaan funktio f (x)=x 3 anonyyminä funktiona. Annetaan funktiolla nimi kuutio. >> kuutio=@(x) x^3 kuutio = @(x) x^3 >> kuutio(2) ans = 8
Toteutetaan funktio f ( x , y)=x 2 + y 2 anonyyminä funktiona. Annetaan funktiolle nimi sqr >> sqr=@(x,y) x^2+y^2 sqr = @(x,y) x^2+y^2 >> sqr(2,-3) ans = 13
MATLAB – Ohjelmointi
15
Toteutetaan vektoriarvoinen funktio f (t)=(cos(t) , sin(t )) anonyyminä funktiona. Annetaan funktiolle nimi cir. >> cir=@(t) [sin(t),cos(t)] cir = @(t)[sin(t),cos(t)] >> cir(0.5) ans = 0.4794
0.8776
TEHTÄVIÄ 1. Määrittele komentorivillä seuraavat anonyymit funktiot 2 a) f ( x)=x + x +1 . Funktion on toimittava alkioittain myös vektorilla. d ( x , y )=|x− y| b) Testaa funktioiden toiminta. 2. Toteuta seuraavat funktiot anonyymeinä funktioina.
a) b) c)
−0,1 x
sin( x) . Laske funktion arvo pisteessä x=1,3 . f ( x , y)=√sin 2 x +0,3 cos2 y . Laske funktion arvo pisteessä x=−3 , y=5 . t f (t)=(5 cos t , 3 sin t , π ) . Laske funktion arvo pisteessä x=π . f ( x)=e
MATLAB – Ohjelmointi
16
3. OHJAUSLAUSEET Ohjauslauseita käyttäen voidaan rakentaa monipuolisia ohjelmia. MATLABissa on toteutettu kaikki modernien ohjelmointikielten ohjauslauseet.
3.1
Toistolauseet
Toistolauseita käytettäessä palataan tietyn ehdon vallitessa yhä uudelleen toistamaan jo aikaisemmin suoritettuja toimenpiteitä. Näin muodostuu ohjelmaan silmukka. Koska matriisien taulukko-operaatiot ovat huomattavasti nopeampia suorittaa kuin toistolause, on aina syytä tarkistaa, voidaanko toistolause korvata matriisien taulukko-operaatioilla. 3.1.1 for-lause For-lauseessa toistetaan käskyjä ennalta määrätty määrä. For-lauseen muoto on for k = alku:askel:loppu lauseita end Oletusarvona on askeleen arvo 1. askel voi olla myös negatiivinen. Lauseen toiminta on seuraava: Silmukkamuuttuja k saa kaikki arvot arvosta alku arvoon loppu askeleella askel: alku, alku+askel, alku+2*askel, …, (loppu)1. Kullakin muuttujan k arvolla suoritetaan lauseet lauseita. ESIMERKKI. Muodosta seuraava tridiagonaalinen matriisi:
[ ] 7 1 0 0 0
1 7 1 0 0
0 1 7 1 0
0 0 1 7 1
0 0 0 1 7
Annetaan seuraavat komennot >> A = 3*eye(5) A = 3 0 0 3 0 0 0 0 0 0
0 0 3 0 0
0 0 0 3 0
0 0 0 0 3
>> for k = 1:4 A(k,k+1)=1; A(k+1,k)=1; end >> A 1
Viimeinen arvo on yhtä suuri kuin loppu, jos loppu on askeleen monikerran päässä muuttujasta alku.
MATLAB – Ohjelmointi A =
3 1 0 0 0
1 3 1 0 0
0 1 3 1 0
0 0 1 3 1
17
0 0 0 1 3
Komentoa diag (ks. help) käyttäen matriisi voidaan muodostaa lyhyemminkin: >> 3*eye(5)+diag(ones(1,4),1)+diag(ones(1,4),-1)
ESIMERKKI. Taulukoidaan funktion y=sin x arvot välillä [0, 2 ] käyttäen askelta 0,4 Toteutus for-lauseella: >> xx = []; yy = [];
% Alustetaan vektorit
>> for x = 0:0.4:2*pi xx = [xx x]; yy = [yy sin(x)]; end >> [xx;yy]' ans = 0 0.4000 0.8000 1.2000 1.6000 2.0000 2.4000 2.8000 3.2000 3.6000 4.0000 4.4000 4.8000 5.2000 5.6000 6.0000
0 0.3894 0.7174 0.9320 0.9996 0.9093 0.6755 0.3350 -0.0584 -0.4425 -0.7568 -0.9516 -0.9962 -0.8835 -0.6313 -0.2794
Nopeampi ja suositeltava tapa: >> x = 0:0.4:2*pi; >> [x;sin(x)]'
Yleisemmin for-lause voidaan esittää seuraavasti: for k = lauseke lauseita end
MATLAB – Ohjelmointi
18
Tässä lausekkeen lauseke sarakkeet tallennetaan yksi kerrallaan silmukkamuuttujaan k. Kullakin muuttujan k arvolla suoritetaan lauseet lauseita. Jos A on mn-matriisi, niin lause for v = A lauseita end tarkoittaa samaa kuin lause for j = 1:n v = A(:,j) lauseita end ESIMERKKI. Kokeillaan >> A=randi(10,2,5) A = 3 4
5 3
9 2
3 2
3 5
>> for v=A disp(v) end 3 4 5 3 9 2 3 2 3 5
ESIMERKKI. Matriisille A komento sum(A) antaa tulokseksi vaakavektorin, jonka alkiot koostuvat matriisin A sarakkeiden summista. Toteutetaan tämä for-lausetta käyttäen. Tapa 1: Tehdään ensin editorilla funktio vect_sum, joka laskee vektorin alkioiden summan. function sum = vect_sum(x) % VECT_SUM Vektorin alkioiden summa sum = 0;
% Alustetaan muuttuja nollaksi
MATLAB – Ohjelmointi for i = 1:length(x) sum = sum + x(i); end;
19
% Muuttujaan sum kerätään summa.
Sen jälkeen tehdään editorilla funktio matr_sum, joka toteuttaa komennon sum. function sar_sum = matr_sum(A) % matr_sum Matriisin rivivektorien summa sar_sum = []; for v = A sar_sum = [sar_sum vect_sum(v)]; end;
% Huomaa laskentatapa!
Tapa 2: Lasketaan suoraan matriisin rivivektorinen summa: function sum = matr_sum1(a) % MATR_SUM1 Matriisin rivivektorien summa sum = 0; for v = A' sum = sum + v; end; sum = sum';
% Alustetaan nollaksi % Lasketaan rivivektorien summat % Ulostuloparametri rivivektorina
Ohjelmia tehtäessä testaus aina tärkeä. Testataan ohjelmat satunnaismatriisilla. >> A= rand(10,5); >> sum(A) ans = 5.7468 4.9347
4.0812
5.4151
4.0064
>> matr_sum(A) ans = 5.7468 4.9347
4.0812
5.4151
4.0064
>> matr_sum1(A) ans = 5.7468 4.9347
4.0812
5.4151
4.0064
Käyttämällä MATLABin taulukko-operaattoreita, voidaan usein välttää for-lauseen käyttö ja suorittaa komennot nopeammin. ESIMERKKI. Lasketaan summa n
1
k k 1
2
1
1 1 1 1 2 4 9 16 n
eri tavoilla. Tehdään toteutukset funktioilla. Tapa 1: for-lauseen käyttö. Tavallisia ohjelmointikieliä käytettäessä toteutus on tämän tapainen function s = summa1(n) % SUMMA1 Lukujonon summan laskenta % for-lauseella
MATLAB – Ohjelmointi s=0; for k=1:n s=s+1/k^2; end
20
% Muuttujan alustus
Tapa 2: Taulukko-operaattoreiden käyttö. Mitään silmukkaa ei tarvita! function s = summa2(n) % SUMMA Lukujonon summan laskenta % taulukko-operaatioilla. k = 1:n; s = sum(1./k.^2);
Testataan toteutusten nopeuksia. Mitataan aika komentoparilla tic-toc. >> tic; summa1(10000000),toc ans = 1.6449 Elapsed time is 0.531663 seconds. >> tic; summa2(10000000),toc ans = 1.6449 Elapsed time is 0.278203 seconds.
Havaitaan, että tapa 2 on noin kaksi kertaa nopeampi 1 kuin tapa 1. Tapa 2 on myös elegantimpana suositeltava. ESIMERKKI. Satunnaiskombinaatio ja lotto. Tehdään ohjelma, joka muodostaa k-vektorin, jonka alkiot ovat satunnaisesti eri kokonaislukuja väliltä 1 .. n. Ohjelmassa komento randi muodostaa satunnaislukuja ja setdiff muodostaa joukkoerotuksen. Näitä asioita on käsitelty kirjan Matematiikkaa MATLABilla luvuissa 3.3 ja 15.3. function v = sat_kombi(n,k) % sat_kombi(n,k) satunnaiskombinaatio. % Ohjelma muodostaa k-vektorin, jonka alkiot ovat % satunnaisesti eri kokonaislukuja väliltä 1 .. n % Input-parametrit: % n - kokonaislukujen joukon yläraja % k - vektorin koko % Oltava k> sat_kombi(39,7) ans = 5 13 37
3
18
28
36
Ohjelmaa sat_kombi käyttäen voidaan tehdä ohjelma, joka arpoo satunnaisesti 6 lottoriviä, joissa esiintyvät ainakin kertaalleen kaikki luvut 1..39. Ohjelman ulostuloparamatri on matriisi, jonka riveillä on arvotut lottorivit. function rivit = lottorivit6() % Lottorivien arvonta % Output-parametri: % rivi -- Matriisi, jonka riveillä ovat arvotut lottorivit. luvut=sat_kombi(39,39); K=sat_kombi(35,3); luvut(40:42)=luvut(K); rivit = reshape(luvut,7,6)';
Ohjelman ajo: >> A=lottorivit6 A = 14 12 11 15 31 6 21 1 18 10 39 36 26 8 17 38 20 29
19 7 24 4 32 30
23 34 2 5 13 12
37 28 35 33 9 2
27 3 22 16 25 14
TEHTÄVIÄ 1. Tee ohjelma, joka laskee n:n ensimmäisen kokonaisluvun neliöiden summan. 2. Tee ohjelma, joka lukee lukuja näppäimistöltä ja tulostaa lukujen keskiarvon. Luettavien lukujen määrä annetaan ennen lukujen syöttöä. 3.1.2 while-lause while-lauseen muoto on seuraava: while ehto lauseita
MATLAB – Ohjelmointi
22
end Lauseen toiminta on seuraava: Lauseita lauseita toistetaan niin kauan kuin toistoehto ehto on tosi eli muuttujan ehto reaaliosa on eri suuri kuin nolla. Toistoehto ehto tarkistetaan ennen lauseen suoritusta. Jos toistoehto on epätosi (0) ensimmäisellä kerralla, lausetta ei suoriteta kertaakaan. ESIMERKKI. Selvitetään mistä k:n arvosta lähtien 2−k ≤eps . >> k = 1; >> while 2^(-k)>eps k=k+1; end >> k k =
52
Tarkistus >> eps ans = 2.2204e-016 >> 2^(-k) ans = 2.2204e-016 >> 2^(-k+1) ans = 4.4409e-016
While-lausetta käyttäen voidaan testata syötön oikeellisuutta ja syötön lopetusta: ESIMERKKI. Tehdään ohjelma, joka laskee harmonisen lukujonon summia. Ohjelma kysyy käyttäjältä kokonaisluvun n arvon ja tulostaa summan. Summien laskenta lopetetaan syöttämällä luku nolla. function harmoninen % Harmonisen lukujonon summan laskenta. disp('Harmonisen lukujonon summan laskenta'); n = 1; while(n~=0) n = input('Anna termien lukumäärä (lopetus = 0): '); s=sum(1./(1:n)); disp(s); end
MATLAB – Ohjelmointi
23
Ohjelman ajo on seuraavanlaista: >> harmoninen Harmonisen lukujonon summan laskenta Anna termien lukumäärä (lopetus = 0): 100 5.1874 Anna termien lukumäärä (lopetus = 0): 1000 7.4855 Anna termien lukumäärä (lopetus = 0): 0 0
TEHTÄVIÄ 1. Tee ohjelma, joka lukee näppäimistöltä positiivisia lukuja ja tulostaa lukujen 1 • aritmeettisen keskiarvon ¯x a = ( x 1+ x 2+⋯+ x n) n • •
geometrisen keskiarvon ¯x g= n√ x 1 x 2⋯ x n n harmonisen keskiarvon ¯x h= 1 1 1 + +⋯+ x1 x2 xn
Lukujen syöttö lopetetaan syöttämällä negatiivinen luku tai nolla.
3.2
Ehtolauseet
Ehtolauseessa ohjelman osa sisältää valinnan vaihtoehtoisten ohjelmahaarojen välillä. Valinta perustuu usein muuttujan arvojen vertailuun tai muuttujan ja vakion väliseen vertailuun. 3.2.1 if-lause if-lauseen muoto on seuraava: if ehto 1 lauseita 1 elseif ehto 2 lauseita 2 … elseif ehto n lauseita n else lauseita end
MATLAB – Ohjelmointi
24
Lauseen toiminta on seuraava: Jos ehto 1 on tosi, niin suoritetaan lauseita 1, muuten jos ehto 2 on tosi, niin suoritetaan lauseita 2 jne…, muuten suoritetaan lauseita. Rakenteesta voi puuttua elseif- ja else-osat, joten yksinkertaisimmillaan if-lause on if ehto lauseita end Jos if-lauseen ehto ei ole skalaari, on kaikkien ehtolausekkeen alkioiden oltava nollasta eroavia. Esimerkiksi matriisille X lause if X lauseita end on yhtäpitävä lauseen if all(X(:)) lauseita end kanssa. ESIMERKKI. Tarkastellaan funktion
{
x+1, kun x≤−1 f (x )= x2 −1, kun −1< x≤2 −x +5, kun x >2 esittämistä ja kuvaajan piirtämistä MATLABissa. Funktio voidaan määritellä seuraavana m-funktiona: function y = fun(x)
MATLAB – Ohjelmointi
25
if x fun(-3),fun(0),fun(3) ans = -2 ans = -1 ans = 2
Vektorille arvot ovat >> fun([-3,0,3]) ans = 8 5 2
Nämä ovat väärin. If-lauseen ehdoissa verrataan koko vektoria. Ehdot x x=-3:0.01:4; >> y = []; >> for t = x y = [y fun(t)]; end >> plot(x,y)
MATLAB – Ohjelmointi
26
Hankaluudet johtuvat if-lauseen käytöstä. Tätä ei tarvitakaan, vaan funktio voidaan määritellä seuraavasti (ks. Matematiikka MATLABilla luku 16.1) function y = gun(x) y = (x-1)&(x2).*(-x+5);
Tällöin vektoriargumentilla laskenta onnistuu >> gun([-3,0,3]) ans = -2 -1 2
ja piirto voidaan suorittaa komennolla >> plot(x,gun(x))
ESIMERKKI. Arvauspeli. Ohjelma arpoo kokonaisluvun tietyltä väliltä. Käyttäjän on arvattava tämä kokonaisluku. Jos käyttäjä vastaa väärin, ilmoittaa ohjelma, onko luku liian suuri vai liian pieni ja antaa käyttäjälle uuden vastausmahdollisuuden. Ohjelma päättyy kun käyttäjä on antanut oikean luvun. Ohjelma on seuraava. Tallenna ohjelma tiedostoon ArvaaLuku.m. function ArvaaLuku() M = 100; rng('shuffle'); luku = randi(M); disp('Arvaa kokonaisluku väliltä'); disp([1,M]); arvaus = input('Arvaus: '); load laughter; while (arvaus ~= luku) sound(y,Fs); if arvaus > luku disp('Luku liian suuri'); else disp('Luku liian pieni'); end; arvaus = input('Arvaus: '); end; disp('Oikein') load handel; sound(y,Fs)
Ohjelmassa on käytetty seuraavia komentoja: load tiedosto: Ladataan muuttujat tiedostosta tiedosto. sound(y,Fs): Soitetaan vektorissa y oleva signaali.
MATLAB – Ohjelmointi
27
ESIMERKKI. Lottorivien tarkistus. Tehdään ohjelma1, jolla voi tarkistaa lottorivien oikeiden numeroiden lukumäärän. function lottotarkistus(rivit, lottonumerot,lisanumerot) % Lottorivin tarkistus. % Input-parametrit % rivit -- Matriisi, jonka riveillä ovat lottorivit % lottonumerot -- Oikea lottorivi vektorina % lisanumerot -- Lisänumerot vektorina [m,n]=size(rivit); for i = 1:m k = length(intersect(rivit(i,:),lottonumerot)); fprintf('rivi %d: %d oikein\n',i,k); if k == 6 if length(intersect(rivit(i,:),lisanumerot)) > 0 fprintf('rivi %d: 6 + lisänumero oikein\n',i); end end end
Ohjelman ajo (lottorivimatriisi on muodostettu luvussa 3.1.1 tehdyllä ohjelmalla lottorivit6. >> A=lottorivit6 A = 12 15 24 17 35 16
33 7 4 1 29 32
36 6 11 10 2 14
23 26 30 19 8 37
27 18 22 38 25 26
13 34 3 9 28 12
39 5 31 20 21 33
>> lottotarkistus(A,[3,11,17,19,29,31,37],[33,1]) rivi 1: 0 oikein rivi 2: 0 oikein rivi 3: 3 oikein rivi 4: 2 oikein rivi 5: 1 oikein rivi 6: 1 oikein
ESIMERKKI. Polynomien yhteenlasku MATLABissa polynomi esitetään rivivektorina, joka sisältää polynomin kertoimet alenevien potenssien mukaan järjestettynä (ks. kirja Matematiikkaa MATLABilla luku 17.2). Esim. polynomi 3
p(x)=2 x −2 x+5 esitetään muodossa >> p = [2 0 -2 5];
Polynomien yhteenlasku suoritetaan siten, että samojen potenssien kertoimet lasketaan yhteen. Esimerkiksi 1
Ohjelmassa käytetään kirjoituskäskyä fprintf, joka esitellään luvussa 10.4
MATLAB – Ohjelmointi
28
(2 x3−2 x +5)+(3 x2 +6 x−2)=2 x3 +3 x 2+ 4 x +3 Tämä ei kuitenkaan onnistu suoraan MATLAB-esityksessä, sillä eo. yhteenlaskua vastaa yhteenlasku >> [2, 0, -2, 5] + [3, 6, -2] ??? Error using ==> + Matrix dimensions must agree.
Ennen yhteenlaskua on vaakavektorien pituudet tehtävä samoiksi lisäämällä mahdollisesti nollia toisen vektorin eteen. >> [2, 0, -2, 5] + [0, 3, 6, -2] ans = 2 3 4 3
Tehdään ohjelma, jolla voidaan suorittaa polynomien yhteenlaskua. Ohjelman on lisäksi poistettava mahdolliset alussa olevat nollat tulosvektorista. Tallennetaan ohjelma tiedostoon polyplus.m function p = polyplus(a,b) % POLYPLUS polynomien yhteenlasku % polyplus(a,b) laskee polynomien a ja b summan. na = length(a); nb = length(b); % Lasketaan polynomien summa: if na > nb p = a + [zeros(1,na-nb),b]; elseif nb > na p = [zeros(1,nb-na),a] + b ; else p = a + b; end % Poistetaan mahdolliset alkunollat: while p(1) == 0 p(1) = []; end
Kokeillaan ohjelmaa: >> polyplus([2, 0, -2, 5],[3, 6, -2]) ans = 2 3 4 3 >> polyplus(2,[-1,1,-3]) ans = -1 1 -1 >> polyplus([4 1 2 3],[-4 -1,1,-3]) ans = 3 0
TEHTÄVIÄ
MATLAB – Ohjelmointi
29
1. Muuta esimerkkiä Arvauspeli (ohjelma ArvaaLuku.m) seuraavasti: Ohjelma pyytää käyttäjää antamaan positiivisen kokonaisluvun, joka on arvattavan luvun suurin arvo. Ohjelma testaa, että annettu luku on positiivinen, jos ei niin ohjelma pyytää lukua uudestaan. 2. Tee ohjelma, joka kysyy käyttäjältä kappalemäärän ja yksikköhinnan. Ohjelma tulostaa tavaraerän hinnan. Alennus määräytyy hinnan perusteella seuraavasti: • jos hinta on yli 100 €, niin alennus on 2% • jos hinta on yli 200 €, niin alennus on 5% • jos hinta on yli 500 €, niin alennus on 10% 3. Tee ohjelma joka lukee Cooperin testin tuloksen (12 min aikana juostu matka miehille 3039 v.) ja tulostaa seuraavan tekstin: • jos matka < 1530, tulostetaan "Erittäin heikko kunto". • jos 1530 £ matka < 1840, tulostetaan "Heikko kunto". • jos 1840 £ matka < 2240, tulostetaan "Välttävä kunto". • jos 2240 £ matka < 2640, tulostetaan "Hyvä kunto". • jos matka ³ 2640, tulostetaan "Erinomainen kunto" 4. Tee ohjelma, joka laskee ns. painoindeksin I. Painoindeksi I määräytyy seuraavasti: m I 2, s missä m on paino kiloina s on pituus metreinä. Ohjelma on tulostettava painoindeksin arvo ja lisäksi seuraava kommentti: • jos I 20, "alipaino" • jos 20 I 25 , "normaalipaino" • jos 25 I 30 , "lievä ylipaino" • jos 30< I ≤35 , "huomattava ylipaino" • jos 35< I ≤40 , ”vaikea ylipaino” • jos I > 40 , "sairaalloinen lihavuus". 3.2.2 switch-lause switch-lauseen muoto on seuraava: switch lauseke case arvo 1 lauseita 1 case arvo 2 lauseita 2 … case arvo n lauseita n
MATLAB – Ohjelmointi
30
otherwise lauseita end Yllä lauseke on skalaari- tai merkkijonolauseke. Lauseen toiminta on seuraava: Lausekkeen lauseke arvo lasketaan ja lausekkeen arvoa verrataan case-osassa määriteltyjen vakiolausekkeiden arvoihin. Vertailu suoritetaan järjestyksessä lähtien arvosta arvo 1. Mikäli lausekkeen lauseke arvo on sama kuin case-osan vakiolausekkeen arvo, ohjelman suoritus siirtyy kyseiseen case-osaan. Vain tässä case-osassa olevat lauseet suoritetaan. Sen jälkeen poistutaan switch-lauseesta. otherwise-osa ei ole pakollinen. Jos lausekkeen lauseke arvo ei vastaa minkään case-osan arvoa, niin ohjelman suoritus siirtyy otherwise-osaan, jos rakenteessa on otherwise-osa switch-lausetta seuraavaan lauseeseen, jos otherwise-osaa ei ole. Perusmuodossaan switch-lauseen toiminta on siten sama kuin seuraavaan if-lauseen toiminta: if lauseke == arvo 1 lauseita 1 elseif lauseke == arvo 2 lauseita 2 … elseif lauseke == arvo n lauseita n else lauseita end case-osassa vertailu tarkoittaa seuraavaa testiä: luvuille: lauseke == arvo merkkijonoille1: strcmp(lauseke, arvo) yhden arvon sijasta voidaan verrata moneen arvoon laittamalla arvot aaltosulkujen sisään eli muodostamalla solutaulukko case {a1, a2, a3, …} lauseita
1
Komento käsitellään myöhemmin merkkijonojen yhteydessä.
MATLAB – Ohjelmointi
31
switch-rakenne ei vuoda läpi: vain ensimmäistä case-arvoa vastaavat lauseet suoritetaan ja sen jälkeen poistutaan rakenteesta. ESIMERKKI. Tehdään funktio, joka ilmoittaa onko arpakuution tulos pariton vai parillinen. Tallennetaan seuraava funktio tiedostoon arpakuutio.m: function arpakuutio(tulos) switch tulos case {1, 3, 5} disp('pariton') case {2, 4, 6} disp('parillinen') otherwise disp('väärä luku') end
Ajetaan ohjelmaa: >> arpakuutio(2) parillinen >> arpakuutio(7) väärä luku >> arpakuutio(1) pariton
ESIMERKKI. Tehdään ohjelma, joka tulostaa arpoo satunnaisia veikkausrivejä. function veikkaus rng('shuffle'); rivi = randi(3,13,1); for k=1:13 switch(rivi(k)) case 1 disp('1') case 2 disp('x') case 3 disp('2') end if mod(k,3)==0 disp(' '); end end
% Alustetaan satunnaislukugener. % Arvotaan rivi
% Tulostetaan tyhjä rivi
Ohjelman ajo tuottaa seuraavanlaisen tuloksen: >> veikkaus x 1 2 1
MATLAB – Ohjelmointi
32
1 x 1 2 2 x 1 2
ESIMERKKI. Satunnaiskävely xy-tasossa. Satunnaiskävelyssä lähdetään liikkeelle origosta ja liikutaan joka askeleella satunnaisesti yksi yksikkö joko vaakasuuntaan oikealle tai vasemmalle tai pystysuuntaan ylös tai alas (neljä vaihtoehtoa). Toteutetaan satunnaiskävely funktiona, jonka sisäänmenoparametrina on askeleiden lukumäärä. function xykavely(n) x = zeros(1,n+1); y = zeros(1,n+1); for k = 1:n suunta = randi(4); switch suunta case 1 x(k+1)=x(k)+1; y(k+1)=y(k); case 2 x(k+1)=x(k)-1; y(k+1)=y(k); case 3 y(k+1)=y(k)+1; x(k+1)=x(k); case 4 y(k+1)=y(k)-1; x(k+1)=x(k); end end plot(x,y,'o-'); hold on plot(x(1),y(1),'r*',x(n+1),y(n+1),'r+') hold off
Ohjelman ajo >> xykavely(100)
% Käydyt pisteet % Alku- ja loppupisteet
MATLAB – Ohjelmointi
33
TEHTÄVIÄ 1. Satunnaiskävely xy-tasossa tietylle etäisyydelle. Muunna esimerkkiä satunnaislukukävelystä siten, että satunnaiskävely päättyy, kun ollaan annetulla etäisyydellä origosta. Toteuta satunnaiskävely funktiona, jonka sisäänmenoparametrina on etäisyys origosta. Ohjelma piirtää kuvan reitistä. Ohjelma ulostuloparametri on askeleiden lukumäärä. 2. Tee ohjelma, joka lukee ensin kaksi reaalilukua ja sitten yhden kokonaisluvun. Luetun kokonaisluvun perusteella tekee seuraavaa: • jos luku on 1, lasketaan reaalilukujen summa • jos luku on 2, lasketaan reaalilukujen erotus • jos luku on 3, lasketaan reaalilukujen tulo • jos luku on 4, lasketaan reaalilukujen osamäärä • jos luku on jokin muu, tulostetaan virheilmoitus. 3.2.3 try-lause try-lauseen muoto on seuraava: try lauseita 1 catch lauseita 2 end Lauseen toiminta on seuraava:
MATLAB – Ohjelmointi
34
Normaalisti suoritetaan sanojen try ja catch välissä olevat lauseet. Jos tapahtuu virhe, jätetään loput lauseet suorittamatta ja siirrytään suorittamaan sanojen catch ja end välissä olevat lauseet. Komennolla lasterr saadaan selville virheen aiheuttaja. ESIMERKKI. Tehdään seuraava skripti ja tallennetaan se m-tiedostoon kokeïlu.m try
X = A+B catch disp('Kertaluvut eivät samoja') end
Työskennellään komentoikkunassa. >> lasterror('reset')
% Alustetaan virheilmoitus perustilaan
>> A=[1,2];B=[4,5];
% OK
>> kokeilu X = 5 7 >> A=[1,2,3];B=[4,5];
% Virheellinen
>> kokeilu Kertaluvut eivät samoja >> lasterr ans = Error using + Matrix dimensions must agree.
3.3
Keskeytyslauseet
Keskeytyslauseilla voidaan keskeyttää rakenteen lauseiden suoritus: voidaan tulla rakenteesta pois tai jättää osa rakenteen lauseista suorittamatta. Toistolauseissa for ja while voidaan käyttää seuraavia keskeytyslauseita: break: siirrytään toistolausetta seuraavaan lauseeseen. continue: pysytään toistolauseessa, mutta jätetään continue-lauseen jälkeiset ohjelmasilmukan lauseet suorittamatta. Funktiosta voidaan poistua return-komennolla. Normaalisti funktiosta poistutaan, kun viimeinen funktion lause on suoritettu. return-lause mahdollistaa poistumisen myös muuten. Ohjelman suoritus voidaan pysäyttää seuraavasti: pause: pysäyttää funktion suorituksen. Suoritus jatkuu, kun jotain näppäintä painetaan. pause(n): pysäyttää ohjelman suorituksen n:n sekunnin ajaksi. ESIMERKKI. pause-komento on kätevä grafiikan esityksessä. Sulje grafiikka-ikkuna. Tee editorilla seuraava skripti ja aja se.
MATLAB – Ohjelmointi
35
t = linspace(0,2*pi,1000); for u = 1:2:20 plot(cos(t).^u,sin(t).^u); axis equal hold on pause(2) end hold off
Saat kahden sekunnin välein käyriä samaan kuvaan.
MATLAB – Ohjelmointi
36
4. DIFFERENSSIYHTÄLÖT 4.1
Teoriaa
4.1.1 Differenssiyhtälö Lukujono x on jono lukuja, jotka on indeksoitu kokonaisluvuilla. Indeksijoukko voi olla kaikki kokonaisluvut tai kokonaislukujen osaväli. Lukujonon indeksiä k vastaavaa alkiota merkitään x k tai x k . Usein koko lukujonoa merkitään lyhyesti x k . Kertalukua n oleva differenssiyhtälö on muotoa F k , x k , x k 1 , , x k n−1 , x k n=0 oleva yhtälö. Seuraavassa tarkastellaan vain sellaisia yhtälöitä, joissa x k n voidaan ratkaista, jolloin yhtälö voidaan esittää muodossa x k n= f k , x k , x k1 , , x kn−1 (1) Jos indeksijoukon alaraja on nolla, on lukujono x k differenssiyhtälön ratkaisu, jos se toteuttaa differenssiyhtälön kaikilla k =0,1 ,2 , . Jos arvoille x 0 , x1 , , x n−1 on annettu mielivaltaiset arvot, voidaan yhtälöstä (1) rekursiivisesti laskea ratkaisun arvot indeksistä n eteenpäin. Siten differenssiyhtälön alkuarvoprobleemalla, jossa on määritettävä se ratkaisu, joka toteuttaa alkuehdot x 0= x1 , x1 =x 2 , , x n−1 =x n on yksikäsitteinen ratkaisu. ESIMERKKI. Eräs pöllölaji lisääntyy 2% vuodessa. Jos x k on pöllöjen määrä k:n vuoden päästä, niin x k 1=x k 0,02 x k =1,02 x k . Lukujono x k toteuttaa siis seuraavan differenssiyhtälön ( k≥0) x k 1=1,02 x k . Jotta x 1 olisi määritelty on tiedettävä x 0 eli pöllöjen määrä alkuhetkellä. Tässä tapauksessa on helppo määrittää yleinen kaava, jolla x k voidaan laskea. ESIMERKKI. Differentiaaliyhtälön diskretointi Analogiset prosessit mallinnetaan usein differentiaaliyhtälöiden avulla. Tällaiset mallit on diskretoitava, kun niitä halutaan käsitellä diskreetillä järjestelmällä. Kun differentiaaliyhtälö diskretoidaan, siitä syntyy differenssiyhtälö. Tarkastellaan esimerkkinä differentiaaliyhtälöä dy +a y= f (t ) . dt Tässä esiintyvä tuntematon funktio y diskretoidaan käyttäen diskretointiaskelta D seuraavasti: Määritellään lukujono y k seuraavasti:
y k = y( k Δ) Derivaatta voidaan diskretoida erotusosamäärällä
MATLAB – Ohjelmointi
37
dy ( k Δ) y (k Δ+ Δ)− y ( k Δ) y k +1− y k ≈ = Δ Δ dt Päädytään seuraavaan differentiaaliyhtälön diskretointiin1:
y k+1− y k , Δ +a y k = f k missä
f k = f (k Δ) Tästä saadaan sieventämällä differenssiyhtälö
y k +1 +(a Δ−1) y k =Δ f k ESIMERKKI. Fibonaccin2 luvut Fibonaccin luvut määritellään seuraavasti: ensimmäinen luku on 1 toinen luku on 1 sen jälkeen luku on kahden edellisen summa. Luvut liittyvät seuraavaan ongelmaan, jota Fibonacci tutki vuoden 1200 tienoilla: Hedelmällinen jänispari sijoitetaan aitaukseen. Kuinka monta jänisparia on vuoden lopussa, jos jänisten lisääntyminen noudattaa seuraavia sääntöjä: Hedelmällinen jänispari tuottaa uuden jänisparin jokaisen kuukauden lopussa. Uusi pari tulee hedelmälliseksi yhdessä kuukaudessa Yksikään jänis ei kuole. Jos k:tta Fibonaccin lukua merkitään f k :lla, niin tämä voidaan ilmaista seuraavasti: f 1=1 f 2=1 f k = f k−1 f k−2
k ≥3
Tässä on kyseessä differenssiyhtälö, jossa on kaksi alkuehtoa. Fibonacci-luvut on määrätty rekursiivisesti: luku on lausuttu edellisten lukujen avulla. Differenssiyhtälö voidaan kirjoittaa myös muotoon f k 2= f k 1 f k k ≥1 Muuttamalla indeksointia voidaan alkuarvoprobleema lausua muodossa f 0=1 f 1=1 f k 2= f k 1 f k
k ≥0 .
1
Tämä johtaa Eulerin menetelmään Leonardo Fibonacci (n. 1180-1240), Leonardo Pisalainen, oli italialainen matemaatikko, jota voidaan pitää Euroopan ensimmäisenä matemaatikkona. Hän sai koulutuksensa Pohjois-Afrikassa. Fibonacci toi Eurooppaan arabialaiset numerot ja niihin liittyvän positiojärjestelmään perustuvan laskutavan. 2
MATLAB – Ohjelmointi
38
4.1.2 Differenssiyhtälöryhmä 1. kertaluvun differenssiyhtälöryhmä on muotoa1
{
x 1 k 1= f 1 k , x1 k , x 2 k , x n k x 2 k 1= f 2 k , x 1 k , x 2 k , x n k ⋯ x n k 1= f n k , x 1 k , x 2 k , x n k
missä x 1 k , x 2 k , , x n k ovat tuntemattomia ratkaistavia lukujonoja. Differenssiyhtälöryhmän ratkaisu koostuu sellaisista lukujonoista, jotka toteuttavat differenssiyhtälöryhmän kaikilla2 k =0,1 ,2 , . Differenssiyhtälöryhmän alkuarvoprobleemassa on löydettävä se ratkaisu, joka indeksin arvolla 0 toteuttaa alkuehdon
{
x1 0= x 1 x 2 0= x 2 ⋯ x n 0= x n
missä x 1 , x 2 , , x n ovat annettuja lukuja. Alkuarvoprobleemalla on yksikäsitteinen ratkaisu, sillä alkuarvoista lähtien voidaan rekursiivisesti laskea ratkaisun arvot indeksien arvoilla 1, 2, 3, … Differenssiyhtälöryhmä voidaan esittää vektorimuodossa x k 1= f k , x k , missä x k on n-vektori ja f on funktio, jonka arvona on n-vektori. Alkuehto on tällöin muotoa x 0=x 0 , missä x 0 on annettu n-vektori. ESIMERKKI. Differenssiyhtälöryhmän alkuarvoprobleeman x (k )−2 y ( k ) x(0)=3 , { {xy((kk+1)=− +1)=−3 x (k )−2 y ( k ) y (0)=2 ratkaisuja voidaan laskea rekursiivisesti: (0)−2 y (0)=−3−2⋅2=−7 {x(1)=−x y(1)=−3 x(0)−2 y(0)=−3⋅3−2⋅2=−13 (1)−2 y (1)=−(−7)−2⋅(−13)=33 {xy(2)=−x (2)=−3 x (1)−2 y (1)=−3⋅(−7)−2⋅(−13)=47 … Ratkaisu voidaan esittää yleisesti muodossa 1 2
Tässä lukujonon alkioita merkitään x(k) Indeksijoukon alaraja on tässä nolla.
MATLAB – Ohjelmointi
39
{
x ( k )=2⋅4 k (−1)k +1 y ( k )=3⋅4 k (−1)k −1
Kertalukua n oleva differenssiyhtälö
xk + n=f (k , xk , xk + 1 , … , xk + n− 1) voidaan muuntaa 1. kertaluvun differenssiyhtälöryhmäksi seuraavasti: Määritellään n lukujonoa
(1)
{ {
y1 (k)=xk y2 (k)=xk + 1 ⋮ yn (k)=xk + n− 1
Suoraan laskemalla todetaan, että nämä lukujonot toteuttavat differenssiyhtälöryhmän y1 (k+1)= y2 (k) y2 (k+1)= y3 (k) ⋮ yn (k+1)=f (k , y1 (k), y2 (k), … , yn (k))
Tämä ryhmä on differenssiyhtälöä (1) vastaava normaaliryhmä. Lukujono x k = y 1 ( k ) on differenssiyhtälön (1) ratkaisu, y 1 ( k ) , y 2 ( k ) ,…, y n ( k ) on vastaavan normaaliryhmän ratkaisu. Jos differenssiyhtälöön (2) liittyy alkuehto
x0= x^ 1 , x 1=^x2 ,… , xn−1= ^xn niin vastaavan normaaliryhmän alkuehto on
{
y1 (0)= x^2 y2 (0)= x^2 ⋮ yn (0)= x^n
ESIMERKKI. Muunnetaan differenssiyhtälö x k +3 −5 x k +2 + x k +1−2 x k =k +2 , x 0 =−1, x 1=2, x 2=4 normaaliryhmäksi. Ratkaistaan ensin x k +3 : x k +3=5 x k+ 2−x k+1 +2 x k + k + 2 Määritellään kolme lukujonoa y1 (k)=xk y2 (k)=xk + 1 y3 (k)=xk + 2 Tällöin
{
jos
ja
vain
jos
MATLAB – Ohjelmointi
{ { {
40
y 1 ( k +1)= x k +1= y 2 ( k ) y 2 ( k +1)= x k +2 = y 3 (k ) y 3 ( k +1)= x k +3=5 x k +2 − x k +1 +2 x k + k + 2=5 y 3 ( k )− y 2 (k )+2 y1 (k )+ k +2
josta saadaan normaaliryhmä y 1 ( k +1)= y 2 ( k ) y 2 ( k +1)= y 3 ( k ) y 3 ( k +1)=5 y 3 ( k )− y 2 (k )+ 2 y1 ( k )+ k + 2 Alkuehdot ovat y 1 (0)=x 0 =−1 y 2 (0)= x 1=2 y 3 (0)= x 2=4
4.2
Numeerinen ratkaiseminen
4.2.1 Differenssiyhtälö Differenssiyhtälön alkuarvoprobleema voidaan ratkaista rekursiivisesti käyttäen esitystä x k +n = f ( k , x k , x k +1 ,… , x k+ n−1 ) . Seuraavassa on esitetty funktio deqsolve, joka toteuttaa tämän: function y = deqsolve(fun,x0,n) % DEQSOLVE Differenssiyhtälön ratkaiseminen % y = deqsolve(fun,x0,n) % Sisäänmenoparametrit: % - fun kahva funktioon y = fun(k,x), joka määrittää differenssiyhtälön % - x0 alkuehdot vektorina [x0, x1, ...] % - n indeksi, johon asti ratkaisuja lasketaan. % Ulostuloparametri: % - ratkaisu vaakavektorina. y = x0; x = x0; for k =0:(n-length(x0)) y1 = fun(k,x); y = [y, y1]; x = [x(2:end),y1]; end
Funktion deqsolve kutsuparametrina oleva kahva funktioon fun määrittelee differenssiyhtälön. Funktion fun esittely on seuraava: function y = fun(k, x), missä k on skalaari x on vektori, joka sisältää arvot [ x k , x k+1 ,… , x k +n−1 ] y on skalaari, joka sisältää lausekkeen f ( k , x k , x k+1 ,… , x k +n−1) arvon. Komento
MATLAB – Ohjelmointi
41
deqsolve(fun,x0,n) ratkaisee differenssiyhtälön välillä 0… n. ESIMERKKI. Määritetään Fibonaccin lukujono arvoja. Fibonaccin lukujono on differenssiyhtälön alkuarvoprobleeman f k +2= f k+1 + f k , f 0=1 , f 1=1 ratkaisu. Differenssiyhtälön määrittelee seuraava m-funktio: function y = defun(k,x) y =x(1)+x(2);
Lasketaan 11 ensimmäistä Fibonaccin lukua: >> deqsolve(@defun,[1,1],10) ans = 1 1 2 3 5
8
13
21
34
55
89
Tuhannes Fibonaccin luku on (indeksointi alkaa 0:sta) >> y = deqsolve(@defun,[1,1],0:999); >> y(999) ans = 2.6864e+208
ESIMERKKI. Ratkaistaan differenssiyhtälö 1 , x 0=1, x 1=2 . 6 x k+2 +6 x k+1−x k = k +1 Ratkaistaan x k+2 : 1 1 . x k+2=−x k+1 + x k + 6 6(k +1) Differenssiyhtälön määrittelee seuraava m-funktio: function y = defun1(k,x) y =-x(2)+1/6*x(1)+1/(6*(k+1));
Määritetään ratkaisu indeksin arvoilla 0…20 ja piirretään kuvaaja. >> y = deqsolve(@defun1,[1,2],20); >> plot(0:20,y,'-o') >> grid
MATLAB – Ohjelmointi
42
Ratkaisujonon 7 ensimmäistä lukua ovat >> y(1:7) ans = 1.0000
2.0000
-1.6667
2.0833
-2.3056
2.6944
-3.0454
4.2.2 Differenssiyhtälöryhmä 1. kertaluvun differenssiyhtälöryhmän alkuarvoprobleema voidaan ratkaista rekursiivisesti käyttäen vektoriesitystä x k 1= f k , x k , Seuraavassa on esitetty funktio dessolve, joka toteuttaa tämän: function y = dessolve(fun,x0,n) % DESSOLVE Differenssiyhtälöryhmän ratkaiseminen % y = dessolve(fun,x0,n) % Sisäänmenoparametrit: % - fun kahva funktioon y = fun(k,x), joka määrittää differenssiyhtälön % - x0 alkuehto vektorina % - n indeksi, johon asti ratkaisuja lasketaan. % Ulostuloparametri: % - ratkaisu matriisina, jonka k:s sarake sisältää ratkaisun indeksin % arvolla k. a = size(x0); if a(1) == 1 x = x0'; else x = x0; end y = x; for k = 0:n-1 x = fun(k,x); y = [y, x]; end
Komento
% x pystyvektori
MATLAB – Ohjelmointi
43
dessolve(fun,x0,n) ratkaisee differenssiyhtälöryhmän välillä 0… n. ESIMERKKI. Ratkaistaan luvun 4.2.1 Esimerkin differenssiyhtälöryhmä x (k )−2 y ( k ) x(0)=3 , { {xy((kk+1)=− +1)=−3 x (k )−2 y ( k ) y (0)=2 Differenssiyhtälön määrittelee seuraava m-funktio: function y=desfun(k,x) y = [-x(1)-2*x(2);-3*x(1)-2*x(2)];
Lasketaan ratkaisu indeksin arvoilla 0…5:. >> dessolve(@desfun,[3;2],5) ans = 3 2
-7 -13
33 47
-127 -193
513 767
-2047 -3073
Siis
{
x (1)=−7 , y (1)=−13
{
x (2)=33 y (2)=47
ESIMERKKI. Ratkaistaan luvun 4.1.2 toisen esimerkin differenssiyhtälö x k +3 −5 x k +2 + x k +1−2 x k =k +2 , x 0 =−1, x 1=2, x 2=4 käyttäen ohjelmia deqsolve1 ja dessolve deqsolve: Ratkaistaan x k +3 : x k +3=5 x k+ 2−x k+1 +2 x k + k + 2 M-funktio: function y = de1fun(k,x) y =5*x(3)-x(2)+2*x(1)+k+2;
Komento >> deqsolve(@de1fun,[-1,2,4],5) ans = -1 2 4 18 93
dessolve: Vastaava normaaliryhmä on
1
Tämä ohjelma on tehty edellisessä luvussa.
459
MATLAB – Ohjelmointi
{
44
y 1 ( k +1)= y 2 ( k ) y 2 ( k +1)= y 3 ( k ) y 3 ( k +1)=5 y 3 ( k )− y 2 (k )+ 2 y1 ( k )+ k + 2
M-funktio: function y=de2fun(k,x) y = [x(2);x(3);5*x(3)-x(2)+2*x(1)+k+2];
Komento >> dessolve(@de2fun,[-1,2,4],5) ans = -1 2 4 2 4 18 4 18 93
18 93 459
93 459 2243
459 2243 10948
Havaitaan, että normaaliryhmän ratkaisumatriisin ensimmäinen rivi on differenssiyhtälön ratkaisu.
MATLAB – Ohjelmointi
45
5. FUNKTION PARAMETREISTA 5.1
Kahvat ja funktioparametrit
Funktio fun(x) kahva (handle) on @fun. Anonyymin funktion nimi, on sen kahva. Funktion fun(x) arvo voidaan kahvaa käyttäen laskea seuraavasti: kahva = @fun kahva(x) Voidaan käyttää myös komentoa feval feval(@fun, x) ESIMERKKI. Funktio sin(x) on MATLABin sisäänrakennettu funktio. Lasketaan sinin arvo eri tavoilla >> sin(0.5) ans = 0.4794
% Normaalisti
>> s=@sin; >> s(0.5) ans = 0.4794
% Kahvan nimeä käyttäen
>> feval(@sin,0.5) ans = 0.4794
% feval-komentoa käyttäen
Funktiossa voi olla kutsuparametreina kahvoja. Tämä mahdollistaa funktioiden välittämisen kutsussa funktioon. Funktio välitetään muodossa @fun, jos funktio on MATLABin funktio tai funktio sijaitsee tiedostossa fun.m. fun, jos funktio on aiemmin määritelty anonyymina funktiona @(arglist) lauseke, jos funktio määritellään anonyymina funktiona kutsussa.
5.2
Sovellus – Haarukointimenetelmä
On määritettävä yhtälön f x =0 välillä [a , b] olevan juuren likiarvo, kun tiedetään, että funktion arvot välin päätepisteissä f a ja f b ovat erimerkkiset. Jos f on jatkuva funktio, niin Bolzanon lauseen mukaan yhtälöllä on ainakin yksi juuri tällä välillä. Haarukointimenetelmässä juuren likiarvo määritetään muodostamalla juurta kohti suppeneva likiarvojen jono x 1 , x 2 , x3 , seuraavasti: ab Valitaan ensimmäiseksi likiarvoksi x 1 välin [a , b] keskipiste x 1= . Jos 2 f x 1 =0 , on juuri löydetty, muuten f x 1 on erimerkkinen kuin f a tai f b , jolloin alkuperäisen välin toisella puolikkaalla on juuri. Valitaan tämän puolikkaan keskipiste uudeksi likiarvoksi x 2 ja jatketaan samaan malliin.
MATLAB – Ohjelmointi
46
Likiarvojen muodostaminen lopetetaan, kun on päästy haluttuun tarkkuuteen. Viimeinen likiarvo x n valitaan juuren likiarvoksi. Tällöin virhe on pienempi kuin ∣x n −x n−1∣ . Toteutetaan tämä seuraavana m-funktiona. Toteutetaan tämä seuraavana MATLAB-funktiona. function y = bisection1(fun,a,b) %BISECTION1 Funktion 0-kohdan määrittäminen haarukointimenetelmällä %Input-parametrit: %fun -- kahva funktioon %a, b -- välin päätepisteet, joissa funktiolla erimerkkiset arvot %Output-parametrit: %y -- juuren likiarvo fa = fun(a); fb = fun(b); if fa*fb > 0 disp('Välin päätepisteessä samanmerkkiset arvot'); y=[]; elseif fa == 0 y = a; elseif fb == 0 y = b; else while abs(a-b) > 1e-6 %Likiarvon tarkkuus 1e-6 y = (a+b)/2; fy = fun(y); if fy*fa > f = @(x) log(x)-(x.^2-7*x+10);
Funktiolla on erimerkkiset arvot välin päätepisteissä: >> f(4),f(7) ans = 3.3863 1
Yhden tuntemattoman yhtälöiden numeerista ratkaisemista on käsitelty kirjan Matematiikkaa MATLABilla luvussa 6.1
MATLAB – Ohjelmointi
47
ans = -8.0541
Määritetään juuren likiarvo kahdella eri tavalla. Anonyymiä funktiota käyttäen: >> bisection1(f,4,7) ans = 5.4881
M-funktiota käyttäen: m-tiedosto fun.m: function y = fun(x) y = log(x)-(x.^2-7*x+10);
komento: >> bisection1(@fun,4,7) ans = 5.4881
Tarkistetaan funktion arvo >> fun(ans) ans = 1.4089e-06
Juuren likiarvo on siis 5,4881. MATLAB-komennolla fzero saadaan sama tulos: >> fzero(f,[4,7]) ans = 5.4881
5.3
Vaihteleva määrä argumentteja
MATLABissa funktioita voidaan kutsua vaihtelevalla määrällä sisäänmeno- ja ulostuloparametreja. Funktiokutsussa olevien parametrien määrä saadaan funktion sisällä selville komennoilla nargin: input-parametrien lukumäärä nargout: output-parametrien lukumäärä ESIMERKKI. Haarukointimenetelmä (jatkoa) Muutetaan edellisen luvun ohjelmaa, siten että siinä on valinnaisena input-parametrian toleranssi ja valinnaisena output-parametrina funktion arvo nollakohdassa: function [y,fy] = bisection2(fun,a,b,tol) %BISECTION2 Funktion 0-kohdan määrittäminen haarukointimenetelmällä %Input-parametrit: %fun -- kahva funktioon %a, b -- välin päätepisteet, joissa funktiolla erimerkkiset arvot
MATLAB – Ohjelmointi
48
%tol -- toleranssi (valinnainen argumentti); oletustoleranssi 1e-6. %Output-parametrit: %y -- juuren likiarvo %fy -- funktion arvo nollakohdan likiarvossa if nargin == 3 tol = 1e-6; else if tol < 0 disp('tol > 0'); y=[]; fy=[]; return end end
%Oletustoleranssi
fa = fun(a); fb = fun(b); if fa*fb > 0 disp('Välin päätepisteessä samanmerkkiset arvot'); y=[]; fy=[]; elseif fa == 0 y = a; fy = 0; elseif fb == 0 y = b; fy = 0; else while abs(a-b) > tol %Likiarvon tarkkuus tol y = (a+b)/2; fy = fun(y); if fy*fa > [y,arvo] = bisection2(f,4,7,1e-2) y = 5.4824 arvo = 0.0216
Käytetään funktiota kolmella input-parametrilla (oletustoleranssi on 1e-6) ja kahdella output-parametrilla: >> [y,arvo] = bisection2(f,4,7) y = 5.4881 arvo = 1
Anonyymi funktio f on määritelty edellisessä luvussa.
MATLAB – Ohjelmointi
49
1.4089e-006
Huomaa toleranssin vaikutus. Seuraavassa on vain yksi output: >> bisection2(f,4,7) ans = 5.4881
Vaihteleva määrä input- ja output-parametreja voidaan välittää funktioon käyttämällä muuttujia varargin syötteisiin varargout ulostuloihin. Nämä ovat solutaulukkoja1, sillä MATLABin pakkaa input-parametrit solutaulukoksi. Output-parametrit on ohjelmassa muutettava solutaulukoksi. ESIMERKKI. Tehdään funktio, joka kerää annetuista rivivektoreista koordinaatit. function [varargout] = collect(varargin) X = []; for i = 1:length(varargin) X = [X; varargin{i}]; end for i = 1:length(varargin{1}) varargout{i} = X(:,i)'; end
Ohjelman toiminta selvinnee seuraavasta ajoesimerkistä Kolme output-muuttujaa: kerätään kaikki koordinaatit >> [a,b,c] = collect([1 2, 4],[2 -3,5], [0, 4, 5], [5 9 -2]) a = 1 2 0 5 b = 2 -3 4 9 c = 4 5 5 -2
Kaksi ulostulo-muuttujaa: kerätään kaksi ensimmäistä koordinaattia >> [a,b] = collect([1 2, 4],[2 -3,5], [0, 4, 5], [5 9 -2]) a = 1 2 0 5 b = 2 -3 4 9
Kerätään vain ensimmäinen koordinaatti: >> collect([1 2, 4],[2 -3,5], [0, 4, 5], [5 9 -2]) ans = 1 2 0 5
1
Solutaulukkoja käsitellään tarkemmin myöhemmin.
MATLAB – Ohjelmointi
50
ESIMERKKI. Tehdään funktio, jonka syötteenä on mielivaltainen määrä samanpituisia vektoreita. Tulosteena saadaan vektoreiden koordinaattien keskiarvot ja keskihajonnat. function [varargout] = stat(varargin) X = []; for i = 1:length(varargin) X = [X; varargin{i}]; end varargout{1} = mean(X); varargout{2} = std(X);
Ajoesimerkki: >> [keskiarvo, hajonta] = stat([1 2, 4],[2 -3,5], [0, 4, 5], [5 9 -2]) keskiarvo = 2 3 3 hajonta = 2.1602 4.9666 3.3665
Pelkät keskiarvot saadaan seuraavasti: >> stat([1 2, 4],[2 -3,5], [0, 4, 5], [5 9 -2]) ans = 2
3
3
Jos funktiossa käytetään sekä tavallisia parametreja että varargin- ja varargout-parametreja on tavallisten parametrien oltava ensin.
MATLAB – Ohjelmointi
51
6. REKURSIIVINEN FUNKTIO MATLABissa voidaan käyttää rekursiivisia funktioita eli sellaisia funktioita, jotka kutsuvat itseään. Rekursiivisen funktion tekemisessä on huolehdittava siitä, että funktiossa on joku muuttuva ehto, joka pysäyttää rekursion jossain vaiheessa. Rekursiivinen funktio voidaan aina myös toteuttaa iteratiivisena funktiona, jossa rekursio toteutetaan iteraatiolla eli ohjelmasilmukalla. Koska rekursio joka kutsukerta tallentaa funktion muuttujat ja kutsutiedot tietokoneen muistiin, on iteraatio useimmiten nopeampi kuin rekursio. Tutkitaan tätä seuraavassa esimerkissä. ESIMERKKI. Tsebyshevin polynomit. Tsebyshevin polynomit T n x määritellään rekursiokaavalla T 0 ( x)=1 T 1 x =x T n x=2 x T n−1 x−T n−2 x , kun n1 Tehdään funktio Tsebyshevin polynomien laskemiseksi. Funktiossa käytetään luvun 3.2.1 esimerkissä tehtyä funktiota polyplus. Polynomit esitetään vaakavektoreina1. Iteratiivinen toteutus: function tn = tseby_it(n) % TSEBYSHEV Tsebyshevin polynomit -- iteratiivinen toteutus % tsebyshev(n) laskee n:nnen asteen Tsebyshevin polynomin x = [1 0]; t0 = 1; t1 = x; if n < 0 disp('n >=0'); elseif n == 0 tn = t0; elseif n == 1 tn = x; else for i = 2:n tn = polyplus(2*conv(x,t1),-t0); t0 = t1; t1 = tn; end end
Rekursiivinen toteutus: function tn = tseby_rek(n) % TSEBYSHEV Tsebyshevin polynomit -- rekursiivinen toteutus % tsebyshev(n) laskee n:nnen asteen Tsebyshevin polynomin x = [1 0]; if n < 0 disp('n >= 0'); elseif n == 0 tn = 1; elseif n == 1 1
Polynomeja on käsitelty kirjan Matematiikkaa MATLABilla luvussa 17.2
MATLAB – Ohjelmointi
52
tn = x;
else end
tn = polyplus(2*conv(x,tseby_rek(n-1)),-tseby_rek(n-2));
Lasketaan 8. asteen Tsebyshevin polynomi: >> tseby_it(8) ans = 128 0 -256
0
160
0
-32
0
1
>> tseby_rek(8) ans = 128 0 -256
0
160
0
-32
0
1
Siis 8
6
4
2
T 8 (x)=128 x −256 x +160 x −32 x +1 Mitataan laskentaan kulunut aika käyttämällä tic-toc komentoparia:
tic käynnistää kellon
toc pysäyttää kellon ja tulostaa komentojen suorittamiseen käytetyn ajan sekunteina. Lasketaan T 20( x ) , jotta saataisiin ero paremmin esille; kertoimia ei tulosteta. >> tic;tseby_it(20);toc Elapsed time is 0.001353 seconds. >> tic;tseby_rek(20);toc Elapsed time is 0.473235 seconds.
Siis iteraatio on huomattavasti nopeampi.
MATLAB – Ohjelmointi
53
7. SOVELLUKSIA 7.1
Funktion maksimointi
Tarkastellaan suljetulla välillä [a , b] määritellyn jatkuvan funktion f x lokaalin maksimikohdan ja maksimiarvon määrittämistä Tällainen lokaali maksimikohta voi olla välin päätepiste 1 tai välin sisäpiste. Viisipistemenetelmässä valitaan väliltä [a , b] tasavälisesti 5 pistettä (päätepisteet ja kolme sisäpistettä). Lasketaan funktion arvot näissä pisteissä ja otetaan niistä suurin arvo ja vastaava piste (jos kaikki arvot ovat yhtä suuria, otetaan sisäpiste). Tämän pisteen ympäristössä on lokaali maksimikohta, joten sen ympäristössä suoritetaan sama menettely. Tätä jatketaan kunnes lokaali maksimikohta on löydetty halutulla tarkkuudella. Menetelmän yksityiskohdat selviävät seuraavasta ohjelmasta. function [ymax,xmax] = maximum(fun,a,b,tol) % Funktion lokaalin maksimikohdan määrittäminen 5-pistemenetelmällä % Input-parametrit: % fun -- funktio % a, b -- välin päätepist, joiden välissä funkt. on lok. maks.kohta % tol -- toleranssi (valinnainen argumentti); oletustoleranssi 1e-6. % Output-parametrit: % ymax -- lokaali maksimiarvo % xmax -- lokaali maksimikohta if nargin == 3 tol = 1e-6; else if tol < 0 disp('tol > kaanto Anna Merkkijono: 13817jejiru95 59urijej71831 Anna Merkkijono: >>
TEHTÄVIÄ 1. Tee ohjelma, joka lukee näppäimistöltä merkkijonoja ja tulostaa merkkijonojen merkkien ASCII-koodit. Lukemisen päättää tyhjä merkkijono. 2. Tee ohjelma, joka lukee merkkijonoja näppäimistöltä ja muuntaa merkkijonon kirjaimet isoiksi kirjaimiksi. Lukemisen päättää tyhjä merkkijono. 9.1.2 Vertailukomentoja Merkkijonojen vertailuun on seuraavia komentoja: Komento strcmp(str1, str2)
Toiminto Merkkijonojen vertailu. Arvo on looginen luku 1, jos samat, muuten looginen luku 0.
strcmpi(str1,str2)
Merkkijonojen vertailu. Muuten sama kuin strcmp, mutta ei erottele isoja ja pieniä kirjaimia.
strncmp(str1,str2,n)
Merkkijonojen vertailu. Arvo on looginen luku 1, jos n ensimmäistä merkkiä samoja, muuten looginen luku 0.
strncmpi(str1,str2,n)
Merkkijonojen vertailu. Muuten sama kuin strcnmpi, mutta ei erottele isoja ja pieniä kirjaimia.
strfind(str1,str2)
Merkkijonojen etsintä. Etsii merkkijonoa str2 merkkijonosta str1. Palauttaa vektorin, joka sisältää merkkijonojen str2 aloituskohdat.
ESIMERKKI. >> nimi = 'Albert Einstein'; nimi1='AlbErt EinstEin'; >> strcmp(nimi,nimi1) ans =
MATLAB – Ohjelmointi
75
0 >> strcmpi(nimi,nimi1) ans = 1 >> strncmp(nimi,nimi1,3) ans = 1 >> strncmp(nimi,nimi1,4) ans = 0 >> strfind(lower(nimi),'ei') ans = 8 13
ESIMERKKI. Tehdään ohjelma, joka lukee lukuja näppäimistöltä ja tulostaa luettujen lukujen keskiarvon. Lukujen lukeminen päätetään kirjaimella s tai S. function y = keskiarvo % KESKIARVO Lukujen keskiarvon laskenta. % Luvut syötetään näppäimistöltä. Syötön lopetus s tai S. disp('Lukujen keskiarvojen laskenta\nSyötön lopetusmerkki: s') luvut = []; jatka = 1; while jatka x = input('Anna luku: ','s'); if strncmpi('s',x,1) jatka = 0; else x = str2num(x); luvut = [luvut, x]; end; end; y = mean(luvut);
9.1.3 Käsittely- ja testauskomentoja Merkkijonojen käsittelyyn ja testaukseen on seuraavia komentoja:
MATLAB – Ohjelmointi
76
Komento
Toiminto
blanks(n)
Luo blankoista koostuva merkkijono, jonka pituus n
deblank(str)
Merkkijonosta poistetaan loppublankot.
ischar(s)
Arvo looginen 1, jos s on merkkijono, muuten arvo looginen 0.
isspace(str)
str:n pituinen vektori, jonka alkio on looginen 1, jos vastaava str:n alkio on blankko, tabulaattori tai rivin vaihto, muuten alkio on looginen 0.
strtok(str)
Palauttaa merkkijonossa str esiintyvän ensimmäisen sanan (token), joka päättyy blankkoon tai tabulaattoriin tai rivinvaihtoon. Alun tyhjät merkit poistetaan.
ESIMERKKEJÄ. >> ischar('abc') ans = 1 >> ischar(123) ans = 0
Etsitään merkkijonosta välilyönnit >> koe = ' a b c' koe = a b c >> isspace(koe) ans = 1 0
1
0
1
0
Merkkijonosta poistetaan välilyönnit seuraavasti: >> koe(~isspace(koe)) ans = abc
% Looginen indeksointi
Komennon strtok laajennettu muoto on [token, rem] = strtok(str,delimiter). Tämä etsii ensimmäisen sanan, joka on ennen rajoitinta delimiter. Sana tallennetaan muuttujaan token. Muuttujaan rem tallennetaan loppu merkkijonosta str. ESIMERKKI. Luetellaan merkkijonon >> viikko = 'ma, ti, ke, to, pe, la, su' viikko = ma, ti, ke, to, pe, la, su
sanat. Sanoja erottaa pilkut. Poistetaan myös välilyönnit sanoista. Toteutetaan tämä seuraavana skriptinä:
MATLAB – Ohjelmointi
77
rem = viikko; while ~isempty(rem) [token,rem] = strtok(rem,','); token = token(~isspace(token)); disp(token) end
Skriptin ajo tuottaa seuraavan tuloksen: ma ti ke to pe la su
Komento isstrprop(str, ‘kategoria’) palauttaa loogisen vektorin, jonka koko on sama kuin merkkijonon str. Vektorin alkiot ovat loogisia lukuja 1 tai 0 riippuen siitä, mihin kategoriaan ko. kohdalla oleva merkkijonon str merkki kuuluu. Kategorioita ovat mm.
alpha: kirjain
alphanum: kirjain tai numero
digit: numero
lower: pieni kirjain
upper: iso kirjain
print: tulostuva merkki
ESIMERKKI. >> aika = 'Kello on 14:22' aika = Kello on 14:22 >> a=isstrprop(aika,'alpha') a = 1 1 1 1 1 0
1
1
0
0
0
0
0
0
0
0
0
1
1
0
1
1
>> aika(a) ans = Kelloon >> a=isstrprop(aika,'digit') a = 0 0 0 0 0 0 >> aika(a) ans =
MATLAB – Ohjelmointi
78
1422
TEHTÄVIÄ 1. Tee ohjelma, joka lukee merkkijonoja näppäimistöltä ja poistaa vokaalit. Lukemisen päättää tyhjä merkkijono. 9.1.4 Evaluointikomentoja Seuraava taulukko sisältää merkkijonojen laskentaan liittyviä komentoja. Komento
Toiminto
eval(str)
Suorittaa merkkijonon str sisältämän komennon.
vectorize(f)
Muodostaa merkkijonona annetusta matemaattisesta lausekkeesta vektoroidun version: laittaa pisteen . operaattoreiden *, /, ^ eteen.
ESIMERKKEJÄ. >> str = '5+6' str = 5+6 >> eval(str) ans = 11
Lauseke merkkijonona: >> f = '3*x^2*y^2-x*y+1' f = 3*x^2*y^2-x*y+1
Vektoroidaan lauseke. >> g=vectorize(f) g = 3.*x.^2.*y.^2-x.*y+1
Lasketaan vektoroidun lausekkeen arvo. >> x = [1 2 3]; y = [0 2 4]; >> eval(g) ans = 1 45 421
MATLAB – Ohjelmointi
79
9.1.5 Merkkijonon kirjoittaminen Merkkijono s kirjoitetaan komennolla s = sprintf(format, A,...), missä A, … ovat matriiseja joiden sisältö kirjoitetaan. format on muotoilun sisältävä merkkijono. Muotoilu format on samanlainen kuin C-kielessä. Se voi sisältää kentänmäärittelyjä, jotka alkavat %-merkillä. Formaatin k:s kentänmäärittely määrää, minkä muotoisena k:s argumentti tulostuu. Muut kuin kentänmäärittelyissä olevat merkit tulostuvat sellaisenaan. Tämä mahdollistaa selittävien tekstien sijoittamisen lukujen yms. tulosteiden ympärille. Kentänmäärittelyn muoto on seuraava (kulmasulkeissa olevat ovat valinnaisia): %tyyppi, jossa etumerkit –
tuloste sijoittuu kentän vasempaan laitaan (oletusarvo: oikea laita).
+ numeerinen tuloste alkaa aina etumerkillä. 0 täytteenä käytetään nollia eikä välilyöntejä. minimileveys Minimileveys määrää tulostettavan kentän vähimmäisleveyden. Jos tulosteessa on minimileveyttä vähemmän merkkejä, käytetään täytemerkkinä välilyöntiä. tarkkuus Desimaalilukuja tulostettaessa tarkkuus kertoo desimaalipisteen jälkeen tulostettavien desimaalien lukumäärän. Merkkijonoa tulostettaessa tarkkuus kertoo tulostettavien merkkien enimmäismäärän. tyyppi c yksittäinen merkki s merkkijono d kokonaisluku tai desimaaliluku e eksponenttiesitysmuoto f kiinteä määrä desimaaleja g tiiviimpi muodoista e ja f Tulostuksen muotoilussa voidaan käyttää myös erikoismerkkejä, joita ovat: \b backspace \f sivunvaihto \n rivinvaihto \r vaunun palautus \t horisontaalinen tabulointi Lisäksi voidaan tulostaa muita merkkejä:
MATLAB – Ohjelmointi %% \\ \"
80
prosenttimerkki kenoviiva heittomerkki
Komento sprintf eroaa vastaavasta C-kielen komennosta print() siten, että se on vektoroitu: formaatissa pyöritään silmukkana kunnes kaikki matriisien alkiot on tulostettu. Matriisien alkiot käydään sarakkeittain läpi. ESIMERKKEJÄ. >> sprintf('%f',pi) ans = 3.141593 >> sprintf('%0.2f',pi) ans = 3.14 >> p = 10^10*pi; >> sprintf('%f %e ans = 31415926535.897930
%g', p, p, p) 3.141593e+010
3.14159e+010
Rivinvaihtomerkin \n käyttö: >> sprintf('luku pii: %0.7f\nluku e ans = luku pii: 3.1415927 luku e : 2.7182818
: %0.7f',pi,exp(1))
Formaatissa pyöritään silmukkana kunnes kaikki alkiot on tulostettu. >> A = rand(1,7) A = 0.4057 0.9355 >> sprintf('%f ans = 0.405706 0.916904 0.893650 0.352868
0.9169
0.4103
%f\n',A)
0.935470 0.410270 0.057891
Matriisin alkiot käydään läpi sarakkeittain. >> A = rand(3,4) A = 0.8132 0.2028 0.0099 0.1987 0.1389 0.6038 >> sprintf('%f %f ans = 0.813166 0.009861 0.202765 0.198722 0.272188 0.198814 0.746786 0.445096
0.2722 0.1988 0.0153 %f\n',A) 0.138891 0.603792 0.015274 0.931815
0.7468 0.4451 0.9318
0.8936
0.0579
0.3529
MATLAB – Ohjelmointi
81
9.1.6 Merkkijonosta lukeminen Formatoitu lukeminen merkkijonosta s suoritetaan komennolla [A, määrä] = sscanf(s, format, koko) missä A on matriisi, johon data luetaan määrä on valinnainen parametri, joka kertoo luetun data määrän. format on muotoilu, joka on samanlainen kuin C-kielessä. koko on valinnainen parametri, joka ilmoittaa luettavan data määrän. Jos parametria ei ole, niin luetaan merkkijonon loppuun asti. koko n
Merkitys Luetaan n alkiota sarakevektoriin.
inf
Luetaan merkkijonon loppuun asti.
[m, n]
Luetaan alkiot mn-matriisin sarakkeittain. Jos alkioita ei riittävästi asetetaan loput alkiot nolliksi.
Komento sscanf eroaa vastaavasta C-kielen komennosta scanf() siten, että se on vektoroitu: formaatissa pyöritään silmukkana kunnes merkkijono s on käyty läpi tai argumentin koko määrä dataa on luettu. Formaatti sisältää kentänmäärittelyjä, jotka alkavat %-merkillä. Kentänmäärittelyn muoto on seuraava (kulmasulkeissa olevat ovat valinnaisia): %tyyppi *
Muotoilu tehdään, mutta tulosta ei sijoiteta mihinkään ts. kenttä ohittuu.
maksimileveys Määrää luettavan kentän enimmäisleveyden. tyyppi c s d, i e, f, g
yksittäinen merkki (myös tyhjä väli) merkkijono (ei tyhjää väliä) kokonaisluku desimaalilukuja
Merkkijonoa tutkittaessa sscanf hyppää automaattisesti tyhjän välin yli, jos muotoilun tyyppi on muu kuin %c. ESIMERKKEJÄ. >> A=sscanf('43.6 67.98','%f %f')
MATLAB – Ohjelmointi
82
A = 43.6000 67.9800 >> A=sscanf('43.6 ... 67.98','%f
%f')
A = 43.6000 >> A=sscanf('43.6 ... 67.98','%f %*s %f') A = 43.6000 67.9800
9.2
Solutaulukot
Solutaulukko on taulukko, jonka alkiot voivat olla eri tyyppiä esim. matriiseja, lukuja, merkkijonoja ... Solutaulukon alkioita sanotaan soluiksi. Solutaulukko eroaa matriisista siinä, että matriisin alkiot ovat kaikki samaa tyyppiä, lukuja. Solutaulukon voi luoda aaltosulkuja {, } käyttäen samaan tapaan kuin matriisi luodaan hakasulkuja käyttäen. Merkintä { } tarkoittaa tyhjää solutaulukkoa. syöttämällä arvot yksittäisiin soluihin. Solujen indeksoinnissa käytetään aaltosulkuja. Jos samanniminen matriisi on olemassa, on matriisi ensin tyhjennettävä esim. clear-komennolla. Tyhjä mn-solutaulukko C luodaan komennolla C = cell(m,n). Komento C = cell(n) on sama kuin komento C = cell(n,n). ESIMERKKEJÄ. Luodaan solutaulukko F aaltosulkuja käyttäen: >> F = {'Einstein','Albert',[1879,1955];'Newton','Isaac',[1642,1727]} F = 'Einstein' 'Albert' [1x2 double] 'Newton' 'Isaac' [1x2 double]
Luodaan solutaulukko M syöttämällä: >> >> >> >> >> >>
M{1,1} M{1,2} M{1,3} M{2,1} M{2,2} M{2,3}
>> M M =
='Eukleides'; = '?'; = [-325,-265]; = 'Pythagoras'; = '?'; = [-569,-475];
MATLAB – Ohjelmointi 'Eukleides' 'Pythagoras'
'?' '?'
83
[1x2 double] [1x2 double]
Yksittäiseen soluun viitataan aaltosulkujen sisällä olevilla indekseillä: >> F{1,3} ans = 1879
1955
Tämä on vektori, jonka alkioihin viitataan vektori-indeksillä >> F{1,3}(1) ans = 1879
Solutaulukkoja voidaan asettaa peräkkäin hakasulkuja käyttäen. Menetelmä on sama kuin matriiseilla. >> T = [F;M] T = 'Einstein' 'Newton' 'Eukleides' 'Pythagoras'
'Albert' 'Isaac' '?' '?'
[1x2 [1x2 [1x2 [1x2
double] double] double] double]
Solutaulukon osiin voi viitata kuten matriisien osiin käyttäen sulkuja tai aaltosulkuja. Solutaulukon koko sisältö voidaan tulostaa näytölle komennolla celldisp(C). ESIMERKKI. >> celldisp(T(1:2,[1,3])) ans{1,1} = Einstein
%tai T{1:2,[1,3]}
ans{2,1} = Newton ans{1,2} = 1879
1955
ans{2,2} = 1642
1727
Solutaulukosta C poistetaan i:s rivi komennolla C(i,:) = [ ] j:s sarake komennolla C(:,j) = [ ] Komento on siis sama kuin matriiseilla. Poistetaan solutaulukosta T toinen sarake:
MATLAB – Ohjelmointi
84
>> T(:,2)=[] T =
'Einstein' 'Newton' 'Eukleides' 'Pythagoras'
[1x2 [1x2 [1x2 [1x2
double] double] double] double]
Funktioon voidaan välittää vaihteleva määrä sisäänmeno- ja ulostulo-argumentteja käyttämällä muuttujia1 varargin syötteisiin (sisäänmenoihin) varargout ulostuloihin. Nämä ovat solutaulukkoja. Tämä mahdollistaa erityyppiset muuttujat argumentteina. Komento C = num2cell(A) muuntaa matriisin A solutaulukoksi C. Muunnos tapahtuu alkioittain. Tuloksena on samaa kertalukua oleva solutaulukko. Komennon muoto
num2cell(A, 1) asettaa sarakkeet erillisiin soluihin num2cell(A, 2) asettaa rivit erillisiin soluihin
ESIMERKKI. >> A = rand(2,3) A = 0.4057 0.9169 0.9355 0.4103 >> C = num2cell(A) C = [0.4057] [0.9169] [0.9355] [0.4103]
0.8936 0.0579
[0.8936] [0.0579]
>> C = num2cell(A,1) C = [2x1 double] [2x1 double] >> celldisp(C) C{1} = 0.4057 0.9355 C{2} = 0.9169 0.4103 C{3} = 0.8936 0.0579 >> C = num2cell(A,2) C = [1x3 double] [1x3 double]
1
Katso luku 5.3.
[2x1 double]
MATLAB – Ohjelmointi >> celldisp(C) C{1} = 0.4057 0.9169 C{2} = 0.9355 0.4103
85
0.8936 0.0579
Solutaulukon C muuntaminen lukutaulukoksi tapahtuu A = cell2mat(C). Tässä solutaulukon C alkioiden dimensioiden on oltava yhteensopivia. ESIMERKKI. >> A = rand(3,7) A =
0.8998 0.8216 0.6449
0.8180 0.6602 0.3420
0.2897 0.3412 0.5341
0.7271 0.3093 0.8385
0.5681 0.3704 0.7027
0.5466 0.4449 0.6946
0.6213 0.7948 0.9568
>> C = num2cell(A,1) C = Columns 1 through 5 [3x1 double] double]
[3x1 double]
[3x1 double]
[3x1 double]
[3x1
Columns 6 through 7 [3x1 double]
[3x1 double]
>> B = cell2mat(C) B = 0.8998 0.8216 0.6449
0.8180 0.6602 0.3420
0.2897 0.3412 0.5341
0.7271 0.3093 0.8385
0.5681 0.3704 0.7027
0.5466 0.4449 0.6946
0.6213 0.7948 0.9568
0.5681 0.3704 0.7027
0.5466 0.4449 0.6946
0.6213 0.7948 0.9568
Tämä voidaan toteuttaa myös for-silmukkaa käyttäen: >> [m,n] = size(C); >> D = []; >> for i = 1:n D = [D C{i}]; end >> D D =
0.8998 0.8216 0.6449
0.8180 0.6602 0.3420
0.2897 0.3412 0.5341
0.7271 0.3093 0.8385
MATLAB – Ohjelmointi
9.3
86
Tietueet
Tietue on joukko loogisesti yhteenkuuluvia tietoja, jotka voivat olla keskenään erityyppisiä. Näitä tietueeseen kuuluvia tietoja sanotaan kentiksi. Tietueet auttavat hallitsemaan monimutkaisia asiakokonaisuuksia ja tekevät ohjelmista helppolukuisempia. Tietue voidaan luoda kahdella eri tavalla: sijoituskäskyllä antamalla arvot yksittäisille kentille. Tietueen kenttiin viitataan siten, että kirjoitetaan tietueen nimi, piste ja kentän nimi. struct-komennolla muodossa s = struct('kenttä1',arvot1,'kenttä2',arvot2,...), joka luo tietueen kenttineen ja antaa kentille arvot. Arvot voivat olla yksittäisiä arvoja tai samankokoisia solutaulukoita. Tyhjä tietue annetuilla kentän nimillä luodaan komennolla s = struct('kenttä1',{ },'kenttä2',{ },...). Tietueen kentän nimen on alettava kirjaimella. ESIMERKKI. Luodaan sijoituskäskyllä tietue henkilo, jossa on kolme: kenttää nimi, ammatti, elinaika. >> henkilo.nimi = 'Einstein Albert'; >> henkilo.ammatti = 'fyysikko'; >> henkilo.elinaika = [1879,1955];
Saatiin 11-taulukko, jonka sisältö voidaan tulostaa kirjoittamalla tietueen nimi: >> henkilo henkilo = nimi: 'Einstein Albert' ammatti: 'fyysikko' elinaika: [1879 1955]
Laajennetaan taulukkoa laittamalla indeksi tietueen nimen perään: >> henkilo(2).nimi = 'Newton Isaac'; >> henkilo(2).ammatti = 'fyysikko'; >> henkilo(2).elinaika = [1642,1727];
Nyt taulukon koko on 12 ja tietueen nimen kirjoittamisen tuloksena saadaan kuvaus tietueen rakenteesta: >> henkilo henkilo = 1x2 struct array with fields: nimi ammatti elinaika
Yksittäinen tietue saadaan tulostettua käyttämällä indeksointia:
MATLAB – Ohjelmointi
87
>> henkilo(2) ans = nimi: 'Newton Isaac' ammatti: 'fyysikko' elinaika: [1642 1727]
Tietueen kenttien ei tarvitse olla kooltaan yhtä suuria. >> henkilo(3).nimi = 'Eukleides'; >> henkilo(3).ammatti = 'matemaatikko'; >> henkilo(3).elinaika = -300;
ESIMERKKI. Luodaan struct-komennolla tietue mittaus, jossa on kaksi kenttää: pituus ja paino. Seuraava komento luo yhden tietueen. >> mittaus = struct('pituus',185,'paino',87) mittaus = pituus: 185 paino: 87
Seuraava komento luo taulukon, jossa on neljä alkiota. >> mittaus = struct('pituus',{185,156,172,179},'paino',{87,65,68,81}) mittaus = 1x4 struct array with fields: pituus paino
Tulostetaan näistä toinen alkio. >> mittaus(2) ans = pituus: 156 paino: 68
Tietueista muodostetun taulukon osiin voi viitata kuten matriisin osiin. Kentän mahdollisiin alkioihin viitataan käyttäen asiaan kuuluvaa indeksointia. ESIMERKKI. (jatkoa) >> uus_henkilo = henkilo(1:2) uus_henkilo = 1x2 struct array with fields: nimi ammatti elinaika >> uus_henkilo(1) ans = nimi: 'Einstein Albert'
MATLAB – Ohjelmointi
88
ammatti: 'fyysikko' elinaika: [1879 1955]
Tulostetaan muuttujan henkilo(1) kentät nimi ja elinaika sekä vektorin elinaika ensimmäinen alkio. >> henkilo(1).nimi ans = Einstein Albert >> henkilo(1).elinaika ans = 1879 1955 >> henkilo(1).elinaika(1) ans = 1879
Taulukkomuotoisen tietueen kenttiin voidaan viitata kerralla. >> mittaus.pituus ans = 185 ans = 156 ans = 172 ans = 179 >> pituudet = [mittaus.pituus] pituudet = 185 156 172 179
Taulukon jokaiseen tietueeseen voidaan lisätä kenttä lisäämällä kenttä yhteen tietueeseen. Muiden tietueiden vastaava kenttä sisältää tyhjän matriisin. >> mittaus(1).nimi = 'TM' mittaus = 1x4 struct array with fields: pituus paino nimi
Seuraavaan taulukkoon on koottu tietueiden käsittelyyn liittyviä komentoja.
MATLAB – Ohjelmointi
89
Komento
Toiminto
fieldnames(s)
Tietueen s kenttien nimet solutaulukkona.
rmfield(s,’kenttä’)
Tietyn kentän poistaminen tietueesta.
struct2cell(s)
Muuntaa tietueen s solutaulukoksi. Jos s on mn-taulukko, jossa on p kenttää, niin tuloksena on pmn-solutaulukko.
isstruct(s)
Arvo on tosi (looginen 1), jos s on tietue, muuten arvo epätosi (looginen 0).
isfield(s, ’kenttä’)
Arvo on tosi (looginen 1), jos kenttä on tietueen s kenttä.
ESIMERKKI. (jatkoa) >> fieldnames(mittaus) ans = 'pituus' 'paino' 'nimi' >> arvot = rmfield(mittaus,'nimi') arvot = 1x4 struct array with fields: pituus paino >> struct2cell(arvot) ans(:,:,1) = [185] [ 89] ans(:,:,2) = [156] [ 65] ans(:,:,3) = [172] [ 68] ans(:,:,4) = [179] [ 81]
MATLAB – Ohjelmointi
10.
90
TIEDOSTOT
Tiedostot ovat tietokoneen pysyväismuistissa sijaitsevia tietovarastoja, joissa ohjelmia ja niiden tarvitsemaa tietoa voidaan säilöä. Koska tiedostot ovat tietojen säilytyspaikkoja, niiden käsittelemiseen riittää varsin niukka toimenpidevalikoima. Tiedoston käsittely voidaan jakaa seuraaviin vaiheisiin: 1. Tiedoston avaaminen komennolla fopen. 2. Tiedoston käsittely a. Luetaan
binääridataa komennolla fread
merkkijonoja riveittäin komennoilla fgetl tai fgets
muotoiltua ASCII-dataa komennolla fscanf b. Kirjoitetaan
binääridataa komennolla fwrite
muotoiltua ASCII-dataa komennolla fprintf
3. Tiedoston sulkeminen komennolla fclose. Seuraavassa esitellään lähemmin näiden komentojen toimintaa. Lisäksi esitellään tiedoston käsittelykohdan muuttamista.
10.1 Tiedoston avaaminen Tiedosto avataan komennolla fopen, jonka on muotoa fid = fopen(’tiedosto’, ’käsittelytapa’). Parametri käsittelytapa ilmoittaa tiedoston käsittelytavan, joita ovat mm.
r
w uuden tiedoston avaaminen vain kirjoittamista varten
vanhan tiedoston avaaminen vain lukemista varten (oletusarvo)
r+ tiedoston avaaminen sekä lukemista että kirjoittamista varten Komento palauttaa tiedoston tunnistimen fid, joka on kokonaisluku. Tällä on seuraava merkitys:
Jos tiedoston avaus onnistuu, niin fid on ei-negatiivinen kokonaisluku, jolla tiedosto tunnistetaan ohjelmassa. Tiedoston tunnistin fid ilmaisee, mihin tiedostoon kulloinenkin käsittely kohdistuu.
Jos tiedoston avaus ei onnistu, niin fid = –1. Lisäksi valinnaiseen toiseen ulostulomuuttujaan tulee virheilmoitus. Aina kun tiedosto avataan, on syytä testata tunnistimen fid arvo. ESIMERKKI. Seuraava ohjelmakoodi sisältää silmukan, jossa pysytään, kunnes lukukelpoisen tiedoston nimi on annettu. fid = -1;
MATLAB – Ohjelmointi
91
while fid < 0 tiedosto = input('Anna tiedosto: ','s'); [fid, ilmoitus] = fopen(tiedosto,'r'); if fid == -1 disp(ilmoitus); end; end;
Tallennetaan ohjelmakoodi tiedostoon avaus.m ja ajetaan se. Tulokseksi saadaan >> avaus Anna tiedosto: avaus No such file or directory Anna tiedosto: avaus.m
Komento tempdir palauttaa tilapäisten tiedostojen hakemiston nimen tempname palauttaa tilapäisen tiedoston nimen. Ohjelman mahdollisesti käyttämä tilapäistiedosto voidaan avata komennolla fid = fopen(tempname,’w’);
10.2 Tiedoston sulkeminen Tiedosto, jonka tunnistin on fid suljetaan funktiolla fclose: status = fclose(fid); Kaikki tiedostot1 suljetaan komennolla status = fclose(‘all’); Komennot palauttavat arvon –1, jos toiminnossa tapahtui virhe, muuten arvon 0. Tiedosto on aina hyvä sulkea itse, vaikka kaikki avoimet tiedostot suljetaankin automaattisesti, kun MATLAB lopetetaan. ESIMERKKI. (jatkoa) Suljetaan edellisen esimerkin tiedosto. >> fclose(fid) ans = 0
10.3 Binääritiedoston käsittely Binääritiedostossa tiedot on tallennettu tietokoneen sisäisessä esitysmuodossa tavujonoina. Binääritiedostoon kirjoitettu ja siitä luettu tieto siirtyy sellaisenaan ilman muunnoksia. Seuraavassa fid tarkoittaa aina tiedoston tunnistinta. 1
Paitsi standard input, output ja error.
MATLAB – Ohjelmointi
92
Binääritiedostoon kirjoitetaan komennolla määrä = fwrite(fid, A, tarkkuus), missä A on matriisi, jonka alkiot kirjoitetaan sarakkeittain tarkkuus on merkkijono, joka ilmoittaa luettavan tiedon formaatin. Seuraava taulukko sisältää joitain yleisesti käytettyjä tarkkuuksia. tarkkuus ’char’
Merkitys merkki (8 bittiä eli 1 tavu)
’short’
kokonaisluku (16 bittiä eli 2 tavua)
’int’
kokonaisluku (32 bittiä eli 4 tavua)
’long’
kokonaisluku (32 tai 64 bittiä)
’float’
desimaaliluku (32 bittiä eli 4 tavua)
’double’
desinaaliluku (64 bittiä eli 8 tavua)
Oletusarvoisesti luvut tallennetaan muodossa ’double’. määrä on valinnainen parametri, joka kertoo kirjoitettujen alkioiden määrän. Binääritiedostosta luetaan komennolla [A, määrä] = fread(fid, koko, tarkkuus), missä A on matriisi, johon data luetaan määrä on valinnainen parametri, joka kertoo luetun data määrän. koko on valinnainen parametri, joka ilmoittaa luettavan data määrän. Jos parametria ei ole, niin luetaan tiedoston loppuun asti. koko
Merkitys
n
Luetaan n alkiota sarakevektoriin.
inf
Luetaan tiedoston loppuun
[m, n]
Luetaan alkiot mn-matriisin sarakkeittain. Jos alkioita ei riittävästi asetetaan loput alkiot nolliksi.
tarkkuus on merkkijono, joka ilmoittaa luettavan tiedon formaatin kuten komennossa fwrite. ESIMERKKI. Luodaan satunnaismatriisi. >> A = rand(2,5) A = 0.9501 0.6068 0.2311 0.4860
0.8913 0.7621
0.4565 0.0185
0.8214 0.4447
MATLAB – Ohjelmointi
93
Avataan uusi binääritiedosto, tallennetaan matriisi A tiedostoon ja suljetaan tiedosto. >> tied = fopen('bindata.bin','w') tied = 4 >> count = fwrite(tied,A,'double') count = 10 >> status = fclose(tied) status = 0
Avataan edellä muodostettu binääritiedosto, luetaan data matriisiin B ja suljetaan tiedosto. >> id = fopen('bindata.bin','r') id = 3 >> B = fread(id,[2,5],'double') B = 0.9501 0.6068 0.8913 0.2311 0.4860 0.7621
0.4565 0.0185
0.8214 0.4447
>> status = fclose(id) status = 0
Tarkistetaan matriisien A ja B yhtäsuuruus >> A==B ans = 1 1
1 1
1 1
1 1
1 1
Siis matriisit A ja B ovat samoja. Avoinna olevaan tiedostoon liittyy käsittelykohta, joka kertoo mihin kohtaan seuraava luku- tai kirjoitusoperaatio suoritetaan. Käsittelykohta ilmoitetaan tavujen määränä tiedoston alusta. Jokainen luku- ja kirjoitusoperaatio siirtää käsittelykohtaa datan koon verran eteenpäin. Käsittelykohtaan liittyviä komentoja on esitetty seuraavassa taulukossa Komento feof(fid)
Toiminto Testaa tiedoston loppumista: arvo 1, jos tiedoston loppu, muuten arvo 0.
frewind(fid)
Käsittelykohta palautetaan tiedoston alkuun.
ftell(fid)
Antaa tiedoston käsittelykohdan.
Laajemmin käsittelykohdan voi määrätä komennolla status = fseek(fid, offset, origin),
MATLAB – Ohjelmointi
94
jossa offset ilmoittaa siirtymän origin on siirtymän lähtökohta, joka sallitut arvot ovat o ’bof’ tai -1: tiedoston alku (beginning of file) o ’cof’ tai 0: nykyinen käsittelykohta (current position of file) o ’eof’ tai 1: tiedoston loppu (end of file) status kertoo toiminnon onnistumisen: 0, jos toiminto onnistui, –1, jos epäonnistui
10.4 Tekstitiedoston käsittely Tekstitiedosto on jono merkkejä. Tekstitiedosto sisältää rivejä, jotka päättyvät rivivaihtomerkkiin. Tekstitiedostoon kirjoitetut merkit usein koodataan ASCII-koodilla, joten kirjoitettaessa tai luettaessa tehdään muunnoksia esitysmuodosta toiseen. Komennolla line = fgetl(fid) luetaan yksi rivi tiedostosta. Jos tiedosto on loppu, niin komento palauttaa arvon –1. Luettu rivi ei sisällä rivinvaihtomerkkiä. Komento fgets on muuten samanlainen, mutta luettu rivi sisältää rivinvaihtomerkin. Formatoitu lukeminen tekstitiedostosta suoritetaan komennolla [A, määrä] = fscanf(fid, format, koko) missä A on matriisi, johon data luetaan määrä on valinnainen parametri, joka kertoo luetun data määrän. format on muotoilu, joka on samanlainen kuin komennossa1 sscanf. koko on valinnainen parametri, joka ilmoittaa luettavan data määrän. Jos parametria ei ole, niin luetaan tiedoston loppuun asti. Muuttujan koko sallitut arvot ovat samat kuin komennossa fread tai sscanf. Formatoitu kirjoittaminen tiedostoon suoritetaan komennolla määrä = fprintf(fid, format, A,...), jossa A, … ovat matriiseja joiden sisältö kirjoitetaan. format on muotoilu, joka on samanlainen kuin komennossa2 sprintf. määrä ilmoittaa kirjoitettujen tavujen määrän. Jos fid jätetään pois, kirjoitetaan näytölle. ESIMERKKI. Seuraava skripti tulostaa käyttäjän antaman tiedoston näytölle lisäten siihen rivinumerot.
1 2
Katso luku 9.1.6 Katso luku 9.1.5
MATLAB – Ohjelmointi
95
fid = -1; while fid < 0 tiedosto = input('Anna tiedosto: ','s'); fid = fopen(tiedosto,'r'); end; i = 1; while feof(fid) == 0 rivi = fgetl(fid); fprintf('%3d: %s\n',i,rivi); i = i + 1; end; fclose(fid);
%rivivaihto merkki \n
Tallennetaan skripti tiedostoon file_nro.m ja ajetaan se. >> file_nro Anna tiedosto: file_nro Anna tiedosto: file_nro.m 1: fid = -1; 2: while fid < 0 3: tiedosto = input('Anna tiedosto: ','s'); 4: fid = fopen(tiedosto,'r'); 5: end; 6: 7: i = 1; 8: while feof(fid) == 0 9: rivi = fgetl(fid); 10: fprintf('%3d: %s\n',i,rivi); %rivivaihto merkki \n 11: i = i + 1; 12: end; 13: fclose(fid);
ESIMERKKI. Seuraava ohjelma, joka kopioi tekstitiedoston toiseksi tekstitiedostoksi. Ohjelmaa voidaan ajaa komennoilla kopio tai kopio('kopiotava_tied') kopio('kopiotava_tied','uusi_tied'). Argumenttien vaihteleva määrä on toteutettu luvussa 5.3 esitetyllä tekniikalla.
function kopio(varargin) n = nargin; if n>0 fid1=fopen(varargin{1},'r'); else fid1 = -1; end while fid1 < 0 tiedosto = input('Anna kopioitava tiedosto: ','s'); fid1 = fopen(tiedosto,'r'); end; if n==2 fid2=fopen(varargin{2},'w'); else
tai
MATLAB – Ohjelmointi end
96
fid2 = -1;
while fid2 < 0 tiedosto = input('Anna uusi tiedosto: ','s'); fid2 = fopen(tiedosto,'w'); end; while feof(fid1) == 0 rivi = fgetl(fid1); fprintf(fid2,'%s\n',rivi); end;
%rivivaihto merkki \n
fclose(fid1); fclose(fid2);
Seuraavassa on ohjelman ajoesimerkkejä. Kopioitava tiedosto on kopio.m. >> kopio Anna kopioitava tiedosto: kopio.m Anna uusi tiedosto: kopio1.m >> kopio('kopio.m') Anna uusi tiedosto: kopio2.m >> kopio('kopio.m','kopio3.m')
TEHTÄVIÄ 1. Muunna esimerkin kopio-ohjelmaa siten, että kopiossa pienet kirjaimet on muutettu isoiksi kirjaimiksi. 2. Muunna tehtävän 1 ohjelmaa siten, että kopioon tulee rivinumerot.
10.5 Komentoikkunan muuttujien tallentaminen Komento save tiedosto muuttuja1 muuttuja2 tallentaa komentoikkunan muuttujat muuttuja1, muuttuja2, … binäärimuodossa työhakemiston tiedostoon tiedosto. Komennon muoto save tiedosto tallentaa kaikki työpöydän muuttujat tiedostoon tiedosto. save tallentaa kaikki työpöydän muuttujat oletustiedostoon matlab.mat. Komennon muoto save tiedosto ’-append’ lisää muuttujat olemassa olevaan tiedostoon tiedosto. Komennolla load tiedosto muuttuja1 muuttuja2 … luetaan muuttujien arvot tiedostosta tiedosto. Komennon muoto
MATLAB – Ohjelmointi
97
load tiedosto lukee kaikki tiedoston tiedosto muuttujat. load lukee kaikki oletustiedoston matlab.mat muuttujat. ESIMERKKI. >> clear >> A = rand(2,2); B = rand(1,3); S = 'Merkkijono'; >> who Your variables are: A B S >> save Saving to: matlab.mat >> clear >> who >> load Loading from: matlab.mat >> who Your variables are: A B S >> save testi A B >> clear >> who >> load testi >> who Your variables are: A B
Työpöydällä annetut komennot voidaan tallentaa tekstitiedostoon diary käyttäen komentoa diary. Komentojen tallentaminen aloitetaan komennolla diary. Uusi diary-komento lopettaa talletamisen, seuraava diary-komento jatkaa tallennusta jne. Komennolla get(0,’Diary’) saadaan selville tallennuksen tilan (on/off). Komennot voidaan tallentaa tiettyyn tiedostoon komennolla diary tiedosto. Komento diary off lopettaa tallennuksen ja komento diary on jatkaa tallennusta aikaisempaan tiedostoon. Muodostunutta tekstitiedostoa voidaan tarkastella tekstinkäsittelyohjelmassa.
MATLAB – Ohjelmointi
98
ESIMERKKI. >> diary
% Aloitetaan tallennus
>> A = rand(2,2) A = 0.6154 0.9218 0.7919 0.7382 >> A^(-1) ans = -2.6776 2.8724
3.3435 -2.2322
>> get(0,'Diary') ans = on
% Tarkistetaan tila
>> diary
% Lopetetaan tallennus
>> get(0,'Diary') ans = off >> det(A) ans = -0.2757
% Tämä komento ei tallennu
>> diary
% Jatketaan tallenusta
>> svd(A) ans = 1.5390 0.1791 >> diary
% Lopetetaan tallennus
Voit tarkastella tiedostoa diary aukaisemalla sen MATLABin editoriin kaksoisklikkaamalla tai aukaisemalla sen jollain tekstinkäsittelyohjelmalla.
TEHTÄVIÄ 1. Kokeile diary-komentoa. Tallenna komennot nimeämääsi tiedostoon. Avaa muodostunut tiedosto tekstinkäsittelyohjelmalla.
10.6 Excel-tiedostojen käsittely Matriisi A voidaan tallentaa Excel-taulukkona työhakemiston tiedostoon tiedosto komennolla xlswrite(tiedosto, A) Komennon muoto xlswrite(tiedosto, A, alue)
MATLAB – Ohjelmointi
99
tallentaa matriisin A osan Exel-taulukon alueeseen alue. Jos Excel-taulukko on olemassa, niin komento jättää ne solut ennalleen, joiden kohdalle ei kirjoiteta mitään. Komento A = xlsread(tiedosto) lukee Excel-tiedoston tiedosto ja tallentaa numeerisen datan matriisiin A. Komennon muoto A = xlsread(tiedosto, alue) lukee alueen alue määräämän osan matriisiin A. Yllä • tiedosto annetaan merkkijonona • alue annetaan merkkijonona Excel-muodossa, esim. 'B2:D5'. Lukukomennon muoto [A, txt, raw] = xlsread(...) lukee • numeerisen datan matriisiin A • tekstikentät solutaulukkoon txt • sekä numeerisen datan että tekstikentät solutaulukkoon raw. HUOMAUTUS. Luettavan Excel-taulukon on hyvä olla MATLABin Nykyisessä hakemistossa. Tällöin tiedostonimeen ei tarvitse laittaa hakemistopolkua. Tiedosto voidaan siirtää Nykyiseen hakemistoon vetämällä se hiirellä MATLABin Nykyinen hakemisto -ikkunaan (Current Folder). Vastaavasti tiedosto voidaan siirtää Nykyisestä hakemistosta muualla vetämällä se hiirellä MATLABin Nykyinen hakemisto -ikkunasta haluttuun paikkaan. Jos Ctrl-näppäin on painettuna luodaan kopio. ESIMERKKI 1. Kirjoittaminen Määritellään matriisi >> A=randi(10,3,5) A = 4 1 5 7 8 10 2 6 7
Komento
7 9 9
>> xlswrite('excel1',A)
tekee Excel-taulukon
6 2 3
MATLAB – Ohjelmointi
100
Komento >> xlswrite('excel2',A,'B2:C3')
tekee Excel-taulukon
ESIMERKKI 2. Lukeminen Työhakemiston tiedostossa ExcelRead.xlsx on seuraava Excel-taulukko
Luetaan taulukon numeeriset arvo matriisiin A: >> A=xlsread('ExcelRead.xlsx') A = 0.3000 0.0480 1.6370 0.7500 0.0480 4.2700 1.1000 0.0480 6.4100 2.5000 0.4800 12.7200 3.0000 0.4800 15.2800
0.0347 0.1054 0.1482 0.2744 0.3256
Luetaan taulukon ensimmäisen sarakkeen numeeriset arvo vektoriin x: >> x=xlsread('ExcelRead.xlsx','A1:A6') x = 0.3000
MATLAB – Ohjelmointi
101
0.7500 1.1000 2.5000 3.0000
Kokeillaan vielä monipuolisempaan lukemista: >> [A,txt,raw]=xlsread('ExcelRead.xlsx') A =
0.3000 0.7500 1.1000 2.5000 3.0000
0.0480 0.0480 0.0480 0.4800 0.4800
1.6370 4.2700 6.4100 12.7200 15.2800
0.0347 0.1054 0.1482 0.2744 0.3256
txt = 'I / mA'
'ΔI / mA'
'U / V'
raw = 'I / mA' [0.3000] [0.7500] [1.1000] [2.5000] [ 3]
'ΔI / mA' [ 0.0480] [ 0.0480] [ 0.0480] [ 0.4800] [ 0.4800]
'U / V' [ 1.6370] [ 4.2700] [ 6.4100] [12.7200] [15.2800]
'ΔU / V' 'ΔU / V' [0.0347] [0.1054] [0.1482] [0.2744] [0.3256]
Muuttujat txt ja raw ovat solutaulukkoja1. Seuraavassa on tulostettu niiden joitain alkioita: >> txt{3} ans = U / V >> raw{2,3} ans = 1.6370
MATLABin Nykyisessä hakemistossa oleva Excel-taulukko voidaan lukea MATLABiin myös kaksoisklikkaamalla sitä MATLABin Nykyinen hakemisto -ikkunassa (Current Folder). Tällöin aukeaa tuonti-ikkuna, jota käyttäen halutut tiedot voidaan lukea MATLABiin. Luettavan datan muoto ilmoitetaan ikkunan yläosassa. Ikkunassa voi hiirellä valita luettavan datan. Luettavalle datalle annetaan nimi data-alueen yläpuolella olevaan kohtaan. ESIMERKKI 3. Luetaan osa edellisen esimerkin Excel-taulukosta ExcelRead.xlsx. Kuvassa on tehty valinnat Numeric Matrix, osoitettu luettava data hiirellä ja annettu matriisille nimi Aosa.
1
Katso luku 9.2.
MATLAB – Ohjelmointi
102
TEHTÄVIÄ 1. Muodosta MATLABilla satunnaisluvuista koostuva 45-matriisi. Tallenna matriisi Exceltaulukoksi ja avaa se Excelillä. Huom. Voit siirtää Excel-taulukon haluamaasi paikkaan hiirellä vetämällä. 2. Tee Excelillä seuraava taulukko
Tallenna taulukko tiedostoon ja siirrä se MATLABin Nykyiseen hakemistoon. Lue sen numeeriset arvot MATLABiin seuraavilla tavoilla: a) MATLABin komennolla. b) Kaksoisklikkaamalla tiedostoa Nykyinen hakemisto -ikkunassa. Anna luetulle datalle nimi AA ja tulosta se näytölle MATLABissa.