Home > matlab > csolve.m

csolve

PURPOSE ^

function [x,rc] = csolve(FUN,x,gradfun,crit,itmax,varargin)

SYNOPSIS ^

function [x,rc] = csolve(FUN,x,gradfun,crit,itmax,varargin)

DESCRIPTION ^

function [x,rc] = csolve(FUN,x,gradfun,crit,itmax,varargin)
 FUN should be written so that any parametric arguments are packed in to xp,
 and so that if presented with a matrix x, it produces a return value of
 same dimension of x.  The number of rows in x and FUN(x) are always the
 same.  The number of columns is the number of different input arguments
 at which FUN is to be evaluated.

 gradfun:  string naming the function called to evaluate the gradient matrix.  If this
           is null (i.e. just "[]"), a numerical gradient is used instead.
 crit:     if the sum of absolute values that FUN returns is less than this,
           the equation is solved.
 itmax:    the solver stops when this number of iterations is reached, with rc=4
 varargin: in this position the user can place any number of additional arguments, all
           of which are passed on to FUN and gradfun (when it is non-empty) as a list of 
           arguments following x.
 rc:       0 means normal solution, 1 and 3 mean no solution despite extremely fine adjustments
           in step length (very likely a numerical problem, or a discontinuity). 4 means itmax
           termination.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [x,rc] = csolve(FUN,x,gradfun,crit,itmax,varargin)
