2016-09-15 11 views
6

का असली हिस्सा प्राप्त करें मुझे वास्तविक और जटिल भागों के लिए परिवर्तनीय z::Array{Complex128,1} को दो सरणी में विभाजित करने की आवश्यकता है। एक तरीका यह है नया चर ::Array{Float64,1} बनाने के लिए और तत्व द्वारा उन्हें तत्व को भरने के लिए है:जूलिया - जटिल सरणी

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

वहाँ यह है कि डेटा की प्रतिलिपि, किसी भी तरह प्रगति और z की ऑफसेट जोड़ तोड़ की तरह शामिल नहीं करता है करने के लिए एक तरीका है?

उत्तर

7

संपादित करें: मूल संस्करण एक अनावश्यक reshape ऑपरेशन का उपयोग करता था। जैसा कि @ डीएनएफ ने टिप्पणियों में बताया, वह अनावश्यक था। जवाब के बाद से संशोधित किया गया है।

मामले ऐसे नकल कोई मुद्दा नहीं है, सिर्फ करना real(z) और imag(z) (नाम बदला real.(z) और v0.6 में imag.(z))। मैं इसे भविष्य के पाठकों की मदद करने के लिए शामिल करता हूं जिनके पास समान समस्या है, लेकिन जो प्रतिलिपि बनाने की परवाह नहीं करते हैं।

जैसा कि आप सुझाव देते हैं, आप डेटा कॉपी करने से बचने के लिए z के चरणों में हेरफेर कर सकते हैं। सीधे शब्दों में

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

संयुक्त, हम देख कोई डेटा नकल (आवंटन ढेर आबंटित सरणी दृष्टिकोण के कारण उत्पन्न कर रहे हैं, और कम से कम कर रहे हैं) नहीं है।

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) 

हम देख सकते हैं, पर्दे के पीछे, इस तरह के एक सरणी strided है:

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

मैं उल्लेख करना चाहिए जब तक कि आपके सरणियों बहुत बड़ा या यह एक बहुत ही तंग पाश में हो रहा है कर रहे हैं, यह है कि आपको बहुत अधिक समय बचाने की संभावना नहीं है - आधुनिक सीपीयू पर डेटा कॉपी करना बहुत तेज़ है। लेकिन एक उपयोग मामला हो सकता है :) – StefanKarpinski

+1

आप 'reshape' ऑपरेशन को छोड़कर * मामूली * कम आवंटन प्राप्त कर सकते हैं, और केवल 'दृश्य (ए, 1: 2: एन) लौट सकते हैं, देखें (ए, 2: 2: एन) '। यह कोड को एक छोटा सा क्लीनर भी बनाता है। आप एक हॉपिंग 64 बाइट्स को बचा सकते हैं: डी – DNF

+0

@ डीएनएफ धन्यवाद! अपडेट किया गया। –