comparison scripts/optimization/fsolve.m @ 9899:9f25290a35e8

more private function and subfunction changes
author John W. Eaton <jwe@octave.org>
date Tue, 01 Dec 2009 22:40:37 -0500
parents f22bbc5d56e9
children dc88a0b6472c
comparison
equal deleted inserted replaced
9898:1ee24979591e 9899:9f25290a35e8
524 %! [x, f, info] = fsolve (@cfun, x, optimset ("ComplexEqn", "on")); 524 %! [x, f, info] = fsolve (@cfun, x, optimset ("ComplexEqn", "on"));
525 %! tol = 1e-5; 525 %! tol = 1e-5;
526 %! assert (norm (f) < tol); 526 %! assert (norm (f) < tol);
527 %! assert (norm (x - x_opt, Inf) < tol); 527 %! assert (norm (x - x_opt, Inf) < tol);
528 528
529 ## Solve the double dogleg trust-region least-squares problem:
530 ## Minimize norm(r*x-b) subject to the constraint norm(d.*x) <= delta,
531 ## x being a convex combination of the gauss-newton and scaled gradient.
532
533 ## TODO: error checks
534 ## TODO: handle singularity, or leave it up to mldivide?
535
536 function x = __dogleg__ (r, b, d, delta)
537 ## Get Gauss-Newton direction.
538 x = r \ b;
539 xn = norm (d .* x);
540 if (xn > delta)
541 ## GN is too big, get scaled gradient.
542 s = (r' * b) ./ d;
543 sn = norm (s);
544 if (sn > 0)
545 ## Normalize and rescale.
546 s = (s / sn) ./ d;
547 ## Get the line minimizer in s direction.
548 tn = norm (r*s);
549 snm = (sn / tn) / tn;
550 if (snm < delta)
551 ## Get the dogleg path minimizer.
552 bn = norm (b);
553 dxn = delta/xn; snmd = snm/delta;
554 t = (bn/sn) * (bn/xn) * snmd;
555 t -= dxn * snmd^2 - sqrt ((t-dxn)^2 + (1-dxn^2)*(1-snmd^2));
556 alpha = dxn*(1-snmd^2) / t;
557 else
558 alpha = 0;
559 endif
560 else
561 alpha = delta / xn;
562 snm = 0;
563 endif
564 ## Form the appropriate convex combination.
565 x = alpha * x + ((1-alpha) * min (snm, delta)) * s;
566 endif
567 endfunction
568