17.01.2013 Views

musicdsp.org source code archive - WSInf

musicdsp.org source code archive - WSInf

musicdsp.org source code archive - WSInf

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

fast exp() approximations (click this to go back to the index)<br />

Type : Taylor series approximation<br />

References : Posted by scoofy[AT]inf[DOT]elte[DOT]hu<br />

Notes :<br />

I needed a fast exp() approximation in the -3.14..3.14 range, so I made some approximations based on the tanh() <strong>code</strong> posted in the <strong>archive</strong> by<br />

Fuzzpilz. Should be pretty straightforward, but someone may find this useful.<br />

The increasing numbers in the name of the function means increasing precision. Maximum error in the -1..1 range:<br />

fastexp3: 0.05 (1.8%)<br />

fastexp4: 0.01 (0.36%)<br />

fastexp5: 0.0016152 (0.59%)<br />

fastexp6: 0.0002263 (0.0083%)<br />

fastexp7: 0.0000279 (0.001%)<br />

fastexp8: 0.0000031 (0.00011%)<br />

fastexp9: 0.0000003 (0.000011%)<br />

Maximum error in the -3.14..3.14 range:<br />

fastexp3: 8.8742 (38.4%)<br />

fastexp4: 4.8237 (20.8%)<br />

fastexp5: 2.28 (9.8%)<br />

fastexp6: 0.9488 (4.1%)<br />

fastexp7: 0.3516 (1.5%)<br />

fastexp8: 0.1172 (0.5%)<br />

fastexp9: 0.0355 (0.15%)<br />

These were done using the Taylor series, for example I got fastexp4 by using:<br />

exp(x) = 1 + x + x^2/2 + x^3/6 + x^4/24 + ...<br />

= (24 + 24x + x^2*12 + x^3*4 + x^4) / 24<br />

(using Horner-scheme:)<br />

= (24 + x * (24 + x * (12 + x * (4 + x)))) * 0.041666666f<br />

Code :<br />

inline float fastexp3(float x) {<br />

return (6+x*(6+x*(3+x)))*0.16666666f;<br />

}<br />

inline float fastexp4(float x) {<br />

return (24+x*(24+x*(12+x*(4+x))))*0.041666666f;<br />

}<br />

inline float fastexp5(float x) {<br />

return (120+x*(120+x*(60+x*(20+x*(5+x)))))*0.0083333333f;<br />

}<br />

inline float fastexp6(float x) {<br />

return 720+x*(720+x*(360+x*(120+x*(30+x*(6+x))))))*0.0013888888f;<br />

}<br />

inline float fastexp7(float x) {<br />

return (5040+x*(5040+x*(2520+x*(840+x*(210+x*(42+x*(7+x)))))))*0.00019841269f;<br />

}<br />

inline float fastexp8(float x) {<br />

return (40320+x*(40320+x*(20160+x*(6720+x*(1680+x*(336+x*(56+x*(8+x))))))))*2.4801587301e-5;<br />

}<br />

inline float fastexp9(float x) {<br />

return (362880+x*(362880+x*(181440+x*(60480+x*(15120+x*(3024+x*(504+x*(72+x*(9+x)))))))))*2.75573192e-6;<br />

}<br />

Comments<br />

from : scoofy@inf.elte.hu<br />

comment : These series converge fast only near zero. But there is an identity:<br />

exp(x) = exp(a) * exp(x-a)<br />

So, if you want a relatively fast polynomial approximation for exp(x) for 0 to ~7.5, you can use:<br />

// max error in the 0 .. 7.5 range: ~0.45%<br />

inline float fastexp(float const &x)<br />

{<br />

if (x

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!