提高性能以生成步长范围内的随机数

时间:2014-01-25 17:23:47

标签: performance matlab random

为了确保这不重复,我已经检查了thisthis

我想生成特定范围中的随机数,包括步长(不是连续分布)。

例如,我想在 -2 3 之间生成随机数,其中两个连续数字之间的步长 0.02 。 (例如[-2 -1.98 -1.96 ... 2.69 2.98 3]所以生成的数字应该是2.96而不是2.95)。

我试过这个:

a=-2*100;
b=3*100;
r = (b-a).*rand(5,1) + a;
for i=1:length(r)
    if r(i) >= 0
        if mod(fix(r(i)),2)
            r(i)=ceil(r(i))/100;
        else
            r(i)=floor(r(i))/100;
        end
    else
        if mod(fix(r(i)),2)
            r(i)=floor(r(i))/100;
        else
            r(i)=ceil(r(i))/100;
        end
    end
end

它有效。

在MATLAB中有另一种方法可以做到这一点:

y = datasample(-2:0.02:3,5,'Replace',false)

我想知道:

  1. 如何更快地完成自己的实施(改进 性能)?
  2. 如果第二种方法更快(对我来说看起来更快),我该怎么办? 在C ++中使用类似的实现?

2 个答案:

答案 0 :(得分:2)

如果您仔细阅读,以前的答案会涵盖您的案例。例如,this one会在步长为1的限制之间生成随机数。但是,让我们将其概括为任意步长,以防您无法弄清楚如何到达那里。有几种不同的方式。这是一个使用randi的地方,我们使用默认步长为1,范围从1到可能数值作为索引:

lo = 2;
hi = 3;
step = 0.02;
v = lo:step:hi;
r = v(randi(length(v),[5 1]))

如果您查看datasample(在命令窗口中键入edit datasample以查看代码),您会发现它正在执行与此答案非常相似的操作。如果'Replace'选项为true,请参阅第135行(至少在R2013a中)。

如果'Replace'选项为false,就像您上面datasample的使用一样,那么实际上需要使用randperm(请参阅第159行左右):< / p>

lo = 2;
hi = 3;
step = 0.02;
v = lo:step:hi;
r = v(randperm(length(v),51))

由于在这种情况下没有替换,51是呼叫中可以请求的最大值数,r的所有值都将是唯一的。

在C ++中,如果您正在进行科学计算并生成大量随机变量,则使用rand()。相反,你应该使用一个大周期随机数生成器,如Mersenne Twister(Matlab中的默认值)。 C ++ 11包含a version of this generator作为的一部分。 rand()中的More here。如果你想要快速的东西,你应该尝试Double precision SIMD-oriented Fast Mersenne Twister。如果要在C ++中实现代码,则必须提出另一个问题。

答案 1 :(得分:1)

您想要的分布是一个简单的整数变换,那么如何:

step = 0.02
r = randi([-2 3] / step, [5, 1]) * step;

在C ++中,rand()也生成整数,所以在那里采用类似的方法应该非常明显。