Mathematica: FindRoot errors

CaptanFunkyFresh picture CaptanFunkyFresh · Jan 11, 2012 · Viewed 14.3k times · Source
FindRoot[
 27215. - 7.27596*10^-12 x + 52300. x^2 - 9977.4 Log[1. - 1. x] == 0
 , 
 {x, 0.000001}
]

converges to the solution {x -> -0.0918521} but how can I get Mathematica to avoid the following error message before the solution:

FindRoot::nlnum: The function value {Indeterminate} is not a list of numbers with dimensions {1} at {x} = {1.}. >>

I am using FindRoot to solve some pretty messy expressions. I also sometimes receive the following error, though Mathematica will still yield an answer, but am wondering if there is a way to avoid it as well:

FindRoot::lstol: The line search decreased the step size to within tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the merit function. You may need more than MachinePrecision digits of working precision to meet these tolerances. >> 

Answer

Arnoud Buzing picture Arnoud Buzing · Jan 12, 2012

The solution you are getting is not the actual solution. The message indicates something was wrong and FindRoot returns the last value of x. This is the last item under 'More Information' for FindRoot:

  • If FindRoot does not succeed in finding a solution to the accuracy you specify within MaxIterations steps, it returns the most recent approximation to a solution that it found. You can then apply FindRoot again, with this approximation as a starting point.

For example, in this case there is also no solution:

FindRoot[x^2 + 1 == 0, {x, 1}]

You will get a FindRoot::jsing warning and Mathematica returns {x -> 0.} (which is the most recent approximation).

A similar case like this, but with a Log function:

FindRoot[1 + Log[1 + x]^2 == 0, {x, 2}]

Gives a FindRoot::nlnum similar to what you are seeing and returns {x -> 0.000269448} (which is the most recent approximation in this case).

This is a plot of the same function, for illustration purposes:

Mathematica graphics

If you want to include complex roots, consider this part of the documentation for FindRoot (under 'More Information' also):

  • You can always tell FindRoot to search for complex roots by adding 0.I to the starting value.

So, for example, you can take a starting value near one complex root, like so:

FindRoot[x^2 + 1 == 0, {x, 1 + 1. I}]

Which converges (without messages) to {x -> 8.46358*10^-23 + 1. I} (so basically I).

Or with a starting value near the other complex root:

FindRoot[x^2 + 1 == 0, {x, 1 - 1. I}]

You will get basically -I (to be precise you get {x -> 8.46358*10^-23 - 1. I}).