I need to split the variable z::Array{Complex128,1} into two arrays for the real and complex parts. One way do this is to make new variables ::Array{Float64,1} and fill them element by element:
for i = 1:size(z)[1]
ri[i] = z[i].re
ii[i] = z[i].im
end
Is there a way to do this that doesn't involve copying data, like somehow manipulating strides and offsets of z?
In the common case where copying is not an issue, just do real.(z) and imag.(z). I include this to help future readers who have a similar issue, but who might not care about copying.
As you suggest, you can manipulate strides of z to avoid copying data. Simply
zfl = reinterpret(Float64, z)
zre = @view zfl[1:2:end-1]
zim = @view zfl[2:2:end]
Combined, we observe that there is no data copying (the allocations are due to the heap-allocated array views, and are minimal).
julia> z = Vector{ComplexF64}(100000);
julia> function reimvec(z)
zfl = reinterpret(Float64, z)
zre = @view zfl[1:2:end-1]
zim = @view zfl[2:2:end]
zre, zim
end
reimvec (generic function with 1 method)
julia> @time reimvec(z);
0.000005 seconds (9 allocations: 400 bytes)
As we can see, behind the scenes, such an array is strided:
julia> strides(reimvec(z)[1])
(2,)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With