Code covered by the BSD License  

Highlights from
Differential Evolution Monte Carlo sampling

image thumbnail
from Differential Evolution Monte Carlo sampling by Corey Yanofsky
easy Bayesian computation for real parameter spaces

DEMC_sample(logtarget, n, states, blockindex, ...
function [saved_states, saved_logprob] = DEMC_sample(logtarget, n, states, blockindex, ...
    current_logprob, temperature_schedule, gamma_schedule, jitter)
% DEMC_SAMPLE Perform Differential Evolution-Markov chain Monte Carlo sampling
% (see References)
%
% Usage
%
% states = DEMC_sample(logtarget, n,  initial_states, blockindex,...
%       initial_logprob, temperature_schedule, gamma_schedule, jitter)
%
% [states, logprob] = DEMC_sample(logtarget, n,  initial_states, blockindex,...  
%       initial_logprob, temperature_schedule, gamma_schedule, jitter)
%
% INPUTS
%
% logtarget - a function accepting a 1-by-d state vector and returning the log
% probability density for that vector. The density may be unnormalized.
% (DEMC may fail if the target density does not have support over R^d.)
%
% n - number of iterates to sample
%
% initial_states - an m-by-d matrix of states where the rows index Markov chains in
% the population and the columns index the random variables defining the
% state.
%
% OPTIONAL INPUTS (may be [], or may be left off the argument list entirely)
%
% blockindex - a cell array of length b, each of the b cells contains the indexes
% of state vector elements belonging to the b'th block. For DE-MC without blocks,
% set blockindex = {1:d}; this is also the default.
%
% initial_logprob - an m-by-1 vector containing the log probability of the
% initial states; if this has been pre-calculated then this can save time,
% especially if this routine is being called in a loop as part of a hybrid
% sampling scheme.
%
% temperature_schedule - schedule for temperatures used in simulated annealing.
% After the schedule is complete, the temperature is set to 1. An empty schedule
% defaults to a constant temperature of 1.
%
% gamma_schedule - schedule for scale factor for vector differences; the default value
% an unchanging schedule of 2.38/sqrt(2d), which is optimal for d-dimensional
% Gaussian targets. For example, a schedule of 9 iterations at gamma = 2.38/sqrt(2.*d)
% followed by one iteration at 0.99 is specified by
% gamma = [2.38/sqrt(2.*d).*ones(1,9) 0.99]
%
% jitter - 1-by-d dimensional vector of scale factors for the jitter; the
% default value is 1e-5.*ones(1,d)
%
% OUTPUT
%
% states - a m-by-d-by-n array of sampled states.
%
% OPTIONAL OUTPUT
%
% logprob - an m-by-n vector containing the log probabilities of the
% final states of each chain.
%
% References
%
% Cajo F.T. Ter Braak, "A Markov Chain Monte Carlo version of the genetic algorithm
% Differential Evolution: easy Bayesian computing for real parameter spaces"
% Stat Comput (2006) 16:239249

%% AUTHOR: Corey Yanofsky
%% $DATE: 08-Dec-2007 00:30:16 $
%% $Revision: 1.3 $
%% DEVELOPED: 7.1.0.246 (R14) Service Pack 3
%% FILENAME: block_DEMC_sample.m
%%
%% This work was supported by grants from Genome Quebec and the National 
%% Science and Engineering Research Council of Canada.

% initialize and set defaults
[m d] = size(states);
if nargin < 8 || isempty(jitter), jitter = 1e-5.*ones(1,d);end
if nargin < 7 || isempty(gamma_schedule), gamma_schedule = 2.38./sqrt(2*d);end
if nargin < 6, temperature_schedule = [];end
if(nargin < 5 ||isempty(current_logprob))
    current_logprob = zeros(m, 1);
    for j = 1:m
        current_logprob(j) = logtarget(states(j,:));
    end
end
if nargin < 4 || isempty(blockindex), blockindex = {1:d};end
nblocks = length(blockindex);

% fill out temperature schedule
temperature_schedule = temperature_schedule(:);
temperature_schedule = [temperature_schedule;ones(n - length(temperature_schedule),1)];

% create gamma index
gamidx = mod(0:(n-1),length(gamma_schedule)) + 1;

saved_states = zeros(m,d,n);
saved_logprob = zeros(m,n);

% sample new states n times...
for i = 1:n
    % for each of the m chains...
    for j = 1:m
        % for each block
        for k = 1:nblocks
            [states(j,:) current_logprob(j)] = DEMC_chain_sample(...
                logtarget,  j, states, current_logprob(j), blockindex{k},...
                temperature_schedule(i), gamma_schedule(gamidx(i)), jitter);
        end % blocks
    end % chains
    saved_states(:,:,i) = states;
    saved_logprob(:,i) = current_logprob;
end % iterates

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [new_state new_logprob] = DEMC_chain_sample(logtarget,i,states,current_logprob, ...
    blockindex, temperature, gamma, jitter)
%
% This function does the actual Metropolis sampling.
%
% [new_state, new_logprob] = DEMC_chain_sample(logtarget,i,states,current_logprob, gamma, jitter) 
% 
% INPUTS
%
% logtarget - a function accepting a 1-by-d state vector and returning the log
% probability density for that vector. The density may be unnormalized.
% (DEMC may fail if the target density does not have support over over R^d.)
%
% states - an m-by-d matrix of states where the rows index Markov chains in
% the population and the columns index the random variables defining the
% state.
%
% i - the index of the Markov chain being updated
% 
% current_logprob - log probability of the state being updated; if this has
% been pre-calculated (for example, in a previous iteration of DE-MC), then 
% this saves time
%
% blockindex - array containing the indices of the elements of the state
% vectors being updated
%
% temperature - simulated annealing temperature parameter
%
% gamma - scale factor for DE-MC; the default value is 2.38/sqrt(2d), which
% is optimal for d-dimensional Gaussian targets
%
% jitter - 1-by-d dimensional vector of scale factors for the jitter; the
% default value is 1e-5.*ones(1,d)
%
% OUTPUT
%
% new_state - a 1-by-d dimensional state vector sampled by DE-MC.
%
% new_logprob - the log probability of new_state. This will probably not be
% useful when the DE-MC is providing a conditional update as part of a 
% hybrid Markov chain; however, if DE-MC is being used for all 
% updates, then this can be fed back into the next iteration, saving
% computation time.

[m,d] = size(states);

% sample two states other than i uniformly without replacement
n1 = ceil(rand*(m-1));
n2 = ceil(rand*(m-2));
if(n1 >= i) 
    n1 = n1 + 1;
    if(n2 >= i), n2 = n2 + 1;end
    if(n2 >= n1), n2 = n2 + 1;end
else
    if(n2 >= n1), n2 = n2 + 1;end
    if(n2 >= i), n2 = n2 + 1;end
end

% generate proposal via differential evolution rule
difference_vector = zeros(1,d);
difference_vector(blockindex) = gamma.*(states(n1,blockindex) - states(n2,blockindex)) + ...
    jitter(blockindex).*randn(1,length(blockindex));
proposal = states(i,:) + difference_vector;

proposal_logprob = logtarget(proposal);

% Metropolis accept/reject step
if(temperature*log(rand) < proposal_logprob - current_logprob)
    new_state = proposal;
    new_logprob = proposal_logprob;
else
    new_state = states(i,:);
    new_logprob = current_logprob;
end

% Created with NEWFCN.m by Frank Gonzlez-Morphy  
% Contact...: frank.gonzalez-morphy@mathworks.de  
% ===== EOF ====== [DEMC_sample.m] ======  

Contact us at files@mathworks.com