Simuleringsberäkningar baserar sig oftast p˚a stokastiska processer

Simuleringsberäkningar baserar sig oftast på stokastiska processer. Sådana beräkningar utförs med hjälp
av slumptal, som i MATLAB genereras med funktionerna rand och randn. Kommandot x = rand
(1000,1) kommer t.ex. att alstra en kolumnvektor med 1000 reella tal, som slumpmässigt valts ut
ur intervallet (0, 1). Fördelningen är likformig, vilket innebär att om a, b är två godtyckliga tal som uppfyller villkoret 0 < a < b < 1, så kommer den bråkdel av de alstrade slumptalen, som ingår i intervallet
[a, b] i medeltal att vara lika med intervallängden b − a. Funktionen randn används om man vill använda
en normalfördelning. Som ett exempel skall vi se på ett program histo.m som använder rand och randn
för att rita histogram med statistiska data:
subplot(2,1,1)
x = rand(1000,1);
hist(x,30)
axis([-1 2 0 60])
xlabel(sprintf(’Medeltal = %5.3f. Median = %5.3f.’,mean(x),median(x)))
title(’Distribution av värden i rand(1000,1)’)
subplot(2,1,2)
x = randn(1000,1);
hist(x,linspace(-3,3,100))
title(’Distribution av värden i randn(1000,1)’)
xlabel(sprintf(’Medeltal = %5.3f. Standard deviation = %5.3f’,mean(x),std(x)))
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
1
Diagrammet nedan visar distributionerna:
Som vi ser väljer rand värden likformigt från intervallet (0, 1), medan randn ger en normalfördelning.
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
2
Histogramfunktionen hist kan användas på flere sätt. Kommandot hist(x,30) fördelar x-värden på 30
delintervall inom intervallet (0, 1). Man kan också specificera delintervallens positioner, såsom i det andra
exemplet (hist(x, linspace(-3, 3, 100))).
Programmet visar också hur man kan formatera figurtext med kommandot sprintf. Detta kommando
har formen sprintf(formatsträng, variabellista), där formatsträngen anger hur texten skall skrivas ut.
Formatet för varje variabel som ingår i variabellistan specificeras med en sträng, som börjar med ett
procenttecken och efterföljs av ett decimaltal och en bokstav. %5.3f betyder t.ex. att 5 tecken reserveras
totalt för variabeln, och 3 tecken för decimalerna. Bokstaven f anger flyttal, e anger exponentframställning.
Ett heltal anges med 0 decimaler. Vi skall se på ett annat program scat.m, som genererar tvådimensionella
spridningsdiagram av distributioner:
p = rand(1000,2);
subplot(1,2,1)
plot(p(:,1),p(:,2),’.’)
title(’Likformig fördelning’)
axis([0 1 0 1])
axis(’square’)
p = randn(1000,2);
subplot(1,2,2)
plot(p(:,1),p(:,2),’.’)
title(’Normalfördelning’)
axis([-3 3 -3 3])
axis(’square’)
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
3
Kommandot p = rand(1000,2) kommer här att alstra en 1000 × 2 matris av slumptal. Nedanstående
bild visar diagrammens utseende:
Man kan också konstruera slumptal med bestämda medeltal och standardavvikelser. Sålunda kommer t.ex.
x=10 + 5*rand(n,1) att alstra likformigt fördelade slumptal inom intervallet (10, 15), och
x=10 + 5*randn(n,1) alstrar normalfördelade slumptal med medeltalet 10 och standardavvikelsen 5.
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
4
Slumptal har använts tidigt för matematiska beräkningar. Mycket känt är det berömda nålproblemet, som
framlades av den franske biologen Georges Louis Leclerc (greve av Buffon) år 1773: Om en nål med längden
l kastas slumpmässigt på ett papper, där man ritat linjer på konstant avstånd d från varandra (d > l),
2l
så är sannolikheten för att nålen skall korsa en linje
. Han ansåg därför att man kunde experimentellt
πd
bestämma π på detta sätt. År 1855 gjorde Ambrose Smith 3204 kastförsök med en stav enligt denna metod,
och beräknade därur värdet på π till 3.1553. År 1901 lyckades den italienska matematikern Lazzarini efter
3408 nålkast (antalet lyckade var 1808) beräkna π med samma metod till 3.1415929, som skiljer sig
först på sjunde decimalen från det korrekta värdet!
Denna beräkning av π kan användas som en enkel illustration till Monte-Carlo metoden, en metod för att
uppskatta integraler med hjälp av slumptal. Talet π kan uppfattas som ytan av enhetscirkeln. Antag att vi
försöker ”träffa” en kvadrant i cirkeln i figuren nedan genom att konstruera slumptal, som har en likformig
fördelning mellan 0 och 1.
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
5
Man åstadkommer en serie ”träffar” i kvadraten OABC genom att välja två slumptal, konstruerade på det
ovannämnda sättet, som får representera x- resp. y -koordinaten för en punkt i kvadraten. Avståndet från
denna slumpmässiga punkt till origo beräknas. Om avståndet är mindre än 1, så har vi träffat det skuggade
området, dvs innanför cirkeln. Om vi totalt skjuter n ”skott”, varav n1 träffar innanför cirkeln, så kan
värdet av π uppskattas som
π=
4 · ytan under kurvan CA
4n1
≈
.
ytan av kvadraten OABC
n
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
6
√
Man kan visa att felet i uppskattningen av ytan är av storleksordningen 1/ n. Vi skall skriva ett MATLAB–
program för att simulera ett dylikt experiment:
clc
figure
rand(’seed’,142857)
traff = 0;
piupp = zeros(500,1);
for k=1:500
x = -1+2*rand(100,1);
y = -1+2*rand(100,1);
traff = traff + sum(x.^2 + y.^2 <= 1);
piupp(k) = (traff/(k*100))*4;
end
plot(piupp)
title(sprintf(’Monte Carlo-uppskattning för pi = %5.3f’,piupp(500)));
xlabel(’Antal försök per hundra’)
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
7
I början av programmet matas slumptalsgeneratorn med ett ’frö’ (142857), ett slumpmässigt heltal som
används för att starta slumptalsberäkningarna. Sedan genereras två vektorer x och y, som innehåller 100
likformigt fördelade slumptal inom intervallet (−1, +1). Vi får alltså 100 punkter (x, y) innanför en
kvadrat med sidan 2 och medelpunkt i origo. Av dessa punkter väljer man ut dem, som uppfyller villkoret
x2 + y 2 ≤ 1 (dvs de punkter, som ligger innanför den inskrivna enhetscirkeln) och lagrar antalet av
dem i variabeln traff (x.^2 + y.^2 <= 1 är ett logiskt uttryck, som då det är sant, har värdet 1, men
värdet 0 i motsatt fall). Slutligen kan vi beräkna en uppskattning av π , då vi vet att förhållandet mellan
cirkelns yta och kvadratens yta är π/4. Proceduren upprepas därpå 500 gånger. Resultatet av beräkningen
visas i figuren nedan. Som vi ser, konvergerar uppskattningarna inte särskilt snabbt mot π . Vi kan därför
konstatera, att nålkastningsexperimenten, som påstods ge nogranna värden av π , inte kan vara pålitliga.
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
8
Ett annat exempel på användningen av slumptal är den brownska rörelsen. Den upptäcktes av den skotska
botanikern Robert Brown 1827, då han med ett mikroskop undersökte pollenkorn suspenderade i vatten,
och fann då en massa små partiklar, som oupphörligt rörde sig hit och dit, fullständigt oregelbundet. Han
trodde först att det sammanhängde med växternas ”vitalitet”, men han upptäckte fenomenet också i vatten
som varit inneslutet i kvarts under miljontals år, och insåg att den förklaringen måste uteslutas. Numera
vet vi att den brownska rörelsen beror på, att vätskans molekyler sätter små dammpartiklar i rörelse, som
kan observeras i mikroskopet (med mörkfältsbelysning). År 1905 skrev Einstein en artikel om den brownska
rörelsen (utan att känna till dess förhistoria), som sedan ledde till hans doktorsavhandling.
Det är ganska lätt att skriva ett Matlab–program, som simulerar Browns rörelse i två dimensioner, och
ritar in den i ett koordinatsystem:
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
9
% brown.m simulerar den brownska rörelsen
N=10000; % antal steg (= antalet punkter som räknas ut)
t=100; h=t/N; % maximitiden=t, h=tidssteget
x=zeros(N,1); % nollställ punkternas x-koordinater
y=zeros(N,1); % nollställ punkternas y-koordinater
x(1)=0.0; y(1)=0.0; % begynnelsepositionen
for i=1:N
% räkna ut N punkter
x(i+1)=x(i)+sqrt(h)*randn;
y(i+1)=y(i)+sqrt(h)*randn;
end;
plot(x,y); % rita ut punkterna
grid on
% lägg till ett rutnät
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
10
Kapitel 5. Introduktion till
numeriska metoder
MATLAB är ett utmärkt system om man vill bekanta sig med numeriska beräkningar, eftersom det gör
det möjligt att experimentera med olika idéer, och genast se resultatet, t.ex. i form av en graf. Vi kommer
här att beskriva enkla numeriska metoder på basen av materialet i C. Van Loan: Introduction to Scientific
Computing.
Vi skall börja med att studera noggrannhet vid beräkningar och talframställning i datorer.
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
11
5.1. Fel och talframställning vid beräkningar
Vid vetenskapliga beräkningar uppträder alla slags fel. Avrundningsfel förekommer i alla slags beräkningar,
approximationsfel uppstår vid numerisk beräkning av derivator, mätfel förekommer i observationsdata, etc.
Detta är något man inte kan undvika, och man bör därför vara medveten om det. Vi skall här koncentrera
oss på approximationsfel och avrundningsfel.
Om x̃ är en approximation för en skalär x, så är det absoluta felet |x̃−x| och det relativa felet |x̃−x|/|x|.
Om det relativa felet är av storleksordningen 10−d, så har x̃ ungefär d korrekta signifikanta siffror, dvs
det existerar ett tal :
e
= ±(. 00 . . . 0 nd+1nd+2 . . .) × 10
|d nollor
{z }
så att x̃ = x + (obs: exponenten e > 0).
För att vi bättre skall förstå absoluta och relativa fel, skall vi se på ett exempel, nämligen Stirling–
approximationen (eller, rättare sagt, en av dem) för fakultetsfunktionen:
Sn =
√
2πn
n n
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
e
≈ n! = 1 · 2 · · · n,
JJ J I II ×
12
där e betecknar det neperska talet 2, 718 . . .. Vi skriver en MATLAB-skript som gör en feltabell:
% Stirling
%
% Prints a table showing error in Stirling’s formula for n!
%
close all
clc
home
disp( ’ ’)
disp(’
Stirling
Absolute
Relative’)
disp(’
n
n!
Approximation
Error
Error’)
disp(’----------------------------------------------------------------’)
e=exp(1);
nfact=1;
for n=1:13
nfact = n*nfact;
s = sqrt(2*pi*n)*((n/e)^n);
abserror = abs(nfact - s);
relerror = abserror/nfact;
s1 = sprintf(’ %2.0f
%10.0f
%13.2f’,n,nfact,s);
s2 = sprintf(’ %13.2f
%5.2e’,abserror,relerror);
disp([s1 s2])
end
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
13
I MATLAB-skripten visas också några nya exempel på formatering av utskrift. Kommandot disp (=display)
används för att visa innehållet i en matris eller en textsträng (såsom ovan). Kommandot sprintf, som
vi tidigare stött på, används här för att konstruera två strängvariabler s1 och s2, som konkateneras med
kommandot disp([s1 s2]) (observera, att man också kan tolka strängar som radvektorer innehållande
alfanumeriska tecken). Med konkatenering bildar man en ny längre radvektor från två kortare radvektorer.
Kommandot clc tömmer kommandofönstret. Nedan visas den färdiga tabellen:
Stirling
Absolute
Relative
n
n!
Approximation
Error
Error
---------------------------------------------------------------1
1
0.92
0.08
7.79e-002
2
2
1.92
0.08
4.05e-002
3
6
5.84
0.16
2.73e-002
4
24
23.51
0.49
2.06e-002
5
120
118.02
1.98
1.65e-002
6
720
710.08
9.92
1.38e-002
7
5040
4980.40
59.60
1.18e-002
8
40320
39902.40
417.60
1.04e-002
9
362880
359536.87
3343.13
9.21e-003
10
3628800
3598695.62
30104.38
8.30e-003
11
39916800
39615625.05
301174.95
7.55e-003
12
479001600
475687486.47
3314113.53
6.92e-003
13
6227020800
6187239475.19
39781324.81
6.39e-003
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
14
Som vi ser, kommer det relativa felet att avta med växande n (Stirlings approximation är asymptotisk).
Som ett annat exempel skall vi studera det relativa felet i exponentialfunktionens Taylor–utveckling, som
kan uttryckas
n
xk
x
e =
+ Rn,
k!
k=0
X
där resttermen Rn är
eθx
n+1
Rn =
x
,
0 < θ < 1.
(n + 1)!
Om man medtar ett ”tillräckligt” antal termer, kommer delsummorna att konvergera. Detta visas av
nedanstående programskript, som ritar delsummornas relativa fel som funktion av n för olika värden av x.
% Script File ExpTaylor
%
% Plots, as a function of n, the relative error in the
% Taylor approximation
%
%
1 + x + x^2/2! +...+ x^n/n!
%
% to exp(x).
close
nTerms = 50;
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
15
for x=[10 5 1 -1 -5 -10]
figure
error = exp(x)*ones(nTerms,1);
s = 1;
term = 1;
for k=1:50
term = x.*term/k;
s = s+ term;
error(k) = abs(error(k) - s);
end;
relerr = error/exp(x);
semilogy(1:nTerms,relerr)
ylabel(’Relative Error in Partial Sum.’)
xlabel(’Order of Partial Sum.’)
title(sprintf(’x = %5.2f’,x))
pause(3)
end
I detta program används en halvlogaritmisk framställning (kommandot semilogy) för att rita graferna.
Detta är lämpligt i detta fall, eftersom det relativa felet varierar många dekader. Kommandot semilogy
används på samma sätt som plot. Programmet alstrar sex bildfönster, ett för vart och ett av de sex
värdena av x. Nedan visas två av dem, nämligen graferna för x = 1 och x = 10.
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
16
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
17
Som vi kan se, avtar felet i delsummorna snabbare för små värden av x än för stora. vilket man kunde
vänta sig. Dessutom ser det som felet inte går exakt till noll, utan slutar att ändra sig då antalet termer
har ökats tillräckligt. Dessa problem förstår vi bättre när vi lär känna flyttalsaritmetiken.
Vi skall studera ett annat exempel, nämligen polynomet p(x) = (x − 1)6, som beräknas inom intervallet
[1 − δ, 1 + δ] ur formeln p(x) = x6 − 6x5 + 15x4 − 20x3 + 15x2 − 6x + 1. MATLAB–programmet
ser ut så här:
%
%
%
%
%
Script File Zoom
Plots (x-1)^6 near x=1 with increasingly refined scale.
Evaluation via x^6 - 6x^5 + 15x^4 - 20x^3 + 15x^2 - 6x +1
leads to severe cancellation.
close
k=0;
for delta = [.1 .01 .008 .007 .005 .003 ]
x = linspace(1-delta,1+delta,100)’;
y = x.^6 - 6*x.^5 + 15*x.^4 - 20*x.^3 + 15*x.^2 - 6*x + ones(100,1);
k=k+1;
subplot(2,3,k)
plot(x,y,x,zeros(1,100))
axis([1-delta 1+delta -max(abs(y)) max(abs(y))])
end
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
18
Resultatet visas i bilden nedan, där x–axlarna ritas mitt på graferna, för att man skall se avvikelser både
uppåt och nedåt. Som vi ser, uppstår ett nästan kaotiskt beteende, då ”förstoringen” ökas. Det ser ut som
om polynomet skulle ha tusentals nollställen!
Om vi istället hade beräknat polynomet med formeln p(x) = (x − 1)6, skulle vi ha få det väntade
utseendet på graferna. Detta betyder, att formler som matematiskt är ekvivalenta, kan bete sig helt olika
när de används i ett datorprogram.
Introduktion till vetenskapliga beräkningar I, Tom Sundius 2009
JJ J I II ×
19