university of oulu · nollakohta = 1.8192 lasketaan fzero-funktion avulla: nollakohta = 1.8192 eli...
TRANSCRIPT
Ohjelmointi ja Matlab – syksy 2010
Kotitehtävä 1 – 06.09.2010 – palautettava 14.9.2010 mennessä Methyl alcohol can be synthesized by passing a mixture of CO and H2 over a suitable catalyst. For a feed mixture containing 2 moles of hydrogen to 1 mole of carbon monoxide, x, the number of moles of hydrogen converted at 300 oC and 240 bar, is indicated by the following equation:
23 429 02 2
x xx x
−⎛ ⎞ ⎛ ⎞ − =⎜ ⎟ ⎜ ⎟− −⎝ ⎠ ⎝ ⎠ (1)
The solution to the problem corresponds to that value x at which 23 429
2 2x xx x
−⎛ ⎞ ⎛ ⎞ −⎜ ⎟ ⎜ ⎟− −⎝ ⎠ ⎝ ⎠ reduces
to zero. Koodaa tehtävän ratkaisu Matlab-ohjelmaa hyväksi käyttäen. Ratkaisumenetelminä käytä Newtonin menetelmää ja sekanttimenetelmää. Ongelmanratkaisu:
Menetelmät: Newtonin menetelmä funktion nollakohdan etsimistä varten on seuraavanlainen
( )( )1 '
kk k
k
f xx x
f x+ = − (2)
Menetelmän käyttöön tarvitaan funktio, sen derivaatta (jonka laskeminen voi olla työlästä) sekä sopiva alkuarvaus 0x . Newtonin menetelmä voi divergoitua, jos alkuarvaus on kovin kaukana todellisesta nollakohdasta. Sekanttimenetelmä funktion nollakohdan etsimistä varten on seuraavanlainen
( )( )( ) ( )
11
1
k k kk k
k k
f x x xx x
f x f x−
+−
−= −
− (3)
Menetelmän käyttöön tarvitaan funktio sekä kaksi alkuarvausta 0x ja 1x . Derivaattaa ei tarvita. Molempia menetelmiä käytettäessä on syytä huomata, että (1) ei ole määritelty pisteessä 2x = .
Tarvittavat tiedot: Funktiomme on seuraavanlainen
( )23 429
2 2x xf xx x
−⎛ ⎞ ⎛ ⎞= ⎜ ⎟ ⎜ ⎟− −⎝ ⎠ ⎝ ⎠− (4)
Funktion derivaatan laskemista varten muokataan funktio seuraavaan muotoon (vakion voimme jättää pois, koska sen derivaatta on nolla...)
( )( )
( 23 3
2xg x xx
=−
)− (5)
Tulon derivointisääntöä soveltamalla saamme
( ) ( )( ) ( )
( )23 3' 3 3
2 2x xg x x D D xx x
⎡ ⎤ 2⎡ ⎤= − + −⎢ ⎥ ⎣ ⎦− −⎢ ⎥⎣ ⎦ (6)
ja edelleen
( ) ( )( ) ( ) ( ) ( )( )
( ) ( ) ( )( )( )
3 2
23 3 3
2 1 3 2 1' 3 2 3 1
2 2 2
x x x xg x x xx x x
⎡ ⎤− − − −⎢ ⎥= − + − −⎡ ⎤⎣ ⎦⎢ ⎥− − −⎢ ⎥⎣ ⎦
(7)
( ) ( )( )
( )( ) ( )3
2 3 3'
22x x
g x x xxx
⎡ ⎤− −= ⎢ −− ⎣ ⎦
1+ − ⎥ (8)
Muoto (8) on tehtävän laskennan suhteen riittävän yksinkertaisessa muodossa, mutta (8) voidaan vielä sieventää muotoon
( )( )418 6'2
xg xx
−=
− (9)
Nyt meillä on käytössämme funktio ja sen derivaatta. Vielä tarvitaan sopiva aloituspiste. Funktion arvot vaihtelevat rajusti ja funktiolla on epäjatkuvuuskohta. Eli tarvitsemme jonkinlaisen käsityksen funktion käyttäytymisestä. Matlabissa on sopiva mokkula tähän käyttötarkoitukseen eli fplot-komento. Haarukoimalla fplot-komennolla päädymme esim. seuraavanlaiseen tilanteeseen:
>> fplot ( '((3-x)/(2-x))^2 * (x/(2-x)) - 429', [1.7 1.9 ]) ; grid ;
1.7 1.72 1.74 1.76 1.78 1.8 1.82 1.84 1.86 1.88 1.9-500
0
500
1000
1500
2000
Nollakohdan summittaisen paikan haarukointiin voi tietysti käyttää myös Excel-taulukko-laskentaohjelmaa. Nyt meillä on tiedossamme kaikki tarpeellinen koodausta varten.
Matlab-koodi: % K1_2010_MetO.m % Hougen, Watson & Ragatz s. 1-2 % 02.06.2010 % Laskee funktion arvot. fun = inline ( '((3-x)/(2-x))^2 * (x/(2-x)) - 429', 'x') ; % Laskee derivaatan arvot. dfun = inline ( '(2*(3-x)/((2-x)^3))*(((3-x)/(2-x))*(1+x)-x)', 'x') ; % Kuvaajan piirto. fplot ( fun, [1.79 1.84 ]) ; grid ; % Newtonin menetelmä. % Tarvitsee KÄSIN lasketun derivaatan. disp ('Lasketaan Newtonin menetelmän avulla:') ; x = 1.8 ; % Aloituspiste. f = fun (x) ; % Funktion arvo aloituspisteessä. f_old = realmax ; disp ( [ x f ] ) ; while ( abs(f_old-f) > 1e-3 ) , x = x - fun(x)/dfun(x) ; % Lasketaan uusi piste. f_old = f ; f = fun (x) ; % Funktion arvo uudessa pisteessä. disp ( [ x f ] ) ; end nollakohta = x % Sekanttimenetelmä. % Ei tarvitse derivaattaa. disp ('Lasketaan sekanttimenetelmän avulla:') ; x0 = 1.8 ; x1 = 1.85 ; % Aloituspisteet. f0 = fun (x0) ; f1 = fun (x1) ; % Funktion arvot aloituspisteissä. disp ( [ x0 f0 x1 f1 ] ) ; while ( abs(f0-f1) > 1e-3 ) , t = (x1-x0)/(f1-f0) ; x = x - t * f1 ; % Lasketaan uusi piste. x0 = x1 ; x1 = x ; f0 = fun (x0) ; f1 = fun (x1) ; % Funktion arvot uusissa pisteissä. disp ( [ x0 f0 x1 f1 ] ) ; end nollakohta = x % Nollakohdan etsintä FZERO-funktion avulla. % ei toimi, jos aloituspiste on 0 tai 2 disp ('Lasketaan FZERO-funktion avulla:') ; nollakohta = fzero ( ' (((3-x)/(2-x))^2 * (x/(2-x) ) -429)', 1.9)
>> K1_2010_MetO Lasketaan Newtonin menetelmän avulla: 1.8000 -105.0000 1.8233 28.8351 1.8194 1.2057 1.8192 0.0023 1.8192 0.0000 1.8192 0 nollakohta = 1.8192 Lasketaan sekanttimenetelmän avulla: 1.8000 -105.0000 1.8500 295.9259 1.8500 295.9259 1.7823 -172.9596 1.7823 -172.9596 1.8073 -69.9548 1.8073 -69.9548 1.8242 35.3277 1.8242 35.3277 1.8185 -4.2530 1.8185 -4.2530 1.8191 -0.2281 1.8191 -0.2281 1.8192 0.0016 1.8192 0.0016 1.8192 -0.0000 1.8192 -0.0000 1.8192 -0.0000 nollakohta = 1.8192 Lasketaan FZERO-funktion avulla: nollakohta = 1.8192 Eli : Methyl alcohol can be synthesized by passing a mixture of CO and H2 over a suitable catalyst. For a feed mixture containing 2 moles of hydrogen to 1 mole of carbon monoxide, the number of moles of hydrogen converted at 300 oC and 240 bar is 1.82.
• Mikä on konversio? • Tehtävän määrittelystä myös näemme, että 0 x 2< < . Miksi?
Menetelmien toiminnan vertailu:
Newtonin menetelmä: • Erittäin nopea, jos aloituspiste on lähellä todellista nollakohtaa • Taipumus divergoitua eli ei löydä nollakohtaa, jos aloituspiste 0x on huonosti valittu • Tarvitsee derivaatan, jonka laskeminen käsin on työlästä ja virhealtista • Numeerisen derivaatan käyttö on mahdollista (ks. opintojakso ’Numeeriset menetelmät’) Sekanttimenetelmä: • Hitaampi kuin Newtonin menetelmä • Ei tarvitse derivaattaa • Aloituspisteiden ( 0x ja 1x ) valinta voi olla ongelmallista Matlabin fzero-funktio: • testattu menetelmä • yleensä on syytä käyttää testattuja menetelmiä • idioottivarmaa numeerista nollakohdan hakumenetelmää ei olekaan . . . Lisää tietoa aiheesta: • Oheinen moniste. • Brent, R., Algorithms for Minimization Without Derivatives, Prentice-Hall, 1973. • Forsythe, G. E., M. A. Malcolm, and C. B. Moler, Computer Methods for Mathematical
Computations, Prentice-Hall, 1976.
1
Ohjelmointi ja Matlab – syksy 2010
Kotitehtävä 2 – 10.09.2010 – palautettava 21.09.2010 mennessä
In analyzing the equilibrium developed in the outgoing gas when a feed mixture of and in a molal ratio of 5 to 1 is passed though a bed of coke maintained at 1100 K and 10 bar, the following two independent equations are obtained:
2H O CO
( )( )( )
0.94421 2 5
x y xx y x
−=
− + − (a)
( )( )( )
21 21.2201
6x y
x y y− +
=− +
(b)
x = moles of converted, per 6 moles of feed, according to the water-gas reaction,
2H O
O+ →2 2H O C CO H+ 2
y = moles of converted, per 6 moles of feed, according to the reaction,
2CO
2+ →2C CO CO
If the numerical values of x and y can be determined, the equilibrium gas composition may be calculated. Koodaa tehtävän ratkaisu Matlab-ohjelmaa hyväksi käyttäen. Ratkaisumenetelminä käytä Newtonin menetelmää (joka tässä tapauksessa tarkoittaa eri menetelmää kuin kotitehtävässä 1) ja Broydenin menetelmää. Menetelmien kuvaukset oheisessa paperissa. Menetelmät:
Menetelmien kuvaukset ja ongelmanratkaisun problematiikka on kuvattu monisteessa (Systems_of_nonlinear_equations.pdf).
Tarvittavat tiedot:
Sekä Newtonin menetelmässä että Broydenin menetelmässä tarvitaan Jacobin matriisia (esim. http://fi.wikipedia.org/wiki/Jacobin_matriisi).
1 1
1
1
n
m m
n
f fx x
Jf fx x
∂ ∂⎡ ⎤⎢ ⎥∂ ∂⎢ ⎥
= ⎢⎢ ⎥∂ ∂⎢ ⎥⎢ ⎥∂ ∂⎣ ⎦
⎥ (c)
Seuraavaksi on laskettava tarvittavat osittaisderivaatat. Nyt derivoitavat funktiot ovat
( ) ( )( )( )1 , 01 2 5
x y xf x y
x y x−
= −− + −
.9442
2
( ) ( )( )( )
2
2
1 2, 1.2201
6x y
f x yx y y− +
= −− +
Nyt saamme ensimmäisestä funktiosta
( )( ) ( ) ( ) ( )( )
( )( )1
2
1 2 51 2 5
1 2 5
x y x x y xx y x x y xf x x
x x y x
∂ − ∂ − + −⎡ ⎤ ⎡⎣ ⎦ ⎣− + − − −⎡ ⎤ ⎡ ⎤⎣ ⎦ ⎣ ⎦∂ ∂ ∂=∂ − + −⎡ ⎤⎣ ⎦
⎤⎦
( )( ) ( ) ( ) ( )( )
( )( )1
2
1 2 51 2 5
1 2 5
x y x x y xx y x x y x
f y yy x y x
∂ − ∂ − + −⎡ ⎤ ⎡⎣ ⎦ ⎣− + − − −⎡ ⎤ ⎡ ⎤⎣ ⎦ ⎣ ⎦∂ ∂ ∂=∂ − + −⎡ ⎤⎣ ⎦
⎤⎦
ja edelleen
( )( ) ( ) ( ) ( )( )( )
12
1 2 5 2 6 2 2
1 2 5
x y x x y x y x x yfx x y x
− + − − − − − + −⎡ ⎤ ⎡ ⎤∂ ⎣ ⎦ ⎣ ⎦=∂ − + −⎡ ⎤⎣ ⎦
( )( ) ( ) ( ) ( )( )( )
12
1 2 5 10 2
1 2 5
x y x x x y xfy x y x
− + − − − − −⎡ ⎤ ⎡ ⎤∂ ⎣ ⎦ ⎣ ⎦=∂ − + −⎡ ⎤⎣ ⎦
x
Toisesta funktiosta saamme
( )( )( )
( ) ( )( )
( )( )
2
2
22
1 2 66 1 2
6
x y x y yx y y x yf x x
x x y y
⎡ ⎤∂ − + ∂ − +⎡ ⎤⎣ ⎦ ⎣⎡ ⎤− + − − +⎡ ⎤⎣ ⎦∂ ⎣ ⎦∂ ∂=∂ − +⎡ ⎤⎣ ⎦
⎦
( )( )( )
( ) ( )( )
( )( )
2
2
22
1 2 66 1 2
6
x y x y yx y y x y
f y yy x y y
⎡ ⎤∂ − + ∂ − +⎡ ⎤⎣ ⎦ ⎣⎡ ⎤− + − − +⎡ ⎤⎣ ⎦ ⎣ ⎦∂ ∂ ∂=∂ − +⎡ ⎤⎣ ⎦
⎦
ja edelleen
( )( ) ( )( ) ( ) ( )( )( )
2
22
6 2 1 2 1 2 6
6
x y y x y x y yfx x y y
⎡ ⎤− + − − + − − + +⎡ ⎤ ⎡ ⎤ ⎡⎣ ⎦ ⎣ ⎦ ⎣∂ ⎣ ⎦=∂ − +⎡ ⎤⎣ ⎦
⎤⎦
( )( ) ( ) ( ) ( )( )( )
2
22
6 4 1 2 1 2 6 2
6
x y y x y x y x yfy x y y
⎡ ⎤− + − + − − + − −⎡ ⎤ ⎡ ⎤ ⎡⎣ ⎦ ⎣ ⎦ ⎣∂ ⎣ ⎦=∂ − +⎡ ⎤⎣ ⎦
⎤⎦
Eo. yhtälöt voisi vielä sievennellä, mutta laskennan kannalta katsottuna se ei ole tarpeen (ks. miten Jacobin matriisi on koodattu Matlab-koodiksi).
3
Aloituspisteen valinta:
Alkuperäisistä yhtälöistä näemme, että aloitusarvoina x ja y eivät voi olla samoja eikä x voi olla 5. Aloitusarvoiksi soveltunevat pienet kokonaisluvut, esim. x = 4 ja y = 3. Voisimme myös ratkaista sekä a:sta että b:stä y:t ja katsoa miten saadut funktiot käyttäytyvät, mutta tämä tapa on suhteellisen työläs.
Matlab koodit:
Ensiksi Newtonin menetelmä:
% K2_2010_MetO_a.m % Newton's method. % 29.10.2009, 9.8.2010 & 17.9.2010 - Juha Jaako format compact ; clear all ; hold on ; disp ( 'Newtonin menetelmä' ) ; x = [ 4 3 ]' ; plot (x(1), x(2), 'k*') ; axis ( [ 3.8 4.1 2.9 3.1 ] ) ; % Määritellään funktiot (inline). f1 = inline ( '(((x-y)*x)/((1-x+2*y)*(5-x))) - 0.9442', 'x', 'y' ) ; f2 = inline ( '((1-x+2*y)^2/((x-y)*(6+y))) - 1.2201', 'x', 'y' ) ; % Määritellään Jacobin matriisi (inline). % Ensimmäinen funktio. t1 = [ '((1-x+2*y)*(5-x))' ] ; t2 = [ '((x-y)*x)' ] ; t3 = [ '(' t1 '^2)' ] ; t4 = [ '(' t1 '*(2*x-y)-' t2 '*(2*x-2*y-6))/' t3 ] ; J11 = inline ( t4, 'x', 'y' ) ; t5 = [ '(' t1 '*(-x)-' t2 '*(10-2*x))/' t3 ] ; J12 = inline ( t5, 'x', 'y' ) ; % Toinen funktio. t1 = [ '((x-y)*(6+y))' ] ; t2 = [ '((1-x+2*y)^2)' ] ; t3 = [ '(' t1 '^2)' ] ; t4 = [ '(' t1 '*((-2)*(1-x+2*y))-' t2 '*(6+y))/' t3 ] ; J21 = inline ( t4, 'x', 'y' ) ; t5 = [ '(' t1 '*(4*(1-x+2*y))-' t2 '*((x-6-2*y)))/' t3 ] ; J22 = inline ( t5, 'x', 'y' ) ; % Asetaan suppenemisparametrit. erosuure = realmax ; % Testisuureen alkuarvo. laskuri = 0 ; % Nollataan kierroslaskuri. TOLERANSSI = 1e-6 ; % Laskentatoleranssi. MAKSIMIKIERROKSET = 10 ; % Asetaan maksikierrosten määrä disp ( [ x' ] ) ; % Aloitetaan laskenta. while ( (erosuure > TOLERANSSI) & (laskuri < MAKSIMIKIERROKSET) ) , %for i = 1 : 10 , laskuri = laskuri + 1 ; % Kasvatetaan kierroslaskuria. f = [ f1(x(1),x(2)) ; f2(x(1),x(2)) ] ;
4
J = [ J11(x(1),x(2)), J12(x(1),x(2)) ; ... J21(x(1),x(2)), J22(x(1),x(2)) ] ; sk = J \ (-f) ; % Lasketaan Newton-askel. s. 239 x = x + sk ; % Uuden pisteen päivityskaava. plot (x(1), x(2), 'k*') ; text (x(1), x(2), [ '\leftarrow' num2str(laskuri) ' ']) ; line ( [x(1), x(1)-sk(1)], [x(2), x(2)-sk(2)] ) ; % Lasketaan uuden testisuureen arvo. erosuure = max (abs ([ f1(x(1),x(2)); f2(x(1),x(2)) ] - f)) ; disp ( [ x' erosuure ] ) ; end % Tulostetaan ratkaisu. disp ( [ 'Ratkaisu:' ] ) ; disp ( x' ) ; disp ( [ 'Kierroksia:' ] ) ; disp (laskuri) ; hold off ;
Kun ohjelma ajetaan komentoikkunasta, saamme
>> K2_2010_MetO_a Newtonin menetelmä 4 3 (erosuure) 3.9049 3.0277 0.3405 3.8496 2.9735 0.0462 3.8475 2.9718 0.0024 3.8475 2.9718 0.0000 3.8475 2.9718 0.0000 Ratkaisu: 3.8475 2.9718 Kierroksia: 5
Ratkaisu löytyy vähin laskentakierroksin, joka johtuu siitä, että alkuarvauksemme oli hyvä. Ks.
seuraava kuvio:
3.8 3.85 3.9 3.95 4 4.05 4.12.9
2.92
2.94
2.96
2.98
3
3.02
3.04
3.06
3.08
3.1
←1
←2 ←3 ←4 ←5
Seuraavaksi Broydenin menetelmä:
% K2_2010_MetO_b.m % Broyden's method.
5
% 03.06.2010 - Juha Jaako format compact ; clear all ; disp ( 'Broydenin menetelmä' ) ; tol = 0.000001 ; xk = [ 4 3 ]' ; % Define functions. f1 = inline ( '(((x-y)*x)/((1-x+2*y)*(5-x))) - 0.9442', 'x', 'y' ) ; f2 = inline ( '((1-x+2*y)^2/((x-y)*(6+y))) - 1.2201', 'x', 'y' ) ; % Define Jacobian. % First function. t1 = [ '((1-x+2*y)*(5-x))' ] ; t2 = [ '((x-y)*x)' ] ; t3 = [ '(' t1 '^2)' ] ; t4 = [ '(' t1 '*(2*x-y)-' t2 '*(2*x-2*y-6))/' t3 ] ; J11 = inline ( t4, 'x', 'y' ) ; t5 = [ '(' t1 '*(-x)-' t2 '*(10-2*x))/' t3 ] ; J12 = inline ( t5, 'x', 'y' ) ; % Second function. t1 = [ '((x-y)*(6+y))' ] ; t2 = [ '((1-x+2*y)^2)' ] ; t3 = [ '(' t1 '^2)' ] ; t4 = [ '(' t1 '*((-2)*(1-x+2*y))-' t2 '*(6+y))/' t3 ] ; J21 = inline ( t4, 'x', 'y' ) ; t5 = [ '(' t1 '*(4*(1-x+2*y))-' t2 '*((x-6-2*y)))/' t3 ] ; J22 = inline ( t5, 'x', 'y' ) ; a = xk(1) ; b = xk(2) ; disp ( 'Initial Jacobian:' ) ; % Compute initial Jacobian. - Vaihtoehto 1. Bk = [ J11(a,b), J12(a,b) ; J21(a,b), J22(a,b) ] % Initial Jacobian = identity matrix. - Vaihtoehto 2. %Bk = eye (2) disp (' ') ; test = realmax ; disp ( [ a b ] ) ; k = 0 ; % Iteration counter while (test > tol) , %for i = 1 : 10 , f = [ f1(a,b); f2(a,b) ] ; sk = Bk \ (-f) ; xk = xk + sk ; a = xk(1) ; b = xk(2) ; yk = ([ f1(a,b); f2(a,b) ] - f ) ; test = max(abs(yk)) ; disp ( [ a b test ] ) ; % Update Jacobian. Bk = Bk + ( (yk-Bk*sk)*(sk') ) / ((sk')*sk) ; k = k + 1 ; end disp ( 'Vastaus:' ) ; disp (xk') ;
6
disp (k) ;
Ajetaan Broydenin menetelmä ensin siten, että käytetään Jacobin matriisia aloituspisteessä [4, 3]
ensimmäisenä arvona:
>> K2_2010_MetO_b Broydenin menetelmä Initial Jacobian: Bk = 3.4444 -2.2222 -1.6667 2.2222 4 3 3.9049 3.0277 0.3405 3.8384 2.9562 0.0575 3.8501 2.9744 0.0258 3.8480 2.9722 0.0016 3.8475 2.9718 0.0004 3.8475 2.9718 0.0000 3.8475 2.9718 0.0000 Vastaus: 3.8475 2.9718 7 Suppeneminen on hitaampaa kuin Newtonin menetelmässä. Ajetaan Broydenin menetelmää myös siten, että emme käytä Jacobin matriisia ollenkaan, Bk = eye (2) : >> K2_2010_MetO_b Broydenin menetelmä Initial Jacobian: Bk = 1 0 0 1 4 3 3.6109 3.2201 3.0700 3.7352 2.6982 3.2849 3.6378 2.6730 0.1996 3.6703 2.7462 0.1086 4.2706 3.5239 1.0212 3.7916 2.9109 0.8363 3.8355 2.9601 0.0429 3.8489 2.9734 0.0102 3.8476 2.9719 0.0014 3.8475 2.9718 0.0002 3.8475 2.9718 0.0000 3.8475 2.9718 0.0000 Vastaus: 3.8475 2.9718 12 Laskenta vie entistä enemmän kierroksia eli 12, kun käytämme samaa lopetusehtoa.
Vastaus:
The equilibrium gas composition: x : moles of converted = 3.85 2H Oy : moles of converted = 2.98 2CO
7
Mitä menetelmää sitten pitäisi käyttää epälineaarisen yhtälöryhmän ratkaisussa? (vrt. moniste Systems_of_nonlinear_equations.pdf). Yksikäsitteistä vastausta kysymykseen ei ole olemassa. Newton-tyyppiset menetelmät ovat epäluotettavia, jos aloituspiste on kaukana haetusta. Käyttämämme menetelmän tulisi olla luotettava ja helppokäyttöinen. Yksi vaihtoehto on seuraava koodi (Broydenin menetelmä): % K2_2010_MetO_b1.m % Broyden's method. % 3.6.2010 & 20.9.2010 - Juha Jaako format compact ; clear all ; % Aloituspiste. x = [ 4 3 ]' ; % Määritellään funktiot. f1 = inline ( '(((x-y)*x)/((1-x+2*y)*(5-x))) - 0.9442', 'x', 'y' ) ; f2 = inline ( '((1-x+2*y)^2/((x-y)*(6+y))) - 1.2201', 'x', 'y' ) ; % Aloitusmatriisina yksikkömatriisi. B = eye (2) ; % Suppenemisen vartiointi. test = realmax ; % Suppenemiskriteerin alkuarvo. k = 0 ; % Kierroslaskuri. maksimikierrokset = 50 ; % Laskentakierrosten yläraja. tol = 1e-6 ; % Lopetustoleranssi. while ((test > tol) & (k < maksimikierrokset)) , f = [ f1(x(1),x(2)) ; f2(x(1),x(2)) ] ; % Funktion arvo. s = B \ (-f) ; % Ratkaistaan lineaarinen yhtälöryhmä. x = x + s ; % Päivitetään ratkaisu. y = ([ f1(x(1),x(2)); f2(x(1),x(2)) ] - f ) ; test = max(abs(y)) ; % Päivitetään suppenemiskriteeri. % Päivitä kerroimatriisi. B = B + ( (y-B*s)*(s') ) / ((s')*s) ; k = k + 1 ; % Päivitetään kierroslaskuri. end disp ( [ 'Vastaus: x = ' num2str(x(1)) ', y = ' num2str(x(2))] ) ; disp ([ 'Laskentakierroksia: ' num2str(k) ]) ; Tuloste: >> K2_2010_MetO_b1 Vastaus: x = 3.8475, y = 2.9718 Laskentakierroksia: 12
Ohjelmointi ja Matlab – syksy 2010
Kotitehtävä 3 – 15.09.2010 – palautettava 27.9.2010 Ohessa on pdf-tiedosto (Cubic_Spline_Interpolation.pdf), jossa on kuvattu, millaisia ovat kuutiolliset splinit. Seuraava data
t = [ 1964 : 1 : 2009 ] ; y = [ 2, 8, 12, 10, 6, 12, 12, 13, 19, 35, 25, 34, 21, 28, 37, ... 33, 42, 23, 33, 30, 25, 14, 22, 28, 25, 27, 34, 38, 44, 64, ... 47, 44, 62, 41, 46, 53, 51, 60, 72, 85, 79, 79, 85, 83, 105, 78 ] ;
kuvaa osastolta valmistuneiden diplomi-insinöörien määriä vuosina 1964-2009. Kun sovitamme datan kuutiollisen splinin avulla, saamme seuraavan kuvaajan:
1965 1970 1975 1980 1985 1990 1995 2000 20050
20
40
60
80
100
120
Data pointsCubic spline
Kuvaaja syntyy seuraavan koodin avulla (K3_2010_MetO_S.m):
clear all;format compact;hold on;t=[1964:1:2009]; y=[2,8,12,10,6,12,12,13,19,35,25,34,21,28,37, ... 33,42,23,33,30,25,14,22,28,25,27,34,38,44,64, ... 47,44,62,41,46,53,51,60,72,85,79,79,85,83,105,78 ] ; plot(t,y,'ko');s=length(t);B=[4,1,zeros(1,s-4)]; for i=2:s-3,temp=[zeros(1,i-2),1,4,1,zeros(1,s-4)];B=[B;temp(1:s-2)]; end;B=[B;zeros(1,s-4),1,4];B=sparse(B);h=t(2)-t(1);k=6/(h^2); for i=1:s-2,z(i)=k*(y(i)-2*y(i+1)+y(i+2));end;z=z';M=B\z;M=[0;M;0]; for i=1:s-1,a(i)=(M(i+1)-M(i))/(6*h);b(i)=((M(i))/2); c(i)=((y(i+1)-y(i))/h)-((M(i+1)+2*M(i))/6)*h;d(i)=y(i); as=['(' num2str(a(i)) ')'];bs=['(' num2str(b(i)) ')']; cs= ['(' num2str(c(i)) ')'];ds=['(' num2str(d(i)) ')']; xi=num2str(t(i)); guns=[ as '*(x-' xi ')^3+' bs '*(x-' xi ')^2+' cs '*(x-' xi ')+' ds ]; gun=inline( guns, 'x');fplot(gun,[ t(i) t(i+1) ],'k-'); end;axis([1964 2009 0 120]);legend('Data points', 'Cubic spline') ; grid;hold off;
Koodi on kuitenkin jätetty kommentoimatta ja se on ulkoasultaan sekä luettavuudeltaan huono. Tehtäväsi on kommentoida koodi (vihje: etsi pdf-tiedostosta se menetelmä, jota on käytetty koodauksen pohjana) sekä parantaa sen ulkoasua ja luettavuutta. Keksi parannuksia koodiin!
28.9.2010 16:34 C:\Users\Juha Jaako\AppData\Local\Microsoft\Windo...\K3_korjattu.m 1 of 2
% Matlab-kurssi 2010% 26.9.2010 clear all ;format compact ;hold on ; % Maaritellaan t eli aika välille 1964-2009t = [1964 : 1 : 2009] ; % Valmistuneiden maarat em. vuosinay = [2, 8, 12, 10, 6, 12, 12, 13, 19, 35, 25, 34, 21, 28, 37, ... 33, 42, 23, 33, 30, 25, 14, 22, 28, 25, 27, 34, 38, 44, 64, ... 47, 44, 62, 41, 46, 53, 51, 60, 72, 85, 79, 79, 85, 83, 105, 78 ] ; % Piirretaan kuvaajaan aluksi valmistuneiden maarat mustina palloina ajan% ollessa x-akselillaplot (t, y, 'ko') ; % Lähdetaan muodostamaan annetuille tiedoille käyrää luonnollisten splinien% menetelmällä. Määritellaan muuttuja s muuttujan t pituuden mukaan eli% tästä saadaan alkuarvo pisteiden määrälle. Splinien muodostamiseen% tarkoitettujen matriisien koko tullaan määrittämään tämän mukaan.s = length(t) ; % Matriisin ensimmainen rivi, muotoa [4 1 0 ... ]B = [4,1,zeros(1,s-4)] ; for i = 2:s-3 , % Matriisin "sisaosa" jossa 1,4,1-osa liukuu vasemmasta laidasta % oikeaan laitaan kierros kierrokselta. temp = [ zeros(1,i-2),1,4,1,zeros(1,s-4) ] ; B = [B;temp(1:s-2)]; end ; % Matriisin viimeinen rivi, muotoa [ ...0 1 4 ]B = [ B;zeros(1,s-4),1,4 ] ; % Poistetaan turhat 0-elementitB=sparse(B) ; % Selvitetaan kahden edellisen arvon välinen ero, muuttuja h, % tässä tapauksessa kaikki arvot ovat vuoden ts. tasaisin valein % eli niiden valinen ero on aina 1. Ainakaan kaavan % mukaan, % jossa h = x(i) - x(i-1). Siis tällä koodilla ei pystytä laskemaan% epatasaisesti x-akselille sijoittuneita pisteita. (Nyt siis lasketaan% vain laiskasti vuosien 1965 ja 1964 erotus.)h = t(2) - t(1) ;k = 6/(h^2) ; for i=1:s-2 , % Rakennetaan matriisi z, joka sisaltaa yhdella rivilla kaikkien % menetelmassa kaytettyjen yi - 2*y2 - y3 - arvot. z(i) = k*(y(i) - 2*y(i+1) + y(i+2)) ; end ; z = z' ; % Transpoosi matriisista zM = B\z ; % Ratkaistaan M.M = [ 0 ; M ; 0 ] ; % Lisätään nollat alkuun ja loppuun. for i=1:s-1 , % Ratkaistaan kierroksen splinin funktion kertoimien arvot a(i) = (M(i+1)-M(i))/(6*h) ; b(i) = ((M(i))/2) ; c(i) = ((y(i+1)-y(i))/h)-((M(i+1)+2*M(i))/6)*h ; d(i) = y(i) ; % Muutetaan luvut merkkijonoiksi. as = ['(' num2str(a(i)) ')'] ; bs = ['(' num2str(b(i)) ')'] ; cs = ['(' num2str(c(i)) ')'] ; ds = ['(' num2str(d(i)) ')'] ; % Muodostetaan kertoimista funktio josta voidaan jokaisella
28.9.2010 16:34 C:\Users\Juha Jaako\AppData\Local\Microsoft\Windo...\K3_korjattu.m 2 of 2
% kierroksella ja t:n arvolla ratkaista y. xi = num2str (t(i)) ; guns=[ as '*(x-' xi ')^3+' bs '*(x-' xi ')^2+' cs '*(x-' xi ')+' ds ] ; gun = inline( guns, 'x') ; % Piirretaan jokaisella kierroksella palanen splinia, edellisestä % pisteestä seuraavaan pisteeseen. fplot (gun, [ t(i) t(i+1) ], 'r-') ; end ; % Määritetään akselitaxis ([1964 2009 0 120]) ; % Selvennetään kaavion merkitlegend ('Data points', 'Cubic spline') ; % Selvennetään akselitylabel ('Valmistuneiden maara')xlabel ('Vuosiluku') grid ; hold off ;
1
Ohjelmointi ja Matlab – syksy 2010
Kotitehtävä 4 – Annettu 21.09.2010 – Palautettava 4.10.2010 klo 23:59 mennessä (H 3.1)
For n = 0, 1, ... , 5, fit a polynomial of degree n by least squares to the following data:
t 0.0 1.0 2.0 3.0 4.0 5.0
y 1.0 2.7 5.8 6.6 7.5 9.9
Make a plot of the original data points along with each resulting polynomial curve (you may make separate graphs for each curve or a single graph containing all of the curves). Which polynomial would you say captures the general trend of the data better? Obviously, this is a subjective question, and its answer depends on both the nature of the given data (e.g., the uncertainty of the data values) and the purpose of the fit. Explain your assumptions in answering. Use Matlab.
Ratkaisu:
Piirretään ensin datapisteet koordinaatistoon: >> clear all >> t = [ 0.0 1.0 2.0 3.0 4.0 5.0 ] ; >> y = [ 1.0 2.7 5.8 6.6 7.5 9.9 ] ; >> plot (t, y, 'ko') ; axis ( [0 7 0 14] ) ; grid on ;
0 1 2 3 4 5 6 70
2
4
6
8
10
12
14
Kuvion perusteella näyttää siltä, että polynomimalli sopii hyvin käyttötarkoitukseemme. On vain valittava sopivin pienimmän neliösumman mielessä.
2
Pienimmän neliösumman menetelmän (PNS, method of least squares, least squares, esim: http://en.wikipedia.org/wiki/Least_squares) käyttöä olitte jo harjoitelleet 24.9.2010 tehdyn harjoitteen puitteissa, jolloin havaittiin, että Matlabia käyttäen ongelman ratkaisu (parametrien suhteen lineaarisessa tapauksessa) ei ole kovin vaikeaa. Koodataan seuraava koodi, joka piirtää kaikki sovitukset samaan kuvioon (voi myös käyttää ’subplot’-komentoja ja piirtää kuusi erillistä pikkukuviota tai piirtää kuusi erillistä isoa kuviota):
% K4_2010_MetO.m % Pienimmän neliösumman menetelmä. % 10.08.2010 & 30.09.2010 - (c) Juha Jaako format compact ; clear all ; % Pito päälle (sallii kuvaa kohti useita piirtokomentoja). hold on ; % Mittaustiedot. t = [ 0.0 1.0 2.0 3.0 4.0 5.0 ] ; y = [ 1.0 2.7 5.8 6.6 7.5 9.9 ] ; % Piirretään mittaustiedot koordinaatistoon. plot (t, y, 'ko') ; % Datapisteet kuvioon. grid on ; % Ruudukko kuvioon. % Lisätään akselitiedot. axis ( [0 7 0 14] ) ; % Määritellään akselit: t 0...6 ; y 0...14 xlabel ( '\it t' ) ; % Teksti x-akselille. ylabel ( '\it y' ) ; % Teksti y-akselille. title ( 'Polynomisovitus: n = 0, 1, ..., 5') ; % Kuvion otsikko. %%% Polynomit : n = 0, 1, 2, 3, 4, 5 % Tähän voisi tehdä for ... end -silmukan. % n = 0 : y = a0 A = [ones(length(t),1)] ; b = y' ; x = A \ b ; a0 = x ; yp = [ '(' num2str(a0) ')' ] ; yf = inline (yp, 't') ; disp (yf) ; fplot (yf, [ 0 7], 'k--' ) ; % Neliösumman arvo. temp = [ yf(t(1)), yf(t(2)), yf(t(3)), yf(t(4)), yf(t(5)), yf(t(6)) ] ; neliosumma0 = sum ((y - temp).^2) % n = 1 : y = a1*t + a0 % PNS-matriisi : A x = b A = [t', ones(length(t),1)] ; b = y' ; x = A \ b ; a1 = x(1) ; a0 = x(2) ; yp = [ '(' num2str(a1) ')*t+(' num2str(a0) ')' ] ; yf = inline (yp, 't') ; disp (yf) ; fplot (yf, [ 0 7], 'b--' ) ; % Neliösumman arvo. temp = [ yf(t(1)), yf(t(2)), yf(t(3)), yf(t(4)), yf(t(5)), yf(t(6)) ] ; neliosumma1 = sum ((y - temp).^2)
3
% n = 2 : y = a2*t^2 + a1*t + a0 % PNS-matriisi : A x = b A = [(t.^2)', t', ones(length(t),1)] ; b = y' ; x = A \ b ; a2 = x(1) ; a1 = x(2) ; a0 = x(3) ; yp = [ '(' num2str(a2) ')*t^2+(' num2str(a1) ')*t+(' num2str(a0) ')' ] ; yf = inline (yp, 't') ; disp (yf) ; fplot (yf, [ 0 7], 'r--' ) ; % Neliösumman arvo. temp = [ yf(t(1)), yf(t(2)), yf(t(3)), yf(t(4)), yf(t(5)), yf(t(6)) ] ; neliosumma2 = sum ((y - temp).^2) % n = 3 : y = a3*t^3 + a2*t^2 + a1*t + a0 % PNS-matriisi : A x = b A = [(t.^3)', (t.^2)', t', ones(length(t),1)] ; b = y' ; x = A \ b ; a3 = x(1) ; a2 = x(2) ; a1 = x(3) ; a0 = x(4) ; yp = [ '(' num2str(a3) ')*t^3+(' num2str(a2) ')*t^2+(' ... num2str(a1) ')*t+(' num2str(a0) ')' ] ; yf = inline (yp, 't') ; disp (yf) ; fplot (yf, [ 0 7], 'k.-' ) ; % Neliösumman arvo. temp = [ yf(t(1)), yf(t(2)), yf(t(3)), yf(t(4)), yf(t(5)), yf(t(6)) ] ; neliosumma3 = sum ((y - temp).^2) % n = 4 : y = a4*t^4 + a3*t^3 + a2*t^2 + a1*t + a0 % PNS-matriisi : A x = b A = [(t.^4)', (t.^3)', (t.^2)', t', ones(length(t),1)] ; b = y' ; x = A \ b ; a4 = x(1) ; a3 = x(2) ; a2 = x(3) ; a1 = x(4) ; a0 = x(5) ; yp = [ '(' num2str(a4) ')*t^4+(' num2str(a3) ')*t^3+(' num2str(a2) ... ')*t^2+(' num2str(a1) ')*t+(' num2str(a0) ')' ] ; yf = inline (yp, 't') ; disp (yf) ; fplot (yf, [ 0 7], 'b.-' ) ; % Neliösumman arvo. temp = [ yf(t(1)), yf(t(2)), yf(t(3)), yf(t(4)), yf(t(5)), yf(t(6)) ] ; neliosumma4 = sum ((y - temp).^2) % n = 5 : y = a5*t^5 + a4*t^4 + a3*t^3 + a2*t^2 + a1*t + a0 % PNS-matriisi : A x = b A = [(t.^5)', (t.^4)', (t.^3)', (t.^2)', t', ones(length(t),1)] ; b = y' ; x = A \ b ; a5 = x(1) ; a4 = x(2) ; a3 = x(3) ; a2 = x(4) ; a1 = x(5) ; a0 = x(6) ; yp = [ '(' num2str(a5) ')*t^5+(' num2str(a4) ')*t^4+(' num2str(a3) ... ')*t^3+(' num2str(a2) ')*t^2+(' num2str(a1) ')*t+(' num2str(a0) ')' ] ; yf = inline (yp, 't') ; disp (yf) ; fplot (yf, [ 0 7], 'r.-' ) ; % Neliösumman arvo. temp = [ yf(t(1)), yf(t(2)), yf(t(3)), yf(t(4)), yf(t(5)), yf(t(6)) ] ; neliosumma5 = sum ((y - temp).^2) % Selitteet. legend ( 'datapisteet', 'n=0', 'n=1', 'n=2', 'n=3', 'n=4', 'n=5', 2 ) ; % Pito pois. hold off ;
4
Saamme seuraavan kuvion
0 1 2 3 4 5 6 70
2
4
6
8
10
12
14
t
y
Polynomisovitus: n = 0, 1, ..., 5
datapisteetn=0n=1n=2n=3n=4n=5
ja tulosteen, josta näkyvät myös lasketut malliparametrit ja neliösummat (ulkoasua muokattu):
>> K4_2010_MetO Inline function: yf(t) = (5.5833) neliosumma0 = 52.7083 Inline function: yf(t) = (1.7057)*t+(1.319) neliosumma1 = 1.7928 Inline function: yf(t) = (-0.094643)*t^2+(2.1789)*t+(1.0036) neliosumma2 = 1.4584 Inline function: yf(t) = (0.071296)*t^3+(-0.62937)*t^2+(3.1557)*t+(0.78968) neliosumma3 = 1.1290 Inline function: yf(t) = (0.10625)*t^4+(-0.9912)*t^3+(2.634)*t^2+(0.11997)*t+(0.97183) neliosumma4 = 0.2000 Inline function: yf(t) = (-0.059167)*t^5+(0.84583)*t^4+(-4.2125)*t^3+(8.3042)*t^2+(-3.1783)*t+(1) neliosumma5 = 4.8193e-006
Yleensä sopivimman mallin valinta tapahtuu silmämääräisesti sekä laskemalla tunnuslukuja. Yleisin tunnusluku on selitysaste R2 tai neliösumman arvo. Selitysaste ilmoittaa, kuinka suuri murto-osa y:n arvoissa todetusta vaihtelusta voidaan selittää t:n arvoissa tapahtuneilla muutoksilla. Selitysasteet eri malleille ovat (miten lasketaan?):
n R2 Neliösumma 0 << 1 52.7083 1 0.966 1.7928 2 0.9723 1.4584 3 0.9786 1.1290 4 0.9962 0.2000 5 1.0000 4.8193e-006 ~ 0
5
Yleensä mallia pidetään hyvänä, jos selitysaste on parempi kuin 0.9 (tai neliösumma ei ole kovin suuri). Nyt tilanne on malleilla n > 0 tämä. Lisäksi mallien selityaste kasvaa polynomin asteen kasvaessa. Arvolla n = 5 selitysaste on jopa 1 (miksi?). Katsotaan nyt mallien n = 0 ... 5 tilannetta.
• malli n = 0 : Kuvaajasta näemme, että malli kuvaa erittäin huonosti dataa (neliösumma suuri). Poistamme tilanteen n = 0 ja saamme seuraavan kuvion.
0 1 2 3 4 5 6 70
2
4
6
8
10
12
14
t
y
Polynomisovitus: n = 1, ..., 5
datapisteetn=1n=2n=3n=4n=5
• mallit n = 4 ja n = 5 : Kuvaajista näemme, että mallit kuvaavat dataa hyvin datapisteissä,
kohtalaisesti datapisteiden välillä (interpolaatio) mutta erittäin huonosti välillä t > 5 (ekstrapolointi). Poistamme tilanteet n = 4 ja n = 5 ja saamme kuvion
0 1 2 3 4 5 6 70
2
4
6
8
10
12
14
t
y
Polynomisovitus: n = 1, ..., 3
datapisteetn=1n=2n=3
6
• mallit n = 1, n = 2 ja n = 3 : Mallit kuvaavat hyvin dataa sekä datapisteiden välillä että välillä x > 5. Periaatteessa kaikki mallit käyvät, mutta koska yleensä pyritään käyttämään mahdolli-simman yksinkertaista mallia, poistetaan tilanne n = 3 tarkastelusta. Saamme
0 1 2 3 4 5 6 70
2
4
6
8
10
12
14
t
yPolynomisovitus: n = 1, 2
datapisteetn=1n=2
Nyt on aika tavalla makuasia, käyttääkö mallia n = 1 vai n = 2. Kummallakin valinnalla on puolensa.
y(t) = 1.7057*t + 1.319 y(t) = -0.094643*t^2 + 2.1789*t + 1.0036
n R2 Neliösumma 1 0.966 1.7928 2 0.9723 1.4584
1
Ohjelmointi ja Matlab – syksy 2010
Kotitehtävä 5 – palautettava 5.10.2010 klo 23:59 mennessä
Suppose that in a certain city, the pollution level is measured at two-hour intervals, beginning at midnight. These measurements were recorded for a one-week period and stored in a Matlab matrix, the first line of which contains the pollution levels for day 1, the second line for day 2, and so on. For example, suppose the pollution matrix for a certain week contains the following data:
A = [ 30, 30, 31, 32, 35, 40, 43, 44, 47, 45, 40, 38 ; ... 33, 32, 30, 34, 40, 48, 46, 49, 53, 49, 45, 40 ; ... 38, 35, 34, 37, 44, 50, 51, 54, 60, 58, 51, 49 ; ... 49, 48, 47, 53, 60, 70, 73, 75, 80, 75, 73, 60 ; ... 55, 54, 53, 65, 70, 80, 90, 93, 95, 94, 88, 62 ; ... 73, 70, 65, 66, 71, 78, 74, 78, 83, 75, 66, 58 ; ... 50, 47, 43, 35, 30, 33, 37, 43, 45, 52, 39, 31 ] ;
A Matlab program (or programs) is (are) to be written to produce a weekly report displaying the pollution levels.
Ongelman ratkaisu:
Ensimmäinen ongelma mittausdataa käsiteltäessä on, että onko viikon ensimmäinen päivä maanantai (kuten Suomessa) vai sunnuntai (kuten Yhdysvalloissa). Tässä käsittelyssä on oletettu, että viikon ensimmäinen päivä on sunnuntai. Mikäli käytämme viikon ensimmäisenä päivänä maanantaita, niin koodeihin on tehtävä vastaavat muutokset.
Millaisia raportteja mittausdatasta voi sitten tehdä? Tarjolla on useita vaihtoehtoja: erilaisia taulukoita, kuvaajia tai edellisten yhdistelmiä.
Tässä esityksessä tehdään yksi taulukko ja neljä erilaista kuvaajaa:
• kellonaika vs. saastetaso eri päivinä (time of day vs. pollution level) • viikonpäivä vs. saastetaso eri kellonaikoina (day of week vs. pollution level) • koko viikko vs. saastetaso (whole week vs. pollution level) • saastetason luokka vs. lukumäärä (values range vs. number of occurrences)
Teemme ensiksi ohjelman (pollution_data.m), joka tallettaa datan (vektorin t ja matriisin A) datatiedostoon ’pollution_data.mat’.
% pollution_data.m % 19.8.2010 & 5.10.2010 - (c) Juha Jaako clear all ; % Mittausajakohdat. t = [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22 ] ; % Saastetaso. A = [ 30, 30, 31, 32, 35, 40, 43, 44, 47, 45, 40, 38 ; 33, 32, 30, 34, 40, 48, 46, 49, 53, 49, 45, 40 ; 38, 35, 34, 37, 44, 50, 51, 54, 60, 58, 51, 49 ; 49, 48, 47, 53, 60, 70, 73, 75, 80, 75, 73, 60 ; 55, 54, 53, 65, 70, 80, 90, 93, 95, 94, 88, 62 ; 73, 70, 65, 66, 71, 78, 74, 78, 83, 75, 66, 58 ; 50, 47, 43, 35, 30, 33, 37, 43, 45, 52, 39, 31 ] ; save pollution_data t A ; disp ( 'Tietojen tallennus tapahtui' ) ;
Nyt voimme ladata mittausdatan aina tarvittaessa ohjelmaan ’load’-komennolla.
2
Voimme esittää datan yksinkertaisessa taulukkomuodossa seuraavasti (esim. siirrettäväksi Word-tekstinkäsittelyohjelmaan):
% pollution_table.m % 19.8.2010 & 5.10.2010 - (c) Juha Jaako clear all ; format compact ; % Ladataan datatiedosto. load pollution_data t A ; % Matriisin koko. [rows, colunms ] = size (A) ; % Viikonpäivät. names = ( [ 'Sunday : ' ; 'Monday : ' ; 'Tuesday : ' ; ... 'Wednesday : ' ; 'Thursday : ' ; 'Friday : ' ; ... 'Saturday : ' ] ) ; % Tehdään taulukko näytölle; taulukon voi kirjoittaa myös tiedostoon. % Lasketaan taulukkoon myös kunkin päivän keskiarvot. disp ( ' ' ) ; disp ( 'Pollution Data for Week X' ) ; disp ( ' Time of Day' ) ; disp ( [ 'Day : ' sprintf('%3d', t) ' Mean' ]) ; disp ( '-----------------------------------------------------' ) ; for i = 1 : rows , disp([names(i,:) sprintf('%3d',A(i,:)) sprintf('%6.1f', mean(A(i,:)))]) ; end
Tulosteena saamme:
>> pollution_table Pollution Data for Week X Time of Day Day : 0 2 4 6 8 10 12 14 16 18 20 22 Mean ----------------------------------------------------- Sunday : 30 30 31 32 35 40 43 44 47 45 40 38 37.9 Monday : 33 32 30 34 40 48 46 49 53 49 45 40 41.6 Tuesday : 38 35 34 37 44 50 51 54 60 58 51 49 46.8 Wednesday : 49 48 47 53 60 70 73 75 80 75 73 60 63.6 Thursday : 55 54 53 65 70 80 90 93 95 94 88 62 74.9 Friday : 73 70 65 66 71 78 74 78 83 75 66 58 71.4 Saturday : 50 47 43 35 30 33 37 43 45 52 39 31 40.4
3
Tehdään ensimmäinen kuvaaja seuraavan koodin avulla: % pollution.m % time of day vs. pollution level % 19.8.2010 - (c) Juha Jaako format compact ; clear all ; % Kuvan pito päälle. hold on ; % Ladataan mittausdata tiedostosta. load pollution_data t A ; % Skaalataan kuvion akselit. axis ( [ 0 26 20 100 ] ) ; % Markkerit. MARKER = [ 'k+-' ; 'bo-' ; 'r*-' ; 'k.-' ; 'bx-' ; 'rs-' ; 'kd-' ] ; % Annetaan kuvion akseleille nimet sekä otsikko. title ('Gotham City - \itPollution level daily') ; xlabel ( '\it time of day, [h]' ) ; ylabel ( '\it pollution level' ) ; % Kuvaajat viikonpäivittäin. DAYS = size (A,1) ; % Päivien lukumäärä. POS = length (A) ; % Mittausajankohtien lukumäärä. for i = 1 : DAYS , plot (t, A(i,:), MARKER(i,:) ) ; % Lasketaan kunkin päivän keskimääräinen saastetaso. ka(i) = mean (A(i,:)) ; text (t(POS), A(i,POS), [ '\leftarrow Avg: ' num2str(ka(i),'%5.1f') ] ) ; end % Viikonpäivien nimet kuvioon. legend ( 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', ... 'Friday', 'Saturday', 2) ; % Ruudukko kuvioon. grid on ; % Kuvan pito pois päältä. hold off ;
4
0 5 10 15 20 2520
30
40
50
60
70
80
90
100Gotham City - Pollution level daily
time of day, [h]
pol
lutio
n le
vel
← Avg: 37.9← Avg: 41.6
← Avg: 46.8
← Avg: 63.6← Avg: 74.9← Avg: 71.4
← Avg: 40.4
SundayMondayTuesdayWednesdayThursdayFridaySaturday
Kuvaajasta näemme, millä kellonlyömällä saastetaso on korkeimmillaan ja mitkä ovat eri viikon-päivien erot. Saastetasot ovat korkeimmillaan ke-pe ja matalimmillaan la-ti. Saastetasot ovat luonnollisesti korkeimmillaan päivittäin iltapäivän ruuhkan aikana (klo 16) lauantaita lukuun ottamatta, jonka saastepiikki on noin klo 18.
5
Seuraava kuvaaja: % pollution_1.m % day of week vs. pollution level % 18.8.2010 - Juha Jaako format compact ; clear all ; % Kuvan pito päälle. hold on ; % Ladataan mittausdata tiedostosta. load pollution_data t A ; % Päivävektori t1 = 1 : 7 ; % Skaalataan kuvion akselit. axis ( [ 1 8 20 100 ] ) ; % Markkerit. MARKER = [ 'k+-' ; 'bo-' ; 'r*-' ; 'k.-' ; 'bx-' ; 'rs-' ; ... 'kd-' ; 'b^-' ; 'rv-' ; 'k>-' ; 'b<-' ; 'rp-' ] ; % Annetaan kuvion akseleille nimet sekä otsikko. title ('Gotham City - \itPollution level at a given time') ; xlabel ( '\it day of week' ) ; ylabel ( '\it pollution level' ) ; % Kuvaajat viikonpäivittäin. DAYS = size (A,1) ; % Päivien lukumäärä. POS = length (A) ; % Mittausajankohtien lukumäärä. for i = 1 : POS , plot (t1, A(:,i), MARKER(i,:) ) ; % Lasketaan kunkin kellonajan keskimääräinen saastetaso. ka(i) = mean (A(:,i)) ; text (t1(DAYS), A(DAYS,i), [ '\leftarrow Avg: ' num2str(ka(i),'%5.1f') ] ) ; end % Kellonajat kuvioon. legend ( '00:00', '02:00', '04:00', '06:00', '08:00', '10:00', ... '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', ... 2) ; % Ruudukko kuvioon. grid on ; % Kuvan pito pois päältä. hold off ;
6
1 2 3 4 5 6 7 820
30
40
50
60
70
80
90
100Gotham City - Pollution level at a given time
day of week
pol
lutio
n le
vel
← Avg: 46.9← Avg: 45.1← Avg: 43.3
← Avg: 46.0
← Avg: 50.0← Avg: 57.0← Avg: 59.1
← Avg: 62.3← Avg: 66.1
← Avg: 64.0
← Avg: 57.4
← Avg: 48.3
00:0002:0004:0006:0008:0010:0012:0014:0016:0018:0020:0022:00
Kuvaajasta näemme, miten eri viikonpäivien saastetasot eroavat toisistaan. Kuvaaja on hiukan sekainen, joten jokin toinen esitysmuoto saattaisi olla parempi.
7
Seuraavan kuvion avulla voimme tarkastella koko viikon saastetason kehitystä: % pollution_2.m % whole week vs. pollution level % 19.8.2010 - Juha Jaako format compact ; clear all ; % Kuvan pito päälle. hold on ; % Ladataan mittausdata tiedostosta. load pollution_data t A ; % Korvataan alkuperäinen t uudella vektorilla. t = [ 0 : 2 : 166 ] ; % Viikossa on 168 h. % Muutetaan A yhdeksi vektoriksi. C = A' ; % Transponoidaan A. B = C(:)' ; % Muutetaan matriisi vektoriksi. % Skaalataan kuvion akselit. axis ( [ 0 180 0 100 ] ) ; % Annetaan kuvion akseleille nimet sekä otsikko. title ('Gotham City - \itPollution level during this week') ; xlabel ( '\it whole week' ) ; ylabel ( '\it pollution level' ) ; % Kuvaaja koko viikolta. plot (t, B, 'k-' ) ; % Lasketaan keskiarvo sekä minimi- ja maksimiarvo ja lisätään kuvioon. POINT = mean (B) ; % Keskiarvo text (t(length(t)), POINT, [ '\leftarrow Avg: ' num2str(POINT,'%5.1f') ] ) ; POINT = max (B) ; % Suurin arvo. text (t(length(t)), POINT, [ '\leftarrow Max: ' num2str(POINT,'%5.1f') ] ) ; POINT = min (B) ; % Pienin arvo text (t(length(t)), POINT, [ '\leftarrow Min: ' num2str(POINT,'%5.1f') ] ) ; % Teksti kuvioon. legend ( 'whole week', 2) ; % Ruudukko kuvioon. grid on ; % Kuvan pito pois päältä. hold off ;
8
0 20 40 60 80 100 120 140 160 1800
10
20
30
40
50
60
70
80
90
100Gotham City - Pollution level during this week
whole week
pol
lutio
n le
vel
← Avg: 53.8
← Max: 95.0
← Min: 30.0
whole week
9
Lopuksi tarkastelemmme saastetasoja sekä niiden esiintymistiheyttä. % pollution_3.m % Distribution of pollution levels. % 19.8.2010 - Juha Jaako format compact ; clear all ;hold on ; % Ladataan mittausdata tiedostosta. load pollution_data t A ; % Muutetaan A yhdeksi vektoriksi. C = A' ; % Transponoidaan A. B = C(:)' ; % Muutetaan matriisi vektoriksi. % Tarkistamme, mille välille luku sattuu. % Välit ovat 30-39, 40-49, 50-59, 60-69, 70-79, 80-89, 90-99. % Välejä on seitsemän. N = 7 ; D = zeros (1,N) ; % Nollataan laskentavektori. for i = 1 : length(B) , luku = B(i) ; if ( luku <= 39 ) , D(1) = D(1)+1 ; elseif ( luku <= 49 ) , D(2) = D(2)+1 ; elseif ( luku <= 59 ) , D(3) = D(3)+1 ; elseif ( luku <= 69 ) , D(4) = D(4)+1 ; elseif ( luku <= 79 ) , D(5) = D(5)+1 ; elseif ( luku <= 89 ) , D(6) = D(6)+1 ; else D(7) = D(7)+1 ; end end % Skaalataan kuvion akselit. axis ( [ 0 8 0 30 ] ) ; % Annetaan kuvion akseleille nimet sekä otsikko. title ('Gotham City - \itPollution distribution during this week') ; xlabel ( '\it values range' ) ; ylabel ( '\it number of occurences' ) ; % Kuvaaja koko viikolta. %plot (1:N, D, 'k-' ) ; bar (D) ; % Pylväsdiagrammi. set (gca,'XTickLabel', ... {' ', '30-39','40-49','50-59','60-69','70-79','80-89', '90-99'}) ; % Ruudukko kuvioon. grid on ; % Kuvan pito pois päältä. hold off ;
10
30-39 40-49 50-59 60-69 70-79 80-89 90-99 0
5
10
15
20
25
30Gotham City - Pollution distribution during this week
values range
num
ber o
f occ
uren
ces
Kuvaajasta huomaamme, että saastetasojen jakauma ei ole normaalijakautunut; korkeita saastepitoisuuksia esiintyy suhteellisen harvoin.