Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
probml
GitHub Repository: probml/pyprobml
Path: blob/master/notebooks/book2/12/rjmcmc_rbf/radialMerge.m
1193 views
1
function [k,mu,M,aMerge,rMerge] = radialMerge(aMerge,rMerge,k,mu,M,delta,x,y,hyper,t,bFunction,sigStar,walkInt);
2
% PURPOSE : Performs the split move of the reversible jump MCMC algorithm.
3
% INPUTS : - aMerge: Number of times the merge move has been accepted.
4
% - rMerge: Number of times the merge move has been rejected.
5
% - k : Number of basis functions.
6
% - mu : Basis functions centres.
7
% - M : Regressors matrix.
8
% - delta : Signal to noise ratio.
9
% - x : Input data.
10
% - y : Target data.
11
% - t : Current time step.
12
% - bFunction: Type of basis function.
13
% - sigStar: Split/merge move parameter.
14
% - walkInt: Parameter defining the compact set from which mu is sampled.
15
16
% AUTHOR : Nando de Freitas - Thanks for the acknowledgement :-)
17
% DATE : 21-01-99
18
19
if nargin < 12, error('Not enough input arguments.'); end
20
[N,d] = size(x); % N = number of data, d = dimension of x.
21
[N,c] = size(y); % c = dimension of y, i.e. number of outputs.
22
insideMerge=1;
23
uD=rand(1);
24
25
% INITIALISE H AND P MATRICES:
26
% ===========================
27
invH=zeros(k(t)+1+d,k(t)+1+d,c);
28
P=zeros(N,N,c);
29
invHproposal=zeros(k(t)+d,k(t)+d,c);
30
Pproposal=zeros(N,N,c);
31
for i=1:c,
32
invH(:,:,i) = (M'*M + (1/delta(t,i))*eye(k(t)+1+d));
33
P(:,:,i) = eye(N) - M*inv(invH(:,:,i))*M';
34
end;
35
36
% PROPOSE FIRST BASIS FUNCTION:
37
% ============================
38
position = unidrnd(length(mu{t}(:,1)),1,1);
39
mu1 = mu{t}(position,:);
40
dist = zeros(k(t),1);
41
for i=1:k(t),
42
if i== position,
43
dist(i) = inf;
44
else
45
dist(i)=norm(mu1-mu{t}(i,:)); % Euclidean distance;
46
end;
47
end;
48
49
% PROPOSE SECOND BASIS FUNCTION:
50
% =============================
51
position2 = find(dist == min(dist));
52
mu2 = mu{t}(position2,:);
53
mumg = .5*(mu1 + mu2);
54
55
% extract components:
56
proposalPos1 = position + d+1;
57
if (proposalPos1==d+1+k(t)),
58
Mproposal = [M(:,1:proposalPos1-1)];
59
else
60
Mproposal = [M(:,1:proposalPos1-1) M(:,proposalPos1+1:k(t)+d+1)];
61
end;
62
if position2>position,
63
proposalPos2 = position2 + d+1;
64
if (proposalPos2==d+1+k(t)),
65
Mproposal = [Mproposal(:,1:proposalPos2-2)];
66
else
67
Mproposal = [Mproposal(:,1:proposalPos2-2) Mproposal(:,proposalPos2:k(t)+d)];
68
end;
69
elseif position2<position,
70
proposalPos2 = position2 + d+1;
71
Mproposal = [Mproposal(:,1:proposalPos2-1) Mproposal(:,proposalPos2+1:k(t)+d)];
72
else
73
error('Something wrong with merge move');
74
end;
75
% add merged component:
76
Mproposal = [Mproposal feval(bFunction,mumg,x)];
77
for i=1:c,
78
invHproposal(:,:,i) = (Mproposal'*Mproposal + inv(delta(t,i))*eye(k(t)+d));
79
Pproposal(:,:,i) = eye(N) - Mproposal*inv(invHproposal(:,:,i))*Mproposal';
80
end;
81
82
% PERFORM A MERGE MOVE:
83
% ====================
84
Jacobian = inv(sigStar);
85
ratio= Jacobian* prod(walkInt) * k(t) * inv(k(t)-1) * sqrt(delta(t,1)) * sqrt((det(invH(:,:,1)))/(det(invHproposal(:,:,1)))) * ((hyper.gamma+y(:,1)'*P(:,:,1)*y(:,1))/(hyper.gamma + y(:,1)'*Pproposal(:,:,1)*y(:,1)))^((hyper.v+N)/2);
86
for i=2:c,
87
ratio= ratio * sqrt(delta(t,i)) * sqrt((det(invH(:,:,i)))/(det(invHproposal(:,:,i)))) * ((hyper.gamma+y(:,i)'*P(:,:,i)*y(:,i))/(hyper.gamma + y(:,i)'*Pproposal(:,:,i)*y(:,i)))^((hyper.v+N)/2);
88
end;
89
acceptance = min(1,ratio);
90
if min(dist)<2*sigStar
91
acceptance = 0; % To ensure reversibility.
92
end;
93
94
% METROPOLIS-HASTINGS STEP:
95
% ========================
96
if (uD<acceptance),
97
previousMu = mu{t};
98
if (proposalPos1==(1+d+1)),
99
muTrunc = [previousMu(2:k(t),:)];
100
elseif (proposalPos1==(1+d+k(t))),
101
muTrunc = [previousMu(1:k(t)-1,:)];
102
else
103
muTrunc = [previousMu(1:proposalPos1-1-d-1,:); previousMu(proposalPos1-d-1+1:k(t),:)];
104
end;
105
if position2>position,
106
if (proposalPos2==(1+d+k(t))),
107
muTrunc = [muTrunc(1:k(t)-2,:)];
108
else
109
muTrunc = [muTrunc(1:proposalPos2-1-d-2,:); muTrunc(proposalPos2-d-1:k(t)-1,:)];
110
end;
111
elseif position2<position,
112
if (proposalPos2==(1+d+1)),
113
muTrunc = [muTrunc(2:k(t)-1,:)];
114
else
115
muTrunc = [muTrunc(1:proposalPos2-1-d-1,:); muTrunc(proposalPos2-d-1+1:k(t)-1,:)];
116
end;
117
else
118
error('Something wrong with merge move');
119
end;
120
mu{t+1} = [muTrunc; mumg];
121
k(t+1) = k(t)-1;
122
M=Mproposal;
123
aMerge=aMerge+1;
124
else
125
mu{t+1} = mu{t};
126
k(t+1) = k(t);
127
rMerge=rMerge+1;
128
M=M;
129
end;
130
131
132
133
134
135
136
137
138
139
140
141