Note that there are some explanatory texts on larger screens.

plurals
  1. POMatlab: poor accuracy of optimizers/solvers
    text
    copied!<p>I am having difficulty achieving sufficient accuracy in a root-finding problem on Matlab. I have a function, <code>Lik(k)</code>, and want to find the value of <code>k</code> where <code>Lik(k)=L0</code>. Basically, the problem is that various built-in Matlab solvers (<code>fzero</code>, <code>fminbnd</code>, <code>fmincon</code>) are not getting as close to the solution as I would like or expect.</p> <p><code>Lik()</code> is a user-defined function which involves extensive coding to compute a numerical inverse Laplace transform, etc., and I therefore do not include the full code. However, I have used this function extensively and it appears to work properly. <code>Lik()</code> actually takes several input parameters, but for the current step, all of these are fixed except <code>k</code>. So it is really a one-dimensional root-finding problem.</p> <p>I want to find the value of <code>k &gt;= 165.95</code> for which <code>Lik(k)-L0 = 0</code>. <code>Lik(165.95)</code> is less than <code>L0</code> and I expect <code>Lik(k)</code> to increase monotonically from here. In fact, I can evaluate <code>Lik(k)-L0</code> in the range of interest and it appears to smoothly cross zero: e.g. <code>Lik(165.95)-L0 = -0.7465, ..., Lik(170.5)-L0 = -0.1594, Lik(171)-L0 = -0.0344, Lik(171.5)-L0 = 0.1015, ... Lik(173)-L0 = 0.5730, ..., Lik(200)-L0 = 19.80</code>. So it appears that the function is behaving nicely.</p> <p>However, I have tried to "automatically" find the root with several different methods and the accuracy is not as good as I would expect...</p> <p>Using <code>fzero(@(k) Lik(k)-L0)</code>: If constrained to the interval <code>(165.95,173)</code>, <code>fzero</code> returns <code>k=170.96</code> with <code>Lik(k)-L0=-0.045</code>. Okay, although not great. And for practical purposes, I would not know such a precise upper bound without a lot of manual trial and error. If I use the interval <code>(165.95,200)</code>, <code>fzero</code> returns <code>k=167.19</code> where <code>Lik(k)-L0 = -0.65</code>, which is rather poor. I have been running these tests with <em>Display</em> set to <em>iter</em> so I can see what's going on, and it appears that <code>fzero</code> hits <code>167.19</code> on the 4th iteration and then stays there on the 5th iteration, meaning that the change in <code>k</code> from one iteration to the next is less than <code>TolX</code> (set to 0.001) and thus the procedure ends. The exit flag indicates that it successfully converged to a solution.</p> <p>I also tried minimizing <code>abs(Lik(k)-L0)</code> using <code>fminbnd</code> (giving upper and lower bounds on <code>k</code>) and <code>fmincon</code> (giving a starting point for <code>k</code>) and ran into similar accuracy issues. In particular, with <code>fmincon</code> one can set both <code>TolX</code> and <code>TolFun</code>, but playing around with these (down to 10^-6, much higher precision than I need) did not make any difference. Confusingly, sometimes the optimizer even finds a k-value on an earlier iteration that is closer to making the objective function zero than the final k-value it returns.</p> <p>So, it appears that the algorithm is iterating to a certain point, then failing to take any further step of sufficient size to find a better solution. Does anyone know why the algorithm does not take another, larger step? Is there anything I can adjust to change this? (I have looked at the list under <em>optimset</em> but did not come up with anything useful.)</p> <p>Thanks a lot!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload