3

我正在尝试编写一个 matlab 函数,该函数生成一个二进制文件,其中包含一系列 64 位随机整数。这些应该质量很好,这就是为什么我想使用 64 位 mersenne twister 算法或更好的原因。内置的randi()函数只能产生 32 位数字。我之前使用以下方法生成了 32 位结果:

rng('shuffle', 'twister');
randi(2^32-1, 'uint32')

但这在 64 位中不可用。如果我记得正确使用多个 32 位整数来生成 64 位随机整数是不好的做法,但如果有一个好的解决方案,我愿意接受。
为了使事情变得更加困难,我目前使用的是 32 位 windows xp 机器。

4

3 回答 3

6

似乎 Matlab 中对 64 位随机整数(以及一般的 64 位整数)的支持仍然很差。

我怀疑“最好的”解决方法是做一些黑客攻击:

% create 32-bit uints, and cast to 64-bit
f = @() uint64( randi([0 intmax('uint32')], 'uint32') );

% bitshift and bitor to convert into a proper uint64        
R = bitor( bitshift(f(),32), f() );

typecast按照 Andrew Jake 的建议使用,以提高可读性:

f = @() randi([0 intmax('uint32')], 'uint32');
R = typecast([f() f()], 'uint64');

创建多个随机数时,您必须更改g为:

% bitshift and bitor: 
% ------------

% create an Nx1 uint32, and cast to 64-bit
g = @(N) uint64( randi([0 intmax('uint32')], N,1, 'uint32') );

tic
R = bitor( bitshift(g(1e7),32), g(1e7) );
toc


% typecast 
% ------------

% create a 1xN uint32, but leave the casting to typecast
g = @(N) randi([0 intmax('uint32')], 1,N, 'uint32');

tic
R = typecast([g(1e7) g(1e7)], 'uint64');   
toc

结果:

Elapsed time is 0.717668 seconds.    % bitor/bitshift
Elapsed time is 0.705700 seconds.    % typecast w/ loop 

它们同样快,所以它真的是你喜欢的任何东西。

Mersenne Twister 主页提到连接两个 s 时分布不会改变uint32(感谢 Andrew 的提醒),因此您确实可以安全地执行此操作。

于 2013-04-09T13:44:47.440 回答
1

这个页面判断,可以使用乘法滞后斐波那契生成器。但是,根据一般标准,我认为它不会比梅森捻线机表现更好。

此外,您需要一台 64 位机器来运行 64 位 Matlab。

编辑:这个问题还表明 64 位版本的 Matlab 已经使用默认设置生成 64 位随机整数。

于 2013-04-09T13:23:32.513 回答
1

如果你真的想要高质量的随机数,Mersenne Twister 的 64 位版本已经发布。这是它的C实现。它说它适用于“64 位机器”,但我认为您也可以在 32 位机器上编译它——它只是使用unsigned long long64 位指针,而不是 64 位指针。将其放入 MEX 文件中,您可以轻松地从 M 代码中调用它。

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/mt19937-64.c

于 2013-04-10T03:18:43.410 回答