function [x, objectivevalue, errorflag] = gauss_newton(fun, x0) % Minimization of the sum of squared residuals with the Gauss-Newton algorithm. % % The objective is to minimize: % % fun(x)'*fun(x) % % with respect to x. % % INPUTS: % - funres [handle] Function from Rᵖ to Rⁿ, which given parameters (x) return the residuals of a non linear equation. % - x0 [double] 1×p vector, initial guess. % % OUTPUTS: % - x [double] 1×p vector, vector of parameters minimizing the sum of squared residuals. % - objectivevalue [double] scalar, optimal value of the objective. % - errorflag [integer] scalar, nonzero if algorithm did not converge. % Copyright © 2018 Dynare Team % % This file is part of Dynare. % % Dynare is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Dynare is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . maxIter = 100; % Maximum number of iteration. h = sqrt(eps(1.0)); % Pertubation size for numerical computation of the Jacobian matrix xtol = 1e-6; % Stopping criterion. phi = .5*(sqrt(5)+1.0); % Golden number. errorflag = 0; noconvergence = true; counter = 0; while noconvergence % Compute residuals and descent direction [r0, J] = jacobian(fun, x0, h); d = pinv(J)*r0; % Update parameters x1 = x0+d; % Test if the step actually reduce the sum of squared residuals. r1 = fun(x1); s0 = r0'*r0; s1 = r1'*r1; if s1>s0 % Gauss-Newton step increased the Sum of Squared Residuals... % We search for another point in the same direction using Golden section search. l1 = 0; l2 = 1; L1 = l2-(l2-l1)/phi; L2 = l1+(l2-l1)/phi; while abs(L1-L2)>1e-6 if ssr(x0+L1*d)xtol; counter = counter+1; x0 = x1; if counter>maxIter break end end x = x0; objectivevalue = s1; errorflag = isequal(counter, maxIter+1); function s = ssr(x) % Evaluate the sum of square residuals. r = fun(x); s = r'*r; end end