-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrunMCMC_fixedT.m
More file actions
115 lines (92 loc) · 3.51 KB
/
Copy pathrunMCMC_fixedT.m
File metadata and controls
115 lines (92 loc) · 3.51 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
function [s_list,HS_list,tau,term_status] = ...
runMCMC_fixedT(costfun,T,s_init,mcmcOptions)
% runMCMC_fixedT: Runs MCMC sampling at a fixed temperature T.
%
% INPUT:
% - costfun: a function handle for the cost function, with one argument
% that is the domain state vector -- e.g., costfun(s)
% - T : the tempering factor / temperature (single number)
% - s_init: initial state (N-vector)
% - mcmcOptions: a struct variable that contains MCMC options
%
% OUTPUT:
% - s_list: the trajectory of domain states sampled in the MCMC chain
% [N M] array, where M is the final # samples in MCMC chain
% each column is a domain state
% - HS_list: the trajectory of cost function values in MCMC chain
% [M 1] vector
% - tau: the relaxation time of the chain
% - term_status: reports by what termination condition the program exits
% ------------------------------------------------------------------------
% Copyright 2018-2020 Min Hyeok Kim & Ji Hyun Bak
%% initialize
% initial state
s_set = s_init;
HS = costfun(s_set);
% unpack MCMC options
minIterMCMC = mcmcOptions.minIterMCMC;
maxIterMCMC = mcmcOptions.maxIterMCMC;
numSampAtEq = mcmcOptions.numSampAtEq; % final sampling after reaching equilibrium
if(isfield(mcmcOptions,'checkEvery'))
checkEvery = mcmcOptions.checkEvery; % set frequency to calculate tau
else
checkEvery = floor(maxIterMCMC/20); % default
end
% termination status
term_status = 0; % 0 means running
%% iterate
cnt = 0; % step index within a MCMC chain
tau = Inf; % initialize just in case of early termination
% track and store the MCMC chain
s_list = zeros(numel(s_init),maxIterMCMC);
HS_list = zeros(maxIterMCMC,1);
while 1
cnt=cnt+1;
% propose next move
s_set_cdd = single_mutation(s_set); % single mutation
s_set_cdd = renumber_clusters(s_set_cdd); % renumber domain indices
HSpos = costfun(s_set_cdd); % cost function at the proposed move
delta_HS = HSpos-HS; % the "energy" difference
acceptance_prob = exp(-delta_HS/T); % Metropolis-Hastings
% accept or reject the move
if(acceptance_prob>rand)
s_set = s_set_cdd; % move accepted: update cluster state
HS = HSpos;
else
% move rejected: keep previous state
end
s_list(:,cnt) = s_set; % store current sample
HS_list(cnt) = HS; % store current H value
% ==== Check for the stopping conditions: =========================
% update the relaxation time every once in a while
if(rem(cnt,checkEvery)==0 && cnt>=minIterMCMC)
autoC = myautocorr(HS_list(1:cnt),cnt-1); % autocorrelation function
diff1 = abs(autoC-exp(-1));
tau = find(diff1<1e-3,1,'first'); % relaxation time tau
if isempty(tau)
tau=inf;
end
% Stopping condition 1: enough samples at equilibrium
if(cnt>5*tau+numSampAtEq)
term_status = 1;
break;
end
end
% Stopping condition 2: iteration takes too long
if(cnt>maxIterMCMC)
% disp(' - premature end of MCMC. maxIter reached.')
term_status = 2;
break;
end
% Stopping condition -1: reports a single-domain state
if max(s_set)==1
term_status = -1; % (negative value: passes a stop signal for the entire SA)
break;
end
% =================================================================
end
% trim lists
idx_keep = (cnt-numSampAtEq)+(1:numSampAtEq);
s_list = s_list(:,idx_keep);
HS_list = HS_list(idx_keep,:);
end