如何在不使用MATLAB循环的情况下从行向量和列向量创建矩阵?

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)

Sue*_*ver 6

如果您使用的是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.