2009-06-11 12 views
85

मुझे आश्चर्य है कि MATLAB में नक्शा फ़ंक्शन नहीं है, इसलिए मैंने एक साथ खुद को हैक किया क्योंकि यह ऐसा कुछ है जिसके बिना मैं नहीं रह सकता। क्या वहां कोई बेहतर संस्करण है? क्या MATLAB के लिए कुछ हद तक मानक कार्यात्मक प्रोग्रामिंग लाइब्रेरी है जो मुझे याद आ रही है?MATLAB में मानचित्र फ़ंक्शन?

function results = map(f,list) 
% why doesn't MATLAB have a Map function? 
results = zeros(1,length(list)); 
for k = 1:length(list) 
    results(1,k) = f(list(k)); 
end 

end 

उपयोग उदा।

map(@(x)x^2,1:10) 
+11

सबक # 1 मैटलैब को अन्य भाषाओं से जा रहा: लूप का प्रयोग न करें, वे परिमाण एक vectorized समाधान की तुलना में धीमी के कुछ आदेश हैं। – CookieOfFortune

+1

रिकर्सन के बारे में क्या? – Dario

+15

जेआईटी की शुरूआत के साथ, लूप के लिए वे जुर्माना नहीं लेते हैं जो उन्होंने एक बार किया था। – MatlabDoug

उत्तर

1

यदि मैटलैब नक्शा समारोह में निर्मित नहीं है, तो यह दक्षता विचारों के कारण हो सकता है। आपके कार्यान्वयन में आप सूची के तत्वों पर पुनरावृत्ति करने के लिए एक लूप का उपयोग कर रहे हैं, जो आमतौर पर मैटलैब दुनिया में फंस जाता है। अधिकांश अंतर्निहित मैटलैब फ़ंक्शंस "वेक्टरकृत" हैं, i। ई। अपने आप को फिर से चालू करने और प्रत्येक तत्व के लिए फ़ंक्शन को कॉल करने के बजाय, संपूर्ण सरणी पर फ़ंक्शन को कॉल करना अधिक कुशल है।

दूसरे शब्दों में, इस


a = 1:10; 
a.^2 

इस


a = 1:10; 
map(@(x)x^2, a) 

नक्शे की अपनी परिभाषा यह सोचते हैं की तुलना में बहुत तेजी से होता है।

+1

मुझे लगता है कि उनका मुद्दा यह नहीं था कि वह इसे लूप के लिए जरूरी रूप से चाहता था, लेकिन आपूर्ति के सरणी के संबंधित तत्वों को आपूर्ति किए गए फ़ंक्शन को लागू करने के परिणामों की सरणी के परिणामस्वरूप इसे निर्दिष्ट किया जा सके। मुझे ज्यादा matlab नहीं पता, लेकिन ऐसा लगता है कि सरणी काम करता है। –

+1

अधिकांश अंतर्निहित मैटलैब फ़ंक्शंस और ऑपरेटर पहले से ही ऐसा करते हैं: वे इनपुट सरणी के प्रत्येक तत्व पर काम करते हैं, और वे परिणामों की एक समान सरणी लौटाते हैं। – Dima

123

संक्षिप्त उत्तर:

>> y = arrayfun(@(x) x^2,1:10) 
y = 

    1  4  9 16 25 36 49 64 81 100 

दो अन्य में निर्मित कार्यों कि समान व्यवहार कर रहे हैं: CELLFUN (जो संचालित में निर्मित समारोह ARRAYFUN वास्तव में क्या आपके नक्शा समारोह संख्यात्मक सरणियों के लिए करता है सेल सरणी के तत्वों पर) और STRUCTFUN (जो संरचना के प्रत्येक क्षेत्र पर संचालित होता है)।

हालांकि, यदि आप वेक्टरेशन का लाभ उठाते हैं, तो विशेष रूप से तत्व-वार arithmetic operators का उपयोग करके इन कार्यों को अक्सर जरूरी नहीं है। उदाहरण आप दे दी है के लिए, एक vectorized समाधान होगा:

>> x = 1:10; 
>> y = x.^2 
y = 

    1  4  9 16 25 36 49 64 81 100 

