[bug?] exp vs. fastexp - fastexp acts linear & has offset!

    May 09 2017 | 9:08 pm
    ...feeding a range of -12 to +12 -> * 0.05776 -> into exp and fast exp
    for values -12, 0 and +12 i get exp: 0.5, 1 and 2 fastexp: 0.486, 0.971 and 1.943
    Feeding the same range +0.69 into [* 0.05776], then to fastexp results in values 0.5, 1 and 2 for -12, 0 and +12, but it is still different.
    Testing further inputting -6, -3, +3 and +6 results in exp: 0.707, 0.841, 1.189 and 1.414 as expected fastexp: 0.750, 0.875, 1.250 and 1.500
    fastexp needs offset on input and has a LINEAR BEHAVIOUR? why???? bug, i'd say.
    Proof of concept, please test
    Max Patcher
    In Max, select New From Clipboard.

    • May 10 2017 | 11:02 am
      hi, it is not a bug, it is an approximation :-)
      by definition, approximations are 'fast' because they 'approximate' the function.
      different approximations for different needs. if you need something rough (like in jit.gen, or for a basic audio rate parameter, etc), then it is useful. if you are doing something that requires high precision it is not useful.
      it just so happens that [fastexp] is very approximate ...
      it is not so much linear as piecewise-linear. that is why it is so cheap. it is easier to get if you graph it:
      Max Patcher
      In Max, select New From Clipboard.
    • May 10 2017 | 11:28 am
      Thank you for your example.
      Okay, so simply fastexp is too broad of an approximation for double tape head pitch calculation, which was essentially, what my patch did. Still don't get, why i have to add an offset to the calculation at all? That to me seems worth correcting at least.
    • May 10 2017 | 11:57 am
      no, you were only adding an offset to one part of the calculation. your offset was wrong for different types of input values. see the graph, your offset would need to modify for each clearly visable linear segment.
      anyway, for very sensitive issues like pitch, math library functions are better. (all the fast* objects are pretty crazy, fast but innacurate bitshifting cleverness - you can see the code by exporting to C++).
      i use the following exp approximation for some 'inbetween' needs as it is still far faster than library exp but much more accurate output than fastexp:
      Max Patcher
      In Max, select New From Clipboard.
      you can get this and a few other approximations in my smFilterPack library, available from your Max 7 Package Manager.
    • May 10 2017 | 12:11 pm
      My offset was actually done by ear, as i needed to achieve clear semitones on the pitch.
      Using that particular offset on fastexp only shifts the range of -12 to + 12 semitones up, so that -12, 0 and + 12 have the same pitch as when using exp. I agree this only makes sense for that particular need.
      Thank you for the insight. I had looked into the C++ code, but are too much of a novice (yet) to find the particular bit.
      By the way, the reason why i started this in the first place was, that i develop free patches for the a programmable pedal (Hoxton OWL) using Gen. Apparently it seems, that their compiler translates exp into using fastexp, eventually for CPU efficiency reasons. If you don't mind i will make use of your workaround for a pitch delay thing there.
    • May 10 2017 | 12:18 pm
      Just listened to halftones using your workaround. It has a nice side effect of extending the octave range a tiny bit, so that one gets to have harmonics resembling natural tuning. That's adjustable of course, but i like the sound of this. Thank you again.
    • May 10 2017 | 1:09 pm
      you said: "Apparently it seems, that their compiler translates exp into using fastexp, eventually for CPU efficiency reasons"
      but i am certain that is not happening, no. if that was happening, trump would have been firing the ceo of C74 this morning instead of the FBI :-)
      anyway, glad the other approximation can help. it is not mine, it is Beat Frei's. pretty sure i credit properly in the library.
      the thing to remember about approximations, is that you shoud build with math functions then see if it is worth / possible to approximate (unless your approximations are also tied into the sound you want, such as the tanh approximations in my afforementioned library). otherwise you can get into all sorts of troubles and bugs.
      the other thing to remember is that gen is not a good environment for approximations as it is an always on 64 bit doubles only environment, so there is not a lot of room to move. life would be a hell of a lot better with a gen-SDK.
      also, if you need a very large range of a math function then these one size fits all solutions are ok, but often we only need a small portion, such as a range of 4 db from a dbtoa conversion. in this case it is better to do curve fitting by hand for the small range you need. curve fitting is annoying though, with no generic solution. i use the os x grapher app. i'm not very good at it. but you'll find you can save masses of cpu with curve fitting.
    • May 10 2017 | 1:42 pm
      I really try to ignore Dumb, and if i succeeded it would be bliss! Fascinating to see US media exploding yesterday over _that_ story, however we have different local issues in Germany ;)
      Yes, actually i was thinking to hardcode the exact values, but that little offness of your workaround sounds good to me. Absolute exactness and music never really go together, As my work is making music i code to play with the results. If exp/fastexp would really work i would probably try to slightly confuse the musical surgery to the point of my ears saying YEAH. Now your approximation does the trick. Running two phasors separetely through exp and your approximation, then just mixing them creates a special phasing, which i wouldn't have come up with by trying to control things. Now all is good.