使用随机数生成进行重复评估

Geo*_*ery 1 julia

我有一个函数

\n
function foo()\n    return sum(rand([1,0], 5))\nend\n
Run Code Online (Sandbox Code Playgroud)\n

它正在做一些事情,包括随机数生成。如何多次重复函数调用并将结果存储在数组中。我知道我可以进行数组理解......

\n
[foo() for i in 1:10]\n
Run Code Online (Sandbox Code Playgroud)\n

但我有一种感觉,一定有类似的东西repeat(),你可以用它来填充相同值的数组:

\n
julia> repeat([4],3,4)\n\n3\xc3\x974 Matrix{Int64}:\n 4  4  4  4\n 4  4  4  4\n 4  4  4  4\n
Run Code Online (Sandbox Code Playgroud)\n

DNF*_*DNF 5

我认为数组理解在这里是完全正确的,也是我推荐的。如果您已经有一个要填充的数组,则可以使用带有一些不错语法的广播

\n
julia> x = zeros(Int, 10);  # pre-allocated array\n\njulia> x .= foo.()  # this works in-place\n
Run Code Online (Sandbox Code Playgroud)\n

顺便说一句,我建议使用该repeat函数用数字填充数组,它效率不高,也不符合习惯。要填充数组,请使用fill(注意名称):

\n
julia> fill(4, 3, 4)\n3\xc3\x974 Matrix{Int64}:\n 4  4  4  4\n 4  4  4  4\n 4  4  4  4\n
Run Code Online (Sandbox Code Playgroud)\n

我还建议更有效地实施foo. 从向量中采样效率不高rand([0,1], 5)。最好这样做

\n
rand(0:1, 5)  # with a range\n
Run Code Online (Sandbox Code Playgroud)\n

最好还是使用元组

\n
rand((0, 1), 5)\n
Run Code Online (Sandbox Code Playgroud)\n

更好的是对布尔值进行采样

\n
rand(Bool, 5)\n
Run Code Online (Sandbox Code Playgroud)\n

如果这还不够,则根本不需要创建所有 0 和 1 或布尔向量:

\n
foo() = sum(rand(Bool) for _ in 1:5)\n
Run Code Online (Sandbox Code Playgroud)\n

该函数不分配任何临时数组,并且比您的foo.

\n

(而且,只是为了好玩,这是我能找到的最快的:

\n
bar() = count_ones(rand(UInt8) & 0b00011111)\n
Run Code Online (Sandbox Code Playgroud)\n

如果样本数最多为 64,那么您可以这样做:

\n
bar(N) = count_ones(rand(Int) & ((1 << N) - 1))\n
Run Code Online (Sandbox Code Playgroud)\n

对于> 64的数字,你可以循环它

\n
function baz(N)\n    (d, r) = divrem(N, 64)\n    s = 0\n    for i in 1:d\n        s += count_ones(rand(Int))\n    end\n    return s + count_ones(rand(Int) & ((1 << r) - 1))\nend\n
Run Code Online (Sandbox Code Playgroud)\n

不过,最终,对于非常大的 N(大约 20,000),执行速度会变得更快sum(bitrand(N))\n)

\n

不过,对于较大的 N,人们可能希望将 Distributions.jl 与二项式分布一起使用:

\n
using Distributions\n\nfoo2(N) = rand(Binomial(N, 0.5))\n\njulia> @btime foo2(20000000)\n  28.056 ns (0 allocations: 0 bytes)\n9995529\n
Run Code Online (Sandbox Code Playgroud)\n