Generate array of complex numbers with absolute value one in Julia?

358 views Asked by At

In Julia, I would like to randomly generate an array of arbitrary size, where all the elements of the array are complex numbers with absolute value one. Is there perhaps any way to do this within Julia?

3

There are 3 answers

2
Dan Getz On BEST ANSWER

I've got four options so far:

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))

We have:

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)

Not a crucial difference.

0
Bill On

One way is:

randcomplex() = (c = Complex(rand(2)...); c / abs(c))

randcomplex(numwanted) = [randcomplex() for _ in 1:numwanted]

or

randcomplex(dims...) = (a = zeros(Complex, dims...); for i in eachindex(a) a[i] = randcomplex() end; a)
4
DNF On

If you are looking for something faster, here are two options. They return a perhaps slightly unfamiliar type, but it is equivalent to a regular 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)