forked from lawrennd/gp
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgpUpdateKernels.m
92 lines (82 loc) · 2.88 KB
/
gpUpdateKernels.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 model = gpUpdateKernels(model, X, X_u)
% GPUPDATEKERNELS Update the kernels that are needed.
% FORMAT
% DESC updates any representations of the kernel in the model
% structure, such as invK, logDetK or K.
% ARG model : the model structure for which kernels are being
% updated.
% RETURN model : the model structure with the kernels updated.
%
% DESC updates any representations of the kernel in the model
% structure, such as invK, logDetK or K.
% ARG model : the model structure for which kernels are being
% updated.
% ARG X : the input locations for update of kernels.
% ARG X_u : the inducing input locations.
% RETURN model : the model structure with the kernels updated.
%
% SEEALSO : gpExpandParam, gpCreate
%
% COPYRIGHT : Neil D. Lawrence, 2005, 2006, 2007, 2009
% GP
jitter = 1e-6;
switch model.approx
case 'ftc'
% Long term should allow different kernels in each dimension here.
model.K_uu = kernCompute(model.kern, X);
if ~isfield(model, 'isSpherical') || model.isSpherical
% Add inverse beta to diagonal if it exists.
if isfield(model, 'beta') && ~isempty(model.beta)
model.K_uu(1:size(model.K_uu, 1)+1:end) = ...
model.K_uu(1:size(model.K_uu, 1)+1:end) + 1./model.beta';
end
[model.invK_uu, U] = pdinv(model.K_uu);
model.logDetK_uu = logdet(model.K_uu, U);
else
for i = 1:model.d
if isfield(model, 'beta') && ~isempty(model.beta)
if size(model.beta, 2) == model.d
betaAdd = model.beta(:, i)';
else
betaAdd = model.beta;
end
if isfield(model, 'beta') && ~isempty(model.beta)
model.K_uu(1:size(model.K_uu, 1)+1:end) = ...
model.K_uu(1:size(model.K_uu, 1)+1:end) + 1./betaAdd;
end
end
ind = gpDataIndices(model, i);
[model.invK_uu{i}, U] = pdinv(model.K_uu(ind, ind));
model.logDetK_uu(i) = logdet(model.K_uu(ind, ind), U);
end
end
case {'dtc', 'dtcvar', 'fitc', 'pitc'}
model.K_uu = kernCompute(model.kern, X_u);
if ~isfield(model.kern, 'whiteVariance') || model.kern.whiteVariance == 0
% There is no white noise term so add some jitter.
model.K_uu = model.K_uu ...
+ sparseDiag(repmat(jitter, size(model.K_uu, 1), 1));
end
model.K_uf = kernCompute(model.kern, X_u, X);
[model.invK_uu, model.sqrtK_uu] = pdinv(model.K_uu);
model.logDetK_uu = logdet(model.K_uu, model.sqrtK_uu);
end
switch model.approx
case {'dtcvar', 'fitc'}
model.diagK = kernDiagCompute(model.kern, X);
case {'pitc'}
if ~isfield(model, 'isSpherical') || model.isSpherical
for i = 1:length(model.blockEnd)
ind = gpBlockIndices(model, i);
model.K{i} = kernCompute(model.kern, X(ind, :));
end
else
for j = 1:model.d
for i = 1:length(model.blockEnd)
ind = gpDataIndices(model, j, i);
model.K{i, j} = kernCompute(model.kern, X(ind, :));
end
end
end
end
model = gpUpdateAD(model, X);