मैट्रिक्स या वेक्टर को किसी भी मैट्रिक्स को खाली या खाली करने के कई तरीके हैं। मैट्रिक्स के आकार पर निर्भर करता है, और आप कितनी बार संलग्न करेंगे। (ध्यान दें कि स्पैर मैट्रिस एक पूरी तरह से अलग जानवर हैं। उन्हें अलग से निपटने की ज़रूरत है।)
सरल योजना 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 में स्पष्ट रूप से सुधार हुआ है, इसलिए फ़ंक्शन हैंडल अब तेज़ है।
इन योजनाओं का एक गुण यह है कि उनके पास लाखों खर्च करने की अनुमति देने के दौरान एक वर्ग प्रदर्शन प्रदर्शन दंड नहीं होगा।
ओह ठीक है, प्रश्न पूछे जाने पर मूल रूप से अनुरोध किया गया था, यह निश्चित रूप से अधिक जानकारी है। शायद किसी को इसके बारे में कुछ मिल जाएगा।
+1 आपके अंतिम वाक्य के लिए +1। MATLAB में मैट्रिक्स को प्रारंभ करने का यह सबसे प्रभावी तरीका है। –