MATLAB: Does batch generate a different sequence of random numbers even when seeding the rng

batchMATLABparforrandomrandom number gene...

My question can be understood by implementing the following MWE:
% Script
% PARAMETERS
replicates = 1000; % number of times the simulation is to be repeated
% Seed the random number generator

rng(0); % this ensures the seed values sampled below are always the same
%============================================================%
% Required arrays and matrices
seed = randi(2^32,1,replicates)-1; % this should ensure model
% (MWE_fn) outcomes are repeatable
solution_array = zeros(1,replicates);
% Loop through the number of replicates
parfor replicate = 1:replicates
solution_array(1,replicate) = MWE_fn(seed,replicate);
end
% Store solution in .txt file
fid_dyn = fopen('MWE_solution_batch4.txt','wt');
fprintf(fid_dyn,'%f\n',solution_array);
fclose(fid_dyn);
function solution = MWE_fn(seed,replicate)
% Seed the random number generator
rng(seed(1,replicate));
% Generate random number for solution
solution = rand;
end
When the code is run using batch the command:
j = batch('MWE_script','Pool',2)
the results are different to when running the code from the command line as follows:
MWE_script
Why is that??? Shouldn't seeding the rng in each replicate with the same value (irrespective of the method used to implement the code) mean the results are the same?

Best Answer

The problem here is that desktop MATLAB has a different default random number generator type than a Parallel Computing Toolbox worker. In particular, desktop MATLAB uses 'twister' by default, and PCT workers use 'combRecursive' by default (this is because 'twister' is not suitable for use in parallel - there is no way to generate parallel streams).
When you call
rng(0)
you are setting the seed of the generator, without changing the generator type. This means that simply calling rng(0) is actually not sufficient to fully specify the random numbers that MATLAB (client or worker) will generate.
To fix this, you need to specify fully the generator state and type. You can do this like so:
rng(0, 'combRecursive');
I'm not an expert on these matters, but my understanding is that for this case, you'd probably be better of generating a single 'combRecursive' stream, and picking a different substream for each iteration of your parfor loop. This is described in some detail in the doc.