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⋅C32 . 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 mn-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<=n % Output-parametri: % v -- satunnaiskombinaatiovektori rng('shuffle'); luvut = 1:n; v = zeros(1,k);

% Satunnaislukugen. alustus

for i = 1:k ind=randi(n+1-i); v(i) = luvut(ind); luvut = setdiff(luvut,luvut(ind)); 1

Käytetty aika riippuu prosessorin kuormituksesta, joten yhden ajon tulos ei ole luotettava.

MATLAB – Ohjelmointi

21

end

Ohjelmaa käyttäen voidaan arpoa lottorivejä seuraavasti: >> 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 <= -1 y = x+1; elseif x <=2 y = x^2-1; else y = -x+5; end

Lasketaan yksittäisiä arvoja >> 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 <= -1 ja x <= 2 eivät päde kaikille vektorin alkiolle, joten päädytään else-osaan. Vektorin alkiot siis lasketaan lausekkeella y = -x+5. Tämä on väärin. M-funktiossa fun ei siis saa käyttää vektoriargumenttia. Jos halutaan piirtää tämän funktion kuvaaja on käytettävä for-lausetta. Määritetään piirtoväli: >> 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).*(x+1)+((x>-1)&(x<=2)).*(x.^2-1)+(x>2).*(-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 k1 ,  , x kn−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: ab  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 <0 b = y; fb = fy; elseif fy*fb < 0 a = y; fa = fy; else break; %fy=0, juuri löydettiin end end end

Kokeillaan ohjelmaa. Määritetään yhtälön1 2

ln x= x −7 x10 välillä [4, 7] oleva juuri. Muodostetaan funktio f  x =ln x− x 2 −7 x10  ,

jonka 0-kohta on määrättävä. Määritellään funktio anonyyminä funktiona: >> 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 <0 b = y; fb = fy; elseif fy*fb < 0 a = y; fa = fy; else break; %fy=0, juuri löydettiin end end end

Käytetään1 ohjelmaa neljällä input-parametrilla, toleranssi on 1e-2 ja kahdella output-parametrilla: >> [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 n1 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 <0') ymax=[]; xmax=[]; return end end delta = (b-a)/5; pisteet=linspace(a,b,5); arvot=[]; for x=pisteet arvot = [arvot,fun(x)]; end eka = 1; while (delta > tol)|eka eka=0; delta = delta/2; [ymax,k]=max(arvot); xmax=pisteet(k); if k==1 k=2; elseif k==5 k=4; end 1

Tarkastellaan funktion arvoja vain ko. välillä.

% Oletustoleranssi

MATLAB – Ohjelmointi pisteet(1)=pisteet(k-1); pisteet(3)=pisteet(k); pisteet(5)=pisteet(k+1); pisteet(2)=pisteet(k)-delta; pisteet(4)=pisteet(k)+delta;

end

arvot(1)=arvot(k-1); arvot(3)=arvot(k); arvot(5)=arvot(k+1); arvot(2)=fun(pisteet(2)); arvot(4)=fun(pisteet(4));

Kokeillaan ohjelmaa. Tarkastellaan funktion 1 f ( x )= 1+|x sin x| suurimman arvon määrittämistä. Määritellään funktio >> f=@(x) 1./(1+abs(x.*sin(x)));

ja piirretään kuvaaja >> x=0:0.01:12; >> plot(x,f(x))

Määritetään lokaali maksimi välillä [1,6] : >> [ymax,xmax]=maximum(f,1,6) ymax = 0.5430 xmax = 1

Eräs lokaali maksimi on siis välin vasemmassa päätepisteessä. Määritetään lokaali maksimi välillä [2,6] : >> [ymax,xmax]=maximum(f,2,6) ymax = 1.0000 xmax =

54

MATLAB – Ohjelmointi

55

3.1416

Eräs lokaali maksimi on siis välin sisäpisteessä  ja arvo 1.

7.2

Funktiosarjojen piirtäminen

Tarkastellaan funktioiden approksimointia Taylorin polynomeilla ja Fourier-sarjojen osasummilla. Approksimaation arvo tietyssä pisteissä voidaan usein määrittää funktiota sum ja vektorointia käyttäen. Piirtoa varten funktion arvojen taulukko voidaan muodostaa for-lauseella. Tarkastellaan asiaa esimerkkien avulla. ESIMERKKI 1. Taylorin polynomi Kosini voidaan esittää Taylorin sarjana cos x =1−

x2 x4 x6 + − +⋯ , 2! 4! 6!

eli ∞

cos x =∑ (−1)k k=0

x2 k , (2k)!

jolloin n

cos x≈ ∑ (−1) k k =0

x2k , (2k)!

kun n on suuri. Tutkitaan tätä asiaa arvolla n=5 . Otetaan piirtoväliksi [−10, 10] . Seuraava skripti piirtää Taylorin polynomin ja kosinifunktion. xx=-10:0.01:10; k=0:5;

% Piirtoväli % n = 5

y=[]; for x=xx y=[y,sum((-1).^k.*x.^(2*k)./factorial(2*k))]; end plot(xx,y) hold; plot(xx,cos(xx)) ylim([-2,2]) hold;

% Piirretään Taylorin polynomi % Piirretään kosinifunktio

MATLAB – Ohjelmointi

56

Approksimaatio on hyvä välillä [−3, 3] . Kun n=10 , on approksimaatio hyvä laajemmalla välillä [−7, 7] .

 ESIMERKKI 2. Trigonometrinen Fourier-sarja Kuvan

jaksollisen kanttiaallon Fourier-sarja on 1 2 2 2 f (t)= + π sin π t+ sin 3 π t+ sin 5 π t+⋯ 2 3π 5π eli 1 ∞ 2 f (t)= + ∑ sin (2 k +1) π t , 2 k=0 ( 2 k +1)π jolloin n

1 2 f (t)≈ + ∑ sin(2 k +1) π t , 2 k=0 ( 2 k + 1)π

MATLAB – Ohjelmointi

57

kun n on suuri. Tutkitaan tätä asiaa arvolla n=10 . Otetaan piirtoväliksi [−4, 4] . Seuraava skripti piirtää Fourier-sarja-approksimaation tt=-4:0.001:4; k=0:10;

% Piirtoväli % n=10

y=[]; for t=tt y=[y,1/2+sum(2./((2*k+1)*pi).*sin((2*k+1)*pi*t))]; end plot(tt,y)

Kanttiaalto voidaan piirtää seuraavalla skriptillä. Tällaista piirtoa on käsitelty kirjan Matematiikkaa MATLABilla luvussa 16.2. Siellä on myös esitelty jaksollisen jatkon muodostava funktio jj. hold; v = jj(tt,0,2); plot(tt, v<=1) hold;

 ESIMERKKI 3. Funktion piirtäminen spektristä Jos jaksollisen funktion amplitudispektri on r k ja vaihespektri ϕk mamuodossa annettu Fourier-sarja on

(k ≥0) , niin vaihekul-



f (t)=±r 0 +2 ∑ r k cos ( k ω t+ϕ k ) , k =1

missä ω on peruskulmataajuus. Kaavassa on + merkki, jos ϕ0=0 ja – merkki, jos ϕ0=π . Olkoon peruskulmataajuus ω=300 , amplitudispektri r 0=70 , r 1=95 , r 2=75 , r 3=53 , r 4 =26 , r 5=9,8 , r 6=7,5 , r 7=6,2 ja vaihespektri ϕ0=0

ϕ1=−0,16 , ϕ2=2,6 , ϕ3=−0,89 , ϕ4 =1,74 , ϕ5=−2,51 ,

ϕ6=−0,86 , ϕ7=1,27

MATLAB – Ohjelmointi

58

Piirretään funktio seuraavalla skriptillä: r0=70; r = [95, 75, 53, 26, 9.8, 7.5, 6.2]; %Amplitudit phi = [-0.16, 2.6, -0.89, 1.74, -2.51, -0.86, 1.27]; %Vaihekulmat omega = 300; %Peruskulmataajuuus k = 1:7; %Kertoimet tt = 0:0.0001:0.05; %Aikaväli y =[]; for t=tt y = [y, r0+2*sum(r.*cos(k*omega*t+phi))]; end plot(tt,y) grid

Funktion kuvaaja on seuraavanlainen:



TEHTÄVIÄ 1. Funktion arkustangentti Taylorin sarja on ∞ x 3 x5 x 7 x 2 k+1 + − +⋯=∑ (−1)k , 3 5 7 2 k +1 k=0 kun |x|≤1 . Jos |x|≤1 , on siis

arctan x=x− n

arctan x≈∑ (−1)k k=0

k 2 k +1 , 2 k +1

kun n on suuri Tutki tätä asiaa arvolla n=3 . Piirrä sekä arkustangentin että Taylorin polynomin kuvaajat välillä [−1,2; 1.2] . Tee tehtävä skriptiä käyttäen. Millä välillä approksimaatio on hyvä? Kokeile suurempi muuttujan n arvoja. Millä välillä approksimaatio voi maksimissaan toimia? 2. Erään jaksollinen funktion Fourier-sarja on

MATLAB – Ohjelmointi

59

k−1

2 ∞ (−1) f (t)= π ∑ k

sin( k π t )

k=1

Selvitä piirtämällä Fourier-sarjan osasummia välillä [−3, 3] minkä jaksollisen funktion Fourier-sarja on kyseessä. 3. Jaksollisen funktion spektristä tiedetään: • peruskulmataajuus: ω=2 π , • amplitudispektri (nollasta eroavat termit): r 0=1 , r 1=4 , r 2=2,5 , r 4 =1 , r 5=0,7 Vaihespektri: ϕ0=0 ϕ1=0,78 , ϕ2=1,57 , ϕ4 =−1,12 , ϕ5=−2,02 , Piirrä funktion kuvaaja välillä [0, 4] . 4. Jaksollisen funktion sinimuotoinen spektri koostuu amplitudeista A k ja vaihesiirtokulmista ϕk , joita käyttäen funktio esitetään muodossa •



f (t)= A0 + ∑ A k sin (2 k π f t+ ϕk ) , k=1

missä f on funktion perusjakso. Olkoon funktion • perustaajuus: f =50 , • amplitudit (nollasta eroavat termit): A 0=0 , A 1=100 , A 3=77 , A 5=51 , A 7=25 , A 9=9.6 , A 11=7.6 , A 13=6,5 , •

Vaihesiirtokulmat (asteissa) ϕ1=−9 ϕ3=151 , ϕ5=−51 , ϕ7=100 , ϕ9=−138 ,

ϕ11=−50 , ϕ13=72 Piirrä funktio välillä [0 ; 0,04 ] . Ohjeita: • • •

7.3

π Vaihesiirtokulmien muunnos radiaaneiksi suoritetaan kertomalla luvulla 180 Käytä piirrossa riittävän pientä askelpituutta Käytä hyväksi sitä,, että positiiviset indeksit ovat parittomia lukuja.

Trigonometrinen Fourier-sarja

Jaksollinen funktio f, jonka on jakso T, voidaan esittää trigonometrisena Fourier-sarjana ∞ a f (t )= 0 + ∑ (a k cos k ω t +b k sin k ω t ) , 2 k =1 missä 2π T on kulmataajuus ja kertoimet lasketaan integraaleina ω=

MATLAB – Ohjelmointi 2 a k= T

bk =

2 T

60

t 0 +T



f (t )cos k ω t dt

(k = 0, 1, 2, …)

f (t )sin k ω t dt

(k = 1, 2, 3, …).

t0

t 0 +T

∫ t0

Toteutetaan tämä MATLABilla. Seuraava ohjelma laskee Fourier-sarjan kertoimet. Ohjelma sisältää kaksi alifunktiota ja m-tiedoston sisäisiä globaaleja muuttujia. function [a,b,w] = four_trig(fun,T1,T2,n) % FOUR_TRIG Trignometrisen funktion Fourier-sarjan kertoimien laskenta. % [a,b,w] = four_trig(fun,T1,T2,n) % Sisäänmenoparametrit: % - fun kahva funktioon % - T1 funktion fun perusjakson alaraja % - T2 funktion fun perusjakson yläraja % - n kokokaisluku, joka ilmoittaa laskettavien Fourier-kertoimien % lukumäärän % Ulostuloparametrit: % - a kosinikertoimet rivivektorina [a0, a1, a2, ...] % - b sinikertoimet rivivektorina [0 b1, b2, ...] % - w jaksoa on vastaava kulmataajuus. global w k f T = T2-T1; w = 2*pi/T; f = fun; a=[]; b=[]; for k=0:n a = [a 2/T*integral(@fun_cos,T1,T2)]; b = [b 2/T*integral(@fun_sin,T1,T2)]; end

function y = fun_cos(t) global w k f y = f(t).*cos(k*w*t);

% Alifunktio

function y = fun_sin(t) global w k f y = f(t).*sin(k*w*t);

% Alifunktio

Fourier-sarjan approksimaation arvoja voidaan laskea seuraavalla ohjelmalla: function y = four_trig_arvo(a,b,w,t) % FOUR_TRIG_ARVO Fourier-sarjan määräämän funktio arvon laskenta % y = four_trig_arvo(a,b,w,t) % Sisäänmenoparametrit: % - a rivivektori, joka sisältää kosinikertoimet % - b rivivektori, joka sisältää sinikertoimet % - w jaksoa vastaava kulmataajuus % - t ajanhetki n = length(a); y = a(1)/2;

MATLAB – Ohjelmointi

61

for k=2:n y = y + a(k)*cos((k-1)*w*t)+b(k)*sin((k-1)*w*t); end

ESIMERKKI. Pulssijonon Fourier-sarja. Käyttäen kirjassa Matematiikkaa MATLABilla luvussa 16 esitettyä tekniikkaa muodostetaan pulssijono (funktio jj on esitelty kirjan luvussa 16.2). Tässä on käytetty anonyymejä funktioita. >> f=@(t) (t>=0)&(t<=2); >> g=@(t) f(jj(t,0,3));

Piirretään kuva pulssijonosta >> t=-7:0.001:7; >> plot(t,g(t)) >> ylim([-0.3,1.3])

Määritetään Fourier-sarjan 20 ensimmäistä kerrointa1. >> [a,b,w]=four_trig(g,0,3,20);

Tulostetaan alku näkyviin. >> w w =

2.0944

>> [a(1:6);b(1:6)] ans = 1.3333 -0.2757 0 0.4775

0.1378 0.2387

-0.0000 0.0000

-0.0689 0.1194

0.0551 0.0955

Tämä mukaan Fourier-sarjan alku on 1.3333 f (t)= −0,2757 cos (2,0944 t)+0,477 sin (2,0944 t)+ 2 +0,1378 cos (2⋅2,0944 t)+0,2387 sin(2⋅2,0944 t)+ ⋯ Piirretään saatu Fourier-sarjan approksimaatio samaan kuvaan kuin pulssijono. >> hold on 1

Komennon integraalin laskentaohjelma antaa varoituksia, mutta ei välitetä niistä.

MATLAB – Ohjelmointi

62

>> y=four_trig_arvo(a,b,w,t); >> plot(t,y) >> hold off



TEHTÄVIÄ 1. Jaksollinen reaaliarvoisen funktio f, jonka on jakso T, voidaan esittää eksponenttimuotoisena Fourier-sarjana ∞

f (t)=



k=−∞

c k ei k ω t ,

missä ω=

2π T

ja 1 ck = T

t 0 +T



f (t) e−i k ω t dt .

t0

Fourier-sarjan kertoimille pätee c−k =̄c k . Tee ohjelmat, joilla voidaan laskea Fourier-sarjan kertoimet ja laskea Fourier-sarjan approksimaation arvoja. 2. Määritä funktion f t =∣sin t∣ trigonometrinen Fourier-sarja. Piirrä kuva signaalista ja Fourier-sarja-approksimaatiosta. 3. Määritä kuvan funktion trigonometrinen Fourier-sarja. Piirrä kuva signaalista ja Fouriersarja-approksimaatiosta. Kokeile Fourier-sarjan kertoimien määrän vaikutusta tulokseen. a)

MATLAB – Ohjelmointi

63

b)

