2016-09-15 19 views
6

Tôi cần chia biến số z::Array{Complex128,1} thành hai mảng cho các phần thực và phức tạp. Một cách làm điều này là để làm cho biến mới ::Array{Float64,1} và điền họ phần tử bằng phần tử:Julia - lấy phần thực của mảng phức tạp

for i = 1:size(z)[1] 
    ri[i] = z[i].re 
    ii[i] = z[i].im 
end 

Có cách nào để làm điều này mà không liên quan đến việc sao chép dữ liệu, như bằng cách nào đó thao tác những bước tiến và hiệu số của z?

Trả lời

7

Chỉnh sửa: Phiên bản gốc đã sử dụng thao tác reshape không cần thiết. Như @ DDF chỉ ra trong các ý kiến, đó là không cần thiết. Câu trả lời đã được sửa đổi kể từ đó.

Trong trường hợp phổ biến mà sao chép không phải là vấn đề, chỉ cần thực hiện real(z)imag(z) (đổi tên real.(z)imag.(z) trong v0.6). Tôi bao gồm điều này để giúp độc giả tương lai có vấn đề tương tự, nhưng những người có thể không quan tâm đến việc sao chép.

Như bạn đề xuất, bạn có thể thao tác các bước tiến của z để tránh sao chép dữ liệu. Đơn giản chỉ cần

zfl = reinterpret(Float64, z) 
zre = @view zfl[1:2:end-1] 
zim = @view zfl[2:2:end] 

Kết hợp, chúng tôi quan sát thấy không có sao chép dữ liệu (phân bổ là do chế độ xem mảng được phân bổ và tối thiểu).

julia> z = Vector{Complex128}(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) 

Như chúng ta có thể thấy, đằng sau hậu trường, một mảng như thế được strided:

julia> strides(reimvec(z)[1]) 
(2,) 
+4

tôi nên đề cập rằng trừ mảng của bạn là rất lớn hay điều này xảy ra trong một vòng lặp rất chặt chẽ, đây là không thể tiết kiệm cho bạn quá nhiều thời gian - sao chép dữ liệu rất nhanh trên các CPU hiện đại. Nhưng có thể có một trường hợp sử dụng :) – StefanKarpinski

+1

Bạn có thể nhận được * ít * phân bổ ít hơn bằng cách thả hoạt động 'reshape' và chỉ trả lại' xem (a, 1: 2: N), xem (a, 2: 2: N) '. Nó cũng làm cho mã một chút sạch hơn. Bạn có thể lưu một whooping 64 byte: D – DNF

+0

@DNF Cảm ơn! Đã cập nhật. –

Các vấn đề liên quan