 
    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-4  
Yleistyy 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+1  
Erityisesti 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|4
Yhteenlaskun 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-16
Matlabin 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-4
Kolme 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.1054
Tä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").
 
 
 Kotiin
Kotiin