如何解决在八度Matlab上矢量化到几个点的距离
我正在写一个k-means
算法。在每个步骤中,我都想计算distance
指向n
的{{1}},没有for循环,并且计算k centroids
的尺寸。
问题是我很难用我知道的Matlab函数来划分尺寸数。这是我当前的代码,d
是我的x
,n 2D-points
是我的y
(当然也是2D点),并且这些点沿维度1分布,并且沿维度2的空间坐标:
k centroids
如何进一步向量化?
3天后进行第一次编辑,自行搜索
由于提出了这个问题,我在使这段代码向量化方面取得了自己的进步。
在我的示例中,上面的代码大约运行 dist = @(a,b) (a - b).^2;
dx = bsxfun(dist,x(:,1),y(:,1)'); % x is (n,1) and y is (1,k)
dy = bsxfun(dist,2),2)'); % so the result is (n,k)
dists = dx + dy; % contains the square distance of each points to the k centroids
[_,l] = min(dists,[],2); % we then argmin on the 2nd dimension
。
我首先使用0.7 ms
来简化广播:
repmat
正如我们所料,由于我们复制矩阵,它运行在dists = permute(permute(repmat(x,1,k),[3,2,1]) - y,1]).^2;
dists = sum(dists,2);
[~,3);
上,所以速度稍慢。
在此示例中,整个过程非常容易使用0.85 ms
,但事实证明运行非常缓慢,它在bsxfun
中运行,比150 ms
比{{ 1}}版本:
150 times slower
为什么这么慢?因为向量化使用cpu上的向量指令,所以向量化不是总是在提高速度吗?我的意思是当然也可以优化简单的for循环来使用它,但是向量化如何使代码变慢?我做错了吗?
使用for循环
为了完整起见,这是我的代码的for循环版本,令人惊讶的是repmat
中运行最快的版本,不知道为什么。
dist = @(a,b) (a - b).^2;
dists = permute(bsxfun(dist,permute(x,1]),y),1]);
dists = sum(dists,3);
解决方法
注意:当问题也被标记为MATLAB时,将写出此答案。删除MATLAB标记后添加到Octave文档的链接。
您可以使用pdist2
MATLAB / Octave 函数来计算两组观测值之间的成对距离。
这样,您就可以将矢量化的麻烦转移给编写MATLAB / Octave的人(他们做得很好)
X = rand(10,3);
Y = rand(5,3);
D = pdist2(X,Y);
D
现在是一个10x5
矩阵,其中第i,j
个元素是第i
个X点和第j
个Y点之间的距离。>
您可以通过第三个参数传递所需的距离-例如'euclidean'
,'minkowski'
等,也可以将函数句柄传递给自定义函数,如下所示:
dist = @(a,b) (a - b).^2;
D = pdist2(X,Y,dist);
正如saastn所述,pdist2(...,'smallest',k)
使k均值变得更容易。这仅返回pdist2
结果的每一列中的最小k个值。八度没有此功能,但可以使用sort()
MATLAB / Octave 轻松复制。
D_smallest = sort(D);
D_smallest = D_smallest(1:k,:);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。