Innhold:

I programmering er det ofte behov for å gjøre de samme arbeidsoppgavene på forskjellige funksjoner. Da må det være mulig å lagre en referanse til en funksjon, slik at ett program kan brukes mot mange ulike funksjoner. Denne artikkelen forklarer hvordan slike referanser, eller pekere til funksjoner, gjøres i Matlab.


Matlab lagrer en referanse til en funksjon i en variabel. Funksjonsvariabelen kan brukes i argumentlista ved kall av egendefinerte funksjoner, akkurat som tall- eller tegnvariable, men inneholder ikke en bestemt verdi. Den inneholder et uttrykk som skal regnes ut for å gi en verdi når den brukes.

Syntaks (skrivemåte)

Matlab trenger informasjon om tre ting for å lagre en referanse eller peker til en funksjon,

  • at det er en referanse til en funksjon som skal lagres, og ikke en vanlig utregning
  • hvor mange frie variable eller argumenter funksjonen bruker
  • hvordan funksjonen regnes ut


For å angi at en variabel mitt_navn skal gjøre en utregning med en eller flere variable når den brukes, må dette skrives på formen:

mitt_navn = @(variabel1,variabel2,...) beregning med variabel1,variabel2,... ;

Tegnet «@» forteller Matlab at det kommer en referanse til en funksjon, og ikke et vanlig uttrykk som skal regnes ut. Variablene som trengs for å angi funksjonsuttrykket kommer så i en liste med vanlige paranteser. Til slutt kommer selve beregningen som skal utføres. I forhold til en helt vanlig programsetning er altså den eneste forskjellen at en referanse til en funksjon starter med «@()». Fjernes denne biten står det igjen en helt vanlig tilordning av en verdi til en variabel.


En referanse til sinus-funksjonen kan lagres i variabelen f med

f = @(x) sin(x);

I forhold til en vanlig tilordning har det ingen betydning om x fins fra før eller ikke; den vil uansett være helt upåvirket av setningen over. I funksjonsuttrykket brukes x bare for å angi første frie variabel. Det er likegyldig hva som brukes, var1,var2,var3,... er like bra som x,y,z,..., men i matematikken brukes vanligvis x,y,z,... som frie variable, og da blir det gjerne slik også i programmering.

Tilordningen av f betyr at både f(pi/2) og sin(pi/2) kan brukes for å regne ut sinus til 90°. Det er ikke særlig nyttig. Det som er nyttig er at f kan brukes som parameter til en hvilken som helst egendefinert funksjon (lagret i m-fil), og at inne i denne funksjonen brukes parameteren som enhver annen innebygget funksjon i Matlab, som sinsqrtlog og tilsvarende.

Funksjonen sin(x) er så enkel at det er ikke behov for å lage en referanse til den bare for å gjøre en utregning. I større uttrykk kan dette være nyttig for å gi et mer oversiktlig program. Skal det for eksempel regnes ut flere verdier av polynomet p3 = x3 - 6x2 + 11x - 6 kan p3 defineres ved programsetningen

p3 = @(x) x.^3 - 6*x.^2 + 11*x - 6

Det kan være lurt å bruke punkt-operatorer (.^) selv om p3 ikke skal brukes på en liste eller tabell av tall, fordi det kan bli bruk for nettopp det på et senere tidspunkt. Blir det nødvendig å plotte funksjonen med Matlab plot må den skrives med punktoperatorer.

 

Eksempel 1

En graf f(x) er symmetrisk om y-aksen hvis f(x) = f(-x). En egendefinert logisk funksjon som sjekker om et funksjonsargument er symmetrisk om y-aksen i et vilkårlig punkt kan skrives som

function iseven = even(f,x)
	iseven = f(x)*f(-x) >= 0;
end

Eksempler på bruk

>> f = @(x) sin(x)/x;
>> even(f, pi/2) ans = 1 
>> p3 = @(u) u^3; 
>> even(p3, 1) ans = 0

 

Eksempel 2

I mange praktiske tilfeller kan midtpunktsregelen brukes til å beregne den deriverte av en funksjon, f'(x), ganske nøyaktig i et punkt. I en del formler, som f.eks. Newtons metode, er det behov for både funksjonen og dens deriverte. Da kan det være tilstrekkelig å lage en funksjon som returnerer den omtrentlige verdien av den deriverte i ett punkt x0 i stedet for å finne formelen for den deriverte og gi dette inn som et ekstra funksjonsargument:

function yp = deriver(f,x)
	if (abs(x) < 1)
		h = sqrt(eps);
	else
		h = abs(x) * sqrt(eps);
	end
	yp = (f(x+h)-f(x-h)) / (2*h);
end

En liten test med sin(π/4) gir en indikasjon på nøyaktigheten

>> fsin = @(x) sin(x) 
>> deriver(fsin,pi/4)-cos(pi/4) 
ans = 2.69225608473533e-09

Feilen på 2.7e-9 er mye større enn eps, som blir maksimumsfeilen hvis uttrykket for den deriverte brukes, men i en del tilfeller er dette kanskje nøye nok. Det er uvanlig at målte størrelser har mer enn 6-7 signifikante sifre.