2010-01-26 15 views
9

मैटलैब में काम करने में सहायता करने के लिए मेरी अलग-अलग लंबाई के साथ एक्स समन्वय के 2 वैक्टर हैं। उदाहरण के लिए:मैपिंग 2 वैक्टर -

xm = [15 20 24 25 26 35 81 84 93]; 
xn = [14 22 26 51 55 59 70 75 89 96]; 

मैं दूसरे शब्दों में xn को xm, या मैप करने के लिए जो xn में निर्देशांक खोजने की जरूरत है xm के सबसे करीब हैं। इसलिए यदि मेरे पास उन निर्देशांक से जुड़े मूल्य हैं, तो मैं इस मानचित्र का उपयोग इंडेक्स के रूप में कर सकता हूं और उन मानों से संबंधित हूं।

दोनों वैक्टर क्रमबद्ध किए गए हैं और प्रत्येक वेक्टर में कोई डुप्लिकेट नहीं है।

मैं के साथ एक सरल समारोह लिखा था के लिए लूप:

function xmap = vectors_map(xm,xn) 
xmap = zeros(size(xm)); 
for k=1:numel(xm) 
    [~, ind] = min(abs(xm(k)-xn)); 
    xmap(k) = ind(1); 
end 

ऊपर उदाहरण के लिए रिटर्न

xmap = 
    1  2  2  3  3  3  8  9 10 

ठीक काम करता है, लेकिन लंबे समय वैक्टर के साथ कुछ समय लगता है है (100,000 से अधिक अंक) ।

कोई भी विचार इस कोड को सदिश कैसे करें?

+0

मैं एक अप्रयुक्त चर को छोड़ने के लिए मैटलैब के नवीनतम संस्करण में नया ~ वाक्यविन्यास का उपयोग कर रहा हूं। यदि आपके पास पहले का संस्करण है, तो बस ~ tmp के साथ प्रतिस्थापित करें। – yuk

+1

बस स्पष्ट करने के लिए, आप प्रत्येक एक्सएम [i] इंडेक्स जे के लिए चाहते हैं कि xm [i] xn [j] के निकटतम है? –

+0

हां। अच्छा सारांश, धन्यवाद। – yuk

उत्तर

5

ओह:

+2

बढ़िया! यह कोड मुझे 10,000-लंबाई वाले वैक्टरों के साथ 50 गुना गति सुधार और 100,000-दसवीं वैक्टर के साथ 1500 (!) बार देता है। एक्सएन (अंत) में एक्सएन मैप किए गए कई अंतिम तत्वों में यह त्रुटि वापस कर सकता है। मैंने लाइनों को 6-7 से बदल दिया: यदि एम yuk

+0

ऐसा लगता है कि मैं टिप्पणियों में कोड को प्रारूपित नहीं कर सकता। :( – yuk

+0

कूल! हाँ! मुझे खुशी है कि यह आपके लिए काम कर रहा है! हाँ, यह कंप्यूटर विज्ञान के बारे में मजेदार चीजों में से एक है, जब आप अचानक कुछ अरब बार तेजी से बनाते हैं ... – rescdsk

1

ऐसा लगता है कि आपके इनपुट वैक्टर सॉर्ट किए गए हैं। निकटतम मैच खोजने के लिए बाइनरी खोज का प्रयोग करें। यह आपको ओ (एन एलएन एन) रन टाइम देगा।

+0

क्या आप कृपया कुछ मैटलैब कोड प्रदान करेंगे? – yuk

+0

हां, वेक्टर क्रमबद्ध हैं। – yuk

+0

आह, बाइनरी खोज! उस बारे में सोचा नहीं था। +1 – John

0

आपका एक्सएम और एक्सएन सॉर्ट किया गया है। यदि यह आम तौर पर मामला है, तो आप पूरे सरणी पर कदम उठाने से कहीं ज्यादा बेहतर कर सकते हैं।

xn में प्रत्येक मान के लिए, मानों की एक श्रृंखला होगी जिसके लिए xm में कोई मान किसी अन्य की तुलना में उस संख्या के करीब होगा। इन अंतरालों को पहले से गणना करें और फिर आप अनुक्रमिक रूप से दोनों सरणी के माध्यम से कदम उठा सकते हैं।

0

का लाभ उठाते हुए हल कर जा रहा है, के रूप में डेविड कहते हैं, तेजी से जब से तुम इतने सारे अंक होगा, लेकिन संदर्भ के लिए एक तरह से इस vectorize करने meshgrid उपयोग करने के लिए होगा:

[X Y] = meshgrid(xn, xm); 
diffs = X - y; 
mins = min(diffs, [], 2); 

ध्यान दें कि यह पैदा करेगा स्मृति में दो 100,000 x 100,000 सरणी, इसलिए यह संभवतः छोटे डेटा सेट के लिए संभव है।

[~, xmap] = min(abs(bsxfun(@minus, xm, xn'))) 
+0

ये, यह बहुत मेमोरी लेता है और बहुत धीमा करता है तो मेरा कार्य छोटे वैक्टर के साथ होता है। – yuk

4

इस vectorized समाधान पर विचार करें! एक अन्य विकल्प: चूंकि आप दो क्रमबद्ध सूचियों के बीच घनिष्ठ पत्राचार की तलाश में हैं, इसलिए आप विलय-जैसी एल्गोरिदम का उपयोग करके एक साथ दोनों के माध्यम से जा सकते हैं। यह ओ होना चाहिए (अधिकतम (लंबाई (एक्सएम), लंबाई (एक्सएन))) - आईएसएच।


match_for_xn = zeros(length(xn), 1); 
last_M = 1; 
for N = 1:length(xn) 
    % search through M until we find a match. 
    for M = last_M:length(xm) 
    dist_to_curr = abs(xm(M) - xn(N)); 
    dist_to_next = abs(xm(M+1) - xn(N)); 

    if dist_to_next > dist_to_curr 
     match_for_xn(N) = M; 
     last_M = M; 
     break 
    else 
     continue 
    end 

    end % M 
end % N 

संपादित करें: देखें @ युक की टिप्पणी, ऊपर कोड पूरी तरह से सही नहीं है!

+0

अच्छा वेक्टरेशन। धन्यवाद। हालांकि, यह मेरे कार्य के बारे में दो बार धीमा है और इसके लिए और अधिक स्मृति की आवश्यकता है, लेकिन बेहतर कोड तो बेहतर है। – yuk

3

सबसे तेज़ कार्यान्वयन मुझे पता है कि इस समस्या को हल करता है this one (सी कोड जिसे .mex फ़ाइल के रूप में संकलित किया जा सकता है; मेरे लिए यह स्वीकार्य उत्तर में rescdsk के कोड से लगभग 20 गुना तेज है)। यह आश्चर्य की बात है कि ऐसा एक सामान्य ऑपरेशन MATLAB अंतर्निहित फ़ंक्शन नहीं है।

+0

धन्यवाद। अभी तक कोशिश नहीं की है लेकिन यह एक अच्छा समाधान की तरह दिखता है। – yuk

संबंधित मुद्दे