home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l455 / 3.ddi / MMLE3.DI$ / MMLEGRAD.M < prev    next >
Encoding:
Text File  |  1993-03-11  |  5.5 KB  |  124 lines

  1. function [llf]=mmlegrad(p,pid,p2snam,perts,gg)
  2. %  FUNCTION USED BY MMLE.M
  3.  %USED BY MMLESTEP & MMLEMARQ TO GET GRADIENT, HESSIAN & OTHER DATA
  4.  %Outputs :
  5.  %  -    llf     = Log Likelihood function. The following outputs are  GLOBAL
  6.  %  -    grad    = Gradient of cost function wrt parameters in PID
  7.  %  -    hes     = Hessian (second gradient) of cost function wrt params in PID
  8.  %  -    c0      = Measurement matrix   %not called by anyone else.
  9.  %  -    e0      = Diagonal of (Kalman gain * C)
  10.  %  -    grade   = Gradient of E0 wrt params in PID
  11.  %  -    rowinq  = Vector giving rows in F in which parameters occur, else [0]
  12.  %  -    proc    = Scalar flag >0 if process noise is being used.
  13.  %
  14.  % Inputs :
  15.  %  -    p       = Parameter vector (row)
  16.  %  -    pid     = Row vector of indices of params in P to be ID'd. eg [1 3 6]
  17.  %  -    p2snam  = Name of user defined function converting P to system.
  18.  %                        e.g. P2SS . <Help ml_p2ss3> gives details.
  19.  %  -    perts   = Amount by which each parameter is perturbed to estimate
  20.  %                 gradients by finite differences. Noncritical- try .001-.0001
  21.  %  -    gg      = Innovations covariance matrix. You get the first guess.
  22.  %  -    uydata  - GLOBAL VARIABLE -- see MMLELIKE.M
  23.  %---------------------------------------------------------------------------
  24.  
  25. global uydata
  26. global grad
  27. global grade
  28. global hes
  29. global e0
  30. global rowinq
  31. global yest
  32. global inovt
  33. global wersum
  34. global rr
  35.  
  36. p2snamp=[p2snam,'(p)']; %                             ACCEPT ANY NAME FOR P2SS
  37. [a,phi,gam,c,d,q,x0,dt,rowinq]=eval(p2snamp);c0=c; %        GET NOMINAL SYSTEM
  38. npid=length(pid);[nm,nx]=size(c);[ndp,xx]=size(uydata); %       GET DIMENSIONS
  39. [nx,nu]=size(gam);num=nu+nm;nnorm=ndp;
  40. grade=ones(nx,npid); %                                      DIMENSION MATRICES
  41. proc=sum(diag(q))>0; %       USER SETS q TO ZERO FOR NO KALMAN GAIN
  42. %-------------------YEST,INOV,RR,LLF FOR NOMINAL P----------------------------
  43. if proc==0,
  44.       k=zeros(nx,nm);
  45. else
  46.       k=lqe(a,eye(nx),c,q*q'/dt/dt,gg)*dt; % EQN 30,MAINE & ILIFF, pp588-579
  47. end
  48. inovt=uydata(:,nu+1:num); % = TEMPORARY STORAGE FOR Y_MEAS
  49. yest=dlsim(phi*(eye(nx)-k*c),... %  SIAM J. Appl. Math. Vol41, No3, Dec81
  50.      [gam-phi*k*d,phi*k],c,[d,0*ones(nm)],uydata,x0);
  51.  
  52. inovt=inovt-yest;
  53. rr=inovt'*inovt/nnorm; %            INNOVATIONS AND SAMPLE COVARIANCE
  54. rtggit=chol(inv(gg))'; %    OUTPUT VECTOR WEIGHTING FOR COST FUNCTION
  55. inovt=inovt*rtggit;yest=yest*rtggit; %             WEIGHT  YEST,INOVT
  56. %-------------------------------------------------------------------
  57.  
  58. e0=diag(k*c); %                    FOR CONSTRAINING DIAG(E0) < EYE
  59. wersum=sum(sum(inovt.*inovt))/nnorm/nm;%        WEIGHTED ERROR SUM
  60. llf=ndp/2*(wersum*nm-2*log(prod(diag(rtggit))));%       FAST DET
  61. %----------------------------NOW GET GRAD, HES, OF COST WRT PARAMS
  62. psav=p;
  63. phipid=[];gampid=[];ctpid=[];dtpid=[];xpid=[];
  64.  
  65. k=zeros(nx,nm);
  66. for jj=1:npid; %        COMPUTE AND STACK KF MATRICES FOR ALL PERTURBATIONS
  67.   p(pid(jj))=p(pid(jj))+perts(pid(jj));
  68.   [a,phi,gam,c,d,q,x0,dt,rowinq]=eval(p2snamp); %      GET PERTURBED SYSTEM
  69.   if proc ~ 0; %                      KALMAN FILTER IF PROCESS NOISE
  70. %      k=lqe(a,eye(nx),c,q*q'/dt/dt,gg)*dt; %   CONT LQE FOR DISC! (SEE REF)
  71.     [zzv,zzd]=eig([a' c'/gg*c;q*q'/dt/dt -a]);% THESE 5 LINES EQUIV TO LQE
  72.     zzd=diag(zzd);[zzd,index]=sort(real(zzd));
  73.     chi=zzv(1:nx,index(1:nx));
  74.     lambda=zzv(nx+1:2*nx,index(1:nx));zzs=-real(lambda/chi);
  75.     k=gg\c*zzs;k=k'*dt;
  76.   end;
  77.   phipid=[phipid;phi*(eye(nx)-k*c)];
  78.   gampid=[gampid;[gam-phi*k*d,phi*k]];
  79.   dtpid=[dtpid [d,0*ones(nm)]'*rtggit];
  80.   grade(:,jj)=(diag(k*c)-e0)/perts(pid(jj)); %        GRADIENT OF DIAG(E=K*C)
  81. %
  82.   ctpid=[ctpid c'*rtggit]; %       STACK C' IN ROWS
  83.   xpid=[xpid;x0]; %                STACK INITIAL CONDITIONS IN ROWS
  84.   p=psav;
  85.   fprintf(' ')
  86. end;fprintf('.')
  87.  
  88. %PHI/GAM/CT/DT....PID MATRICES LOADED WITH ALL KALMAN FILTERS, XPID WITH IC's
  89.  
  90. hes=zeros(npid);
  91. grad=zeros(npid,1);
  92. onepid=ones(1,npid);fstn=1;
  93. maxel=4094/2;%                  REDUCING THIS SLOWS ALGO, USES LESS MEMORY
  94. %                                YOU CAN MAKE IT GLOBAL BEFORE CALLING MMLE
  95.  
  96. blocklen=fix(min([maxel/num,maxel/nm/npid]));%   MAX BLOCK LENGTH (MEMORY!)
  97.  
  98. fstn=1;
  99. while fstn<=ndp, %       RUN KF AND SUM GRAD, HES IN TIME-BLOCKS (MEMORY!)
  100.    lstn=min([ndp,fstn+blocklen-1]); %               END CURRENT DATA BLOCK
  101.    len=lstn-fstn+1;
  102.    yes=yest(fstn:lstn,:)';yes=yes(:); %      LONG COL OF NOMINAL KF OUTPUT
  103.    gradz=yes*onepid;% NOMINAL ESTIMATE
  104.    for i=1:npid           % GET GRADIENT OF INNOVATIONS WRT EACH PARAMETER
  105.        xrows=[1+(i-1)*nx:i*nx]; %     ROWS/COLS STORING THIS KF'S MATRICES
  106.        ycols=[1+(i-1)*nm:i*nm];
  107.        a=phipid(xrows,:);b=gampid(xrows,:);
  108.        x=ltitr(a,b,uydata(fstn:lstn,:),xpid(i,:)); %    PROPAGATE KF STATES
  109.        xpid(i,:)=x(len,:)*a'+uydata(lstn,:)*b'; %          COMPUTE NEXT IC.
  110.        x=x*ctpid(:,ycols)+uydata(fstn:lstn,:)*dtpid(:,ycols); %  KF OUTPUTS
  111.        x=x';
  112.        gradz(:,i)=gradz(:,i)-x(:);%  SUBTRACT COL VECTORS IN A LONG COL
  113.     end,
  114.     smes=(uydata(fstn:lstn,nu+1:num)*rtggit)';
  115.     grad=grad+gradz'*(smes(:)-yes); % ACCUMULAATE GRAD. (INNOV IN PARENTHESES)
  116.     hes=hes+gradz'*gradz; %   ACCUMULATE HES
  117.     fstn=fstn+blocklen; %     START OF NEXT BLOCK
  118.     fprintf(' ') %            SHOW SOME LIFE
  119. end
  120. grad=grad./perts(pid)';ans=diag(exp(-log(perts(pid))));
  121. hes=ans*hes*ans; %       ACCOUNT FOR SIZE OF PERT
  122. fprintf(':');disp(' ')
  123. %------------------------------------------------------------end mmlegrad.m
  124.