c)

4. Määritä kuvan funktion trigonometrinen Fourier-sarja. Piirrä kuva signaalista ja Fouriersarja-approksimaatiosta. Kokeile Fourier-sarjan kertoimien määrän vaikutusta tulokseen. a)

b)

MATLAB – Ohjelmointi

7.4

64

Lentorata heittoliikkeessä

Jatketaan kirjan1 Matematiikkaa MATLABilla luvussa 19.3.2 käsiteltyä kappaleen lentoradan tarkastelua heittoliikkeessä, kun ilmanvastus otetaan huomioon. Jos tuulen vaikutusta ei oteta huomioon, tapahtuu liike pystysuorassa tasossa. Asetetaan tähän tasoon xy-koordinaatisto siten, että x-akseli on vaakasuunnassa, y-akseli pystysuoraan ylös ja kappaleen lähtöpiste koordinaatiston origossa. Oletetaan, että ilmanvastus on suoraan verrannollinen nopeuden suuruuden neliöön. Ilmanvastus on liikesuunnan vastainen voima. Jos kappaleen nopeus on v , on ilmanvastus2 F i =−D∥v∥v , missä kerroin D=

C A . 2

Tässä 

 on ilman tiheys



A on kappaleen liikesuuntaa vastaan kohtisuoran pinnan poikkileikkauksen ala



