-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsp_infFRK.m
52 lines (46 loc) · 2.46 KB
/
sp_infFRK.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
function [post nlZ dnlZ] = infFRK(hyp, mean, cov, lik, x, y)
% Exact inference for a GP with Gaussian likelihood. Compute a parametrization
% of the posterior, the negative log marginal likelihood and its derivatives
% w.r.t. the hyperparameters. See also "help infMethods".
%
% Copyright (c) by Carl Edward Rasmussen and Hannes Nickisch, 2014-12-08.
% File automatically generated using noweb.
%
% See also INFMETHODS.M.
if iscell(lik), likstr = lik{1}; else likstr = lik; end
if ~ischar(likstr), likstr = func2str(likstr); end
if ~strcmp(likstr,'likGauss') % NOTE: no explicit call to likGauss
error('Exact inference only possible with Gaussian likelihood');
end
[n, D] = size(x);
K = feval(cov{:}, hyp.cov, x); % evaluate covariance matrix
m = feval(mean{:}, hyp.mean, x); % evaluate mean vector
sn2 = exp(2*hyp.lik); % noise variance of likGauss
if sn2<1e-6 % very tiny sn2 can lead to numerical trouble
L = chol(K+sn2*eye(n)); sl = 1; % Cholesky factor of covariance with noise
pL = -solve_chol(L,eye(n)); % L = -inv(K+inv(sW^2))
else
L = chol(K/sn2+eye(n)); sl = sn2; % Cholesky factor of B
pL = L; % L = chol(eye(n)+sW*sW'.*K)
end
alpha = solve_chol(L,y-m)/sl;
post.alpha = alpha; % return the posterior parameters
post.sW = ones(n,1)/sqrt(sn2); % sqrt of noise precision vector
post.L = pL;
if nargout>1 % do we want the marginal likelihood?
nlZ = (y-m)'*alpha/2 + sum(log(diag(L))) + n*log(2*pi*sl)/2; % -log marg lik
%[afm]fprintf('nlZ = %.2f: %.2f %.2f %.2f ',nlZ, (y-m)'*alpha/2,sum(log(diag(L))),n*log(2*pi*sl)/2)
%fprintf(' lik = %.2f cov =[%.2f %.2f] n(alpha) = %.2f\n',sn2, hyp.cov(1),hyp.cov(2), norm(alpha))
%fprintf(' lik = %.2f n(alpha) = %.2f\n',sn2, norm(alpha))
if nargout>2 % do we want derivatives?
dnlZ = hyp; % allocate space for derivatives
Q = solve_chol(L,eye(n))/sl - alpha*alpha'; % precompute for convenience
for i = 1:numel(hyp.cov)
dnlZ.cov(i) = sum(sum(Q.*feval(cov{:}, hyp.cov, x, [], i)))/2;
end
dnlZ.lik = sn2*trace(Q);
for i = 1:numel(hyp.mean),
dnlZ.mean(i) = -feval(mean{:}, hyp.mean, x, i)'*alpha;
end
end
end