2016-09-15 14 views
6

Potrzebuję podzielić zmienną z::Array{Complex128,1} na dwie tablice dla części rzeczywistych i złożonych. Jeden sposób to zrobić, aby tworzyć nowe zmienne ::Array{Float64,1} i wypełnić je element po elemencie:Julia - pobierz prawdziwą część złożonej tablicy

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

Czy istnieje sposób na to, że nie wymaga kopiowania danych, jak jakoś manipulowania postępy i przesunięciami z zrobić?

Odpowiedz

7

Edytuj: Oryginalna wersja wykorzystała niepotrzebną operację reshape. Jak zaznaczył @DNF w komentarzach, nie było to konieczne. Odpowiedź została zmieniona, ponieważ.

We wspólnym przypadku kopiowania nie jest problemem, po prostu zrób real(z) i imag(z) (przemianowany real.(z) i imag.(z) w v0.6). Załączam to, aby pomóc przyszłym czytelnikom, którzy mają podobny problem, ale którzy mogą nie dbać o kopiowanie.

Jak sugerujesz, możesz manipulować krokami z, aby uniknąć kopiowania danych. Wystarczy

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

Combined, możemy stwierdzić, że brak jest kopiowanie danych (przydziały są ze względu na poglądy tablicy sterty przydzielone, a są minimalne).

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) 

Jak widzimy, za kulisami, taka tablica jest strided:

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

należy wspomnieć, że jeśli twoje tablice są bardzo duże czy to ma miejsce w bardzo napięty pętli, to jest mało prawdopodobne, aby zaoszczędzić Ci zbyt dużo czasu - kopiowanie danych jest bardzo szybkie na nowoczesnych procesorach. Ale może być przypadek użycia :) – StefanKarpinski

+1

Możesz uzyskać * marginalnie * mniej alokacji, porzucając operację 'reshape', i właśnie zwracając' widok (a, 1: 2: N), widok (a, 2: 2: N) '. Dzięki temu kod jest trochę czystszy. Możesz zapisać koklusz 64 bajty: D – DNF

+0

@DNF Dzięki! Zaktualizowano. –

Powiązane problemy