2009-04-23 15 views
14

पर वेक्टर को जोड़ना मुझे मैट्रिक्स कोड मिला है जो मैट्रिक्स (myPointMatrix) में एन-आयामी बिंदु (एन> 1) डालने वाला है और मुझे पहले बिंदु को सम्मिलित करने के बारे में विचार है।एक खाली MATLAB मैट्रिक्स

अभी एक कार्यक्रम डालने से पहले कार्यक्रम myPointMatrix के आकार की जांच करता है। यदि यह 1x1 है, myPointMatrix वर्तमान बिंदु के बराबर सेट है। अन्यथा वर्तमान बिंदु जोड़ा गया है। यह if -स्टेटमेंट केवल एक बार सच है, लेकिन हर बार जब मैं एक बिंदु डालता हूं, तो इसका मूल्यांकन किया जाता है, जो अक्सर होता है।

if को हटाने और myPointMatrix में जोड़ने की कोशिश कर रहा है MATLAB समझदारी से मैट्रिक्स आयामों के बारे में शिकायत नहीं करता है जो लगातार नहीं है। if दोनों को हटाने और myPointMatrix = 0 के इनलाइजेशन को MATLAB को myPointMatrix अपरिभाषित करने का कारण बनता है। यह भी समझ में आता है।

मैं myPointMatrix कैसे शुरू करूं ताकि मैं if -स्टेटमेंट को हटा सकूं? या क्या कोई और स्मार्ट समाधान है?

myPointMatrix = 0; 
for x=0:limit 
    for y=0:limit 
     for z=0:limit 
      tempPoint = [x y z]; 
      if (length(myPointMatrix) == 1) 
       myPointMatrix = tempPoint; 
      else 
       myPointMatrix = [myPointMatrix; tempPoint]; 
      end 
     end 
    end 
end 

उत्तर

13

मैट्रिक्स को आरंभ करने के लिए myPointMatrix = []; का उपयोग करें।

बड़ा myPointMatrix है, धीमा परिचालन होगा। यह धीमा और धीमा हो जाता है, क्योंकि प्रत्येक बार जब आप एक बिंदु मैटलैब जोड़ते हैं तो नए आकार के नए मैट्रिक्स को आवंटित करता है और आपके पुराने मैट्रिक्स से जानकारी को प्रतिलिपि बनाता है + नया मैट्रिक्स में आपका नया बिंदु।

इसके बाद अंतिम आकार के साथ MyPointMatrix प्रारंभ करना और मैट्रिक्स में दिए गए पदों में अंक डालना बेहतर है।

+2

+1 आपके अंतिम वाक्य के लिए +1। MATLAB में मैट्रिक्स को प्रारंभ करने का यह सबसे प्रभावी तरीका है। –

3

आपका सबसे अच्छा विकल्प मैट्रिक्स को पूर्व-आवंटित करना और लूप चर का उपयोग करना है। यह काफी तेज़ होना चाहिए।

limit = 9; 
myPointMatrix = nan((limit+1)^3,3); 

loopVar = 1; 
for x=0:limit 
    for y=0:limit 
     for z=0:limit 
      myPointMatrix(loopVar,:) = [x y z]; 
      loopVar = loopVar + 1; 
     end 
    end 
end 
0

मेरा मानना ​​है कि समाधान आप देख रहे हैं 0 लाइनों और 3 कॉलम के साथ एक मैट्रिक्स के लिए myPointMatrix प्रारंभ करने में है, यानी

myPointMatrix = zeros(0, 3); 

तो पहला काम

myPointMatrix = [myPointMatrix; tempPoint]; 

सही ढंग से काम करेंगे, साथ ही बाद वाले वाले। काम लिखने के लिए एक बराबर तरीका

myPointMatrix(end+1,:) = tempPoint; 

हालांकि एक मैट्रिक्स से बढ़ रहा से ध्यान में रखना जैसे कि, कुशल नहीं है और, के रूप में AnnaR का कहना है कि भारतीय विदेश सेवा अंतिम आकार के साथ myPointMatrix आरंभ, यदि ज्ञात एक बेहतर समाधान है।

28

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

