Home > . > csminwel.m

csminwel

PURPOSE ^

[fhat,xhat,ghat,Hhat,itct,fcount,retcodehat] = csminwel(fcn,x0,H0,grad,crit,nit,varargin)

SYNOPSIS ^

function [fh,xh,gh,H,itct,fcount,retcodeh] = csminwel(fcn,x0,H0,grad,crit,nit,varargin)

DESCRIPTION ^

[fhat,xhat,ghat,Hhat,itct,fcount,retcodehat] = csminwel(fcn,x0,H0,grad,crit,nit,varargin)
 fcn:   string naming the objective function to be minimized
 x0:    initial value of the parameter vector
 H0:    initial value for the inverse Hessian.  Must be positive definite.
 grad:  Either a string naming a function that calculates the gradient, or the null matrix.
        If it's null, the program calculates a numerical gradient.  In this case fcn must
        be written so that it can take a matrix argument and produce a row vector of values.
 crit:  Convergence criterion.  Iteration will cease when it proves impossible to improve the
        function value by more than crit.
 nit:   Maximum number of iterations.
 varargin: A list of optional length of additional parameters that get handed off to fcn each
        time it is called.
        Note that if the program ends abnormally, it is possible to retrieve the current x,
        f, and H from the files g1.mat and H.mat that are written at each iteration and at each
        hessian update, respectively.  (When the routine hits certain kinds of difficulty, it
        write g2.mat and g3.mat as well.  If all were written at about the same time, any of them
        may be a decent starting point.  One can also start from the one with best function value.)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [fh,xh,gh,H,itct,fcount,retcodeh] = csminwel(fcn,x0,H0,grad,crit,nit,varargin)
