2012-04-06 33 views
2

我有一个问题,在PARFOR循环产生炒拟蒙特卡罗的数字。遇到类似问题炒拟蒙特卡罗数字在PARFOR循环

的问题是,当我一个PARFOR循环内产生的多组这些数据的,每组中的数字最终是相同的。我在下面包括一个非常简单的例子。

D = 3; 
M = 1000; 
numbers = cell(1,4); 

mystream = qrandstream(scramble(sobolset(D),'MatousekAffineOwen')); 
myfun = @(x) qrand(mystream,x); 

parfor i = 1:4 
    numbers{i} = myfun(M); 
end 

为了证明这个问题,在运行此代码后,在数字数字{1},数字{2},数字{3}和数字{4}是相同的为:

>>numbers{1}(1:3,:) 
ans = 
      0.76   0.05   0.77 
      0.33   0.96   0.23 
      0.60   0.72   0.52 

>> numbers{2}(1:3,:) 
ans = 
      0.76   0.05   0.77 
      0.33   0.96   0.23 
      0.60   0.72   0.52 

我想知道是否有人可以考虑解决这个问题。我认为必须有一些我可以做的事情,因为当我使用普通的随机数字流时,问题不会发生。

我应该指出,这是不可能的,我利用类似的“跳过”或准随机数流“大跃进”的属性。其原因是,我在我并行运行较大的MATLAB程序使用的代码片断上面...

回答

4

你需要一个单独的呼叫争抢每个并行工作。这可以通过在移动PARFOR循环内的qrandstream相关语句来完成:

D = 3; 
M = 1000; 
numbers = cell(1,4); 

parfor i = 1:4 
    mystream = qrandstream(scramble(sobolset(D),'MatousekAffineOwen')); 
    myfun = @(x) qrand(mystream,x); 

    numbers{i} = myfun(M); 
end 

为什么: 虽然MatousekAffineOwen确实有一个随机扰乱秩序,MATLAB把准随机序列作为一个巨大的预先定义的数组和每次需要新样本时,都可以随时计算样本数据。加扰改变了这个顺序,但是qrandstream对象的行为就好像它发生过一次,一旦调用被调用。之后,qrandstream是一个确定性的数字流。在非并行代码中(或者如果你在没有首先启用matlabpool的情况下使用parfor),这个设置可以在单个qrandstream b/c中正常工作。MATLAB每次调用qrand时都会继续工作(虚拟)列表。

但在PARFOR,所有需要的变量,函数等的副本被传递到每个员工。结果,每个工人都得到一个重复的,预先确定的准随机数字流,从而得到每个工人的相同样本流。顺便说一句,这并不意味着所有的数字{i}将具有相同的值。对于大于并行工作器(机器核心)数量的parfor循环范围,多个循环迭代将在同一个worker上发生,因此共享相同的非重复qrandstream。在我的两个核心机的4次迭代的示例代码显示出与numbers{1}==numbers{4}numbers{2}==numbers{3}

这种行为