कुछ आपरेशन स्वचालित रूप से करते हैं जबकि अन्य ऑपरेटरों तत्व के लिहाज से आपरेशन के लिए एक विशेष वाक्य रचना है (एक वेक्टर के लिए एक अदिश मूल्य को जोड़ना) तत्वों भर में संचालित होगा (निरूपित किया ऑपरेटर से पहले "।" द्वारा। MATLAB में कई फ़ंक्शन तत्व-वार ऑपरेशंस का उपयोग करके वेक्टर और मैट्रिक्स तर्कों पर काम करने के लिए डिज़ाइन किए गए हैं, और इस प्रकार मानचित्र कार्यों की आवश्यकता नहीं है।

संक्षेप में, यहाँ एक सरणी में प्रत्येक तत्व वर्ग के लिए कुछ अलग तरीके हैं:

x = 1:10;  %// Sample array 
f = @(x) x.^2; %// Anonymous function that squares each element of its input 

%// Option #1: 
y = x.^2; %// Use the element-wise power operator 

%// Option #2: 
y = f(x); %// Pass a vector to f 

%// Option #3: 
y = arrayfun(f,x); %// Pass each element to f separately 
बेशक

, इस तरह के एक सरल ऑपरेशन के लिए, विकल्प # 1 सबसे समझदार विकल्प है।

+2

किसी को ध्यान रखना चाहिए कि विकल्प 1 न केवल सरल है, बल्कि तेज़ है (विकल्प 3, 2 की तुलना में 1 के समान होना चाहिए)! –

0

आपको map की आवश्यकता नहीं है क्योंकि मूल्यों की सूची पर लागू स्केलर-फ़ंक्शन प्रत्येक मान पर लागू होता है और इसलिए map के समान काम करता है। बस

l = 1:10 
f = @(x) x + 1 

f(l) 

, तुम भी

l.^2 
+9

-1: यह वास्तव में सच नहीं है। Matlab में स्केलर फ़ंक्शन निर्दिष्ट करने के लिए पर्याप्त प्रकार की प्रणाली नहीं है। एफ को वेक्टर के साथ बुलाया जाता है और आपके उदाहरण में एक एकल वेक्टर जोड़ किया जाता है। इसे सत्यापित करने के लिए, कोड चलाने से पहले अपने कोड नमूना ("प्रोफ़ाइल पर" प्रोफ़ाइल करें, उसके बाद "प्रोफ़ाइल बंद करें" इसके बाद)। आप देखेंगे कि एफ के लिए एक ही कॉल है। –

10

लिख सकता वेक्टर और तत्व के लिहाज से संचालन के अलावा कोशिश अपने विशेष मामले में, वहाँ भी cellfun सेल सरणियों से अधिक मानचित्रण कार्य के लिए है।उदाहरण के लिए:

cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false) 
ans = 
    'A' 'B' 'C' 

यदि 'UniformOutput' सच है (या नहीं प्रदान की), यह सेल सरणी के आयाम के अनुसार परिणाम को श्रेणीबद्ध करने के लिए है, तो प्रयास करेंगे

cellfun(@upper, {'a', 'b', 'c'}) 
ans = 
ABC 
3

एक नहीं बल्कि सरल उपाय , मैटलैब के vectorization का उपयोग कर होगा:

a = [ 10 20 30 40 50 ]; % the array with the original values 
b = [ 10 8 6 4 2 ]; % the mapping array 
c = zeros(1, 10); % your target array 

अब, टाइपिंग

c(b) = a 

रिटर्न

c = 0 50  0 40  0 30  0 20  0 10 

ग (ख) ख द्वारा दिए गए सूचकांक में ग के तत्वों के साथ आकार 5 का एक वेक्टर के लिए एक संदर्भ है। अब यदि आप इस संदर्भ वेक्टर में मानों को मानते हैं, तो सी में मूल मान ओवरराइट किए जाते हैं, क्योंकि सी (बी) में सी के मानों और कोई प्रतियां नहीं हैं।

1

ऐसा लगता है कि निर्मित arrayfun यदि परिणाम की जरूरत समारोह की एक सरणी है काम नहीं करता: जैसे: नक्शा (@ (x) [xx^2 x^3], 1: 10)

कर नीचे इस काम बेहतर मामूली mods:

function results = map(f,list) 
% why doesn't MATLAB have a Map function? 
for k = 1:length(list) 
    if (k==1) 
     r1=f(list(k)); 
     results = zeros(length(r1),length(list)); 
     results(:,k)=r1; 
    else 
     results(:,k) = f(list(k)); 

    end; 
end; 
end 
+5

[ARRAYFUN] (http://www.mathworks.com/help/techdoc/ref/arrayfun.html) आपके उदाहरण के लिए काम करेगा, आपको केवल इनपुट तर्क '...,' UniformOutput ', false को शामिल करना होगा); 'अपने सरणी वाले सेल सरणी आउटपुट को बनाने के लिए, फिर प्रारूपित करें और उन्हें गठबंधन करें, हालांकि आप एक गैर-सेल सरणी में चाहते हैं। – gnovice

-1

समाधान पिछले जवाब में वर्णित के रूप vectorizing गति के लिए शायद सबसे अच्छा समाधान है। वेक्टरिज़िंग भी बहुत मैटलबी है और अच्छा लगता है।

इसके साथ मैटलैब में अब एक नक्शा कंटेनर क्लास है।

देखें http://www.mathworks.com/help/matlab/map-containers.html

+0

ओप उच्च-आदेश फ़ंक्शन के बारे में बात कर रहा है, यानी 'सेलफुन' एट अल।, हैश टेबल या कुंजी-मूल्य जोड़े नहीं। –

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

  • कोई संबंधित समस्या नहीं^_^