function ADEM_visual
% DEM demo for active inference (i.e. action-perception optimisation of free
% energy).  This simulation calls on spm_ADEM to simulate visual sampling of
% the world and demonstrate retinal stabilisation or visual tracking. We
% simulate a simple 2-D plaid stimulus and subject it to an exogenous
% perturbations. By employing tight and broad priors on the location of the
% stimulus, we can show that action does and does not explain away the visual
% consequences of the perturbation (i.e., the movement is seen or not).  This
% illustrates how one can reframe stabilisation or tracking in terms of
% sampling sensory input to ensure conditional expectations are met; and
% how these expectations are shaped by prior expectations.
%__________________________________________________________________________
% Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
 
% Karl Friston
% $Id: ADEM_visual.m 4826 2012-08-03 16:45:09Z karl $
 
 
% recognition model (M)
%==========================================================================
M             = struct;
M(1).E.s      = 1;                          % smoothness
M(1).E.n      = 4;                          % smoothness
M(1).E.d      = 2;                          % smoothness
 
% level 1:
% the hidden states correspond to horizontal and vertical displacement of a
% Gaussian modulated plaid
%--------------------------------------------------------------------------
pE      = struct;
pE.f    = [-1  4   ;                        % the Jacobian for the
           -2 -1]/8;                        % hidden states (x and y)
pE.h    = [1; 0];                           % input parameters
M(1).x  = [0; 0];
M(1).f  = inline('P.f*x + P.h*v','x','v','P');
M(1).g  = inline('ADEM_plaid(x)','x','v','P');
M(1).pE = pE;                               % prior expectation
M(1).V  = exp(4);                           % error precision
M(1).W  = exp(8);                           % error precision
 
% level 2:
% a perturbation to x(1)
%--------------------------------------------------------------------------
M(2).v  = 0;                                % inputs
M(2).V  = exp(-8);                          % flat priors on movement
 
% Generative model (G)
%==========================================================================
G       = M;
pE.a    = [1; 0];                           % action parameter
 
% first level
%--------------------------------------------------------------------------
G(1).f  = inline('P.f*x + P.h*v + P.a*a','x','v','a','P');
G(1).g  = inline('ADEM_plaid(x)','x','v','a','P');
G(1).pE = pE;                               % prior expectation
G(1).V  = exp(16);                          % error precision
G(1).W  = exp(16);                          % error precision
G(1).U  = exp(2);                           % error precision

% second level
%--------------------------------------------------------------------------
G(2).a  = 0;                                % action
G(2).V  = exp(16);
 
 
% generate and invert
%==========================================================================
N       = 64;                               % length of data sequence
C       = exp(-((1:N) - 12).^2/(4.^2));     % this is the perturbation
DEM.G   = G;
DEM.M   = M;
DEM.C   = C;
DEM     = spm_ADEM(DEM);
 
% overlay true values
%--------------------------------------------------------------------------
spm_DEM_qU(DEM.qU,DEM.pU)
 
 
% repeat with informative priors
%--------------------------------------------------------------------------
DEM.M(2).V  = exp(16);
ADEM        = spm_ADEM(DEM);
spm_DEM_qU(ADEM.qU,ADEM.pU)
 
% plot results
%==========================================================================
spm_figure('GetWin','Figure 1');
x   = [-4 4];
 
subplot(3,1,1)
imagesc(x,x,ADEM_plaid([0; 0],128))
axis square
title('stimulus','FontSize',16)
x   = linspace(-3.5,3.5,6);
hold on
plot(kron(x.^0,x),kron(x,x.^0),'.w','MarkerSize',16), hold off
 
subplot(3,2,3)
plot(DEM.pU.x{1}(1,:),DEM.pU.x{1}(2,:),DEM.qU.x{1}(1,:),DEM.qU.x{1}(2,:),'r')
axis square
title('under flat priors','FontSize',16)
xlabel('displacement','FontSize',14)
legend({'real', 'perceived'})
axis([-1 1 -1 1]*2)
 
subplot(3,2,4)
plot(ADEM.pU.x{1}(1,:),ADEM.pU.x{1}(2,:),ADEM.qU.x{1}(1,:),ADEM.qU.x{1}(2,:),'r')
axis square
title('under tight priors','FontSize',16)
xlabel('displacement','FontSize',14)
axis([-1 1 -1 1]*2)
 
subplot(3,1,1)
hold on
plot(ADEM.pU.x{1}(1,:),ADEM.pU.x{1}(2,:),ADEM.qU.x{1}(1,:),ADEM.qU.x{1}(2,:),'r')
hold off
 
subplot(3,2,5)
plot([1:N],DEM.qU.a{2},[1:N],DEM.qU.v{2},[1:N],DEM.pU.v{2})
axis square
title('action and cause','FontSize',16)
xlabel('time','FontSize',14)
axis([1 N -1 1])
 
subplot(3,2,6)
plot([1:N],ADEM.qU.a{2},[1:N],ADEM.qU.v{2},[1:N],ADEM.pU.v{2})
axis square
title('action and cause','FontSize',16)
xlabel('time','FontSize',14)
axis([1 N -1 1])
legend({'action', 'perceived perturbation', 'true perturbation'})
