📄 spm_mar.m.svn-base
字号:
function [mar,y,y_pred] = spm_mar (X,p,prior)
% Bayesian Multivariate Autoregressive Modelling
% FORMAT [mar,y,y_pred] = spm_mar (X,p,prior)
%
% Matrix of AR coefficients are in form
% x_t = -a_1 x_t-1 + -a_2 x_t-2 + ...... + -a_p x_t-p
% where a_k is a d-by-d matrix of coefficients at lag k and x_t-k's are
% vectors of a d-variate time series.
%
% X T-by-d matrix containing d-variate time series
% p Order of MAR model
% prior Prior on MAR coefficients (see marprior.m)
%
% mar.lag(k).a AR coefficient matrix at lag k
% mar.noise_cov Estimated noise covariance
% mar.F Free energy of model
% mar.wmean MAR coefficients stored in a matrix
% y Target values
% y_pred Predicted values
%___________________________________________________________________________
% Copyright (C) 2007 Wellcome Department of Imaging Neuroscience
% Will Penny
% $Id$
d=size(X,2); % dimension of time series
N=size(X,1); % length of time series
% Embedding of multiple time series
% giving x=[(x1(t-p) x2(t-p) .. xd(t-p)) (x1(t-p+1) x2(t-p+1)..xd(t-p+1)) ...
% (x1(t-1) x2(t-1) .. xd(t-1))] on each row
x=[];
for i=1:p,
tmpx=X(i:N-p+i,:);
x=[x,tmpx];
end
% Reorder columns of x
% giving x=[(x1(t-1) x2(t-1) .. xd(t-1)) (x1(t-2) x2(t-2)..xd(t-2)) ...
% (x1(t-p) x2(t-p) .. xd(t-p))] on each row
for i=1:p
start=(i-1)*d+1;
stop=start+d-1;
chunk(i).x=x(:,[start:1:stop]);
end
x=[];
for i=p:-1:1,
x=[x chunk(i).x];
end
% and remove last row
Nrows=size(x,1);
x=x(1:Nrows-1,:);
y=X([p+1:1:N],:);
k=p*d*d;
if nargin < 3 | isempty(prior)
prior.type='global';
prior.groups=1;
prior.group(1).index=ones(1,k);
end
% Compute terms that will be used many times
xtx=x'*x;
yty=y'*y;
inv_xtx=inv(xtx);
xty=x'*y;
vec_xty=xty(:);
% Get maximum likelihood solution
w_ml = pinv(-1*x)*y;
% Swap signs to be consistent with paper (swap back at end !)
w_ml=-1*w_ml;
y_pred = x*w_ml;
e=y-y_pred;
%noise_cov=(e'*e)/(N-k);
noise_cov=(e'*e)/N;
sigma_ml=kron(noise_cov,inv_xtx);
% Priors on alpha(s)
b_alpha_prior=1000;
c_alpha_prior=0.001;
mean_alpha_prior=b_alpha_prior*c_alpha_prior;
% Initialise
w_mean=w_ml;
w_cov=sigma_ml;
max_iters=32;
w=zeros(p*d,d);
tol=0.0001;
for it=1:max_iters,
% Update weight precisions
for j=1:prior.groups,
Ij=diag(prior.group(j).index);
kj=sum(prior.group(j).index);
E_wj=0.5*w_mean(:)'*Ij*w_mean(:);
b_alpha=E_wj+0.5*trace(Ij*w_cov*Ij)+(1/b_alpha_prior);
group(j).b_alpha=1/b_alpha;
group(j).c_alpha=0.5*kj+c_alpha_prior;
group(j).mean_alpha=group(j).b_alpha*group(j).c_alpha;
group(j).E_w=E_wj;
end
yy_pred=x*w_mean;
ee=y-yy_pred;
E_d_av=ee'*ee;
Omega = spm_get_omega (p,d,w_cov,xtx);
E_d_av=E_d_av+Omega;
% Update noise precision posterior
B=E_d_av;
a=N;
mean_lambda=a*inv(B);
ilambda=(1/a)*B;
prior_cov=zeros(k,k);
for j=1:prior.groups,
Ij=diag(prior.group(j).index);
prior_cov=prior_cov+(1/group(j).mean_alpha)*Ij;
end
% Convergence criterion
old_w=w;
w=w_mean;
if (it<=2)
w=w_mean;
else
change=norm(w(:)-old_w(:))/k;
disp(sprintf('Iteration %d Delta_w=%1.6f',it,change));
if change < tol
break;
end
end;
% Update weight posterior
data_precision=kron(mean_lambda,xtx);
prior_prec=zeros(k,k);
for j=1:prior.groups,
Ij=diag(prior.group(j).index);
prior_prec=prior_prec+group(j).mean_alpha*Ij;
end
w_cov=inv(data_precision+prior_prec);
vec_w_mean=w_cov*data_precision*w_ml(:);
w_mean=reshape(vec_w_mean,p*d,d);
end
% Compute Negative Free Energy
kl_alpha=0;
for j=1:prior.groups,
kl_alpha=kl_alpha+spm_kl_gamma(group(j).b_alpha,group(j).c_alpha,b_alpha_prior,c_alpha_prior);
end
kl_weights=spm_kl_eig_normal(w_mean(:),w_cov,prior_cov);
lga=spm_lg_gamma(d,0.5*a);
acc=-0.5*N*log(det(B));
f_m=acc-kl_weights-kl_alpha+lga;
disp(sprintf('Iteration %d Acc=%1.3f KL_w=%1.3f KL_alpha=%1.3f LogGena=%1.3f Fm=%1.3f',it,acc,kl_weights,kl_alpha,lga,f_m));
% Load up returning data structure
mar.p=p;
% This is the ML estimate
mar.noise_cov=noise_cov;
mar.sigma_ml=sigma_ml;
mar.w_cov=w_cov;
mar.group=group;
mar.prior=prior;
mar.mean_lambda=mean_lambda;
mar.fm=f_m;
mar.bic=-0.5*N*log(det(B))-0.5*k*log(N);
mar.iterations=it;
for i=1:p,
start=(i-1)*d+1;
stop=(i-1)*d+1+(d-1);
% Transpose and swap signs for compatibility with spectral estimation function
mar.lag(i).a=-w_mean(start:stop,:)';
end
% Swap signs for compatibility with spectral estimation function
mar.wmean=-w_mean;
% Compute the effective degrees of freedom
gamma=k;
for j=1:prior.groups,
Ij=diag(prior.group(j).index);
gamma=gamma-group(j).mean_alpha*trace(Ij*w_cov*Ij);
end
mar.gamma=gamma;
mar.d=d;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -