-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnll_diff_is.m
93 lines (78 loc) · 3.36 KB
/
nll_diff_is.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
function [nllk] = nll_diff_is(x,trl,stiPar,config_pool,condIdx)
%--Difference model with both inference noise and sensory noise--
% This script uses Monte-Carlo simualtions to estimate response distribution
% and computes negative log-likelihood of the model.
% trl: structure containing data and config label
% required field: trl.estD, trl.estC, trl.config, trl.target_x
% stiPar: the structure containing stimulus locations
if ~exist('condIdx','var') || isempty(condIdx)
condIdx = ':';
end
simntrl = 10000; %sample size of MonteCarlo simulation per trial
ux = stiPar.ux;
uy = stiPar.uy;
sig_s = stiPar.sig_s;
nr = stiPar.nr;
ncat = stiPar.ncat;
%%
trl.estD = trl.estD(condIdx);
trl.estC = trl.estC(condIdx);
trl.config = trl.config(condIdx);
trl.target_x = trl.target_x(condIdx);
trl.target_y = trl.target_y(condIdx);
%%
k = sort([-Inf x(1:3) Inf]); %boundaries for 4-point confidence report
sig_x = 10^x(5); %sensory noise
alpha = 10^x(4); %Diricelet inference noise
lapse = x(6);
%%
pMat = cell(max(config_pool),1);
for config = config_pool
temp_s = trl.target_x(trl.config==config)';
ntrl = length(temp_s);
ux_vec = ux(config,:);
pMat{config} = nan(ncat, nr, ntrl);
sim_xMat = repmat(temp_s,simntrl,1) + randn(simntrl,ntrl)*sig_x; %measurement matrix: simntrl X ntrial
sim_xMat = repmat(sim_xMat,1,1,ncat); %measurement matrix: simntrl X ntrial X ncat
cMatx = kron(ux_vec',ones(simntrl*ntrl,1));
cMatx = reshape(cMatx,simntrl,ntrl,ncat);
%sim_lh = 1./sqrt(2*pi*sig_s^2) .* exp(-(sim_xMat - cMatx).^2 ./ (2*sig_s^2)); %likelihood: category X ntrial
%Run this part for 2 dimensions
temp_sy = trl.target_y(trl.config==config)';
uy_vec = uy(config,:);
sim_yMat = repmat(temp_sy,simntrl,1) + randn(simntrl,ntrl)*sig_x; %measurement matrix: simntrl X ntrial
sim_yMat = repmat(sim_yMat,1,1,ncat); %measurement matrix: simntrl X ntrial X ncat
cMaty = kron(uy_vec',ones(simntrl*ntrl,1));
cMaty = reshape(cMaty,simntrl,ntrl,ncat);
sig_p = sqrt(sig_s^2 + sig_x^2);
sim_lh = 1./(2*pi*sig_p*sig_p) .* exp(-((sim_xMat - cMatx).^2 +(sim_yMat - cMaty).^2) ./ (2*sig_p^2)); %likelihood: category X ntrial
%Inject Dirichlet decision noise
sim_post = bsxfun(@rdivide,sim_lh,sum(sim_lh,3));
sim_post = gamrnd(sim_post*alpha,1);
sim_post = bsxfun(@rdivide,sim_post,sum(sim_post,3));
[~,sim_d] = max(sim_post,[],3); %category decision
temp = sort(sim_post,3);
sim_c_diff = temp(:,:,end) - temp(:,:,end-1); %DIFF confidence
%Get probability map given a set of parameter value
[~,sim_r] = histc(sim_c_diff,k,1); %transform internal confidnece to 4-point confidence report based on k
sim_r = max(min(sim_r,4),1); %prevent some numerical issue (if ever happens)
for tr = 1:ntrl
for d = 1:ncat
for r = 1:nr
temp = sum(sim_d(:,tr)==d & sim_r(:,tr)==r)/simntrl;
pMat{config}(d,r,tr) = (1-lapse)*temp + lapse*(1/(ncat*nr));
end
end
end
pMat{config} = max(pMat{config},eps);
end
%%
nllk = 0;
for config = config_pool
[ncat,nr,ntrl] = size(pMat{config});
temp_D = trl.estD(trl.config==config);
temp_C = trl.estC(trl.config==config);
ind = sub2ind([ncat,nr,ntrl],temp_D,temp_C,(1:ntrl)');
llk = sum(log(pMat{config}(ind)));
nllk = nllk-llk;
end