0002 %[fhat,xhat,ghat,Hhat,itct,fcount,retcodehat] = csminwel(fcn,x0,H0,grad,crit,nit,varargin)
0003 % fcn:   string naming the objective function to be minimized
0004 % x0:    initial value of the parameter vector
0005 % H0:    initial value for the inverse Hessian.  Must be positive definite.
0006 % grad:  Either a string naming a function that calculates the gradient, or the null matrix.
0007 %        If it's null, the program calculates a numerical gradient.  In this case fcn must
0008 %        be written so that it can take a matrix argument and produce a row vector of values.
0009 % crit:  Convergence criterion.  Iteration will cease when it proves impossible to improve the
0010 %        function value by more than crit.
0011 % nit:   Maximum number of iterations.
0012 % varargin: A list of optional length of additional parameters that get handed off to fcn each
0013 %        time it is called.
0014 %        Note that if the program ends abnormally, it is possible to retrieve the current x,
0015 %        f, and H from the files g1.mat and H.mat that are written at each iteration and at each
0016 %        hessian update, respectively.  (When the routine hits certain kinds of difficulty, it
0017 %        write g2.mat and g3.mat as well.  If all were written at about the same time, any of them
0018 %        may be a decent starting point.  One can also start from the one with best function value.)
0019 global bayestopt_
0020 [nx,no]=size(x0);
0021 nx=max(nx,no);
0022 Verbose=1;
0023 NumGrad= isempty(grad);
0024 done=0;
0025 itct=0;
0026 fcount=0;
0027 snit=100;
0028 %tailstr = ')';
0029 %stailstr = [];
0030 % Lines below make the number of Pi's optional.  This is inefficient, though, and precludes
0031 % use of the matlab compiler.  Without them, we use feval and the number of Pi's must be
0032 % changed with the editor for each application.  Places where this is required are marked
0033 % with ARGLIST comments
0034 %for i=nargin-6:-1:1
0035 %   tailstr=[ ',P' num2str(i)  tailstr];
0036 %   stailstr=[' P' num2str(i) stailstr];
0037 %end
0038 f0 = feval(fcn,x0,varargin{:});
0039 %ARGLIST
0040 %f0 = feval(fcn,x0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13);
0041 % disp('first fcn in csminwel.m ----------------') % Jinill on 9/5/95
0042 if f0 > 1e50, disp('Bad initial parameter.'), return, end
0043 if NumGrad
0044    if length(grad)==0
0045       [g badg] = numgrad(fcn,x0, varargin{:});
0046       %ARGLIST
0047       %[g badg] = numgrad(fcn,x0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13);
0048    else
0049       badg=any(find(grad==0));
0050       g=grad;
0051    end
0052    %numgrad(fcn,x0,P1,P2,P3,P4);
0053 else
0054    [g badg] = feval(grad,x0,varargin{:});
0055    %ARGLIST
0056    %[g badg] = feval(grad,x0,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13);
0057 end
0058 retcode3=101;
0059 x=x0;
0060 f=f0;
0061 H=H0;
0062 cliff=0;
0063 while ~done
0064    bayestopt_.penalty = f;
0065    g1=[]; g2=[]; g3=[];
0066    %addition fj. 7/6/94 for control
0067    disp('-----------------')
0068    disp('-----------------')
0069    %disp('f and x at the beginning of new iteration')
0070    disp(sprintf('f at the beginning of new iteration, %20.10f',f))
0071    %-----------Comment out this line if the x vector is long----------------
0072    %   disp([sprintf('x = ') sprintf('%15.8g %15.8g %15.8g %15.8g\n',x)]);
0073    %-------------------------
0074    itct=itct+1;
0075    [f1 x1 fc retcode1] = csminit(fcn,x,f,g,badg,H,varargin{:});
0076    %ARGLIST
0077    %[f1 x1 fc retcode1] = csminit(fcn,x,f,g,badg,H,P1,P2,P3,P4,P5,P6,P7,...
0078    %           P8,P9,P10,P11,P12,P13);
0079    % itct=itct+1;
0080    fcount = fcount+fc;
0081    % erased on 8/4/94
0082    % if (retcode == 1) | (abs(f1-f) < crit)
0083    %    done=1;
0084    % end
0085    % if itct > nit
0086    %    done = 1;
0087    %    retcode = -retcode;
0088    % end
0089    if retcode1 ~= 1
0090       if retcode1==2 | retcode1==4
0091          wall1=1; badg1=1;
0092       else
0093          if NumGrad
0094             [g1 badg1] = numgrad(fcn, x1,varargin{:});
0095             %ARGLIST
0096             %[g1 badg1] = numgrad(fcn, x1,P1,P2,P3,P4,P5,P6,P7,P8,P9,...
0097             %                P10,P11,P12,P13);
0098          else
0099             [g1 badg1] = feval(grad,x1,varargin{:});
0100             %ARGLIST
0101             %[g1 badg1] = feval(grad, x1,P1,P2,P3,P4,P5,P6,P7,P8,P9,...
0102             %                P10,P11,P12,P13);
0103          end
0104          wall1=badg1;
0105          % g1
0106          save g1 g1 x1 f1 varargin;
0107          %ARGLIST
0108          %save g1 g1 x1 f1 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13;
0109       end
0110       if wall1 % & (~done) by Jinill
0111          % Bad gradient or back and forth on step length.  Possibly at
0112          % cliff edge.  Try perturbing search direction.
0113          %
0114          %fcliff=fh;xcliff=xh;
0115          Hcliff=H+diag(diag(H).*rand(nx,1));
0116          disp('Cliff.  Perturbing search direction.')
0117          [f2 x2 fc retcode2] = csminit(fcn,x,f,g,badg,Hcliff,varargin{:});
0118          %ARGLIST
0119          %[f2 x2 fc retcode2] = csminit(fcn,x,f,g,badg,Hcliff,P1,P2,P3,P4,...
0120          %     P5,P6,P7,P8,P9,P10,P11,P12,P13);
0121          fcount = fcount+fc; % put by Jinill
0122          if  f2 < f
0123             if retcode2==2 | retcode2==4
0124                   wall2=1; badg2=1;
0125             else
0126                if NumGrad
0127                   [g2 badg2] = numgrad(fcn, x2,varargin{:});
0128                   %ARGLIST
0129                   %[g2 badg2] = numgrad(fcn, x2,P1,P2,P3,P4,P5,P6,P7,P8,...
0130                   %      P9,P10,P11,P12,P13);
0131                else
0132                   [g2 badg2] = feval(grad,x2,varargin{:});
0133                   %ARGLIST
0134                   %[g2 badg2] = feval(grad,x2,P1,P2,P3,P4,P5,P6,P7,P8,...
0135                   %      P9,P10,P11,P12,P13);
0136                end
0137                wall2=badg2;
0138                % g2
0139                badg2
0140                save g2 g2 x2 f2 varargin
0141                %ARGLIST
0142                %save g2 g2 x2 f2 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13;
0143             end
0144             if wall2
0145                disp('Cliff again.  Try traversing')
0146                if norm(x2-x1) < 1e-13
0147                   f3=f; x3=x; badg3=1;retcode3=101;
0148                else
0149                   gcliff=((f2-f1)/((norm(x2-x1))^2))*(x2-x1);
0150                   if(size(x0,2)>1), gcliff=gcliff', end
0151                   [f3 x3 fc retcode3] = csminit(fcn,x,f,gcliff,0,eye(nx),varargin{:});
0152                   %ARGLIST
0153                   %[f3 x3 fc retcode3] = csminit(fcn,x,f,gcliff,0,eye(nx),P1,P2,P3,...
0154                   %         P4,P5,P6,P7,P8,...
0155                   %      P9,P10,P11,P12,P13);
0156                   fcount = fcount+fc; % put by Jinill
0157                   if retcode3==2 | retcode3==4
0158                      wall3=1; badg3=1;
0159                   else
0160                      if NumGrad
0161                         [g3 badg3] = numgrad(fcn, x3,varargin{:});
0162                         %ARGLIST
0163                         %[g3 badg3] = numgrad(fcn, x3,P1,P2,P3,P4,P5,P6,P7,P8,...
0164                         %                        P9,P10,P11,P12,P13);
0165                      else
0166                         [g3 badg3] = feval(grad,x3,varargin{:});
0167                         %ARGLIST
0168                         %[g3 badg3] = feval(grad,x3,P1,P2,P3,P4,P5,P6,P7,P8,...
0169                         %                         P9,P10,P11,P12,P13);
0170                      end
0171                      wall3=badg3;
0172                      % g3
0173                      badg3
0174                      save g3 g3 x3 f3 varargin;
0175                      %ARGLIST
0176                      %save g3 g3 x3 f3 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13;
0177                   end
0178                end
0179             else
0180                f3=f; x3=x; badg3=1; retcode3=101;
0181             end
0182          else
0183             f3=f; x3=x; badg3=1;retcode3=101;
0184          end
0185       else
0186          % normal iteration, no walls, or else we're finished here.
0187          f2=f; f3=f; badg2=1; badg3=1; retcode2=101; retcode3=101;
0188       end
0189    else 
0190       f2=f;f3=f;f1=f;retcode2=retcode1;retcode3=retcode1;
0191    end
0192    %how to pick gh and xh
0193    if f3 < f - crit & badg3==0
0194       ih=3
0195       fh=f3;xh=x3;gh=g3;badgh=badg3;retcodeh=retcode3;
0196    elseif f2 < f - crit & badg2==0
0197       ih=2
0198       fh=f2;xh=x2;gh=g2;badgh=badg2;retcodeh=retcode2;
0199    elseif f1 < f - crit & badg1==0
0200       ih=1
0201       fh=f1;xh=x1;gh=g1;badgh=badg1;retcodeh=retcode1;
0202    else
0203       [fh,ih] = min([f1,f2,f3]);
0204       disp(sprintf('ih = %d',ih))
0205       %eval(['xh=x' num2str(ih) ';'])
0206       switch ih
0207          case 1
0208             xh=x1;
0209          case 2
0210             xh=x2;
0211          case 3
0212             xh=x3;
0213       end %case
0214       %eval(['gh=g' num2str(ih) ';'])
0215       %eval(['retcodeh=retcode' num2str(ih) ';'])
0216       retcodei=[retcode1,retcode2,retcode3];
0217       retcodeh=retcodei(ih);
0218       if exist('gh')
0219          nogh=isempty(gh);
0220       else
0221          nogh=1;
0222       end
0223       if nogh
0224          if NumGrad
0225             [gh badgh] = numgrad(fcn,xh,varargin{:});
0226          else
0227             [gh badgh] = feval(grad, xh,varargin{:});
0228          end
0229       end
0230       badgh=1;
0231    end
0232    %end of picking
0233    %ih
0234    %fh
0235    %xh
0236    %gh
0237    %badgh
0238    stuck = (abs(fh-f) < crit);
0239    if (~badg)&(~badgh)&(~stuck)
0240       H = bfgsi(H,gh-g,xh-x);
0241    end
0242    if Verbose
0243       disp('----')
0244       disp(sprintf('Improvement on iteration %d = %18.9f',itct,f-fh))
0245    end
0246    % if Verbose
0247       if itct > nit
0248          disp('iteration count termination')
0249          done = 1;
0250       elseif stuck
0251          disp('improvement < crit termination')
0252          done = 1;
0253       end
0254       rc=retcodeh;
0255       if rc == 1
0256          disp('zero gradient')
0257       elseif rc == 6
0258          disp('smallest step still improving too slow, reversed gradient')
0259       elseif rc == 5
0260          disp('largest step still improving too fast')
0261       elseif (rc == 4) | (rc==2)
0262          disp('back and forth on step length never finished')
0263       elseif rc == 3
0264          disp('smallest step still improving too slow')
0265       elseif rc == 7
0266          disp('warning: possible inaccuracy in H matrix')
0267       end
0268    % end
0269    f=fh;
0270    x=xh;
0271    g=gh;
0272    badg=badgh;
0273 end
0274 % what about making an m-file of 10 lines including numgrad.m
0275 % since it appears three times in csminwel.m

Generated on Fri 16-Jun-2006 09:09:06 by m2html © 2003