在 MATLAB 中对复杂向量进行高效分类
Speed-efficient classification for complex vectors in MATLAB
我正在尝试优化这段代码并摆脱已实现的嵌套循环。我发现很难将矩阵应用于 pdist 函数
例如,1+j // -1+j // -1+j // -1-j 是初始点,我正在尝试检测 0.5+0.7j 到它所属的点 min距离方法 .
感谢任何帮助
function result = minDisDetector( newPoints, InitialPoints)
result = [];
for i=1:length(newPoints)
minDistance = Inf;
for j=1:length(InitialPoints)
X = [real(newPoints(i)) imag(newPoints(i));real(InitialPoints(j)) imag(InitialPoints(j))];
d = pdist(X,'euclidean');
if d < minDistance
minDistance = d;
index = j;
end
end
result = [result; InitialPoints(index)];
end
end
解决方法很简单。但是,您确实需要我的 cartprod.m function 来生成笛卡尔积。
首先为每个变量生成随机复杂数据。
newPoints = exp(i * pi * rand(4,1));
InitialPoints = exp(i * pi * rand(100,1));
使用 cartprod
.
生成 newPoints
和 InitialPoints
的笛卡尔积
C = cartprod(newPoints,InitialPoints);
第 1 列和第 2 列的区别是复数的距离。然后abs
会求距离的大小
A = abs( C(:,1) - C(:,2) );
由于生成了笛卡尔积,因此它首先排列 newPoints
个变量,如下所示:
1 1
2 1
3 1
4 1
1 2
2 2
...
我们需要reshape
它并使用min
得到最小值来找到最小距离。我们需要转置来找到每个 newPoints
的最小值。否则如果没有转置,我们将得到每个 InitialPoints
.
的最小值
[m,i] = min( reshape( D, length(newPoints) , [] )' );
m
给你最小值,而 i
给你指数。如果你需要得到最小的 initialPoints
,只需使用:
result = initialPoints( mod(b-1,length(initialPoints) + 1 );
可以通过引入逐元素操作来消除嵌套循环,使用欧氏范数来计算距离,如下所示。
result = zeros(1,length(newPoints)); % initialize result vector
for i=1:length(newPoints)
dist = abs(newPoints(i)-InitialPoints); %calculate distances
[value, index] = min(dist);
result(i) = InitialPoints(index);
end
对于 vectorized solution
-
,您可以使用 Speed-efficient classification in Matlab
中列出的高效欧氏距离计算
%// Setup the input vectors of real and imaginary into Mx2 & Nx2 arrays
A = [real(InitialPoints) imag(InitialPoints)];
Bt = [real(newPoints).' ; imag(newPoints).'];
%// Calculate squared euclidean distances. This is one of the vectorized
%// variations of performing efficient euclidean distance calculation using
%// matrix multiplication linked earlier in this post.
dists = [A.^2 ones(size(A)) -2*A ]*[ones(size(Bt)) ; Bt.^2 ; Bt];
%// Find min index for each Bt & extract corresponding elements from InitialPoints
[~,min_idx] = min(dists,[],1);
result_vectorized = InitialPoints(min_idx);
快速运行时测试 newPoints
作为 400 x 1
& InitialPoints
作为 1000 x 1
:
-------------------- With Original Approach
Elapsed time is 1.299187 seconds.
-------------------- With Proposed Approach
Elapsed time is 0.000263 seconds.
我正在尝试优化这段代码并摆脱已实现的嵌套循环。我发现很难将矩阵应用于 pdist 函数
例如,1+j // -1+j // -1+j // -1-j 是初始点,我正在尝试检测 0.5+0.7j 到它所属的点 min距离方法 .
感谢任何帮助
function result = minDisDetector( newPoints, InitialPoints)
result = [];
for i=1:length(newPoints)
minDistance = Inf;
for j=1:length(InitialPoints)
X = [real(newPoints(i)) imag(newPoints(i));real(InitialPoints(j)) imag(InitialPoints(j))];
d = pdist(X,'euclidean');
if d < minDistance
minDistance = d;
index = j;
end
end
result = [result; InitialPoints(index)];
end
end
解决方法很简单。但是,您确实需要我的 cartprod.m function 来生成笛卡尔积。
首先为每个变量生成随机复杂数据。
newPoints = exp(i * pi * rand(4,1));
InitialPoints = exp(i * pi * rand(100,1));
使用 cartprod
.
newPoints
和 InitialPoints
的笛卡尔积
C = cartprod(newPoints,InitialPoints);
第 1 列和第 2 列的区别是复数的距离。然后abs
会求距离的大小
A = abs( C(:,1) - C(:,2) );
由于生成了笛卡尔积,因此它首先排列 newPoints
个变量,如下所示:
1 1
2 1
3 1
4 1
1 2
2 2
...
我们需要reshape
它并使用min
得到最小值来找到最小距离。我们需要转置来找到每个 newPoints
的最小值。否则如果没有转置,我们将得到每个 InitialPoints
.
[m,i] = min( reshape( D, length(newPoints) , [] )' );
m
给你最小值,而 i
给你指数。如果你需要得到最小的 initialPoints
,只需使用:
result = initialPoints( mod(b-1,length(initialPoints) + 1 );
可以通过引入逐元素操作来消除嵌套循环,使用欧氏范数来计算距离,如下所示。
result = zeros(1,length(newPoints)); % initialize result vector
for i=1:length(newPoints)
dist = abs(newPoints(i)-InitialPoints); %calculate distances
[value, index] = min(dist);
result(i) = InitialPoints(index);
end
对于 vectorized solution
-
Speed-efficient classification in Matlab
中列出的高效欧氏距离计算
%// Setup the input vectors of real and imaginary into Mx2 & Nx2 arrays
A = [real(InitialPoints) imag(InitialPoints)];
Bt = [real(newPoints).' ; imag(newPoints).'];
%// Calculate squared euclidean distances. This is one of the vectorized
%// variations of performing efficient euclidean distance calculation using
%// matrix multiplication linked earlier in this post.
dists = [A.^2 ones(size(A)) -2*A ]*[ones(size(Bt)) ; Bt.^2 ; Bt];
%// Find min index for each Bt & extract corresponding elements from InitialPoints
[~,min_idx] = min(dists,[],1);
result_vectorized = InitialPoints(min_idx);
快速运行时测试 newPoints
作为 400 x 1
& InitialPoints
作为 1000 x 1
:
-------------------- With Original Approach
Elapsed time is 1.299187 seconds.
-------------------- With Proposed Approach
Elapsed time is 0.000263 seconds.