Skip to content

Commit

Permalink
Added Gauss Newton code.
Browse files Browse the repository at this point in the history
  • Loading branch information
Clark Zinzow committed Jul 28, 2016
1 parent 1b0b254 commit 11d819d
Showing 1 changed file with 117 additions and 0 deletions.
117 changes: 117 additions & 0 deletions src/GaussN.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
function [inform, x] = GaussN(fun, x, nparams)
% GaussN implements the Gauss Newton method for finding a solution to
%
% min f(x) = 1/2 * sum_{j=1}^m r_j^2(x)
%
% Input:
%
% fun - a pointer to a function
% x - the following structure:
% * x.p - the starting point values
% * x.f - the function value of x.p
% * x.g - the gradient value of x.p
% * x.h - the Hessian value of x.p
% with only x.p guaranteed to be set.
% nparams - the following structure, as an example:
%
% nparams = struct('maxit',1000,'toler',1.0e-4,
% 'lsmethod','chol');
%
% Note that 'lsmethod' can be 'chol', 'qr', or 'svd'.
%
% Output:
%
% inform - structure containing two fields:
% * inform.status - 1 if gradient tolerance was
% achieved;
% 0 if not.
% * inform.iter - the number of steps taken
% x - the solution structure, with the solution point along with
% function, gradient, and Hessian evaluations thereof.

global numf numg numh resid % resid - function pointer defined in hwk6.m.

numf = 0; % Number of function evaluations.
numg = 0; % Number of gradient evaluations.
numh = 0; % Number of Hessian evaluations.

% Populate local versions of nparams parameters.
toler = nparams.toler; % Set gradient tolerance.
maxit = nparams.maxit; % Set maximum number of allowed iterations.
lsmethod = nparams.lsmethod; % Set method to find search direction.

% Populate params structure, to be provided to StepSize.
params = struct('ftol', 1e-4, 'gtol', 0.9, 'xtol', 1e-6, 'stpmin', 0, ...
'stpmax', 1e20, 'maxfev', 10000);

alfa = 1; % Initial value of alpha.
xc.p = x.p; % Set the current point to the initial point, x.p.

for i = 1:maxit
xc.f = feval(fun, xc.p, 1); % Compute function at current point.
xc.g = feval(fun, xc.p, 2); % Compute gradient at current point.

% Check if norm of gradient at current point is below toler.
if norm(xc.g) < toler
inform.status = 1; % Indicates success.
inform.iter = i; % Set number of iterations.
x.p = xc.p;
x.f = xc.f;
return;
end

% Calculate residual function value and Jacobian at current point.
r = feval(resid, xc.p, 1); % Residual function value at current point.
J = feval(resid, xc.p, 2); % Residual Jacobian at current point.

% Determine which method should be used for finding the search direction.
switch lsmethod
% Get the Cholesky factorization of J'*J, use the result to get pgn.
case 'chol'
% If J'*J is pd, R upper triangular matrix such that R'*R = J'*J.
% Else, Cholesky failed and flag is a positive integer.
[R, flag] = chol(J'*J);
% If the Cholesky factorization failed, return with fail status.
if flag ~= 0
inform.status = 0;
inform.iter = maxit;
x.p = xc.p;
x.f = xc.f;
return;
end
% J'Jp = -J'r and R'R = -J'r, hence pgn = -R\(R'\(J'*r)).
pgn = -R \ (R' \ (J' * r));
% Get the QR factorization of J, use the result to get pgn.
case 'qr'
% P permutation matrix, Q unitay matrix, and R upper triangular
% matrix with diagonal arranged in absolute decreasing order.
[Q R P] = qr(J);
n = size(J, 2);
Q1 = Q(1:end, 1:n);
R = R(1:n, 1:end);
% By Q being unitary and P being a permutation matrix.
pgn = -P * (R \ (Q1' * r));
% Get the SVD factorization of J, use the result to get pgn.
case 'svd'
% U and V unitary matrices, S diagonal matrix.
[U S V] = svd(full(J));
n = size(J, 2);
U1 = U(1:end, 1:n);
S = S(1:n, 1:n);
% By results in lecture 34.
pgn = -V * inv(S) * U1' * r;
end

% Calculate the step size and the current candidate solution point.
[alfa, x] = StepSizeSW(fun, xc, pgn, alfa, params);
% Update our current point by taking a step in the calculated direction.
xc.p = xc.p + alfa * pgn;

end
% If reached, method failed.
inform.status = 0; % Update status to failure indicator, 0.
inform.iter = maxit; % Number of iterations i = maxit at this point.
x.p = xc.p;
x.f = xc.f;
return; % Return inform and final point x
end

0 comments on commit 11d819d

Please sign in to comment.