[tim-janik/beast] BSE: bsemathsignal: add approximations: Bse::fast_log2 and Bse::fast_exp2 (#124)

• From: Stefan Westerfeld <notifications github com>
• To: tim-janik/beast <beast noreply github com>
• Cc: Subscribed <subscribed noreply github com>
• Subject: [tim-janik/beast] BSE: bsemathsignal: add approximations: Bse::fast_log2 and Bse::fast_exp2 (#124)
• Date: Tue, 10 Sep 2019 05:35:12 -0700

First of all, this adds a function that was missing in bsemathsignal: a `fast_log2` implementation. It works by using the float exponent and approximating the rest of the value using a polynomial. I found a tool that gives optimal polynomial coefficients for a given order: https://github.com/samhocevar/lolremez

Since I was at it already, I also looked at our exp2 approximations. Comparing them to what lolremez would produce, what we do is not ideal. So I also added `fast_exp2`. This has consistently better relative errors. So I suggest as next step replacing `bse_approxN_exp2` by `fast_exp2<N>` everywhere, which should be as fast, but more accurate. Please review the API and let me know if this can be the canonical API for porting the old functions to.

Remarks:

• unlike `bse_approxN_exp2`, our new `fast_exp2<N>` no longer guarantees almost zero error if the argument is an integer; however I think we don't really need to preserve this property
• I like `Bse::fast_log2` better than `Bse::approx_log2` because when reading code "fast" gives me an idea what the function does and why it was used instead of log2

Relative `exp2(x)` approximation errors in interval [-1:1]:

``````rxprec: bse_approx2_exp2: 0.009017387
rxprec: bse_approx3_exp2: 0.0007944462
rxprec: bse_approx4_exp2: 5.568432e-05
rxprec: bse_approx5_exp2: 3.24224e-06
rxprec: bse_approx6_exp2: 1.614916e-07
rxprec: bse_approx7_exp2: 7.028907e-09
rxprec: bse_approx8_exp2: 2.716875e-10
rxprec: bse_approx9_exp2: 9.445048e-12

rxprec: fast_exp2<2, double>: 0.001724763
rxprec: fast_exp2<3, double>: 7.478144e-05
rxprec: fast_exp2<4, double>: 2.593371e-06
rxprec: fast_exp2<5, double>: 7.493647e-08
rxprec: fast_exp2<6, double>: 1.8558e-09
rxprec: fast_exp2<7, double>: 4.021119e-11
rxprec: fast_exp2<8, double>: 7.746751e-13
rxprec: fast_exp2<9, double>: 1.375958e-14
``````

Commit Summary

• BSE: bsemathsignal: add approximations: Bse::fast_log2 and Bse::fast_exp2