在Matlab中正确使用arrayfun / bsxfun - 简单的例子

时间:2016-02-29 09:08:09

标签: arrays matlab bsxfun simplification

假设我们有1-d矩阵,随机长度:

M = [102,4,12,6,8,3,4,65,23,43,111,4]

此外,我有一个向量,其值与M的索引相关联:

V = [1,5]

我想要的是一个简单的代码:

counter = 1;
NewM = zeros(length(V)*3,1);
for i = 1:length(V)
    NewM(counter:(counter+2)) = M(V(i):(V(i)+2))
    counter = counter+3;
end

所以,结果将是

NewM = [102,4,12,8,3,4]

换句话说,我希望在一个新数组中从M到V + V + 2值。 我很确定这可以做得更容易,但我对如何在arrayfun / bsxfun中实现它感到困惑......

bsxfun(@(x,y) x(y:(y+2)),M,V)

3 个答案:

答案 0 :(得分:3)

使用bsxfun,它是关于在一个维度上获取V i 而在另一个维度上获得+ 0,+ 1 + 2:

M = [102,4,12,6,8,3,4,65,23,43,111,4];
V = [1,5];
NewM = M( bsxfun(@plus, V(:), 0:2) )

NewM =
    102     4    12       
      8     3     4   

或者如果你想要一条线:

NewM = reshape(NewM.', 1, [])

NewM =
    102     4    12     8     3     4   

答案 1 :(得分:2)

使用arrayfun(请注意M在此范围内用作"外部" 矩阵实体,而arrayfun匿名函数参数x对应于V

中的元素
NewM = cell2mat(arrayfun(@(x) M(x:x+2), V, 'UniformOutput', false));

结果

NewM =

   102     4    12     8     3     4

答案 2 :(得分:1)

一个完全向量化的解决方案是扩展V以创建正确的索引向量。在你的情况下:

[1,2,3,5,6,7]

您可以展开V复制每个元素n次,然后添加0:(n-1)的重复向量:

n = 3;
idx = kron(V, ones(1,n)) + mod(0:numel(V)*n-1,n)

因此,此处kron(V, ones(1,n))将返回[1,1,1,5,5,5],而mod(0:numel(V)*n-1,n)将返回[0,1,2,0,1,2],这将累加到所需的索引向量[1,2,3,5,6,7]

现在它只是

M(idx)

请注意,kron <{1}}的替代方案稍快一些reshape(repmat(V,n,1),1,[])