C on vastuskerroin, joka riippuu kappaleen muodosta.

[]

x Kirjan luvussa 19.3.2 on johdettu differentiaaliyhtälöryhmä, jonka kappaleen sijainti x = y toteuttaa. Kyseessä on toisen kertaluvun differentiaaliyhtälöryhmä

{

x ' ' =−

D m

 x ' 2 y ' 2 x '

y ' ' =−g−

D m

 x ' 2 y ' 2 y '

jonka alkuehdot ovat

{

x 0=0 , y 0=0

{

x ' 0=v 0 cos  . y ' 0=v 0 sin 

Differentiaaliyhtälöryhmässä m on kappaleen massa. Määrittelemällä funktiot

{

z 1= x z 2 =x ' z 3= y z4= y '

voidaan differentiaaliyhtälö muuntaa 1. kertaluvun differentiaaliyhtälöryhmäksi (ks. kirjan luku 19.3.2)

1 2

Tässä luvussa kirja tarkoittaa tätä kirjaa. Merkintä ∥v∥ tarkoittaa vektorin v normia.

MATLAB – Ohjelmointi

{

65

z 1 ' =z 2 z 2 ' =−

D z z 2 z 2 m 2 2 4

z 3 ' =z 4 z 4 ' =−g −

D z 4  z 22 z 24 m

jonka alkuehdot ovat

{

z 1 0=0 z 2 0=v 0 cos  z 3 0=0 z 4 0=v 0 sin 

Tarkastellaan samaa tapausta kuin kirjan luvussa 19.3.2 eli baseballin lentorataa. Kerroin D lasketaan seuraavia arvoja käyttäen:  = 1,2 kg/m3 2 A=π r , missä r = 0,0366 m C = 0,5 Baseballin massa on m = 0,145 kg. Käytetään yksiköitä m, kg, s. Lasketaan kerroin D. Määritellään muuttuja D globaaliksi.

>> global D >> rho=1.2; A=pi*0.0366^2; C=0.5; >> D=rho*C*A/2 D = 0.0013

Ratkaistaan differentiaaliyhtälö numeerisesti. Differentiaaliyhtälön määräävä m-funktio on function y=lento(t,z) global D m=0.145; g=9.81; y=[0;0;0;0]; y(1)=z(2); y(2)=-D/m*z(2)*sqrt(z(2)^2+z(4)^2); y(3)=z(4); y(4)=-g-D/m*z(4)*sqrt(z(2)^2+z(4)^2);

Koska differentiaaliyhtälön ratkaisuvälin loppupiste on se ajan t arvo, jolla kappaleen korkeus on nolla y=0 ⇔ z 3=0 , on lopetusehdon määräävä tapahtumafunktio m-funktiona function [arvo, toiminta, suunta] = lop(t,z) arvo = z(3);

MATLAB – Ohjelmointi

66

toiminta = 1; suunta = -1;

Kirjan Matematiikkaa MATLABilla luvussa 19.3.2 on ratkaistu lentorata, kun kappaleen lähtönopeus on 50 m/s ja lähtökulma 35. Tulokseksi saatiin, että kappaleen lentoaika on 4,53 s ja heiton pituus on 106,30 m. Pyritään selvittämään, mikä lähtökulman on oltava, jotta kappale lentäisi mahdollisimman pitkälle1. Oletetaan, että lähtönopeus on 50 m/s. Muodostetaan funktio, joka määrittää heiton pituuden lähtönopeuden ja lähtökulman funktiona: function y=heiton_pituus(v0,alfa) % Input-parametrit: % v0: lähtönopeus (m/s) % alfa: lähtökulma asteina % Output-parametrit: % y = lennon pituus (m) z0=[0;v0*cosd(alfa);0;v0*sind(alfa)]; [t, z, te, ze, ie] = ode45(@lento, [0, 10], z0, odeset('Events',@lop)); y=ze(1);

Kokeillaan funktion toimintaa: Tarkistetaan luvussa 19.3.2 laskettu tulos: >> heiton_pituus(50,35) ans = 106.3024

Piirretään lennon pituus lähtökulman funktiona, kun lähtönopeus on 50 m/s. Lasketaan lentoradan pituus, kun lähtökulma on välillä 1 … 90 : >> y=[]; >> kulma=1:90; >> for k=kulma y=[y, heiton_pituus(50,k)]; end

Esitetään kuva xy-koordinaatistossa >> plot(kulma,y) >> grid

1

Kirjan Matematiikkaa MATLABilla luvussa 19.3.3 on tarkasteltu vastaavaa asiaa, kun ilmanvastusta ei oteta huomioon.

MATLAB – Ohjelmointi

67

ja napakoordinaateissa >> polar(kulma*pi/180,y)

Kuvista zoomailemalla nähdään, että lennon pituus on suurimmillaan, kun lähtökulma on n 38,5  0,5. Tarkempi tulos saadaan piirtämällä kuva pienemmällä askelvälillä.

MATLAB – Ohjelmointi

68

Vielä parempi tulos saadaan maksimoimalla numeerisesti heiton pituus. Käytetään minimointifunktiota1 fminbnd. Määritellään ensin minimoitava funktio: >> f=@(x) -heiton_pituus(50,x);

ja sitten funktion f minimikohta, joka on muuttujan x funktion heiton_pituus(50,x) maksimikohta: >> [x,arvo]=fminbnd(f,0,90) x = 38.4122 arvo = -106.8545 >> -arvo ans = 106.8545

Siis lennon pituus on suurimmillaan, kun lähtökulma on 38,4 ja tällöin lennon pituus on 106,85 m.

1

Katso kirja Matematiikkaa MATLABilla luku 6.2.

MATLAB – Ohjelmointi

69

8. HIIREN KÄYTTÖ GRAFIIKKAIKKUNASSA Tässä luvussa tarkastellaan hiiren käyttöä grafiikkaikkunassa. Seuraavassa taulukossa on esitetty joitain komentoja. Komento

Toiminto

[x,y] = ginput

Lukee hiiren painallusten koordinaatit grafiikkaikkunasta. Koordinaatit tallennetaan vaakavektoreihin x ja y. Lukeminen lopetetaan Enterin painalluksella.

[x,y] = ginput(n)

Lukee n:n hiiren painalluksen koordinaatit grafiikkaikkunasta. Voidaan keskeyttää Enterin painalluksella.

[x,y,t] = ginput(…)

Palauttaa lisäksi vektorin t, jolla on seuraavat arvot: 1. 1, jos on painettu hiiren vasenta painiketta 2. 2, jos on painettu hiiren keskimmäistä painiketta 3. 3 jos on painettu hiiren oikeaa painiketta 4. näppäimen ASCII-koodin, jos on painettu näppäintä.

waitforbuttonpress

Odotetaan, kunnes aktiivisessa grafiikkaikkunassa on painettu hiiren painiketta tai näppäintä. Funktio palauttaa arvon  0, jos on painettu hiiren painiketta  1, jos on painettu näppäimistöä.

zoom on

Zoomaus 2-ulotteisessa kuvassa:  Suurentaminen hiiren vasemmalla näppäimellä  Vaihtoehtoja hiiren oikealla näppäimellä  Alue voidaan myös valita hiirellä vetämällä. Zoomaus pois päältä.

zoom off

ESIMERKKI. Tallenna seuraava skripti tiedostoon monikulmio.m. Skripti piirtää monikulmion, jonka kärjet annetaan hiirellä osoittamalla. Skripti tulostaa myös monikulmion pinta-alan. Tutki skriptin toimintaa. Skriptissä komento polyarea määrittää monikulmion pinta-alan ja funktio num2str muuttaa luvun merkkijonoksi. % Monikulmion piirtäminen n = figure;

% Uusi grafiikkaikkuna

disp('MONIKULMION PIIRTO') disp('Osoita monikulmion käret painamalla hiiren vasenta näppäintä') disp('Lopeta painamalla hiiren oikeaa näppäintä') axis([-10 10 -10 10]); hold on; [x1,y1,t] = ginput(1); plot(x1,y1,'o'); xx = x1; yy = y1; while t ~= 3 [x,y,t] = ginput(1); if t ~= 3 plot(x,y,'o'); end xx = [xx x]; yy = [yy y];

% Luetaan ens. koordinaatit % Merkitään tämä pallolla % Tallennetaan koordinaatit

% Ei piirr. oik. näpp. painallusta

MATLAB – Ohjelmointi

70

end xx(end) = x1; yy(end) = y1; plot(xx,yy);

% Viim. koord. on ens. koordinaatti

A = polyarea(xx,yy); title(['Pinta-ala = ' num2str(A)]); disp('Klikkaa kuva, kun olet valmis.') waitforbuttonpress; delete(n);



TEHTÄVIÄ 1. Tutki zoomauksen toimintaa poistamalla Esimerkin skriptistä kolme viimeistä komentoa ja korvaa ne komennolla zoom on.

MATLAB – Ohjelmointi

71

9. TIETOTYYPPEJÄ 9.1

Merkkijonot

Merkkijono on vaakavektori, jonka alkiot ovat merkkejä. Sisäisesti merkit tallennetaan ASCIIkoodeina. Merkkijono esitetään ympäröimällä merkit yksinkertaisilla lainausmerkeillä. ESIMERKKI. Tallennetaan merkkijono muuttujaan nimi >> nimi = 'Albert Einstein' nimi = Albert Einstein

Muuttuja nimi on vaakavektori, jossa on 15 alkiota. >> size(nimi) ans = 1 15

Merkkijonon alkioihin voidaan viitata kuten vektorin alkioihin. >> nimi(8) ans = E >> nimi(1:6) ans = Albert

Merkkijonoja voidaan asettaa peräkkäin matriisien tapaan: >> ammatti = 'fyysikko'; >> [nimi,', ',ammatti] ans = Albert Einstein, fyysikko

 Merkkijonoihin liittyy paljon erilaisia käsittelykomentoja. Seuraavissa luvuissa esitellään joitain niistä. 9.1.1 Muunnoskomentoja Seuraava taulukko sisältää merkkijonojen muunnoskomentoja.

MATLAB – Ohjelmointi Komento

Toiminto

double(str)

Merkkijonon str merkkien ASCII-koodit vektorina.

char(x)

Kokonaislukuvektorin x alkioita vastaavat ASCII-merkit.

num2str(A)

Muuntaa lukumatriisin A merkkijonoksi.

num2str(A,format)

Muuntaa lukumatriisin A merkkijonoksi käyttäen muotoilua format1.

int2str(n)

Muuntaa kokonaisluvun n merkkijonoksi.

str2num(str)

Muuntaa merkkijonon str luvuksi.

lower(str)

Muuntaa kirjaimet pieniksi kirjaimiksi

upper(str)

Muuntaa kirjaimet isoiksi kirjaimiksi

strcat(str1,str2, …)

Asettaa merkkijonot str1, str2, … peräkkäin. Poistaa merkkijonojen lopussa olevat blankot.

strrep(str1,str2,str3)

Korvaa kaikki merkkijonon str2 esiintymät merkkijonossa str1 merkkijonolla str3.

bin2dec(str)

Muuntaa merkkijonon str sisältämän binääriluvun desimaaliluvuksi.

dec2bin(n)

Muuntaa ei-negatiivisen kokonaisluvun binääriluvuksi, joka esitetään merkkijonona.

hex2dec(str)

Muuntaa merkkijonon str sisältämän heksadesimaaliluvun desimaaliluvuksi.

dec2hex(n)

Muuntaa ei-negatiivisen kokonaisluvun heksadesimaaliluvuksi, joka esitetään merkkijonona.

ESIMERKKEJÄ. >> x = double('abc') x = 97 98 99

%Merkkijonon merkkien ASCII-koodit

>> char(x) ans = abc

%Muunnetaan takaisin merkkijonoksi

>> x = '123.45' x = 123.45

%Luku merkkijonona

>> 1/x ??? Error using ==> mrdivide Matrix dimensions must agree. >> x = str2num(x) x = 123.4500 >> 1/x ans = 0.0081

%Muunnetaan luvuksi %Nyt voidaan laskea.

>> nimi = 'Albert Einstein'; 1

72

format samanlainen kuin sprintf-komennossa, joka esitellään myöhemmin.

MATLAB – Ohjelmointi

73

>> upper(nimi) ans = ALBERT EINSTEIN >> strcat(nimi,', ','fyysikko') ans = Albert Einstein,fyysikko

%Peräkkäinasettelu %välilyönti pilkun perästä poistuu!

>> nimi1 = strrep(nimi,'e','E') nimi1 = AlbErt EinstEin >> x = dec2bin(51) x = 110011

%Muunnetaan binääriluvuksi

>> x+1 ans = 50

%Tulos on merkkijono. %Sillä ei kannata laskea

50

>> double(x) ans = 49 49

49

48

49

48

50

49

50

%Edellinen lisäsi taulukon %alkioihin luvun 1

49

>> char(x+1) ans = 221122 >> x = bin2dec(x) x = 51

%Muunnetaan desimaaliluvuksi

>> x+1 ans = 52

%Tulos luku!

 ESIMERKKI. Tulostetaan ASCII-merkit väliltä 30…127. >> for i = 30:10:127 disp([num2str(i,'%03d'),': ',char(i:i+9)]) end 030: - !"#$%&' 040: ()*+,-./01 050: 23456789:; 060: <=>?@ABCDE 070: FGHIJKLMNO 080: PQRSTUVWXY 090: Z[\]^_`abc 100: defghijklm 110: nopqrstuvw 120: xyz{|}~

Alkupään ja loppupään merkit eivät tulostuneet. Oikeastaan tulostettiin merkkiin 129 asti. 

MATLAB – Ohjelmointi

74

ESIMERKKI. Seuraava ohjelma muuntaa syötettyjen rivien merkkien järjestyksen käänteiseksi. Syöttö päätetään tyhjällä merkkijonolla. function kaanto a = ' '; while length(a) ~= 0 a = input('Anna Merkkijono: ','s'); disp(a(end:-1:1)); end

Ohjelman ajo: >> 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): %<.tarkkuus>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 mn-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ä mn-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 11-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 12 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 mn-taulukko, jossa on p kenttää, niin tuloksena on pmn-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 mn-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 45-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.

MATLAB - Ohjelmointi.pdf

Page 1. Whoops! There was a problem loading more pages. Retrying... MATLAB - Ohjelmointi.pdf. MATLAB - Ohjelmointi.pdf. Open. Extract. Open with. Sign In.

638KB Sizes 60 Downloads 175 Views

Recommend Documents

matlab
The MathWorks, Inc. 3 Apple Hill Drive. Natick, MA 01760-2098. For contact information about worldwide offices, see the MathWorks Web site. Neural Network ...

MATLAB BOOK.pdf
Page 1. Whoops! There was a problem loading more pages. Retrying... MATLAB BOOK.pdf. MATLAB BOOK.pdf. Open. Extract. Open with. Sign In. Main menu.

MATLAB Primer
The plain TEX source and corresponding PostScript file of the latest printing of the ... MATLAB is an interactive, matrix-based system for scientific and engineering numeric .... multiple windows, you will want to keep MATLAB active in one window and

System Objects in MATLAB Code Generation - MATLAB & Simulink ...
System Objects in MATLAB Code Generation - MATLAB & Simulink.pdf. System Objects in MATLAB Code Generation - MATLAB & Simulink.pdf. Open. Extract.

INTRODUCTION TO MATLAB
7.1 Solve a Linear System . .... a sequence of Matlab commands that will be executed from top to bottom just as if you had typed them on the command ... There is also a wealth of information under Help Desk in the Help menu of Matlab's ...

INTRODUCTION TO MATLAB
Get on a department PC or buy Student Matlab for your own machine and start the .... x=0:h:20; % build an array of points [0,h,2h,...,20] ..... looks good. ... Note: the example in the box below is available on the Physics 330 course website, as.

MATLAB Projects - IEEE Projects
... Human Action Recognition with Multimodal Feature Selection and Fusion. ... Medical Image Segmentation by Combining Graph Cuts and Oriented Active.

MATLAB Projects - IEEE Projects
(IEEE 2013). 2. Tracking Human with Multi-channel Interacting Multiple Models (IEEE 2013). ... MATLAB based INTELLIGIENT TRANSPORTATION. 1. CoSLAM: ...

Matlab 2011 windows
arrest, students ofjuvenilecrimeremain fascinated with theidea ofintervening in thelives ... Amour.Itswallows stac.Thereis no proper way to dissect this novel,and their is no bottomto the ... fables..776828849851472850 Photoshop tutorial pdf.

Basics of MATLAB
A file containing a list or table of numbers in ASCII format can be loaded into matlab. The variable containing the data is given the same name as the file name without the extension. For example, if a file nums.dat contained ASCII data, load nums.da

Detecting Cars Using Gaussian Mixture Models - MATLAB ...
Detecting Cars Using Gaussian Mixture Models - MATLAB & Simulink Example.pdf. Detecting Cars Using Gaussian Mixture Models - MATLAB & Simulink ...

Free PDF MATLAB Popular
... a file format used to present documents in a manner independent of application software, ... transition from one platform to the other as quick and painless as.