2011-03-17 33 views
24

संभव डुप्लिकेट:
How can I divide each row of a matrix by a fixed row?मैट्रिक्स की प्रत्येक पंक्ति से वेक्टर को घटाना कैसे करें?

मैं एक मैट्रिक्स की प्रत्येक पंक्ति से एक ही वेक्टर घटाना एक सुंदर रास्ता तलाश कर रहा हूँ। इसे करने का एक सुरुचिपूर्ण तरीका यहां है।

a = [1 2 3]; 
b = rand(7,3); 
c(:,1) = b(:,1) - a(1); 
c(:,2) = b(:,2) - a(2); 
c(:,3) = b(:,3) - a(3); 

इसके अलावा, सुरुचिपूर्ण तरीका इस विधि से धीमा नहीं हो सकता है।

मैं

c = b-repmat(a,size(b,1),1); 

की कोशिश की है और यह धीमी लगती है।

संपादित करें: विजेता यह तरीका है।

c(:,1) = b(:,1) - a(1); 
c(:,2) = b(:,2) - a(2); 
c(:,3) = b(:,3) - a(3); 

संपादित करें: अधिक विधियों, और टिक toc परिणाम:

n = 1e6; 
m = 3; 
iter = 100; 
a = rand(1,m); 
b = rand(n,m); 

tic 
c = zeros(size(b)); 
for i = 1:iter 
    c(:,1) = b(:,1) - a(1); 
    c(:,2) = b(:,2) - a(2); 
    c(:,3) = b(:,3) - a(3); 
end 
toc 

tic 
c = zeros(size(b)); 
for i = 1:iter 
    c(:,1) = b(:,1) - a(1); 
    c(:,2) = b(:,2) - a(2); 
    c(:,3) = b(:,3) - a(3); 
end 
toc 

tic 
c = zeros(size(b)); 
for i = 1:iter 
    for j = 1:3 
     c(:,j) = b(:,j) - a(j); 
    end 
end 
toc 

tic 
for i = 1:iter 
    c = b-repmat(a,size(b,1),1); 
end 
toc 

tic 
for i = 1:iter 
    c = bsxfun(@minus,b,a); 
end 
toc 

tic 
c = zeros(size(b)); 
for i = 1:iter 
    for j = 1:size(b,1) 
     c(j,:) = b(j,:) - a; 
    end 
end 
toc 

परिणाम

Elapsed time is 0.622730 seconds. 
Elapsed time is 0.627321 seconds. 
Elapsed time is 0.713384 seconds. 
Elapsed time is 2.621642 seconds. 
Elapsed time is 1.323490 seconds. 
Elapsed time is 17.269901 seconds. 
+2

यह मूल रूप से इन अन्य प्रश्नों (एक ही विचार, विभिन्न अंकगणितीय ऑपरेशन) का डुप्लिकेट है: [MATLAB में कॉलम रकम द्वारा मैट्रिक्स तत्वों को कैसे विभाजित किया जा सकता है?] (Http://stackoverflow.com/questions/1773099/how- do-i-divide-matrix-elements-by-column-sums-in-matlab), [मैं एक निश्चित पंक्ति से मैट्रिक्स की प्रत्येक पंक्ति को कैसे विभाजित कर सकता हूं?] (http: // stackoverflow।कॉम/प्रश्न/4723824/कैसे-कैन-आई-डिवाइड-प्रत्येक-पंक्ति-ऑफ-ए-मैट्रिक्स-बाय-ए-फिक्स्ड-पंक्ति) – gnovice

+4

उन लोगों के लिए जो लिंक का पालन करने के लिए आलसी हैं: 'c = bsxfun (@minus, बी, ए); ' – Jonas

+0

bsxfun धीमा लगता है, – Miebster

उत्तर

1

केवल तीन स्पष्ट जवाब नहीं है, और आप अपने सवाल में उनमें से दो दे दी है।

तीसरे, पंक्ति के द्वारा होता है

c(1,:) = b(1,:) - a; %... 

लेकिन मैं उम्मीद थी, क्योंकि यह तत्व तक पहुँचता स्मृति के आदेश से बाहर है कि बड़े matrixes के लिए अपने द्वारा कॉलम प्रसंस्करण की तुलना में धीमी होने के लिए।

यदि आप अपनी बाय-कॉलम प्रोसेसिंग को for लूप को * .m फ़ाइल या उपखंड में बदलते हैं, तो यह repmat संस्करण से अभी भी तेज़ है?

एक और चीज जो आप गति के लिए जांच सकते हैं: c को पूर्ववत करने का प्रयास करें।

c = b - ones(size(b))*diag(a)

अब यह परीक्षण गति:

c = zeros(size(b)); 
c(:,1) = b(:,1) - a(1); %... 
+0

चौथाई 'bsxfun' का उपयोग करके है, जैसा कि डुप्लिकेट उत्तरों के साथ-साथ मेरी टिप्पणी में बताया गया है। – Jonas

6

यहाँ मेरी योगदान है

tic 
for i = 1:10000 
    c = zeros(size(b)); 
    b = rand(7,3); 
    c = b - ones(size(b))*diag(a); 
end 
toc 

परिणाम:

Elapsed time is 0.099979 seconds.

उतना तेज़ नहीं है, लेकिन यह साफ़ है।

+0

यह भी काम करता है: 'बी - वाले (आकार (बी, 1), आकार (ए, 1)) * ए' – suzanshakya

+0

ध्यान दें कि यदि आकार (बी) बहुत बड़ा है, तो यह स्मृति में बहुत धीमा और बेहद अक्षम होगा। रिपैम उस मामले में बेहतर काम करेगा। –

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