您的位置:首页 > 编程语言 > MATLAB

bsxfun vs. repmat in Matlab

2014-04-16 23:48 281 查看
Documentation from Matlab:
bsxfun:
Apply element-by-element binary operation to two arrays withsingleton
expansion enabled.

repmat:
Replicate and tile an array.

Overview:

There are two approaches to apply element-by-element binary operation to two arrays with singleton expansion enabled, using bsxfun directly or applying repmat first and then make binary
operation. 

Example:

>> a=rand(3,2)
a =

    0.8721    0.3843
    0.9016    0.0373
    0.9518    0.9271

>> b=zeros(3,1)
b =

     0
     0
     0

>> bsxfun(@minus,a,b)% operation
with singleton expansion enabled
ans =

    0.8721    0.3843
    0.9016    0.0373
    0.9518    0.9271

>> a-b % operation with singleton expansion disabled
Error using  - 
Matrix dimensions must agree.

>> a-repmat(b,1,2)
ans =

    0.8721    0.3843
    0.9016    0.0373
    0.9518    0.9271

Speed test:

Below is a speed test of the two approaches. Please find code at Appendix 1.



As shown in the graph, bsxfun is almost twice faster than repeat.

Why bsxfun is faster:

There are two reasons why bsxfun is faster than the other approach:

1. bsxfun avoids explicit allocation of memory and actual replication of the array;

2. bsxfun is one of the multi-threaded Matlab functions.

Furthermore...

Is it a good idea to replace normal (vars in same dimension) element-by-element operation with bsxfun?
Below is the result of my test. Please find test code in Appendix 2.



As shown in the graph, there is no need to replace normal element-by-element operation with bsxfun.

Appendix 1.

Comparison of bsxfun and repmat.

clear;

n = 300;
k = 1; 
a = ones(10,1);

repmat_result = zeros(n,1);
bsxf_result = zeros(n,1);

num_repeat = 100;

tt = zeros(num_repeat,1);
for i = 1:n;
   r = rand(1,i*k);
  
for it = 1:num_repeat;
      tic,
      x = bsxfun(@plus,a,r);
      tt(it) = toc;
  
end;
   bsxf_result(i) = mean(tt) / n;
  
for it = 1:num_repeat;
      tic,
      y = repmat(a,1,i*k)+repmat(r,10,1);
      tt(it) = toc;
  
end;
   repmat_result(i) = mean(tt) / n;
end

plot(bsxf_result,'-r')
hold
on
plot(repmat_result,'-b')
legend('bsxfun','repmat')
xlabel('Complexity')
ylabel('Speed')

title('Speed test of element-by-element binary operation')

Appendix 2.
Comparison of normal binary operation and bsxfun.

clear;

n = 300;
k = 1; 

repmat_result = zeros(n,1);
bsxf_result = zeros(n,1);

num_repeat = 100;

tt = zeros(num_repeat,1);
for i = 1:n;
   r = rand(k,i*k);
  
for it = 1:num_repeat;
      tic,
      x = bsxfun(@plus,r,r);
      tt(it) = toc;
  
end;
   bsxf_result(i) = mean(tt) / n;
  
for it = 1:num_repeat;
      tic,
      y = r+r;
      tt(it) = toc;
  
end;
   repmat_result(i) = mean(tt) / n;
end

plot(bsxf_result,'-r')
hold
on
plot(repmat_result,'-b')
legend('bsxfun','+')

xlabel('Complexity')
ylabel('Speed')
title('Speed test of element-by-element binary operation')
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: