yuy*_*809 0 matlab loops vector matrix vectorization
我有两个向量,比如A大小为nx1,B大小为1xm.我想C从非线性公式创建一个结果矩阵(nxm)
C(i,j) = A(i)/(A(i)+B(j)).
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过循环执行此操作,例如:
for i=1:n,
C(i,1:m)=A(i)./(A(i)+B(1:m));
end
Run Code Online (Sandbox Code Playgroud)
但是有可能在某种程度上不使用循环吗?
编辑:谢谢你的回答!作为一个小小的补充,在我看到它们之前,朋友提出了以下解决方案:
C = A*ones(1,m)./(ones(n,1)*B+A*ones(1,m))
Run Code Online (Sandbox Code Playgroud)
如果您使用的是MATLAB R2016a或更早版本,则需要使用它bsxfun来完成此任务
result = bsxfun(@rdivide, A, bsxfun(@plus, A, B));
Run Code Online (Sandbox Code Playgroud)
如果您使用的是R2016b或更新版本,则会有隐式扩展,允许您删除bsxfun并直接应用元素运算符
result = A ./ (A + B);
Run Code Online (Sandbox Code Playgroud)
基准
下面是使用一个真正的基准timeit来比较使用的执行速度bsxfun,repmat隐式广播和for循环.从结果中可以看出bsxfun,隐式广播方法产生的执行时间最快.
function comparision()
sz = round(linspace(10, 5000, 30));
times1 = nan(size(sz));
times2 = nan(size(sz));
times3 = nan(size(sz));
times4 = nan(size(sz));
for k = 1:numel(sz)
A = rand(sz(k), 1);
B = rand(1, sz(k));
times1(k) = timeit(@()option1(A,B));
A = rand(sz(k), 1);
B = rand(1, sz(k));
times2(k) = timeit(@()option2(A,B));
A = rand(sz(k), 1);
B = rand(1, sz(k));
times3(k) = timeit(@()option3(A,B));
A = rand(sz(k), 1);
B = rand(1, sz(k));
times4(k) = timeit(@()option4(A,B));
end
figure
p(1) = plot(sz, times1 * 1000, 'DisplayName', 'bsxfun');
hold on
p(2) = plot(sz, times2 * 1000, 'DisplayName', 'repmat');
p(3) = plot(sz, times3 * 1000, 'DisplayName', 'implicit');
p(4) = plot(sz, times4 * 1000, 'DisplayName', 'for loop');
ylabel('Execution time (ms)')
xlabel('Elements in A')
legend(p)
end
function C = option1(A,B)
C = bsxfun(@rdivide, A, bsxfun(@plus, A, B));
end
function C = option2(A,B)
m = numel(B);
n = numel(A);
C = repmat(A,1,m) ./ (repmat(A,1,m) + repmat(B,n,1));
end
function C = option3(A, B)
C = A ./ (A + B);
end
function C = option4(A, B)
m = numel(B);
n = numel(A);
C = zeros(n, m);
for i=1:n,
C(i,1:m)=A(i)./(A(i)+B(1:m));
end
end
Run Code Online (Sandbox Code Playgroud)
有关隐式扩展和比较的更多信息,请参阅此答案bsxfun.