2009-10-10 10 views
24

मैं दो स्तंभों के साथ परिवर्तनीय लंबाई का शून्य मैट्रिक्स स्थापित करने की कोशिश कर रहा हूं जिसमें मैं थोड़ी देर के लूप के परिणाम आउटपुट कर सकता हूं (समायोजित समय-चरणों के साथ यूलर विधि से चरण डेटा को स्टोर करने के लिए इसका उपयोग करने के इरादे से) । लंबाई लूप के पुनरावृत्तियों की संख्या द्वारा निर्धारित किया जाएगा।MATLAB में अज्ञात लंबाई का मैट्रिक्स?

मुझे आश्चर्य है कि अगर मैं लूप चला रहा हूं या मुझे इसे शुरू करने के लिए इसे सेट करने की आवश्यकता है, और इसे करने के बारे में कैसे जाना है, तो मैं ऐसा कर सकता हूं।

+0

इसके अलावा, अगर इस क्लास असाइनमेंट पर है और आप पुनरावृत्तियों दिखाने की जरूरत है; आप अपने यूलर कार्यान्वयन के भीतर sprintf का उपयोग कर सकते हैं। – ccook

+0

एक और संबंधित प्रश्न: [एक खाली MATLAB मैट्रिक्स में वेक्टर जोड़ना] (http://stackoverflow.com/q/781410/97160) – Amro

उत्तर

14

स्तंभों की संख्या तय हो गई है तो आप हमेशा अपने मैट्रिक्स के लिए पंक्तियों में जोड़ सकते हैं (पाश अंदर) यदि

उदा

while (....) 
    ..... 
    new_row =[x y] ; % new row with values x & y 
    mat = [mat ; new_row]; 
निश्चित रूप से

यदि आप पहले जबकि पाश इसे और अधिक करने के लिए सक्षम है पुनरावृत्तियों की संख्या पता मैट्रिक्स

+0

बहुत बहुत धन्यवाद! मुझे यह अर्थपूर्ण लग रहा है। आप एक प्रोग्रामिंग इकाई के लिए सोचते हैं, वे हमें कुछ सिखाते हैं लेकिन इसके बजाय वे भेड़ियों को फेंक देते हैं। मुझे बचाने के लिए धन्यवाद :) – Flick

+2

उपरोक्त कोड की अंतिम पंक्ति के लिए वैकल्पिक वाक्यविन्यास का उपयोग करके यह अधिक स्पष्ट हो जाता है कि आप मैट्रिक्स को विस्तारित कर रहे हैं: 'mat (end + 1, :) = new_row;' – nhowe

7

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

लेकिन यह रास्ता अधिक कुशल पहले मैट्रिक्स के लिए स्मृति को आबंटित करने और तो इसका इस्तेमाल होता है। लेकिन अगर आपके कार्यक्रमों को इस तरह की लचीलापन की आवश्यकता है, तो इसके लिए जाओ।

मुझे लगता है कि आपको अपने मैट्रिक्स में पंक्तियों को जोड़ने की आवश्यकता है। निम्नलिखित कोड काम करना चाहिए।

Matrix = []; 

while size(Matrix,1) <= 10 
    Matrix = [Matrix;rand(1,2)]; 
end 

disp(Matrix); 

यहाँ, हम गतिशील अंतरिक्ष Matrix के लिए हर बार जब आप एक नई पंक्ति जोड़ना आवश्यक पुनः दिए जा रहे हैं। यदि आप पहले से जानते हैं, तो कहें, पंक्तियों की संख्या पर ऊपरी बाउंड, आप Matrix = zeros(20,2) घोषित कर सकते हैं और फिर प्रत्येक पंक्ति को मैट्रिक्स में वृद्धिशील रूप से सम्मिलित कर सकते हैं।

% Allocate space using the upper bound of rows (20) 
Matrix = zeros(20,2); 
k = 1; 
for k = 1:10 
    Matrix(k,:) = rand(1,2); 
end 
% Remove the rest of the dummy rows 
Matrix(k+1:end,:) = []; 
+0

+1 मैं इसे हर समय उपयोग करता हूं। ध्यान दें कि आप केवल काउंटर का उपयोग भी कर सकते हैं, और मैटलैब सरणी को बढ़ाएगा। – ccook

+0

मैं यह देखना शुरू कर रहा हूं कि आप क्या कर रहे हैं और यह क्यों कुशल है। बहुत उपयोगी, धन्यवाद। – Flick

4

एक ही बात का एक और स्वाद है कि याकूब तैनात पूर्व आवंटित।

for counter = 1:10 
    Matrix(counter,:) = rand(1,2); 