सरल योजना concatenation का उपयोग करेगा। उदाहरण के लिए, मैं एक यादृच्छिक सरणी बनाउंगा। जबकि मुझे पता है कि रैंड के लिए एक कॉल यहां उचित समाधान होगा, मैं केवल तुलना उद्देश्यों के लिए कर रहा हूं।

n = 10000; 
tic 
A = []; 
for i = 1:n 
    Ai = rand(1,3); 
    A = [A;Ai]; 
end 
toc 

Elapsed time is 9.537194 seconds. 

देखें कि आवश्यक समय उचित रूप से उच्च था, जिसे मैंने सीधे रैंड कहा था।

tic,rand(n,3);toc 
Elapsed time is 0.008036 seconds. 

संलग्न करने के अन्य तरीके समय के समान हैं। उदाहरण के लिए, आप भी अनुक्रमणित करके जोड़ सकते हैं।

A = []; 
A(end+1,:) = rand(1,3); 
A 
A = 
     0.91338  0.63236  0.09754 

यह संगतता के माध्यम से जोड़ने के समय के समान होगा। समझने के लिए एक दिलचस्प तथ्य यह है कि एक सरणी में नई पंक्तियों को जोड़ना नए कॉलम जोड़ने से काफी अलग है। कॉलम की तुलना में पंक्ति जोड़ने में थोड़ा और समय लगता है। यह MATLAB में तत्वों को संग्रहीत करने के तरीके के कारण है। एक नई पंक्ति को जोड़ना मतलब है कि तत्वों को वास्तव में स्मृति में शफल किया जाना चाहिए।

A = zeros(10000,3); 
B = zeros(3,10000); 

tic,for i = 1:100,A(end+1,:) = rand(1,3);end,toc 
Elapsed time is 0.124814 seconds. 

tic,for i = 1:100,B(:,end+1) = rand(3,1);end,toc 
Elapsed time is 0.116209 seconds. 

किसी भी संलग्न संचालन के साथ समस्या यह है कि MATLAB स्मृति एक के लिए आवश्यक पुनः आवंटित करना चाहिए, और इसलिए हर बार मैट्रिक्स आकार में बढ़ता है। चूंकि ए का आकार रैखिक रूप से बढ़ता है, इसलिए कुल समय आवश्यक है n के साथ चौकोर रूप से बढ़ता है। तो क्या हम एन के आकार को दोगुना कर रहे थे, गतिशील रूप से उगाए जाने वाले ए को निर्माण के लिए चार गुना लंबा लगेगा। यह वर्गिक व्यवहार यही कारण है कि लोग आपको अपने MATLAB सरणी को आवंटित करने के लिए कहते हैं जब वे गतिशील रूप से उगाए जाएंगे। वास्तव में, यदि आप संपादक में मिलिंट झंडे देखते हैं, तो MATLAB आपको यह चेतावनी देता है जब यह हो रहा है।

यदि आप ए के अंतिम आकार को जानते हैं तो एक बेहतर समाधान है, इसे अंतिम आकार में ए आवंटित करना है। तो बस में सूचकांक।

tic 
A = zeros(n,3); 
for i = 1:n 
    A(i,:) = rand(1,3); 
end 
toc 

Elapsed time is 0.156826 seconds. 

इस जबकि गतिशील हो गई सरणी तुलना में काफी बेहतर यह अभी भी रैंड के एक vectorized उपयोग से भी बदतर है,। तो जहां भी संभव हो, इस तरह के कार्यों के वेक्टरकृत रूप का उपयोग करें।

समस्या यह है कि, कभी-कभी आप नहीं जानते कि आप कितने तत्वों का अंत करेंगे। गंदे वर्गिक विकास से बचने के लिए अभी भी कई चालें उपयोग कर सकती हैं।

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

पॉइंटर्स का उपयोग करने के लिए एक दूसरी चाल है। जबकि MATLAB वास्तव में पॉइंटर्स के रास्ते में अधिक क्षमता प्रदान नहीं करता है, एक सेल सरणी उस दिशा में एक कदम है।

tic 
C = {}; 
for i = 1:n 
    C{end+1} = rand(1,3); 
end 
A = cat(1,C{:}); 
toc 

Elapsed time is 3.042742 seconds. 

