Group Abstract Group Abstract

Message Boards Message Boards

Problems using InverseFunction

GROUPS:

Hi all,

Do anyone know how Mathematica computes Inverse of a function using InverseFunction? The details of my issue are provided below:

First Issue:

I would like to evaluate the following:

Table[InverseFunction[(0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/0.015 &][i], {i, 1, 20, 1}]

There is no problem in computing the above. I get the answer to this almost instantly. But I couldn't evaluate the same function when my input is 201. i.e., When I do the following, Mathematica couldn't find an answer.

InverseFunction[(0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/ 0.015 &][201]

Second Issue:

Solving the Inverse function for 20 values takes almost no time. i.e., the following :

Table[InverseFunction[(0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/0.015 &][i], {i, 1, 20, 1}]

But if I try to evaluate the same using solve, it takes a long time even to Solve for a single value. i.e.,

Solve[-0.218Log[0.015 - 0.203 x] + 0.203*Log[x] == 3, x]

Please help me out what I'm missing and why the computations are taking time when I try evaluating the same using Solve and also why Mathematica couldn't evaluate the function value at certain points such as 201?

POSTED BY: Kaushik Kandakatla
Answer
1 month ago

You are using floating point numbers. In most cases InverseFunction is used with symbolic numbers instead because it is a symbolic function. There are major differences between floating point and symbolic numbers.

Use Rationalize to convert most of your formula to symbolic numbers.

Rationalize@(0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/0.015
66.6667 (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000)

This is enough to allow InverseFunction to work.

InverseFunction[66.6` (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000)/0.015 &][201]

Remember though that you have to be careful with the precision you have. If we use Rationalize[#,0]& as work with a completely symbolic formula, it's possible to get a situation where there is no precision left in your result. InverseFunction[200/3 (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000) &][201.]

It is easy to make your calculations meaningless by losing all precision. I'm not sure how many digits of accuracy your coefficients have to begin with, but it's possible that InverseFunction might not be a very stable operation in this case.

POSTED BY: Sean Clarke
Answer
1 month ago

Hi Clarke,

Thanks for your reply. But I would like to point to you that there is a small mistake in what you have mentioned.

After using rationalize for the whole function in first step of the following,

Rationalize@(0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/0.015
66.6667 (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000)

why did you again divide the entire output using 0.015 in the inverse function?

InverseFunction[66.6` (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000)/0.015 &][201]

Also, if I put it correctly to solve again, Mathematica couldn't solve and give a proper output

POSTED BY: Kaushik Kandakatla
Answer
1 month ago

I may have miscopied the code. The suggestion however is to try computing the values symbolically in some way. Or you may want to investigate why this isn't numerically stable.

Rationalize[(0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/0.015]
200/3 (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000)

InverseFunction[200/3 (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000) &][201]

This gives back a Root expression, which is just a complicated way of describing a number. You can run N on it to try returning a decimal approximation. You may need to use arbitrary precision computing however.

POSTED BY: Sean Clarke
Answer
1 month ago

Hi Clarke,

I tried what you said.

But doing so I got a completely different answer when I used the method you suggested me. Explanation as follows:

When I tried to compute the following expression directly in float, I got the following:

 InverseFunction[ (0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/0.015 &][1]
0.0101108

But when I did the same using the method you suggested me (first using rationalize and then solving it using N ), provided me altogether different solution and the solution doesn't change even when I change the input after the input is 24.

Rationalize[(0.203*Log[#] - 0.218*Log[0.015 - 0.203*#])/0.015]
200/3 (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000)
N[InverseFunction[ 200/3 (-(109/500) Log[3/200 - (203 #1)/1000] + (203 Log[#1])/1000) &][1]]
4.26674*10^9

Please tell me how to deal with this problem.

POSTED BY: Kaushik Kandakatla
Answer
1 month ago

I would really appreciate if someone could help me deal with this issue.

POSTED BY: Kaushik Kandakatla
Answer
1 month ago

The difference in value is probably floating point error. If you're comfortable knowing the result is close to 0, then the result might be fine. How much precision are you look for in your result? You may be able to get it using arbitrary precision arithmetic.

http://reference.wolfram.com/language/tutorial/ArbitraryPrecisionNumbers.html

If InverseFunction isn't working out at all, then some serious numerical work will have to be done to get a good answer. Typically, computing the inverse of a function is viewed as a root finding problem. You may want to experiment with different Methods for FindRoot. The three statements below are essentially equivalent.

NSolve[f[x] == b,x]

x = InverseFunction[f][b]

FindRoot[f[x]-b, {x,0}]
POSTED BY: Sean Clarke
Answer
1 month ago

I think I was not clear in my previous post.

I tried to find the inverse function using 2 methods for the same expression. Directly solving using InverseFunction gave me a result which is 0.0101108 ; while solving it first by using Rationalize and then solving it using N gave me a result which is 4.26674*10^9.

Please note that there are many orders of magnitude difference between the both but not a floating point error.

POSTED BY: Kaushik Kandakatla
Answer
1 month ago

Having many orders of magnitude between the two results is fairly normal for a floating point error. Very often you have to come up with a technique specific to the problem. In this case rephrasing as a root finding problem seems sufficient to get a reasonable answer:

FindRoot[200/3 (-(109/500) Log[3/200 - (203 x)/1000] + (203 Log[x])/1000) - 201, {x, 0.1}]
POSTED BY: Sean Clarke
Answer
1 month ago

Clarke,

Thank you for your timely reply :)

Finally I could get correct answers provided I give the correct value for x to search (i.e., 0.1 in the above code you mentioned).

Can you please give me further tips on how to select the value for x to search for?

POSTED BY: Kaushik Kandakatla
Answer
27 days ago