Alternatieve Sinus Functie
Over het algemeen kost het aanroepen van een sinusfunctie binnen een programmeertaal een hoop clock-cycles. Daarvoor krijg je wel een hele nette benadering van de sinus van een getal. Vaak veel te netjes als het mij vraagt. Zijn er alternatieven voor wanneer je wat minder detail nodig hebt? Ja, en die zijn een stuk sneller. [1].
Wat dacht je van:
sinX = 1.2732395*x + (0.4052847*x*x) * (x<0?1:-1);
Het is een aardige benadering van de sinusfunctie die op mijn vaste computer wel even 20x zo snel is als de ingebouwde Processing/Java sinus functie.
Wil je nou iets meer detail dan kun je ‘m nog finetunen door met het resultaat van de vorige berekening nog even het volgende uit te halen.
sinX= .225*((x<0?-1:1)*sinX*sinX-sinX)+sinX;
Die is nog steeds 9x zo snel als de standaard sinus functie.
Ben je benieuwd hoe dit werkt zoek dan even op Taylor reeksen want volgens mij hebben we het oorspronkelijk aan hem te danken.
Taylor wilde iedere willekeurige functie schrijven als een polynoom.
Eventueel met graad oneindig, oftewel: als een oneindige reeks.
De gedachte achter dit polynoom is, dat hij voor het punt x=0 de
zelfde waarde heeft als f(x), maar ook dezelfde afgeleide en 2e
afgeleide, enz. [2]
Fijn om te weten is misschien waar die twee getalletjes (1.2732395 en 0.4052847) precies vandaan komen. Waarom weet ik niet maar de eerste staat voor 4/PI en de tweede voor 4/PI2.
Sourcecode
Zie source Alternatieve-Sinus-Functie
Zie source qSin-Color-Wave-Demo
Zoals je ziet is voor zoiets als het onderstaande de grove benadering prima voldoende:

Externe links
* http://home.wanadoo.nl/rule-off/wis/reeksen.htm
* http://lab.polygonal.de/
* http://lab.polygonal.de/wp-content/articles/fast_trig/fastTrig.as



Hoi Rick,
Volgens mij is dit niet de officiele Taylor reeks van sinus. Deze is speciaal gemaakt om met een polynoom van graad twee zo dicht bij mogelijk te komen. Waarschijnlijk gebruikten ze regressie om deze functie te krijgen.
Normaal maak je een Taylor rond x=0 door eerst de functie in te vullen voor x=0:
sin 0 = 0
Daarna, de afgeleide van de functie in te vullen voor x=0:
cos 0 = 1
zo ga je door…
-sin 0 = 0
-cos 0 = -1
sin 0 = 0
…
Je krijgt nu een reeks van 0,1,0,-1,0,1,…
Om de polynoom te krijgen gebruik je deze formule:
a[n]/n! x^n
dus voor deze functie:
sin(x) = 0 + 1/1! x + 0/2! * x^2 + -1/3! * x^3 …
sin(x) = x - 1/6 x^3 …
Mijn favorite manier blijft toch om een array aan te maken met voorberekende waardes van sinus.
Dus drie methodes:
* een simpelere functie fitten. (handig als je precies weet hoeveel precisie je nodig hebt en daar niet van wil afwijken)
* taylor benadering (handig als je ‘on the fly’ van precisie wil veranderen)
* tabel vullen met waardes (handig als je precies weet op welke precisie je de functie aanroept. bv. wel sin(0.1) niet sin(0.11))
Groetjes,
Joris
Comment by Joris — 21 November 2007 @ 10:37
@Joris: Super! Dank.
Comment by Rick Companje — 21 November 2007 @ 10:48