【问题标题】:Generating arrays using bsxfun with anonymous function and for elementwise subtractions - MATLAB使用带有匿名函数和元素减法的 bsxfun 生成数组 - MATLAB
【发布时间】:2014-12-22 22:31:49
【问题描述】:

我有以下代码:

n = 10000; 
s = 100;
Z = rand(n, 2);
x = rand(s, 1);
y = rand(s, 1);
fun = @(a) exp(a);

原则上,匿名函数f 可以有不同的形式。我需要创建两个数组。

首先,我需要使用通用元素创建一个大小为n x s x s 的数组

fun(Z(i, 1) - x(j)) * fun(Z(i, 2) - y(k))

其中i=1,...nj,k=1,...,s。我可以轻松做的是使用bsxfun 构造矩阵,例如

bsxfun(@(x, y) fun(x - y), Z(:, 1), x');
bsxfun(@(x, y) fun(x - y), Z(:, 2), y');

但是我需要通过将这两个矩阵的每一列按元素相乘来将它们组合成 3D 数组。


在第二步中,我需要创建一个大小为n x 3 x s x s 的数组,它从一侧看起来像下面的矩阵

[ones(n, 1), Z(:, 1) - x(i), Z(:, 2) - y(j);]

i=1,...sj=1,...s。我可以用类似的东西循环两个额外的维度

A = [ones(n, 1), Z(:, 1) - x(1), Z(:, 2) - y(1)];
for i = 1:s
    for j = 1:s
        A(:, :, i, j) = [ones(n, 1), Z(:, 1) - x(i), Z(:, 2) - y(j);];
    end
end

有没有办法避免循环?


在第三步中,假设在获得数组out1(从第一步输出)后,我想创建一个维度为n x n x s x s的新数组out3,其中包含主上的原始数组out1对角线,即out3(i,i,s,s) = out1(i, s, s)out3(i,j,s,s)=0 对于所有i~=j。是否有某种替代 diag 来创建“对角线数组”?或者,如果我创建 n x n x s x s 零数组,有没有办法将 out1 放在主对角线上?

【问题讨论】:

    标签: matlab vectorization bsxfun


    【解决方案1】:

    代码

    exp_Z_x = exp(bsxfun(@minus,Z(:,1),x.')); %//'
    exp_Z_y = exp(bsxfun(@minus,Z(:,2),y.')); %//'
    out1 = bsxfun(@times,exp_Z_x,permute(exp_Z_y,[1 3 2]));
    
    Z1 = [ones(n,1) Z(:,1) Z(:,2)];
    X1 = permute([ zeros(s,1) x zeros(s,1)],[3 2 1]);
    Y1 = permute([ zeros(s,1) zeros(s,1) y],[4 2 3 1]);
    out2 = bsxfun(@minus,bsxfun(@minus,Z1,X1),Y1);
    
    out3 = zeros(n,n,s,s); %// out3(n,n,s,s) = 0; could be used for performance
    out3(bsxfun(@plus,[1:n+1:n*n]',[0:s*s-1]*n*n)) = out1; %//'
    
    %// out1, out2 and out3 are the desired outputs
    

    【讨论】:

    • @Laimond 第二部分有一个bug,一个很大的。请检查修复的编辑!
    • 我犯了一个错误。它应该是 Z1 的第三列中的 Z(:, 2)。谢谢!
    • @Laimond 已编辑! :) 如果您不介意被打扰,只是好奇 - 这些解决方案与您的 bsxfun with anonymous functions 相比如何?任何运行时比较?
    • 确实,这是一个非常好的加速。用@minus 做 bsxfun 比用匿名函数做 bsxfun 快 50 倍以上(我做了一个单独的模拟)。我印象非常深刻!:) 谢谢!
    • @Laimond 太棒了,感谢您的这些测试!好吧,我也有这种预感,只是想加强它! :)
    猜你喜欢
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 2015-05-14
    相关资源
    最近更新 更多