-
Notifications
You must be signed in to change notification settings - Fork 0
/
slgetloglppmodelStep2.m
83 lines (68 loc) · 2.3 KB
/
slgetloglppmodelStep2.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
%slgetloglppmodelStep2.m
%
%
%
% author : steeve laquitaine
%purpose : get the logl of the pp model for parameters rho, tau and sigma
function [nglogl,fp] = slgetloglppmodelStep2(eta,nu,fp)
%get params. We substract 20 because we add 20 before entering the function
%to increase step size to 1 instead of actual parameter magnitude*5%. This
%make the search more explorative and speed up convergence
% fp = fp - 20;
% rho = fp(1);
% tau = fp(2:end-1);
% sigma = fp(end);
rho = fp(1) - 2*100;
tau = fp(2:end-1,1) - 1.4*100;
sigma = fp(end) - 1.8*100;
%sanity checks
if rho < 0 || rho >1 || any([rho;tau;sigma]<0)
nglogl = inf;
fprintf('%s \n', 'rho cannot be <0')
return
end
%# of channels
K = size(eta,1);
%# of voxels
Nv = size(nu,1);
%# of instances
Ni = size(nu,2);
%probability of p_eta given the model parameters
p_eta = mvnpdf(eta',zeros(1,K),sigma^2*eye(K,K));
%probability of nu given the model parameters
SIGMA = rho*(tau*tau')+ (1-rho)*times(eye(Nv,Nv),tau*tau');
%get probability of each nu. The covariance matrix SIGMA must be
%symmetric, positive definite so make sure SIGMA is a valid covariance
%matrix.
[~,err] = cholcov(SIGMA,0);
if err~=0
fprintf('%s \n', 'Sigma was not a valid covariance matrix: not >0 definite or symmetric')
nglogl = inf; return
elseif det(SIGMA)==0
fprintf('%s \n', 'Sigma is singular.')
nglogl = inf; return
end
p_nu = mvnpdf(nu',zeros(Ni,Nv),SIGMA);
%get the logl of the residual noises observed given the model params
%add different lapse rates lpss to deal with cases when data are never
%predicted by the model (nglogl = - inf) due to e.g., numerical
%precision. p_eta and p_nu do not have the same lapses because p_nu
%is typically much lower (most values are near 0) that p_eta because
%it is produced by a multivariate Gaussian on on many more dimensions
%than p_eta so we re-scale to improve the fit of rho
% lps_eta = 0;
% lps_nu = 0;
% p_eta = p_eta + lps_eta;
% p_nu = p_nu + lps_nu;
% nglogl = - sum(log(p_eta)+log(p_nu)) + lps_eta;
nglogl = - sum(log([p_eta(:); p_nu(:)]));
% hold on; plot(nglogl,'o')
% drawnow
%objective value Blow-up
if nglogl==-inf
dbstack
keyboard
end
%print
fprintf('%s %s %s %s \n','nglogl','rho','sigma','mean(tau)')
fprintf('%.005f %.006f %.006f %.006f \n',nglogl,rho,sigma,nanmean(tau))