gpt4 book ai didi

matlab - 将 bsxfun 与具有三维矩阵的单例扩展一起使用

转载 作者:太空宇宙 更新时间:2023-11-03 19:54:54 25 4
gpt4 key购买 nike

我正在使用 bsxfun在大小矩阵之间通过单例扩展对操作进行矢量化:

MS: (nms, nls)
KS: (nks, nls)

运算是对每个值的绝对差求和MS(m,l)m1:nmsl1:nls , 和每个 KS(k,l)k1:nks .

我是通过代码实现的:

[~, nls] = size(MS);
MS = reshape(MS',1,nls,[]);
R = sum(abs(bsxfun(@minus,MS,KS)));

R尺寸为 (nls, nms) .

我想将此操作概括为样本列表,因此新的大小将是:

MS: (nxs, nls, nms)
KS: (nxs, nls, nks)

这可以通过 for 循环轻松实现,该 for 循环为每个二维矩阵执行第一段代码,但我怀疑通过添加新维度来概括以前的代码,性能可能会好得多。

R有大小:(nxs, nls, nms)

我尝试 reshape MS到 4 个维度没有成功。这可以通过 reshape 和 bsxfun 来完成吗? ?

最佳答案

你可能需要这个:

% generate small dummy data
nxs = 2;
nls = 3;
nms = 4;
nks = 5;
MS = rand(nxs, nls, nms);
KS = rand(nxs, nls, nks);

R = sum(abs(bsxfun(@minus,MS,permute(KS,[1,2,4,3]))),4)

这将产生一个大小为 [2,3,4] 的矩阵,即 [nxs,nls,nms]。每个元素[k1,k2,k3]都会对应

R(k1,k2,k3) == sum_k abs(MS(k1,k2,k3) - KS(k1,k2,k))

例如,在我的随机运行中

R(2,1,3)

ans =

1.255765020150647

>> sum(abs(MS(2,1,3)-KS(2,1,:)))

ans =

1.255765020150647

诀窍是使用permute 引入单一维度:permute(KS,[1,2,4,3]) 的大小为[nxs, nls,1,nks],而大小为 [nxs,nls,nms]MS 也隐式为大小 [nxs,nls,nms ,1]:假定 MATLAB 中的每个数组都具有可数无限数量的尾随单维度。从这里很容易看出如何将 bsxfun 大小为 [nxs,nls,nms,1][nxs,nls,1,nks] 的数组组合在一起,分别获得一个大小为[nxs,nls,nms,nks]。沿着维度 4 求和就可以达成协议(protocol)。


我在评论中指出,置换 求和索引放在第一位可能会更快。事实证明,这本身会使代码运行变慢。然而,通过 reshape 数组以减小维度大小,整体性能会提高(由于优化内存访问)。比较一下:

% generate larger dummy data
nxs = 20;
nls = 30;
nms = 40;
nks = 500;
MS = rand(nxs, nls, nms);
KS = rand(nxs, nls, nks);

MS2 = permute(MS,[4 3 2 1]);
KS2 = permute(KS,[3 4 2 1]);
R3 = permute(squeeze(sum(abs(bsxfun(@minus,MS2,KS2)),1)),[3 2 1]);

我所做的是将求和 nks 维度放在第一位,然后将其余维度按降序排列。这可以自动完成,我只是不想使示例过于复杂。在您的用例中,您可能无论如何都知道维度的大小。

上述两个代码的运行时间:原始代码为 0.07028 秒,重新排序的代码为 0.051162 秒(5 个中最好的)。不幸的是,更大的例子现在不适合我的内存。

关于matlab - 将 bsxfun 与具有三维矩阵的单例扩展一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34777775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com