dynare/scilab/solve.sci

111 lines
2.0 KiB
Scilab

function [x,%check]=solve(func,x,varargin)
%check=[];
// Copyright (C) 2001 Michel Juillard
//
nn = size(x,1);
fjac = zeros(nn,nn);
g = zeros(nn,1);
tolf = %eps^(2/3);
tolmin = .000000000037;
tolx = .000000000037;
stpmx = 100;
maxit = 2000;
%check = 0;
if argn(2) > 2
fvec = evstr(func+'(x,varargin)');
else
fvec = evstr(func+'(x)');
end
f = .5*fvec'*fvec;
if max(abs(fvec))<.01*tolf then
return
end
stpmax = stpmx*max([abs(sqrt(x'*x));nn]);
if argn(2) > 2
func_call = func+'(xdh,varargin)';
else
func_call = func+'(xdh)';
end
for its = 1:maxit
dh = max(abs(x),gstep_*ones(nn,1))*(%eps^(1/3));
for j = 1:nn
xdh = x;
xdh(j) = xdh(j)+dh(j);
fjac(:,j) = (evstr(func_call)-fvec) ./ dh(j);
g(j) = fvec'*fjac(:,j);
end
if debug_ then
cond(fjac);
end
p = -fjac\fvec;
xold = x;
fold = f;
if argn(2) > 2
[x,f,fvec,%check] = lnsrch(xold,fold,g,p,stpmax,func,varargin);
else
[x,f,fvec,%check] = lnsrch(xold,fold,g,p,stpmax,func);
end
if %check>0 then
den = max([f;.5*nn]);
if max(abs(g) .* max([abs(x');ones(1,nn)])')/den<tolmin then
return
else
dyn_disp(' ');
dyn_disp('SOLVE: Iteration '+string(its));
dyn_disp('Spurious convergence.');
dyn_disp(x);
return
end
if max(abs(x-xold) ./ max([abs(x);ones(1,nn)])')<tolx then
dyn_disp(' ');
dyn_disp('SOLVE: Iteration '+string(its));
dyn_disp('Convergence on dX.');
dyn_disp(x);
return
end
elseif max(abs(fvec)) < tolf then
return
end
end
%check = 1;
dyn_disp(' ');
dyn_disp('SOLVE: maxit has been reached');
// 01/14/01 MJ lnsearch is now a separate function
// 01/16/01 MJ added varargin to function evaluation
// 04/13/01 MJ added test f < tolf !!
// 05/11/01 MJ changed tests for 'check' so as to remove 'continue' which is
// an instruction which appears only in version 6
// 09/26/01 MJ translated to Scilab
// 10/08/01 MJ changed end criterium from f < tolf to max(abs(fvec)) < tolf