有没有一种快速的方法来规范化3维矩阵的每一行而不需要在Matlab中使用慢速for循环?
说我的输入数据如下所示:
d(:,:,1) =
1 2 3
4 5 6
d(:,:,2) =
7 8 9
10 11 12
我知道我可以使用
获得每行的标准norms = sqrt(sum(d.^2,2))
norms(:,:,1) =
3.7417
8.7750
norms(:,:,2) =
13.9284
19.1050
但是现在如何将这些规范值与第二维分开?
我知道在2个dims中我可以使用./
但是这似乎不适用于3维数据。
答案 0 :(得分:3)
bsxfun
是你的朋友:
out = bsxfun(@rdivide, d, norms);
它的作用是暂时创建一个3D矩阵,复制norms
的每一行,其列数与d
中的列数一样多,并且它以元素方式将每个元素与{ {1}}和d
。
我们得到:
norms
我们还可以通过独立确定每行的平方和并确保每个结果总和为1来验证每一行是否为L2规范化:
>> d = cat(3, [1 2 3; 4 5 6], [7 8 9; 10 11 12]);
>> norms = sqrt(sum(d.^2,2));
>> out = bsxfun(@rdivide, d, norms)
out(:,:,1) =
0.2673 0.5345 0.8018
0.4558 0.5698 0.6838
out(:,:,2) =
0.5026 0.5744 0.6462
0.5234 0.5758 0.6281
如果使用>> sum(out.^2, 2)
ans(:,:,1) =
1.0000
1.0000
ans(:,:,2) =
1.0000
1.0000
的方法没有意义,您可以使用的替代方法是使用repmat
创建一个与bsxfun
相同的维度的矩阵。 ..那么你可以执行你想要的元素划分:
d
使用>> out = d ./ repmat(norms, [1 size(d,2) 1])
out(:,:,1) =
0.2673 0.5345 0.8018
0.4558 0.5698 0.6838
out(:,:,2) =
0.5026 0.5744 0.6462
0.5234 0.5758 0.6281
指定要在每个维度中复制矩阵的次数。我们只希望在列上复制矩阵,而行和切片的数量相同...因此,向量repmat
指定了在每个维度中复制矩阵的次数。
实际上,这就是[1 size(d,2) 1]
无需处理创建此临时矩阵的难题的问题。无需您考虑就可以完成此复制。