Inverting Function Numerically

Aug 7, 2011 at 4:17pm
I am writing a library to handle quantities with units (e.g. metres, etc).

Originally, units were described as SI units plus a numeric scale factor. However, this excluded annoying units like Celsius, which are shifted instead of (or as well as) scaled.

Thus I decided to represent a unit by a function to map the SI unit to the new unit. Users could use lambdas (the library uses C++0x) to easily describe simple scales and translations, while also theoretically being able to come up with whatever crazy units they want with more complex functions.

However, it is necessary to go both from the custom unit to SI and back. Thus an inverse function is needed. Previously, one would just reciprocate the scale factor, but obviously it's more complicated now. Is there some generic way I can numerically invert a given function f:R->R (i.e. long double f(long double))? If not, do I have any option other than to have the user provide the function and its inverse.

Thanks,
-Xander

EDIT: It occurs to me that I should probably somehow impose that the functions be monotonic (not that I can think how to effectively do that...), then it would be possible to (inefficiently) compute an inverse by trial and improvement.
Last edited on Aug 7, 2011 at 4:33pm
Aug 7, 2011 at 4:42pm
I don't think there's a way to invert an arbitrary function. Some function don't even have one.

If you're resticting your conversion function to the form sf * (x + shift) = y, then you could do it with a templated class using static method.

Though you'd prob need more that one scaling class (decibel scales occur to me, which behave differently).

You could provide the custom option you suggest for any unexpected cases!

Andy
Aug 7, 2011 at 4:46pm
I would limit myself to affine transformations, and maybe throw in a log somewhere. Can you think of any phenomenon that is measured with one function in one unit and with a totally different function in another?
Aug 7, 2011 at 4:46pm
Okay, yeah some functions aren't invertible. I would like to impose the monotonicity (either all increasing or all decreasing) of functions used - otherwise the units will be badly defined anyway.

Now, any monotonic function does have an inverse, I think. I considered y=ax+b at first, but due to the existence of funny (logarithmic?) scaled units such as dB, I hoped to keep things general.

I can possibly invert an arbitrary monotonic function, though with poor efficiency. So the new question is how can I impose monotonicity (at runtime) in an efficient way?
Aug 7, 2011 at 4:46pm
You are looking at a whole lot of hurt for something simple.
Why not just have the inverse function also programmed in?
Aug 7, 2011 at 5:00pm
@helios Well the Richter scale and pH are also logarithmic IIRC, though I'm not sure where the Richter scale comes in anyway, with regard to mass/length/time/current/temperature/amount of substance/luminous intensity. However, the library is supposed to allow custom units and who I am to tell the end user he can't measure in exp(sin^2) metres ;)

@Duoas It looks like it will be a lot of hurt, but I thought it might be a bad idea to trust the user to invert his/her own function. Perhaps I could let the user enter both, but throw an exception if the f(f^-1(x)) != x for a range of values of x?
Last edited on Aug 7, 2011 at 5:00pm
Aug 7, 2011 at 5:16pm
Well the Richter scale and pH are also logarithmic IIRC
I have no idea how Richter values are calculated, but I don't think they're convertible to any other unit.
pH is an affine transformation with a decimal logarithm wedged in.

You could do it like this: have the user enter a, b, c, and base, and the conversion function is automatically defined:
If c==0: ax + b
If c==1: a logbase x + b
If c==2: logbase ax + b
If c==3: logbase(ax + b)

EDIT: You can have negative values turn the logarithm into an exponentiation, too, or the other way around.
Last edited on Aug 7, 2011 at 5:18pm
Topic archived. No new replies allowed.