Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions core/adapt_beta.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
fprintf(1,'------------------------------------------------------\n');
fprintf(1,' Adapting chain temperatures . . .\n');
% based on acceptance rate of all chains
swap_acceptance_rate = sum( swap_acceptance(:,(swap_idx-cfg.adapt_beta_interval+1):swap_idx), 2) ...
/ cfg.adapt_beta_interval;
recent_swaps = swap_acceptance(:,(swap_idx-cfg.adapt_beta_interval+1):swap_idx);
acceptances = sum( recent_swaps == 1, 2 );
attempts = sum( recent_swaps ~= 0, 2 );
swap_acceptance_rate = acceptances ./ max(attempts, 1);
old_beta = beta;
% chain 1 has fixed temperature. adjust chains in order of coolest to hottest.
% whenever a temperature changes, we proportionally increase the temperature of the hotter chains as well
Expand Down
6 changes: 4 additions & 2 deletions core/display_chains.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
end
fprintf(1,' swapping rates :\n' );
for chain_idx = 1:cfg.nchains-1
accepts = sum(swap_acceptance(chain_idx,1:swap_idx) == 1);
attempts = sum(swap_acceptance(chain_idx,1:swap_idx) ~= 0);
rate = accepts / max(attempts, 1);
fprintf(1,' %d <-> %d = %-8.3f\n', ...
chain_idx, chain_idx+1, ...
sum(swap_acceptance(chain_idx,:))/swap_idx );
chain_idx, chain_idx+1, rate );
end
else
for chain_idx = 1:cfg.nchains
Expand Down
52 changes: 38 additions & 14 deletions core/energy_gaussian.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
end
energy = -logprior;

% start integration timer
simtimer = tic;

% equillibrate, if required
if isfield(cfg, 'equilibrate_fcn')
[err,state,~] = cfg.equilibrate_fcn( params );
Expand All @@ -27,26 +24,41 @@
end

% simulate experiments
for d = 1:cfg.nexpt
parworkers = 0;
if isfield(cfg, 'parallel') && cfg.parallel
parworkers = Inf; % Use all available workers
if isfield(cfg, 'maxlabs')
parworkers = min([cfg.maxlabs, parworkers]);
end
end

expt_energy = zeros(cfg.nexpt, 1);
expt_time = zeros(cfg.nexpt, 1);

parfor (d = 1:cfg.nexpt, parworkers)

t_expt = tic;

% simulate experiment (default initial conditions)
[err,~,obsv] = cfg.data{d}.protocol_fcn( cfg.data{d}.time, init, params );
if (err)
energy = cfg.big_energy;
return;
expt_energy(d) = Inf;
expt_time(d) = toc(t_expt);
continue; % parfor does not support return
end

% normalize obsv
[obsv] = norm_obsv( obsv, params, cfg );

% heuristic penalties (do this before transformating obsv)
penalty_val = 0;
if isfield(cfg.data{d}, 'heuristic_penalty_fcn')
penalty = cfg.data{d}.heuristic_penalty_fcn(obsv, params);
if isinf(penalty)
energy = cfg.big_energy;
return;
penalty_val = cfg.data{d}.heuristic_penalty_fcn(obsv, params);
if isinf(penalty_val)
expt_energy(d) = Inf;
expt_time(d) = toc(t_expt);
continue;
end
energy = energy + penalty;
end

% if necessary, transform simulated trajectory for computing fitness
Expand All @@ -56,13 +68,25 @@

% calculate log-likelihood as weighted sum of square errors
loglike = nansum(nansum( -cfg.data{d}.weight .* (obsv - cfg.data{d}.mean).^2 ./ (2*(cfg.data{d}.stdev).^2) ));
% subtract likelihood from energy
energy = energy - loglike;

% accumulate experiment energy
expt_energy(d) = penalty_val - loglike;

expt_time(d) = toc(t_expt);

end

% check for any failures
if any(isinf(expt_energy))
energy = cfg.big_energy;
return;
end

% update energy with valid experiment results
energy = energy + sum(expt_energy);

% penalize for slow integrations
dt = toc(simtimer);
dt = sum(expt_time);
energy = energy + cfg.timepenalty*dt^2;

% all done
Expand Down
51 changes: 37 additions & 14 deletions core/energy_tdistr.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
end
energy = -logprior;

% start integration timer
simtimer = tic;

% equillibrate, if required
if isfield(cfg, 'equilibrate_fcn')
[err,state,~] = cfg.equilibrate_fcn( params );
Expand All @@ -27,26 +24,41 @@
end

% simulate experiments
for d = 1:cfg.nexpt
parworkers = 0;
if isfield(cfg, 'parallel') && cfg.parallel
parworkers = Inf; % Use all available workers
if isfield(cfg, 'maxlabs')
parworkers = min([cfg.maxlabs, parworkers]);
end
end

expt_energy = zeros(cfg.nexpt, 1);
expt_time = zeros(cfg.nexpt, 1);

parfor (d = 1:cfg.nexpt, parworkers)

t_expt = tic;

% simulate experiment (default initial conditions)
[err,~,obsv] = cfg.data{d}.protocol_fcn( cfg.data{d}.time, init, params );
if (err)
energy = cfg.big_energy;
return;
expt_energy(d) = Inf;
expt_time(d) = toc(t_expt);
continue; % parfor does not support return
end

% normalize obsv
[obsv] = norm_obsv( obsv, params, cfg );

