【发布时间】:2014-06-24 19:20:13
【问题描述】:
根据定义,函数srand(seed) 为rand() 使用的随机数生成器提供种子。如果不调用,则根据the documentation,默认种子为1。考虑以下 MEX 代码test.c:
#include "mex.h"
#include <stdlib.h>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
srand(1);
mexPrintf("%lf\n",(double)rand()/(double)RAND_MAX);
}
从 Matlab 调用时总是返回相同的随机数:
>> mex test.c
>> test
0.001251
>> test
0.001251
>> test
0.001251
考虑以下代码test2.c,其中srand()在随机数生成之前没有被调用:
#include "mex.h"
#include <stdlib.h>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
mexPrintf("%lf\n",(double)rand()/(double)RAND_MAX);
}
此代码在第一次调用时返回相同的随机数,但每次后续调用返回不同的数字:
>> mex test2.c
>> test2
0.001251
>> test2
0.563585
>> test2
0.193304
鉴于srand() 的默认行为,我不明白为什么省略srand(1) 会在每次调用时产生不同的随机数。事实上,在 Matlab 之外编译和运行test2.c(使用printf 代替mexPrintf、int main() 代替void mexFunction(...) 等)总是返回相同的随机数,正如预期的那样。
为什么 MEX 会这样?
【问题讨论】:
-
也许您已经知道这一点,但是使用“内置”随机数生成器,例如
rand、irand和drand48,几乎总是一个糟糕的选择——尤其是对于任何科学计算或研究。请参阅规则 #1 here (PDF)。 Matlab 的默认 PRNG,Mersenne Twister 在C, C++, and many other languages 中免费提供,而且通常速度更快。 -
@horchler:如果您真的想使用来自 MEX 的 MATLAB 的 Mersenne Twister PRNG,您可以链接到
libmwmathrng.dll并调用未记录的 C++ 函数mrRandu(其签名:void mrRandu(double *arr, size_t len);)。这将共享相同的底层 RNG 状态向量,因此调用它将推进 MATLAB 使用的内部随机流。 From what I understand,MATLAB 使用您提到的相同参考实现(仅稍作修改以从rand输出中排除零值) -
在 DLL
libmwmathrng.dll中当然还有其他版本的这个函数,匹配rand/randi/randn的所有变体。只需使用“Dependency Walker”浏览导出的 C/C++ 函数列表。但与任何未记录的函数一样,它不能保证在所有 MATLAB 版本中都保留在那里(我的是 R2014a)。安全(记录在案)的方法是使用mexCallMATLAB并从 MATLAB 调用rand。
标签: c matlab random mex standard-library