2

Is there any way to generate pseudo-random numbers to less precision and thus speed the process up?

Another thing is that I know it saves time if random numbers are generated all at once (e.g. rand(100,1000)), instead of one by one. Could someone explain why this is true?

Dev-iL
  • 23,742
  • 7
  • 57
  • 99
moon1234
  • 123
  • 3
  • Per [the documentation](http://www.mathworks.com/help/matlab/ref/rand.html) you can specify the output to be `'single'` precision. Without more context on what exactly you're doing it's hard to answer the question of "why is this slow" – sco1 Aug 31 '16 at 13:48
  • 1
    I think specifying the output as 'single' only changes the output itself. So the numbers are calculated up to the same precision as before and they are rounded just afterwards, which would not help with the speed. There is no specific program this is connected to, I'm just interested if it is possible at all. – moon1234 Aug 31 '16 at 13:59
  • There has to be *some* program that's generating this question. Generating 9 million random numbers takes `0.047` seconds on my machine. That's not slow. – sco1 Aug 31 '16 at 14:11
  • The why is almost certainly because Matlab is an interpreter which calls compiled library modules after the interpreter phase parses the statement. One call to a compiled library module with args to do 1000 computations internally is going to be faster than 1000 interpreter parses/calls to do one operation per invocation. – pjs Aug 31 '16 at 14:12
  • @excaza yes, I agree that it is not slow but all I'm interested in is whether, in theory, it is possible to generate them up to less precision or if it is defined by the generating algorithm that they are calculated up to a certain precision. – moon1234 Aug 31 '16 at 14:46
  • @pjs thanks for the answer, this makes sense. – moon1234 Aug 31 '16 at 14:46
  • If you really need more speed, you can also compile [an optimized version of the Mersenne Twister algorithm](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html#dSFMT) into a MEX file. Or, if you don't need the huge period of Mersenne Twister, you can try a more modern generator like [xorshift+/xorshift*](http://xoroshiro.di.unimi.it). I've been able to get a 2–10x speedup doing this. – horchler Aug 31 '16 at 20:47

3 Answers3

4

If you have a CUDA-capable GPU, you can do random number generation on it, as it's supposed to be much faster... Specifically Philox4x32-10:

parallel.gpu.rng(0, 'Philox4x32-10');
R = gpuArray.rand(sZ,'single'); % run this for more info: doc('gpuArray/rand')

Example from the MATLAB documentation

Dev-iL
  • 23,742
  • 7
  • 57
  • 99
3

MATLAB actually implements more than one random number generator. They differ significantly in terms of execution time and in terms of "randomness" (I think, but I didn't verify). However, I understand from your question that speed is more important for you.

% 'twister' is the default in MATLAB Versions 7.4 and later
tic();
for i=1:1000000
    rand('twister'); 
end
toc();
%Elapsed time is 2.912960 seconds.

% 'state' is the default in MATLAB versions 5 through 7.3
tic();
for i=1:1000000
    rand('state'); 
end
toc(); 
% Elapsed time is 2.162040 seconds.

% 'seed' is the default in MATLAB version 4
tic();
for i=1:1000000
    rand('seed'); 
end
toc();
% Elapsed time is 0.758830 seconds.

Important note: I ran the script above with an rather old version of MATLAB (v.7.6, a.k.a. R2008a). In newer versions, the syntax rand(generator) is discouraged . Instead, you should use the function rng(seed, generator) (online documentation). As a side effect, rng(seed, generator) gives you even more random number generators to choose from. Check the documentation for details.

Regarding the second question: Whatever generator you pick, generating many random numbers at once will always be faster than generating many single random numbers. This is because MATLAB's internals are heavily optimized for parallel processing.

tic();
for i=1:100000
    rand(); 
end
toc();
% Elapsed time is 0.024388 seconds.

tic();
rand(100, 1000);
toc();
% Elapsed time is 0.000680 seconds.
Martin S
  • 814
  • 2
  • 11
  • 24
2

Since R2015a the rng function for configuring and seeding the global generator has a 'simdTwister' option that uses a faster "SIMD-oriented Fast Mersenne Twister" algorithm:

rng(1,'twister');
R = rand(1e4); % Warmup for timing
tic
R = rand(1e4);
toc

rng(1,'simdTwister');
R = rand(1e4); % Warmup for timing
tic
R = rand(1e4);
toc

This will probably be the fastest builtin generator for your system (excepting the possibility of GPU-based generators). On my computer it's a little more than twice as fast as the default Mersenne Twister algorithm for large arrays.

horchler
  • 18,384
  • 4
  • 37
  • 73