问题描述
使用MATLAB,想象一下一个Nx6的数字数组,该数组代表N个段,其初始和终点坐标为3 + 3 = 6.
Using MATLAB,Imagine a Nx6 array of numbers which represent N segments with 3+3=6 initial and end point coordinates.
假设我有一个function Calc_Dist( Segment_1, Segment_2 )
,它将两个1x6数组作为输入,并且在执行某些操作后返回一个标量,即这两个段之间的最小欧氏距离.
Assume I have a function Calc_Dist( Segment_1, Segment_2 )
that takes as input two 1x6 arrays, and that after some operations returns a scalar, namely the minimal euclidean distance between these two segments.
我想计算列表中所有N个段之间的成对最小距离,但希望避免出现双循环.
I want to calculate the pairwise minimal distance between all N segments of my list, but would like to avoid a double loop to do so.
我无法全神贯注于MATLAB bsxfun
函数的文档,因此无法进行这项工作.举一个最小的例子(距离计算显然是不正确的):
I cannot wrap my head around the documentation of the bsxfun
function of MATLAB, so I cannot make this work. For the sake of a minimal example (the distance calculation is obviously not correct):
function scalar = calc_dist( segment_1, segment_2 )
scalar = sum( segment_1 + segment_2 )
end
和主要
Segments = rand( 1500, 6 )
Pairwise_Distance_Matrix = bsxfun( @calc_dist, segments, segments' )
有没有办法做到这一点,还是我不得不使用双循环?
Is there any way to do this, or am I forced to use double loops ?
谢谢您的任何建议
推荐答案
我认为您需要 pdist
而不是bsxfun
. pdist
可以以两种不同的方式使用,其中第二种适用于您的问题:
I think you need pdist
rather than bsxfun
. pdist
can be used in two different ways, the second of which is applicable to your problem:
-
具有内置的距离功能,以字符串形式提供,例如
'euclidean'
,'hamming'
等.
具有自定义距离功能,是您要提供的手柄.
With a custom distance function, a handle to which you supply.
第二种情况是距离函数
function D2 = distfun(XI, XJ),
以一个1
-by- N
向量XI
作为参数,该向量包含一行X
,一个 M2
-by- N
矩阵XJ
,其中包含X
的多行,并返回 距离D2
的M2
by- 1
向量,其第J
个元素是距离 在观测值XI
和XJ(J,:)
之间.
taking as arguments a 1
-by-N
vector XI
containing a single row of X
, an M2
-by-N
matrix XJ
containing multiple rows of X
, and returning an M2
-by-1
vector of distances D2
, whose J
th element is the distance between the observations XI
and XJ(J,:)
.
尽管文档没有说明,但是第二种方法很可能不如第一种有效(双循环甚至可能更快,谁知道),但是您可以使用它.您将需要定义您的函数,使其满足规定的条件.使用示例函数很容易:对于这一部分,您将使用bsxfun
:
Although the documentation doesn't tell, it's very likely that the second way is not as efficient as the first (a double loop might even be faster, who knows), but you can use it. You would need to define your function so that it fulfills the stated condition. With your example function it's easy: for this part you'd use bsxfun
:
function scalar = calc_dist( segment_1, segment_2 )
scalar = sum(bsxfun(@plus, segment_1, segment_2), 2);
end
请注意
-
pdist
可用于行(而不是列),这是您所需要的. -
pdist
通过利用任何距离函数必须具有的属性来减少操作.即,已知元素到其自身的距离为零.由于对称性,每对线的距离仅需计算一次.如果要以矩阵形式排列输出,请使用squareform
.
pdist
works with rows (not columns), which is what you need.pdist
reduces operations by exploiting the properties that any distance function must have. Namely, the distance of an element to itself is known to be zero; and the distance for each pair can be computed just once thanks to symmetry. If you want to arrange the output in the form of a matrix, usesquareform
.
因此,在适当修改了实际距离函数(可能是最困难的部分)之后,请使用:
So, after your actual distance function has been modified appropriately (which may be the hard part), use:
distances = squareform(pdist(segments, @calc_dist));
例如:
N = 4;
segments = rand(N,6);
distances = squareform(pdist(segments, @calc_dist));
产生
distances =
0 6.1492 7.0886 5.5016
6.1492 0 6.8559 5.2688
7.0886 6.8559 0 6.2082
5.5016 5.2688 6.2082 0
这篇关于MATLAB:bsxfun不清楚.想要加快线段之间的最小距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!