maalaus hiiren vasemmalla cat > horner.m hiiren keskimmäinen kopioi tähän CTR-D % Tiedoston loppu
function p=horner(c,x) l=length(c);p=c(1); for k=2:l p=p.*x+c(k); end;
%Ensin skalaarilaskenta: %%%%%%%%%%%%%%%%%%%%%%%% x=5; count1=zeros(1,10); count2=zeros(1,10); value1=zeros(1,10);value2=zeros(1,10); for n=1:10 c=rand(1,n+1); flops(0);value1(n)=polyval(c,x);count1(n)=flops; flops(0);value2(n)=horner(c,x);count2(n)=flops; end; n=1:10; [n' count1' count2'] plot(n,count1,n,count2) title('Skalaaritapaus') xlabel('Polynomin asteluku'),ylabel('Liukulukuoperaatioiden lukumäärä') text(n(5),count1(5),'Matlabin polyval') text(n(5),count2(5),'Oma Horner') value1-value2 % Sitten vektori: %%%%%%%%%%%%%%%%%%%% x=linspace(0,1,200); N=30 count1=zeros(1,N); count2=zeros(1,N); %value1=zeros(1,10);value2=zeros(1,10); for n=1:N c=rand(1,n+1); flops(0);polyval(c,x);count1(n)=flops; flops(0);horner(c,x);count2(n)=flops; end; n=1:N; [n' count1' count2'] plot(n,count1,n,count2) title('Vektorilaskenta') xlabel('Polynomin asteluku'),ylabel('Liukulukuoperaatioiden lukumäärä') text(n(floor(N/3)),count1(floor(N/2)),'Matlabin polyval') text(n(floor(N/3)),count2(floor(N/3)),'Oma Horner') grid type polyval
merkki | eksp (8 bittiä) | mantissa (23 bittiä) |
Esim:
0 | 1 0 0 1 1 0 1 1 | 1 0 1 0 1 1 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 |
Normalisointi: m=1.b1b2 ... b23 , 1 <= m < 2
-127 < e <= 127
Lukualue
[L,U] = [2-126, 2127] = [10-38, 1038]Pienin: (1.000 ... 0)2 2-126 = 1.17549 10-38
merkki | eksp (11 bittiä) | mantissa (52 bittiä) |
Lukualue: [10-307, 10307], tarkkuus n. 15 numeroa.
IEEE-standardiin kuuluvat symbolit NaN ("Not A Number") ja Inf ("Infinity").
1/0 -> Inf 0/0, 0*Inf, arcsin 2, ... antavat NaN.Viimeksi mainittu on esimerkki funktion soveltamisesta lukuun, joka ei kuulu funktion määrittelyjoukkoon.
Pyöristystä on kahta lajia, katkaisu ("truncate") ja oikea pyöristys ("round"). Jälkimmäinen on huomattavasti parempi, ei vain siksi, että se on hieman tarkempi, vaan ennen kaikkea siksi, että siinä tapahtuu tilstollisluonteista pyöristysvirheiden kumoutumista, jolloin laskentatulokset ovat tavallisesti ylärajaennusteita selvästi parempia.
Pyöristys tehdään koulussa opitun säännön mukaan. Yksi esimerkki riittäköön: Lasketaan 5-numeroisessa 10-järjestelmän aritmetiikassa: Olkoon x=2.64575... ja esitetään se 5:llä numerolla normalisoidussa muodossa ja oikein pyöristettynä. , joten float(x)=2.6458 . Normalisoinnin takia |x| > 1 ja siten
|x-float(x)|/|x| < 5*10-5 = 1/2*10-4Yleistyy välittömästi, jos 5:n sijasta on yleinen mantissan pituus t ja 10:n sijalla yleinen kantaluku beta:
|x-float(x)|/|x| < 1/2*beta-t+1Erityisesti binäärijärjestelmässä:
|x-float(x)|/|x| < 2-t
Katsotaan edelleen 10-järj. 5-pituista aritmetiikkaa. (beta=10, t=5).
1.0000| 0.0000|49999 -------------- 1.0000|4Yhteenlaskun tulos = 1.0 Kone-epsilon voidaan myös määritellä suurimpana liukulukuna eps , joka toteuttaa ehdon 1+eps=1 (tai pienimpänä positiivisena, jolle 1+eps > 1 .
Suuruusluokka on tärkeä, 2*eps on ihan yhtä hyvä kuin eps.
Ensin näin (editoidaan outputista turhia pois):
>> format long; n=50;1+2.^-(1:n) ans = Columns 1 through 4 1.50000000000000 1.25000000000000 1.12500000000000 1.06250000000000 ............... Columns 45 through 48 1.00000000000003 1.00000000000001 1.00000000000001 1.00000000000000 Columns 49 through 50 1.00000000000000 1.00000000000000Nyt olemme viisaampia:
format long;N=40:50; [N' (1+2.^-N)'] >> format long;N=40:50; [N' (1+2.^-N)'] ans = 40.00000000000000 1.00000000000091 41.00000000000000 1.00000000000045 42.00000000000000 1.00000000000023 43.00000000000000 1.00000000000011 44.00000000000000 1.00000000000006 45.00000000000000 1.00000000000003 46.00000000000000 1.00000000000001 47.00000000000000 1.00000000000001 48.00000000000000 1.00000000000000 49.00000000000000 1.00000000000000 50.00000000000000 1.00000000000000 >> 2^-48 ans = 3.552713678800501e-15 >> eps ans = 2.220446049250313e-16Matlabin sisäänrakennettu kone-epsilon näyttää olevan hieman liian pieni, mutta lähes 10 ei ole näissä hommissa iso kerroin.
x=3.7214 y=3.7202 -------------- x-y= 0.00013 = 1.3000*10-4Kolme viimeistä 0:aa eivät sisällä mitään informaatiota. Suhteellista tarkkuutta katoaa erotuksesta likimain senverran, kuin alkupäässä on samoja numeroita. Asia on helppo ymmärtää myös siten, että vähennyslaskussa absoluuttinen virhe on samaa luokkaa (kork. 2 kertaa) kuin termien abs. virhe, mutta kun luvut ovat lähes samat, on erotuksen suhteellinen virhe suuri.
Esim: Lasketaan exp(x) Taylorin kehitelmän avulla.
exp(x)=1+x+x2/2!+ x3/3! + ...
Lasketaan e-5.5
|\^/| Maple V Release 5.1 (Helsinki University of Technology) ._|\| |/|_. Copyright (c) 1981-1998 by Waterloo Maple Inc. All rights \ MAPLE / reserved. Maple and Maple V are registered trademarks of <____ ____> Waterloo Maple Inc. | Type ? for help. Digits:=5: x:=-6.5: seq(x^k/k!,k=0..30); seq(add(x^k/k!,k=0..n),n=0..30); exp(x); > Digits:=5: > x:=-6.5: > seq(x^k/k!,k=0..30); 1, -6.5, 21.125, -45.772, 74.379, -96.692, 104.75, -97.266, 79.030, -57.077, 37.100, -21.923, 11.875, -5.9373, 2.7566, -1.1946, .48526, -.18555, .067003, -.022922, .0074500, -.0023059, .00068128, -.00019254, .000052145, -5 -6 -6 -7 -.000013558, .33894 10 , -.81598 10 , .18942 10 , -.42457 10 , -8 .91992 10 > seq(add(x^k/k!,k=0..n),n=0..30); 1, -5.5, 15.625, -30.147, 44.232, -52.460, 52.290, -44.976, 34.054, -23.023, 14.077, -7.846, 4.029, -1.9083, .8483, -.3463, .13896, -.04659, .020413, -.002509, .0049410, .0026351, .0033164, .0031239, .0031760, .0031624, .0031658, .0031650, .0031652, .0031652, .0031652 > exp(x); .0015034 > (.0015034-.0031652)/.0015034; -1.1054Tämän pitemmälle ei kannata laskea, koska summa ei enää muutu. Suhteellinen virhe on yli 110% .
Entä, jos laskemme kaavalla exp(-6.5)=1/exp(6.5) .
Digits:=5: x:=6.5: seq(1/add(x^k/k!,k=0..n),n=0..30); exp(-x); > Digits:=5: > x:=6.5: > seq(1/add(x^k/k!,k=0..n),n=0..30); 1, .13333, .034934, .013441, .0067213, .0040738, .0028553, .0022347, .0018993, .0017135, .0016111, .0015561, .0015279, .0015141, .0015078, .0015051, .0015040, .0015036, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034, .0015034 > exp(-x); .0015034
Alla oleva Maple-teksti on saatu FILE-valikon EXPORT -> txt.
# Määritellään kiintopisteiteraatiota havainnollistavia # apufunktioita. # Määrittelemme ensin funktion porras, joka palauttaa # grafiikkaobjektin, joka puolestaan edustaa "porrasta" # [x,x],[x,f(x)],[f(x),f(x)]. Annamme f:n olla yleinen, toistaiseksi # määrittelemätön globaali symboli. # # Tämän tyylin idea on peräisin Robert Israelilta. # > porras:=x->plot([[x,x],[x,f(x)],[f(x),f(x)]]): # Käyttöesimerkki, leikkaa/liimaa sovellukseesi. # Ensin funktiomäärittely ja alkupiste. > with(plots): > f:=x->3.0*x-x^2: x0:=1.4: > # Seuraavaksi muodostamme iteraatiojonon ja piirrämme koko prosessin. # Erityisesti seuraava solu kannattaa leikata/liimata > X:=[seq((f@@k)(x0),k=0..30)]; # Tämän voit synnyttää myös > for-silmukalla > fjaxkuva:=plot([x,f(x)],x=1.3 .. 2.6,color=[blue,black]): > display({fjaxkuva,seq(porras(X[i]),i=1..nops(X))}); > > display([seq(display([fjaxkuva,porras(X[i])]),i=1..nops(X))],insequenc > e=true);
clear x=linspace(-1,1,6);y=x; [X,Y]=meshgrid(x,y) cgrid=X+i*Y % Varustetaan jokainen ruutu omalla värillään, ensin numeroidaan % kokonaisluvuilla 1:36: Z=reshape(1:36,6,6);Z=Z' clf plot(X(:),Y(:),'.r');hold on % Piirretään väri kerrallaanOikeassa tilanteessa valitaan alkup. hilasta se alkupistejoukko, joka näyttää suppenevan kohti "punaista 0-kohtaa". Jne.
Toinen tapa on käyttää pintapiiroksen colormappiä:
clf surf(X,Y,Z);view(2) %shading flat %colormap(flipud(jet)) colorbar
clear x=linspace(-1,1,50);y=x; [X,Y]=meshgrid(x,y); cgrid=X+i*Y; Z=reshape(rem(1:50*50,8),50,50);Z=Z'; clf surf(X,Y,Z);view(2) shading flat colormap(flipud(jet)) %colorbarHuomaa, että kun valitaan jotain ehtoja toteuttavia alkioita, niin usein on kätevää luiskauttaa pitkiksi vektoreiksi tyylin X(:) . Lopuksi voidaan koota takaisin matriisiksi reshape:llä
Kirjassa Eva PE Anders Sjöberg s. 296-298 on ohjelma mandelbrotprog.m
Alkuperäinen väli olkoon [a,b] ja f vaihtakoon merkkiä.
Skalaariorientoitunut Matlab-toteutus on tässä
a=-1; b=1 x=linspace(a,b);y=sin(x);I=find(sign(y(1)) ~= sign(y)); I1=I(1);a=x(I1-1),b=x(I1)Voit keksiä elegantimmankin, mutta periaate on tänänkaltainen. Kenties olisi mahdollista paikantaa kaikki merkinvaihtokohdat samanaikaisesti. No mutta hyvä näinkin.
Tästä funktio! Voit tietysi tehdä n_osaa, jossa n on parametrina. (Ei ole synonyymi ilmaisulle "en osaa" (edellisestä puuttuu aspiraatio).) Formuloi ja todista "sataosaalause", "n_osaa-lause" (ilman aspiraatiota). (Ai pahus, nykyisin kai harrastetaan ännää eikä ennää, hyvä sanaleikki meni osittain pilalle.)
Mikä on virhearvio? Ehkä olis kiintoisaa verrata aikoja bisektion ja sataosaa:n välillä. (Matlab:ssa tic, toc).
Nämä menetelmät rajaavat (sulkevat) 0-kohdan ("bracket a zero").