0002 %function [x,rc] = csolve(FUN,x,gradfun,crit,itmax,varargin)
0003 % FUN should be written so that any parametric arguments are packed in to xp,
0004 % and so that if presented with a matrix x, it produces a return value of
0005 % same dimension of x.  The number of rows in x and FUN(x) are always the
0006 % same.  The number of columns is the number of different input arguments
0007 % at which FUN is to be evaluated.
0008 %
0009 % gradfun:  string naming the function called to evaluate the gradient matrix.  If this
0010 %           is null (i.e. just "[]"), a numerical gradient is used instead.
0011 % crit:     if the sum of absolute values that FUN returns is less than this,
0012 %           the equation is solved.
0013 % itmax:    the solver stops when this number of iterations is reached, with rc=4
0014 % varargin: in this position the user can place any number of additional arguments, all
0015 %           of which are passed on to FUN and gradfun (when it is non-empty) as a list of
0016 %           arguments following x.
0017 % rc:       0 means normal solution, 1 and 3 mean no solution despite extremely fine adjustments
0018 %           in step length (very likely a numerical problem, or a discontinuity). 4 means itmax
0019 %           termination.
0020 
0021 % Original file downloaded from:
0022 % http://sims.princeton.edu/yftp/optimize/mfiles/csolve.m
0023 
0024 % Copyright (C) 1993-2007 Christopher Sims
0025 % Copyright (C) 2007-2011 Dynare Team
0026 %
0027 % This file is part of Dynare.
0028 %
0029 % Dynare is free software: you can redistribute it and/or modify
0030 % it under the terms of the GNU General Public License as published by
0031 % the Free Software Foundation, either version 3 of the License, or
0032 % (at your option) any later version.
0033 %
0034 % Dynare is distributed in the hope that it will be useful,
0035 % but WITHOUT ANY WARRANTY; without even the implied warranty of
0036 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0037 % GNU General Public License for more details.
0038 %
0039 % You should have received a copy of the GNU General Public License
0040 % along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
0041 
0042 %---------- delta --------------------
0043 % differencing interval for numerical gradient
0044 delta = 1e-6;
0045 %-------------------------------------
0046 %------------ alpha ------------------
0047 % tolerance on rate of descent
0048 alpha=1e-3;
0049 %---------------------------------------
0050 %------------ verbose ----------------
0051 verbose=0;% if this is set to zero, all screen output is suppressed
0052           %-------------------------------------
0053           %------------ analyticg --------------
0054 analyticg=1-isempty(gradfun); %if the grad argument is [], numerical derivatives are used.
0055                               %-------------------------------------
0056 nv=length(x);
0057 tvec=delta*eye(nv);
0058 done=0;
0059 if isempty(varargin)
0060     f0=feval(FUN,x);
0061 else
0062     f0=feval(FUN,x,varargin{:});
0063 end   
0064 af0=sum(abs(f0));
0065 af00=af0;
0066 itct=0;
0067 while ~done
0068     %   disp([af00-af0 crit*max(1,af0)])
0069     if itct>3 && af00-af0<crit*max(1,af0) && rem(itct,2)==1
0070         randomize=1;
0071     else
0072         if ~analyticg
0073 % $$$          if isempty(varargin)
0074 % $$$             grad = (feval(FUN,x*ones(1,nv)+tvec)-f0*ones(1,nv))/delta;
0075 % $$$          else
0076 % $$$             grad = (feval(FUN,x*ones(1,nv)+tvec,varargin{:})-f0*ones(1,nv))/delta;
0077 % $$$          end
0078             grad = zeros(nv,nv);
0079             for i=1:nv
0080                 grad(:,i) = (feval(FUN,x+tvec(:,i),varargin{:})-f0)/delta;
0081             end
0082         else % use analytic gradient
0083              %         grad=feval(gradfun,x,varargin{:});
0084             [f0,grad] = feval(gradfun,x,varargin{:});
0085         end
0086         if isreal(grad)
0087             if rcond(grad)<1e-12
0088                 grad=grad+tvec;
0089             end
0090             dx0=-grad\f0;
0091             randomize=0;
0092         else
0093             if(verbose),disp('gradient imaginary'),end
0094             randomize=1;
0095         end
0096     end
0097     if randomize
0098         if(verbose),fprintf(1,'\n Random Search'),end
0099         dx0=norm(x)./randn(size(x));
0100     end
0101     lambda=1;
0102     lambdamin=1;
0103     fmin=f0;
0104     xmin=x;
0105     afmin=af0;
0106     dxSize=norm(dx0);
0107     factor=.6;
0108     shrink=1;
0109     subDone=0;
0110     while ~subDone
0111         dx=lambda*dx0;
0112         f=feval(FUN,x+dx,varargin{:});
0113         af=sum(abs(f));
0114         if af<afmin
0115             afmin=af;
0116             fmin=f;
0117             lambdamin=lambda;
0118             xmin=x+dx;
0119         end
0120         if ((lambda >0) && (af0-af < alpha*lambda*af0)) || ((lambda<0) && (af0-af < 0) )
0121             if ~shrink
0122                 factor=factor^.6;
0123                 shrink=1;
0124             end
0125             if abs(lambda*(1-factor))*dxSize > .1*delta;
0126                 lambda = factor*lambda;
0127             elseif (lambda > 0) && (factor==.6) %i.e., we've only been shrinking
0128                 lambda=-.3;
0129             else %
0130                 subDone=1;
0131                 if lambda > 0
0132                     if factor==.6
0133                         rc = 2;
0134                     else
0135                         rc = 1;
0136                     end
0137                 else
0138                     rc=3;
0139                 end
0140             end
0141         elseif (lambda >0) && (af-af0 > (1-alpha)*lambda*af0)
0142             if shrink
0143                 factor=factor^.6;
0144                 shrink=0;
0145             end
0146             lambda=lambda/factor;
0147         else % good value found
0148             subDone=1;
0149             rc=0;
0150         end
0151     end % while ~subDone
0152     itct=itct+1;
0153     if(verbose)
0154         fprintf(1,'\nitct %d, af %g, lambda %g, rc %g',itct,afmin,lambdamin,rc)
0155         fprintf(1,'\n   x  %10g %10g %10g %10g',xmin);
0156         fprintf(1,'\n   f  %10g %10g %10g %10g',fmin);
0157     end
0158     x=xmin;
0159     f0=fmin;
0160     af00=af0;
0161     af0=afmin;
0162     if itct >= itmax
0163         done=1;
0164         rc=4;
0165     elseif af0<crit;
0166         done=1;
0167         rc=0;
0168     end
0169 end

Generated on Mon 21-May-2012 02:42:43 by m2html © 2005