2016-02-26 22:06:49 +01:00
|
|
|
function [x,f,fvec,check]=lnsrch1(xold, fold, g, p, stpmax, func, j1, j2, tolx, varargin)
|
|
|
|
% function [x,f,fvec,check]=lnsrch1(xold,fold,g,p,stpmax,func,j1,j2,tolx,varargin)
|
2007-12-21 17:32:21 +01:00
|
|
|
% Computes the optimal step by minimizing the residual sum of squares
|
2005-02-18 20:54:39 +01:00
|
|
|
%
|
2007-12-21 17:32:21 +01:00
|
|
|
% INPUTS
|
|
|
|
% xold: actual point
|
|
|
|
% fold: residual sum of squares at the point xold
|
|
|
|
% g: gradient
|
|
|
|
% p: Newton direction
|
|
|
|
% stpmax: maximum step
|
|
|
|
% func: name of the function
|
|
|
|
% j1: equations index to be solved
|
|
|
|
% j2: unknowns index
|
2016-02-26 22:06:49 +01:00
|
|
|
% tolx: tolerance parameter
|
2007-12-21 17:32:21 +01:00
|
|
|
% varargin: list of arguments following j2
|
|
|
|
%
|
|
|
|
% OUTPUTS
|
|
|
|
% x: chosen point
|
|
|
|
% f: residual sum of squares value for a given x
|
|
|
|
% fvec: residuals vector
|
|
|
|
% check=1: problem of the looping which continues indefinitely
|
|
|
|
%
|
2017-05-16 15:10:20 +02:00
|
|
|
%
|
2007-12-21 17:32:21 +01:00
|
|
|
% SPECIAL REQUIREMENTS
|
|
|
|
% none
|
|
|
|
|
2017-10-10 10:05:59 +02:00
|
|
|
% Copyright (C) 2001-2018 Dynare Team
|
2008-08-01 14:40:33 +02:00
|
|
|
%
|
|
|
|
% 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 <http://www.gnu.org/licenses/>.
|
2007-12-21 17:32:21 +01:00
|
|
|
|
2009-12-16 18:17:34 +01:00
|
|
|
alf = 1e-4 ;
|
|
|
|
alam = 1;
|
|
|
|
|
|
|
|
x = xold;
|
|
|
|
nn = length(j2);
|
2016-02-26 22:06:49 +01:00
|
|
|
summ = sqrt(p'*p);
|
|
|
|
|
2017-05-16 15:10:20 +02:00
|
|
|
if ~isfinite(summ)
|
2016-07-03 12:37:30 +02:00
|
|
|
if ~isequal(func,@perfect_foresight_problem)
|
|
|
|
eq_number_string=[];
|
|
|
|
for ii=1:length(j1)-1
|
|
|
|
eq_number_string=[eq_number_string, num2str(j1(ii)), ', '];
|
|
|
|
end
|
|
|
|
eq_number_string=[eq_number_string, num2str(j1(end))];
|
|
|
|
var_string=[];
|
|
|
|
Model=evalin('base','M_');
|
|
|
|
for ii=1:length(j2)-1
|
2017-10-10 10:05:59 +02:00
|
|
|
var_string=[var_string, Model.endo_names{j2(ii)}, ', '];
|
2016-07-03 12:37:30 +02:00
|
|
|
end
|
2017-10-10 10:05:59 +02:00
|
|
|
var_string=[var_string, Model.endo_names{j2(end)}];
|
2017-05-16 15:10:20 +02:00
|
|
|
fprintf('\nAn infinite element was encountered when trying to solve equation(s) %s \n',eq_number_string)
|
2016-07-03 12:37:30 +02:00
|
|
|
fprintf('with respect to the variable(s): %s.\n',var_string)
|
|
|
|
fprintf('The values of the endogenous variables when the problem was encountered were:\n')
|
|
|
|
for ii=1:length(xold)
|
2017-10-10 10:05:59 +02:00
|
|
|
fprintf('%-s % 8.4g \n', Model.endo_names{ii}, xold(ii));
|
2016-07-03 12:37:30 +02:00
|
|
|
end
|
2017-05-16 15:10:20 +02:00
|
|
|
skipline();
|
2013-07-18 15:04:00 +02:00
|
|
|
end
|
2005-02-18 20:54:39 +01:00
|
|
|
error(['Some element of Newton direction isn''t finite. Jacobian maybe' ...
|
2010-01-05 11:46:10 +01:00
|
|
|
' singular or there is a problem with initial values'])
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
if summ > stpmax
|
2016-02-26 22:06:49 +01:00
|
|
|
p = p*stpmax/summ ;
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
2005-02-18 20:54:39 +01:00
|
|
|
|
2009-12-16 18:17:34 +01:00
|
|
|
slope = g'*p ;
|
2005-02-18 20:54:39 +01:00
|
|
|
|
2009-12-16 18:17:34 +01:00
|
|
|
test = max(abs(p)'./max([abs(xold(j2))';ones(1,nn)])) ;
|
|
|
|
alamin = tolx/test ;
|
|
|
|
|
|
|
|
if alamin > 0.1
|
2005-02-18 20:54:39 +01:00
|
|
|
alamin = 0.1;
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
while 1
|
2005-02-18 20:54:39 +01:00
|
|
|
if alam < alamin
|
2009-12-16 18:17:34 +01:00
|
|
|
check = 1 ;
|
|
|
|
return
|
2005-02-18 20:54:39 +01:00
|
|
|
end
|
|
|
|
x(j2) = xold(j2) + (alam*p) ;
|
|
|
|
fvec = feval(func,x,varargin{:}) ;
|
|
|
|
fvec = fvec(j1);
|
2016-02-26 22:06:49 +01:00
|
|
|
f = 0.5*(fvec'*fvec) ;
|
2005-02-18 20:54:39 +01:00
|
|
|
if any(isnan(fvec))
|
2009-12-16 18:17:34 +01:00
|
|
|
alam = alam/2 ;
|
|
|
|
alam2 = alam ;
|
|
|
|
f2 = f ;
|
|
|
|
fold2 = fold ;
|
2005-02-18 20:54:39 +01:00
|
|
|
else
|
2009-12-16 18:17:34 +01:00
|
|
|
if f <= fold+alf*alam*slope
|
|
|
|
check = 0;
|
2017-05-16 12:42:01 +02:00
|
|
|
break
|
2009-12-16 18:17:34 +01:00
|
|
|
else
|
|
|
|
if alam == 1
|
|
|
|
tmplam = -slope/(2*(f-fold-slope)) ;
|
|
|
|
else
|
|
|
|
rhs1 = f-fold-alam*slope ;
|
|
|
|
rhs2 = f2-fold2-alam2*slope ;
|
|
|
|
a = (rhs1/(alam^2)-rhs2/(alam2^2))/(alam-alam2) ;
|
|
|
|
b = (-alam2*rhs1/(alam^2)+alam*rhs2/(alam2^2))/(alam-alam2) ;
|
|
|
|
if a == 0
|
|
|
|
tmplam = -slope/(2*b) ;
|
|
|
|
else
|
|
|
|
disc = (b^2)-3*a*slope ;
|
|
|
|
|
|
|
|
if disc < 0
|
|
|
|
error ('Roundoff problem in nlsearch') ;
|
|
|
|
else
|
|
|
|
tmplam = (-b+sqrt(disc))/(3*a) ;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if tmplam > 0.5*alam
|
|
|
|
tmplam = 0.5*alam;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
alam2 = alam ;
|
|
|
|
f2 = f ;
|
|
|
|
fold2 = fold ;
|
|
|
|
alam = max([tmplam;(0.1*alam)]) ;
|
|
|
|
end
|
2005-02-18 20:54:39 +01:00
|
|
|
end
|
2009-12-16 18:17:34 +01:00
|
|
|
end
|
2005-02-18 20:54:39 +01:00
|
|
|
|
|
|
|
% 01/14/01 MJ lnsearch is now a separate function
|
|
|
|
% 01/12/03 MJ check for finite summ to avoid infinite loop when Jacobian
|
|
|
|
% is singular or model is denormalized
|