उगाए गए सरणी से पूरा करने में कम समय लगा। क्यूं कर? हम केवल कोशिकाओं को पॉइंटर्स की एक सरणी बना रहे थे। इसके बारे में एक अच्छी बात यह है कि यदि प्रत्येक संलग्न चरण में पंक्तियों की एक चर संख्या है, तो यह अभी भी अच्छी तरह से काम करता है।

सेल सरणी के साथ एक समस्या, यह बहुत कुशल नहीं है जब तत्वों को जोड़ने के लिए लाखों तत्व हैं। यह अभी भी एक वर्गबद्ध ऑपरेशन है, क्योंकि हम प्रत्येक चरण में पॉइंटर्स की सरणी बढ़ रहे हैं।

उस समस्या का समाधान ऊपर दिखाए गए दो शैलियों का एक मिश्रण का उपयोग करना है। इस प्रकार, आकार में मामूली रूप से बड़े होने के लिए सेल सरणी के प्रत्येक कक्ष को परिभाषित करें।अब सेल में ए की नई पंक्तियों को भरने के लिए अनुक्रमण का उपयोग करें। जब अगले सेल को अगले ऐपेंड चरण से बड़ा किया जाना चाहिए, तो सेल सरणी में बस एक नया सेल जोड़ें।

कुछ साल पहले, यह चर्चा MATLAB समाचार समूह पर उभरी, और इन पंक्तियों के साथ कई समाधान प्रस्तावित किए गए। मैंने MATLAB केंद्रीय फ़ाइल एक्सचेंज पर फ़ाइलों के रूप में growdata & growdata2 समाधान पोस्ट किए। Growdata2 इस्तेमाल किया समारोह समस्या को हल करने संभालता है:

tic 
Ahandle = growdata2; 
for i = 1:n 
    Ahandle(rand(1,3)) 
end 
% unpack the object into a normal array 
A = Ahandle(); 
toc 

Elapsed time is 1.572798 seconds. 

समय में, यह लगातार चर का उपयोग करने के लिए कुछ हद तक एक तेजी से दृष्टिकोण था।

tic 
growdata 
for i = 1:n 
    growdata(rand(1,3)) 
end 
A = growdata; 
toc 

Elapsed time is 2.048584 seconds. 

तब से फ़ंक्शन हैंडल के कार्यान्वयन में MATLAB में स्पष्ट रूप से सुधार हुआ है, इसलिए फ़ंक्शन हैंडल अब तेज़ है।

इन योजनाओं का एक गुण यह है कि उनके पास लाखों खर्च करने की अनुमति देने के दौरान एक वर्ग प्रदर्शन प्रदर्शन दंड नहीं होगा।

ओह ठीक है, प्रश्न पूछे जाने पर मूल रूप से अनुरोध किया गया था, यह निश्चित रूप से अधिक जानकारी है। शायद किसी को इसके बारे में कुछ मिल जाएगा।

0

यह तुम क्या जरूरत है

myPointMatrix=[]; 
for x=0:limit 
for y=0:limit 
for x=0:limit 
    myPointMatrix(:,end+1)=[x y z]; 
end 
end 
end 

है, लेकिन केवल मामला है कि आप, [X Y Z] के साथ कुछ nonlinear आपरेशन कर इससे पहले कि आप आवंटित में। नहीं तो आप इस प्रकार के ऊपर लाइनों लिख सकते हैं:

myPointMatrix=[]; 
myPointMatrix(1,:)=kron([1:limit],ones(1,limit^2)); 
myPointMatrix(2,:)=kron([1:limit^2],ones(1,limit)); 
myPointMatrix(3,:)=kron(ones(1,limit^2),[1:limit]); 

ऊपर पूरी तरह से vectorised है, हालांकि एक edit kron.m करना चाहते हैं और logical के साथ कुछ find बदल सकता है ... लेकिन आप कि अपने आप को मुझे लगता है क्या कर सकते हैं .. : डी

0
%appending to matlab array "f": 

lfg=[697 770 852 941]; 
hfg=[1209 1336 1477]; 
f=[]; 
for i=1:4, 
    for j=1:3, 
     %f = [ f [lfg(i);hfg(j)] ]; 
     append(f , [lfg(i);hfg(j)]); 
    end 
end 
f