Att beräkna sin(x) och exp(x) på en dator
(en något uppdaterad gammal laboration)
De flesta programspråk ger tillgång till en uppsättning elementära funktioner. Går man tillbaks några datorgenerationer (Sun3-familjen t.ex.) var dessa funktioner implementerade i flyttalsprocessorn. I Sun3:ans FPU-chip, Motorola MC6888[12] fanns alla vanliga (och några inte fullt så vanliga) funktioner.
För att beräkna t.ex. sin(x) i en RISC-dator måste vi dock
länka till ett numerisk bibliotek. Programmerar vi i C heter detta
bibliotek, i allmänhet, /usr/lib/libm.so
(so för shared
object). Tittar man på vad /usr/lib/libm.a
innehåller känner man igen namnen
på flera funktioner. Kwok C. Ng har skrivit (så vitt jag vet)
Suns bibliotek för elementära funktioner och
källkoden ligger
på nätet. Det är dessa rutiner som används i Java (enligt
första
versionen av standarden, i alla fall)
Antag att vi vill beräkna sin(x).
Ett funktionsvärde, f(x), beräknas normalt i tre steg.
Först
transformeras x till ett värde y som ligger i ett litet intervall
[a, b] nära origo. y måste givetvis ha den egenskapen att det
är enkelt att beräkna f(x) givet f(y). Detta steg kallas
argumentreduktion.
Eftersom
intervallet är litet brukar det vara enkelt att approximera funktionen
med ett polynom (eller en rationell funktion), p, på [a, b].
Slutligen
transformeras p(y) så vi erhåller approximationen till f(x).
Låt oss nu titta på specialfallet sin(x).
Att reducera argumentet x till att ligga i [0, pi/4] kallas argumentreduktion och det är viktigt men rätt svårt.
Man kan fråga sig hur man har kommit fram till serieutvecklingen i k_sin.c och vilka egenskaper den har.
För att beräkna ett polynom som har ett fördelat fel enligt ovan brukar man använda Remezalgoritmen
vi avstår från att studera denna algoritm dock. Om Du vill kan
Du testa Mathematica-implementationen, MiniMaxApproximation
, av Remezalgoritmen för att beräkna ett sådant polynom för
exponentialfunktionen. Namnet MiniMax kommer sig av följande:
Givet en funktion f(x) och ett intervall [a, b] vill vi beräkna ett polynom p(x), av ett givet gradtal n, sådant att det maximala relativa felet
max | 1 - p(x) / f(x) | a <= x <= b
minimeras över alla polynom av grad n. Ett sådant problem, när man vill minimera ett maximum, kallas minimaxproblem. Eftersom vi dividerar med f(x) måste vi kräva att f(x) inte har något nollställe i intervallet. Så här kan man gå till väga.