微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在八度Matlab上矢量化到几个点的距离

如何解决在八度Matlab上矢量化到几个点的距离

我正在写一个k-means算法。在每个步骤中,我都想计算distance指向n的{​​{1}},没有for循环,并且计算k centroids的尺寸。

问题是我很难用我知道的Matlab函数来划分尺寸数。这是我当前的代码d是我的xn 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 举报,一经查实,本站将立刻删除。