Message Boards Message Boards

FindRoot help with precision and accuracy

Posted 9 years ago

Hi,

I'm solving a non-linear system of equations with FindRoot. The system is very sparse, if I can say that about a non-linear system. After a few seconds of computation, Mathematica outputs the answer and gives me the error

    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. >>

I have played around with DampingFactor, WorkingPrecision and AccuracyGoal to no avail: When I verify the solutions that Mathematica gives me, at best about 1/3 of them are not satisfied. Can you help me figure out what should I be looking at?

POSTED BY: Miguel Olivo-V
11 Replies

I did not do a very complete search, as the DifficultyFactor, which determines the number of function evaluations, was set to a low value. I was trying to illustrate that minimizing the sum of squares of the equations is a viable approach. Do you know what the bounds on the variables are? I based the bounds I used (0 and 200) on the starting values you set up for FindRoot.

POSTED BY: Frank Kampas
Posted 9 years ago

Thanks Frank, what does that mean? The system has no solution (at least with the restriction that the values must lie in [0,200])? If you think about it, it must have a solution given that it can be viewed as a system of recursive equations with terminal conditions. Using backwards substitution, one should be able to reach to the solution.

POSTED BY: Miguel Olivo-V

Using MathOptimizer Professional http://www.wolfram.com/products/applications/mathoptpro/ to do a global search, I was able to reduce the sum of squares error from 1.88 * 10^7 to 1.99 * 10^6. I assumed the variables have lower bounds of 0 and upper bounds of 200.

In[31]:= Dimensions[
 varrule = init /. ( {var_, initval_} -> var -> initval)]

Out[31]= {1368}

In[34]:= equations.equations /. varrule // N

Out[34]= 1.88301*10^7

In[35]:= Needs["MathOptimizerProLF`callLGO`"]

In[36]:= initbnds = init /. {var_, val_} -> {var, 0, val, 200};

In[41]:= AbsoluteTiming[
 mosln = callLGO[equations.equations, {}, initbnds, 
    DifficultyFactor -> 0.001];]

Out[41]= {22.9501, Null}

In[40]:= First @mosln

Out[40]= 1.98812*10^6
POSTED BY: Frank Kampas

I don't think this is a precision or accuracy issue. I think that FindRoot, starting at the initial values, cannot improve the solution in its first step, so it is returning the starting values. Given the complexity and number of equations, very good starting values are probably a necessity.

POSTED BY: Frank Kampas
Posted 9 years ago

I previously tried using FindMinimum on the sum of squares like you suggested. But it takes way longer with a simplified version of the model, I have not tried it with the full version but presumably would take even longer. I am wondering if compiling the system of equations would be faster. I thought Mathematica did that automatically for functions like FindMinimum.

Also, if I use machine-precision numbers with FindMinimum, do you think I would get the same precision error as before? As you know, machine-precision numbers allow the computation to run faster.

POSTED BY: Miguel Olivo-V

Like I said, it's probably better to form a sum of squares of differences and use FindMinimum. Getting a good approximate root with FindRoot might be too hard, given the complexity of the system of equations.

POSTED BY: Daniel Lichtblau
Posted 9 years ago

Hi guys,

I avoided using inexact numbers an still get the same error. Can you please take a look at the attached notebook?

Thanks.

Attachments:
POSTED BY: Miguel Olivo-V

Looking at the last part of the notebook, I suggest that you calculate the constraint violations to test the result, rather than checking if they are within your defined tolerance. That may give a clue as to what is going on.

POSTED BY: Frank Kampas

You might do better to form a sum of squares and use FindMinimum or NMinimize. Also read what I wrote about using higher WorkingPrecision: it requires higher precision input (easy in this case; make every constant exact instead of machine number).

POSTED BY: Daniel Lichtblau
Posted 9 years ago

Thanks Daniel. I have attached a notebook with the system. I increased the precision to 30 with the same results. Hopefully my code is not too unreadable for you.

Attachments:
POSTED BY: Miguel Olivo-V

If the input has machine doubles, maybe change them to high precision using SetPrecision. Other than that, without the actual system it's difficult to guess what might be at issue.

POSTED BY: Daniel Lichtblau
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract