是否有一个版本的bsxfun可以在结构数组上工作?



为什么我可以这样做:

a = [1 2];
b = [3 4];
bsxfun(@(ai,bj) ai + bj, a, b')
% 4     5
% 5     6

但不是这个:

a = struct('x', {1 2});
b = struct('x', {3 4});
bsxfun(@(ai,bj) ai.x + bj.x, a, b');
% Error using bsxfun
% Operands must be numeric arrays.

是否存在一个在两种情况下都有效的替代函数?

这可能不是一个通用的解决方案*但是对于您的特定示例,很容易将您的结构数组转换为数值数组 bsxfun中,通过使用逗号分隔列表生成器语法,然后使用您的原始匿名函数,即

>> bsxfun(@(ai, bj) ai+bj, [a.x], [b.x]')
ans =
     4     5
     5     6

,这应该仍然利用bsxfun赋予的计算效率(例如,与慢得多的"repmat + arrayfun"方法相反)。


* <子>。如果字段包含数组而不是标量,则可能无法正常工作,因为展开到逗号分隔的列表将是不同的

变通方法:

function res = bsxfun_struct(f, A, B)
    % best way to ensure our output size matches the behaviour of bsxfun is just to call it
    dummy = bsxfun(@(ai, bj) ai+bj, zeros(size(A)), zeros(size(B)));
    res_size = size(dummy);
    % repeat the matrices as needed
    Arep = repmat(A, res_size ./ size(A));
    Brep = repmat(B, res_size ./ size(B));
    % now we can just apply the function pairwise
    res = arrayfun(f, Arep, Brep);
end

最新更新