% heuristic penalties (do this before transformating obsv)
penalty_val = 0;
if isfield(cfg.data{d}, 'heuristic_penalty_fcn')
penalty = cfg.data{d}.heuristic_penalty_fcn(obsv, params);
if isinf(penalty)
energy = cfg.big_energy;
return;
penalty_val = cfg.data{d}.heuristic_penalty_fcn(obsv, params);
if isinf(penalty_val)
expt_energy(d) = Inf;
expt_time(d) = toc(t_expt);
continue;
end
energy = energy + penalty;
end

% if necessary, transform simulated trajectory for computing fitness
Expand All @@ -58,13 +70,24 @@
t = (cfg.data{d}.mean - obsv)./(cfg.data{d}.stdev./sqrt(cfg.data{d}.nsamples));
loglike = nansum(nansum( cfg.data{d}.weight .* tlogpdf(t, cfg.data{d}.nsamples) ));

% subtract likelihood from energy
energy = energy - loglike;
% accumulate experiment energy
expt_energy(d) = penalty_val - loglike;

expt_time(d) = toc(t_expt);

end

% check for any failures
if any(isinf(expt_energy))
energy = cfg.big_energy;
return;
end

% update energy with valid experiment results
energy = energy + sum(expt_energy);

% penalize for slow integrations
dt = toc(simtimer);
dt = sum(expt_time);
energy = energy + cfg.timepenalty*dt^2;

% all done
Expand Down
24 changes: 17 additions & 7 deletions core/init_chains.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,29 @@
fprintf(1,'Initializing chains...\n');
params_curr = zeros(cfg.nchains,cfg.nparams);
energy_curr = zeros(cfg.nchains,1);
for chain_idx = 1 : cfg.nchains
parworkers = 0;
if isfield(cfg, 'parallel') && cfg.parallel
parworkers = min( [cfg.maxlabs, cfg.nchains] );
end
parfor (chain_idx = 1 : cfg.nchains, parworkers)
fprintf(1,'chain %d . . . ', chain_idx );
energy_curr(chain_idx) = Inf;

tmp_energy = Inf;
tmp_params = zeros(1, cfg.nparams);

for counter = 1 : cfg.max_init_steps
params = cfg.proposal_fcn( params_init, epsilon(chain_idx,:) );
energy = cfg.energy_fcn( params );
if ( energy < energy_curr(chain_idx) )
params_curr(chain_idx,:) = params;
energy_curr(chain_idx) = energy;
if ( energy < tmp_energy )
tmp_params = params;
tmp_energy = energy;
end
if ( energy_curr(chain_idx) < cfg.energy_init_max )
if ( tmp_energy < cfg.energy_init_max )
break;
end
end
fprintf(1,'initial energy = %g\n', energy_curr(chain_idx) );

params_curr(chain_idx,:) = tmp_params;
energy_curr(chain_idx) = tmp_energy;
fprintf(1,'initial energy = %g\n', tmp_energy );
end
37 changes: 24 additions & 13 deletions core/parallel_tempering.m
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@
% start labs
nlabs = min( [cfg.maxlabs, cfg.nchains] );
fprintf(1,'[ nlabs=%d ]\n', nlabs );
matlabpool( 'local', nlabs );
poolobj = gcp('nocreate');
if isempty(poolobj)
parpool( 'local', nlabs );
end
spmd
% initialize random number stream for each lab
RandStream.setGlobalStream( labstreams{labindex} );
Expand Down Expand Up @@ -247,24 +250,32 @@
end % loop over chains


% Try to Swap Chains (highest temperature to lowest temperature)
for chain_idx = cfg.nchains : -1 : 2
% Try to Swap Chains (randomized even-odd pairs)
start_chain_idx = 1 + randi([0, 1]); % randomly start with 1 or 2
for chain_idx = start_chain_idx : 2 : (cfg.nchains - 1)

% chains to swap
c1 = chain_idx;
c2 = chain_idx + 1;

% Mark that a swap was attempted (using -1 to track attempts while 1 means accepted)
swap_acceptance(c1, swap_idx) = -1;

% Difference.
delta_energy = energy_curr(chain_idx, 1) - energy_curr(chain_idx-1,1);
delta_beta = beta(chain_idx) - beta(chain_idx-1);
delta_energy = energy_curr(c2, 1) - energy_curr(c1, 1);
delta_beta = beta(c2) - beta(c1);

if ( delta_beta*delta_energy > log(rand(1)) )
% swap chains . . .
energy_tmp = energy_curr(chain_idx-1, 1);
params_tmp = params_curr(chain_idx-1, :);
energy_tmp = energy_curr(c1, 1);
params_tmp = params_curr(c1, :);

energy_curr(chain_idx-1, 1) = energy_curr(chain_idx, 1);
energy_curr(chain_idx, 1) = energy_tmp;
energy_curr(c1, 1) = energy_curr(c2, 1);
energy_curr(c2, 1) = energy_tmp;

params_curr(chain_idx-1,:) = params_curr(chain_idx, :);
params_curr(chain_idx,:) = params_tmp;
swap_acceptance(chain_idx-1,swap_idx) = 1;
params_curr(c1, :) = params_curr(c2, :);
params_curr(c2, :) = params_tmp;
swap_acceptance(c1, swap_idx) = 1;
end
end

Expand Down Expand Up @@ -331,7 +342,7 @@
% ---- close processor pool -------------------------------------------
fprintf(1,'------------------------------------------------------\n');
if (cfg.parallel)
matlabpool close;
delete(gcp('nocreate'));
end


Expand Down