sarmabat.m

来自「This functions computes SARMA or multipl」· M 代码 · 共 137 行

M
137
字号
function [mbest,minaic,pbest,qbest,Pbest,Qbest]=sarmabat(x,pvec,qvec,Pvec,Qvec,T)
%
%   [mbest,minaic,pbest,qbest,Pbest,Qbest]=sarmabat(x,pvec,qvec,Pvec,Qvec,T)
%
% This functions computes SARMA or multiplicative (p,q) x (P,Q) models for 
% (p,q,P,Q) in (pvec x qvec x Pvec x Qvec); it returns the best according to AIC
% where AIC has been modified to account for fixed parameters
%
% x = input data
% pvec = vector of p's ; set pvec=[0] for no AR
% qvec = vector of q's; set qvec=0[] for no MA
% Pvec = vector of P's
% Qvec = vector of Q's
% T period for multiplicative model

% now estimate ARMA model; ARMAX is AX=BU + Ce so identify phi with A and theta with C
nx=length(x);
np=length(pvec);
nP=length(Pvec);
nq=length(qvec);
nQ=length(Qvec);
aicsave=-99*ones(np,nP,nq,nQ);
fpesave=-99*ones(np,nP,nq,nQ);
minaic=1e+6;
for pp=1:np     
    p=pvec(pp);
    for PP=1:nP
        P=Pvec(PP);
        for qq=1:nq
            q=qvec(qq);
            for QQ=1:nQ
                Q=Qvec(QQ);
                if p+P+q+Q ~=0
                    %  now we must set up an initial model structure and freeze the correct coeffs
                    % to do this we will first use dummy coefficients of 1 everywhere
                    phi=ones(1,p+1);      % phi becomes A for matlab 
                    Phi=ones(1,P+1);
                    PhiT=zeros(1,1+(length(Phi)-1)*T);
                    indexes=[1:T:length(PhiT)];
                    PhiT(indexes)=Phi;  % PhiT now has sparse ones
                    
                    theta=ones(1,q+1);    % theta becomes C for matlab
                    Theta=ones(1,Q+1);
                    ThetaT=zeros(1,1+(length(Theta)-1)*T);
                    indexes=[1:T:length(ThetaT)];
                    ThetaT(indexes)=Theta;
                    
                    % now build the product polynomials
                    thetaM=conv(theta,ThetaT);
                    phiM=conv(phi,PhiT);
                    
                    % this just changes to matlab notation to help programming
                    A=phiM; % starting poly
                    Bdum=[];
                    C=thetaM; % starting poly
                    Ddum=[];
                    
                    mi=idpoly(A,Bdum,C,Ddum); % A is phi and C is theta here
                    
                    zphiM=find(mi.a==0);    % addresses where phiM==0
                    pset=[];                % pset is the collection of parameter numbers to be frozen
                    if length(zphiM)     
                        zphiM=zphiM-1;      % adjust down as leading 1 does not count
                        pset=[pset zphiM];  
                    end
                    zthetaM=find(mi.c==0);  % addresses where thetaM==0
                    if length(zthetaM)
                        zthetaM=zthetaM-1+mi.na;    % subtract 1 as leading 1 does not count and
                        pset=[pset zthetaM];        % add the number of parameters from A=phiM    
                    end                             % that can be changed (the a part of mi.par=length(mi.a)-1)
                    % now set the starting parameters to zero except the leading ones
                    A=zeros(size(phiM));
                    A(1)=1;
                    C=zeros(size(thetaM));
                    C(1)=1;
                    mi=idpoly(A,Bdum,C,Ddum);  % set mi again 
                    set(mi,'FixedParameter',pset);   % set the fixed places by number
                    
                    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% now finally ready to do armax
                    
                    m=armax(x,mi);          % m is a structure with the model stuff in it
                    resids=pe(m,x);         % pe returns the prediction errors
                    nres=length(resids);
                    rhores=acf(resids,1); % this returns the acf normalized by the variance
                    nrho=length(rhores);             
                    % next compute the Ljung - Box statistic and P-values
                    deltak=floor(nrho/10)+1;
                    kvec=[p+q+P*T+Q*T+1:deltak:p+q+P*T+Q*T+1+4*deltak];
                    for kk=1:5
                        Qsum=0;
                        for j=2:kvec(kk)+1
                            Qsum=Qsum+(rhores(j).^2)/(nx-j);
                        end
                        Qsum=nx*(nx-1)*Qsum;
                        ljpv(kk)=1-chi2cdf(Qsum,kvec(kk)-p-q-P-Q);  % df=kvec(kk)-less no. pars
                    end
                    
                    fpeval=fpe(m);
                    fpesave(pp,PP,qq,QQ)=fpeval;

                    nval = m.EstimationInfo.DataLength;
                    vval = m.EstimationInfo.LossFcn;
                    totalpars=m.na+m.nc;  % BD adds 1 here, probably for the mean; we omit for now
                    netpars=totalpars-length(m.fix);
                    aicval=log(vval)+2*netpars/nval;
                    % aicval=aic(m); % the standard way not taking fixed ones into account
                    aicsave(pp,PP,qq,QQ)=aicval;
                    bicval=log(vval)+netpars*log(nval)/nval;
                    aiccval=log(vval)+2*netpars/(nval-2*netpars); % my best understanding of adapting
                    if aicval < minaic                            % BD to Choi and matlab
                        minaic=aicval; % save the min
                        pbest=p;
                        qbest=q;
                        Pbest=P;
                        Qbest=Q;
                        mbest=m;
                        % put this here to only prints the ones that improve
                        %disp(sprintf('(p,q)(P,Q)=(%d,%d)(%d,%d) aic=%g  fpe=%g',p,q,P,Q,aicval,fpeval));
                    end
                    % next is routine print
                    disp(sprintf('(p,q)(P,Q)=(%d,%d)(%d,%d) aic=%g  aicc=%g bic=%g fpe=%g',...
                        p,q,P,Q,aicval,aiccval,bicval,fpeval));

                    % next was for debugging
                    %disp(sprintf('(p,d,q)(P,D,Q)=(%d,%d,%d)(%d,%d,%d) aic=%g  fpe=%g',p,d,q,P,D,Q,...
                     %   aicsave(pp,PP,qq,QQ),fpesave(pp,PP,qq,QQ)));
                    LJPV=[kvec;ljpv];
                    % next is routine print
                    %disp(sprintf('Ljung-Box P-values : '));
                    %disp(sprintf('  K=%d P-v=%6.4f \n',LJPV(:)));
                    

                end % if p+P+q+Q 
            end % QQ loop
        end     % qq loop
    end         % PP loop
end             % pp loop

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?