Why is the calculation of skew using exp and log?

While l was looking at the NormalisableRange class I just wondered:
ConvertTo0To1 uses
std::pow (proportion, skew)
to calculate skew - good!

ConvertFrom0To1 uses
std::exp (std::log (proportion) / skew)

Wouldn‘t it be more efficient to do
std::pow (proportion, 1.0 / skew)
because it‘s just one pow instead of one exp and one log?

Just curious!
Thanks!

1 Like

I think pow(a,b) is actually implemented as exp(ln(a)*b). Reason being, you need a way to actually calculate those powers. The most classical way is a polynomial series converging towards the pow() function. These are pretty expensive and there are faster ways to compute exp(). I don’t know what actual implementation is used in the end, but I guess its easier to find a cheap implementation for exp() and log() than for an arbitrary exponent base.

interesting, so actually the convertTo0To1 should use exp and log too. I was just confused that the implementation is different in those functions, although mathematically they are the same.
Thanks!

Yeah I didn’t know it either (did some research after being intruiged by your question).

I think the thing to take away from this is that every time you have a pow function with a constant base

pow(2.f, x);

you can replace it by its exp form

//ln(2) = 0.69314718056
exp(0.69314718056 * x);

and save around half the execution time.

1 Like

I’d assume most compilers will optimize exp(ln(2.f)*x) to exp(0.69…*x).

What I find a bit strange is that the skew is implemented the way it is with pow(normalizedValue, skew). IMO, there are generally three different types of parameters: stepped, linear and log. And to do a log parameter correctly it should be done using normalized = log(plain/min)/log(max/min) and plain = min * exp(normalized * log(max/min)).

For some reason skew is implemented similarily in IPlug but I must admit I always change this to the above calculations for log parameters. With skew it might be easier to add neg log parameters but I never came to a point where I needed that.
Of course, with JUCE it is now quite easy to use lambdas for such behavior but I still never understood why a skew was added in the first place. That doesn’t mean that there might not have been a reason, I simply can’t see it.