我想随机生成一个任意大小的数组,其中数组的所有元素都是绝对值为一的复数。在 Julia 中有什么办法可以做到这一点吗?
到目前为止我有四个选择:
f1(n) = exp.((2*im*π).*rand(n))
f2(n) = map(x->(z = x[1]+im*x[2] ; z ./ abs(z) ),
eachcol(randn(2,n)))
f3(n) = [im*x[1]+x[2] for x in sincos.(2π*rand(n))]
f4(n) = cispi.(2 .*rand(n))
我们有:
julia> using BenchmarkTools
julia> begin
@btime f1(1_000);
@btime f2(1_000);
@btime f3(1_000);
@btime f4(1_000);
end;
29.390 μs (2 allocations: 23.69 KiB)
15.559 μs (2 allocations: 31.50 KiB)
25.733 μs (4 allocations: 47.38 KiB)
27.662 μs (2 allocations: 23.69 KiB)
不是关键区别。
一种方法是:
randcomplex() = (c = Complex(rand(2)...); c / abs(c))
randcomplex(numwanted) = [randcomplex() for _ in 1:numwanted]
或
randcomplex(dims...) = (a = zeros(Complex, dims...); for i in eachindex(a) a[i] = randcomplex() end; a)
如果您正在寻找更快的东西,这里有两个选择。它们返回一个可能有点陌生的类型,但它相当于一个常规的 Vector
function f5(n)
r = rand(2, n)
for i in 1:n
a = sqrt(r[1, i]^2 + r[2, i]^2)
r[1, i] /= a
r[2, i] /= a
end
return reinterpret(reshape, ComplexF64, r)
end
using LoopVectorization: @turbo
function f5t(n)
r = rand(2, n)
@turbo for i in 1:n
a = sqrt(r[1, i]^2 + r[2, i]^2)
r[1, i] /= a
r[2, i] /= a
end
return reinterpret(reshape, ComplexF64, r)
end
julia> @btime f5(1000);
4.186 μs (1 allocation: 15.75 KiB)
julia> @btime f5t(1000);
2.900 μs (1 allocation: 15.75 KiB)