Eng*_*ero 3 matlab vectorization octave bsxfun
我有一个数据集,X即m x 2三个存储在矩阵C = [c1'; c2'; c3']中的向量3 x 2.我试图对我的代码进行矢量化,为每个数据点找到X哪个矢量C最接近(平方距离).我想减去每个向量(行)C从每个向量(行)X,导致m x 6或3m x 2的的元素之间的差异矩阵X和的元素C.我目前的实现一次只进行一行X:
for i = 1:size(X, 1)
diffs = bsxfun(@minus, X(i,:), C); % gives a 3 x 2 matrix result
[~, idx(i)] = min(sumsq(diffs), 2); % returns the index of the closest vector
% in C to the ith vector in X
end
Run Code Online (Sandbox Code Playgroud)
我想摆脱这个for循环,只是矢量化整个事情,但bsxfun(@minus, X, C)在Octave中给我一个错误:
错误:bsxfun:不一致的尺寸:300x2和3x2
我有什么想法可以"超广播"这两个矩阵之间的减法运算?
此问题的核心是计算D大小的距离矩阵,m x 3该矩阵包含所有数据点X和所有数据点之间的成对距离C.第i个矢量x_i输入X和第j个矢量c_j输入之间的欧几里德距离C可以改写为:
|x_i-c_j|^2 = |x_i|^2 - 2<x_i, c_j> + |c_j|^2
Run Code Online (Sandbox Code Playgroud)
其中<,>指内在产品.这个等式的右边可以很容易地进行矢量化,因为所有对的内积X * C'都是BLAS3操作.这种计算距离矩阵的dist2方法在Christopher Bishop的书籍模式识别和机器学习中被称为函数.我稍微修改了下面的功能.
function D = dist2(X, C)
tempx = full(sum(X.^2, 2));
tempc = full(sum(C.^2, 2).');
D = -2*(X * C.'?;
D = bsxfun(@plus, D, tempx);
D = bsxfun(@plus, D, tempc);
Run Code Online (Sandbox Code Playgroud)
在full这里的情况下,使用X或C是稀疏矩阵.
注意:D由于数字舍入误差,以这种方式计算的距离矩阵可能具有微小的负数条目.为了防范这种情况,请使用
D = max(D, 0);
Run Code Online (Sandbox Code Playgroud)
C可以从D以下位置检索最近矢量的索引:
[~, idx] = min(D, [], 2);
Run Code Online (Sandbox Code Playgroud)