arrayfun/bsxfun 在 Matlab 中的正确用法 - 简单示例
Correct usage of arrayfun/bsxfun in Matlab - simple example
假设我们有一个一维矩阵,长度随机:
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)
使用arrayfun
(注意M
在此范围内用作"external"矩阵实体,而arrayfun
匿名函数参数x
对应V
)
中的元素
NewM = cell2mat(arrayfun(@(x) M(x:x+2), V, 'UniformOutput', false));
有结果
NewM =
102 4 12 8 3 4
一个完全向量化的解决方案是扩展 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))
将 return [1,1,1,5,5,5]
和 mod(0:numel(V)*n-1,n)
将 return [0,1,2,0,1,2]
加起来就是所需的索引向量 [1,2,3,5,6,7]
现在只是
M(idx)
请注意 kron
稍微快一点的替代方法是 reshape(repmat(V,n,1),1,[])
bsxfun
是关于在一个维度上获得 Vi 和在另一个维度上获得 +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
假设我们有一个一维矩阵,长度随机:
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)
使用arrayfun
(注意M
在此范围内用作"external"矩阵实体,而arrayfun
匿名函数参数x
对应V
)
NewM = cell2mat(arrayfun(@(x) M(x:x+2), V, 'UniformOutput', false));
有结果
NewM =
102 4 12 8 3 4
一个完全向量化的解决方案是扩展 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))
将 return [1,1,1,5,5,5]
和 mod(0:numel(V)*n-1,n)
将 return [0,1,2,0,1,2]
加起来就是所需的索引向量 [1,2,3,5,6,7]
现在只是
M(idx)
请注意 kron
稍微快一点的替代方法是 reshape(repmat(V,n,1),1,[])
bsxfun
是关于在一个维度上获得 Vi 和在另一个维度上获得 +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