MATLAB

12

में बहुत बड़ी matrices के कुशल गुणात्मकता मेरे पास एक विकर्ण डी-बाय-डी मैट्रिक्स बनाने के लिए पर्याप्त स्मृति नहीं है, क्योंकि डी बड़ा है। मैं 'स्मृति से बाहर' त्रुटि प्राप्त करता रहता हूं।MATLAB

पहले गुणा में एम एक्स डी एक्स डी संचालन करने के बजाय, मैं एम एक्स डी ऑपरेशंस करता हूं, लेकिन फिर भी मेरे कोड को चलाने के लिए उम्र लगती है।

क्या किसी को गुणा A'*B*A गुणा करने के लिए एक और अधिक प्रभावी तरीका मिल सकता है? (एम प्रतियों के साथ

D=20000 
M=25 

A = floor(rand(D,M)*10); 
B = floor(rand(1,D)*10); 

for i=1:D 
    for j=1:M 
     result(i,j) = A(i,j) * B(1,j); 
    end 
end  

manual = result * A'; 
auto = A*diag(B)*A'; 
isequal(manual,auto) 

alt text

+0

मैं उलझन में हूं। क्या मैट्रिक्स बी डी-बाय-डी या एम-बाय-एम होना चाहिए? आपकी छवि पूर्व कहती है लेकिन आपका कोड बाद वाले को सुझाव देता है। – gnovice

+0

अच्छी तरह से देखा गया, अब – matcheek

+0

को सही किया गया है, क्या आप ए '* बी * ए की गणना करने की कोशिश कर रहे हैं, जो आपको एम-बाय-एम परिणाम देगा? – gnovice

उत्तर

12

आपकी समस्या को हल करने वाला एक विकल्प sparse matrices का उपयोग कर रहा है। यहाँ एक उदाहरण है:

D = 20000; 
M = 25; 
A = floor(rand(D,M).*10); %# A D-by-M matrix 
diagB = rand(1,D).*10;  %# Main diagonal of B 
B = sparse(1:D,1:D,diagB); %# A sparse D-by-D diagonal matrix 
result = (A.'*B)*A;   %'# An M-by-M result 

एक अन्य विकल्प समारोह REPMAT का उपयोग कर एक एम-दर-डी मैट्रिक्स बनाने के लिए B की मुख्य विकर्ण साथ डी तत्वों को दोहराने के लिए हो सकता है, तो का उपयोग element-wise multiplicationA.' साथ:

B = repmat(diagB,M,1); %# Replicate diagB to create an M-by-D matrix 
result = (A.'.*B)*A; %'# An M-by-M result 

और फिर भी एक और विकल्प समारोह BSXFUN उपयोग करने के लिए होगा:

result = bsxfun(@times,A.',diagB)*A; %'# An M-by-M result 
+0

बहुत बहुत धन्यवाद, अगर मेमोरी एक मुद्दा है, तो मुझे – matcheek

+2

पर जाने के लिए घंटे लग गए, 'bsxfun' को' repmat' 'के लिए प्राथमिकता दी जाती है, क्योंकि यह एक प्रतिकृति मैट्रिक्स नहीं बनाता है। हालांकि, 'bsxfun' Matlab 2006 तक उपलब्ध नहीं हुआ था ... – shabbychef

+0

बहुत कुछ समझाते हुए, रोजाना सीखना – matcheek

3

शायद मैं एक brainfart यहाँ का एक सा हो रही है, लेकिन आप एक DXM मैट्रिक्स में अपने DxD मैट्रिक्स चालू नहीं कर सकता: यहाँ क्या मैं अब तक का प्रयास किया गया है वेक्टर का आपको दिया गया है) और फिर। * पिछले दो मैट्रिक्स उन्हें गुणा करने के बजाए (और फिर, ज़ाहिर है, आमतौर पर पाए गए उत्पाद मात्रा के साथ पहले गुणा करें)?

+0

प्राप्त करने की कोशिश कर रहा हूं, मैं 'स्मृति त्रुटि से बाहर' की वजह से डी एक्स डी नहीं बना रहा हूं, यह तब आसान होगा। आपका समाधान मुझे 'स्मृति से बाहर' त्रुटि देता है लगभग स्पॉट खान पर थोड़ा सा समय लगता है लेकिन वास्तव में वही करता है। वे दोनों सही हैं, लेकिन matrices विशाल हैं। – matcheek

+0

मेरे समाधान और gnovice दोनों केवल ओ (डीएक्सएम) भंडारण की आवश्यकता है। मुझे नहीं पता कि मेरा समाधान गलत क्यों है जबकि वह ठीक है। वास्तव में, उसका प्रतिनिधि समाधान मेरा है (गुणा के क्रम तक, जो कोई फर्क नहीं पड़ता)। –

+0

आपके उत्तर के लिए धन्यवाद। इसे स्पष्ट करने के लिए, मैंने आपके समाधान का प्रयास किया लेकिन 'स्मृति से बाहर' त्रुटि को दूर नहीं कर सका। – matcheek

3
  1. आपको "स्मृति से बाहर" मिल रहा है क्योंकि MATLAB को संपूर्ण मैट्रिक्स को समायोजित करने के लिए पर्याप्त मेमोरी का एक हिस्सा नहीं मिल सकता है। in MATLAB documentation वर्णित इस त्रुटि से बचने के लिए विभिन्न तकनीकें हैं।

  2. MATLAB में आपको स्पष्ट रूप से अधिकांश मामलों में प्रोग्रामिंग स्पष्ट लूप की आवश्यकता नहीं है क्योंकि आप ऑपरेटर * का उपयोग कर सकते हैं। मैट्रिक्स गुणा को तेज करने के लिए एक तकनीक मौजूद है यदि यह स्पष्ट लूप के साथ किया जाता है, तो यहां an example in C# है। यह एक अच्छा विचार है कि कैसे (संभावित रूप से बड़े) मैट्रिक्स को छोटे मैट्रिस में विभाजित किया जा सकता है। MATLAB में इन छोटी मैट्रिक्स को रखने के लिए आप सेल मैट्रिक्स का उपयोग कर सकते हैं। यह शायद अधिक है कि सिस्टम को दो छोटे उप-मैट्रिक्स को समायोजित करने के लिए पर्याप्त रैम मिलती है जिसके परिणामस्वरूप बड़े मैट्रिक्स होते हैं।

+1

मैं एक बड़ा अज्ञान हूं और कैश मिस, लूप अनोलिंग या शाखा भविष्यवाणी के बारे में एक पल के लिए घटना नहीं सोचा है , लेकिन एक अनुस्मारक – matcheek

+0

@matcheek के लिए धन्यवाद: छोटे मैट्रिक्स को छोटे में विभाजित करने की तकनीक रैम पर उसी तरह लागू की जा सकती है जैसे इसे कैश पर लागू किया जाता है। आपके लिए कैश बिल्कुल कोई फर्क नहीं पड़ता, लेकिन रैम करता है। – Mikhail