2011-03-17 34 views
24

thể trùng lặp:
How can I divide each row of a matrix by a fixed row?Làm thế nào để trừ một vector từ mỗi hàng của một ma trận?

Tôi đang tìm kiếm một cách thanh lịch để trừ vector tương tự từ mỗi hàng của một ma trận. Đây là một cách không thanh lịch để làm điều đó.

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); 

Ngoài ra, cách thanh lịch không thể chậm hơn phương pháp này.

Tôi đã thử

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

và có vẻ như chậm hơn.

EDIT: Người chiến thắng là phương pháp này.

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

EDIT: Nhiều phương pháp, và tic toc kết quả:

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 

kết quả

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

Về cơ bản đây là bản sao của các câu hỏi khác (cùng ý tưởng, hoạt động số học khác nhau): [Làm cách nào để phân chia các phần tử ma trận theo tổng cột trong MATLAB?] (Http://stackoverflow.com/questions/1773099/how- do-i-phân-ma trận-yếu tố-by-cột-tổng-trong-matlab), [Làm thế nào tôi có thể chia mỗi hàng của một ma trận bởi một hàng cố định?] (http: // stackoverflow.com/questions/4723824/how-can-i-divid-each-row-of-a-ma-ma-by-a-hàng cố định) – gnovice

+4

Đối với những người quá lười biếng để theo các liên kết: 'c = bsxfun (@minus, b, a); ' – Jonas

+0

bsxfun có vẻ chậm hơn, xem chỉnh sửa – Miebster

Trả lời

1

Chỉ có ba câu trả lời rõ ràng, các ngươi đã cho hai người bọn họ trong câu hỏi của bạn.

Thứ ba là bởi hàng,

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

nhưng tôi mong đợi rằng sẽ chậm hơn so với bạn chế biến theo cột ma trận lớn vì nó truy cập các yếu tố ra khỏi trật tự nhớ.

Nếu bạn chuyển xử lý theo cột thành một vòng lặp for trong tệp * .m hoặc hàm phụ, nó vẫn nhanh hơn phiên bản repmat?

Một điều khác bạn có thể kiểm tra tốc độ: Thử preallocating c.

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

Thứ tư là bằng cách sử dụng 'bsxfun', như được giải thích trong các câu trả lời trùng lặp cũng như nhận xét của tôi. – Jonas

6

Đây là đóng góp của tôi:

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

Bây giờ tốc độ thử nghiệm nó:

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

Kết quả:

Elapsed time is 0.099979 seconds.

Không khá nhanh, nhưng nó sạch sẽ.

+0

Điều này cũng hoạt động: 'b - cái (kích thước (b, 1), kích thước (a, 1)) * a' – suzanshakya

+0

Lưu ý rằng nếu kích thước (b) là rất lớn, điều này sẽ rất chậm và cực kỳ không hiệu quả trong bộ nhớ. repmat có thể sẽ hoạt động tốt hơn trong trường hợp đó. –

Các vấn đề liên quan