changeset 20694:a7dbc4fc3732

fminunc.m: Correctly calculate gradient and hessian even when fminunc fails (bug #40101) * fminunc.m: Add routine to calculate grad and hess if requested and fminunc has finished with info value of -1, 2, or 3.
author José Vallet <jose.vallet@aalto.fi>
date Mon, 03 Feb 2014 17:25:32 +0200
parents 7751bd56d0be
children 6faaab833605
files scripts/optimization/fminunc.m
diffstat 1 files changed, 25 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/optimization/fminunc.m	Wed Nov 11 20:09:31 2015 +0100
+++ b/scripts/optimization/fminunc.m	Mon Feb 03 17:25:32 2014 +0200
@@ -340,6 +340,31 @@
     endwhile
   endwhile
 
+  ## When info != 1, recalculate the gradient and hessian using the final x.
+  if (nargout > 4 && (info == -1 || info == 2 || info == 3))
+    grad0 = grad;  
+    if (has_grad)
+      [fval, grad] = fcn (reshape (x, xsiz));
+      grad = grad(:);
+    else
+      grad = __fdjac__ (fcn, reshape (x, xsiz), fval, typicalx, cdif)(:);
+    endif
+    
+    if (nargout > 5)
+      ## Use the damped BFGS formula.
+      y = grad - grad0;
+      sBs = sumsq (w);
+      Bs = hesr' * w;
+      sy = y' * s;
+      theta = 0.8 / max (1 - sy / sBs, 0.8);
+      r = theta * y + (1-theta) * Bs;
+      hesr = cholupdate (hesr, r / sqrt (s' * r), "+");
+      hesr = cholupdate (hesr, Bs / sqrt (sBs), "-");
+    endif
+    ## Return the gradient in the same shape as x
+    grad = reshape (grad, xsiz);
+  endif
+
   ## Restore original shapes.
   x = reshape (x, xsiz);