end 
disp(Matrix); 

इसके बारे में एक "अच्छी" बात यह है कि आप प्रदर्शन के लिए सहायता करने के लिए न्यूनतम आकार अनुमान लगा सकते हैं।

यह रूप में अच्छी तरह ब्याज की हो सकती है: http://www.mathworks.com/help/matlab/math/resizing-and-reshaping-matrices.html#f1-88760

+0

+1 - क्लीनर – Jacob

47

एक और दृष्टिकोण को ध्यान में प्रदर्शन किया है, जबकि अभी भी अंतरिक्ष कुशल बनने की कोशिश कर, बड़े बैचों में स्मृति preallocate के लिए है, और अधिक बैचों रूप में की जरूरत को जोड़ने। यह अच्छी तरह उपयुक्त है अगर आपको बिना किसी जानकारी के कितने सामानों को जोड़ना है।

BLOCK_SIZE = 2000;       % initial capacity (& increment size) 
listSize = BLOCK_SIZE;      % current list capacity 
list = zeros(listSize, 2);     % actual list 
listPtr = 1;        % pointer to last free position 

while rand<1-1e-5       % (around 1e5 iterations on avrg) 
    % push items on list 
    list(listPtr,:) = [rand rand];   % store new item 
    listPtr = listPtr + 1;     % increment position pointer 

    % add new block of memory if needed 
    if(listPtr+(BLOCK_SIZE/10) > listSize) % less than 10%*BLOCK_SIZE free slots 
    listSize = listSize + BLOCK_SIZE;  % add new BLOCK_SIZE slots 
    list(listPtr+1:listSize,:) = 0; 
    end 
end 
list(listPtr:end,:) = [];     % remove unused slots 

संपादित: एक समय की तुलना के रूप में, निम्नलिखित मामलों पर विचार करें:

  1. एक ही कोड के रूप में ऊपर 50000 पुनरावृत्तियों के लिए किया।
  2. पूरे मैट्रिक्स Preallocating पहले से मैट्रिक्स को list = zeros(50000,2); list(k,:) = [x y];
  3. गतिशील रूप से जोड़ने वैक्टर: list = []; list(k,:) = [x y];

मेरी मशीन पर, परिणाम थे:

1) बीता समय ०.०८०२१४ सेकंड है।
2) विलुप्त समय 0.065513 सेकेंड है।
3) विलुप्त समय 24.433315 सेकंड है।


अद्यतन: टिप्पणी में

के बाद विचार विमर्श, मैं कुछ नवीनतम R2014b रिहाई का उपयोग कर परीक्षण को फिर से चलाएं गए हैं। निष्कर्ष यह है कि MATLAB के हाल के संस्करणों ने स्वचालित सरणी विकास के प्रदर्शन में काफी सुधार किया है!

हालांकि एक पकड़ है; सरणी अंतिम आयाम (2 डी matrices के मामले में कॉलम) में बढ़ना चाहिए। यही कारण है कि मूल रूप से इच्छित पंक्तियों को जोड़ना अभी भी बिना किसी पूर्वस्थापन के धीमा है। यह वह जगह है जहां उपरोक्त प्रस्तावित समाधान वास्तव में मदद कर सकता है (बैचों में सरणी को विस्तारित करके)।

परीक्षण का पूरा सेट के लिए यहाँ देखें: https://gist.github.com/amroamroamro/0f104986796f2e0aa618

+4

लगता है वू हू! एक अंतर्दृष्टि बिंदु + माप करने के लिए माप। धन्यवाद। –

+8

पी। सबसे परिवर्तनीय आकार के तरीकों (जैसे स्ट्रिंग क्लास) एक निश्चित ब्लॉक आकार का उपयोग नहीं करते हैं, बल्कि एक गुणात्मक कारक के आकार को आकार में बढ़ाते हैं (आमतौर पर के = 2)। यह ओ (लॉग एन) को आवंटन चरणों के # को बाध्य करता है, और यदि आप स्मृति दक्षता की परवाह करते हैं तो आप हमेशा के = 1.2 या 1.1 चुन सकते हैं और आवंटन चरणों के दक्षता/# को बंद करने के लिए गणित गणना हिट से निपट सकते हैं। –

+5

आप शायद सही हैं .. आप ऐसा करने के लिए कोड को आसानी से संशोधित कर सकते हैं। कई पैरामीटर भी ट्यून किए जा सकते हैं: आकार बढ़ाने के लिए, कितना भी, शायद एक बढ़ता कारक (के = 1.1 से शुरू होता है और 2 तक बढ़ता है) – Amro

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

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