MATLAB 中复杂向量的高效分类

Posted

技术标签:

【中文标题】MATLAB 中复杂向量的高效分类【英文标题】:Speed-efficient classification for complex vectors in MATLAB 【发布时间】:2015-07-03 20:00:57 【问题描述】:

我正在尝试优化这段代码并摆脱实现的嵌套循环。我在将矩阵应用于 pdist 函数时遇到了困难

例如,1+j // -1+j // -1+j // -1-j 是初始点,我试图通过最小距离方法检测 0.5+0.7j 到它所属的点. 任何帮助表示赞赏

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

【问题讨论】:

InitialPointsnewPoints 的大小是多少?每组中任意 2 个点之间的最小距离? 你可以通过矢量化摆脱一个循环:mathworks.com/matlabcentral/newsreader/view_thread/47487 我有一个更好的方法,但这取决于点的尺寸。 要点很复杂 InitialPoints 大小为 1 -- 4 , 8 ,16 , 64 newpoints 大小就足够了 【参考方案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

【讨论】:

这个解决方案本质上是@brodroll 的参考。我的参考使用 1 cellfun 循环来生成笛卡尔积并且不使用任何显式循环。此外,如果我没记错的话,abs 已经计算了幅度,这意味着您的解决方案中实际上不需要 ^sqrtsum 这提醒了我,我需要在我的代码中添加一个重塑:3 @krisdestruction 谢谢,我不知道abs 返回了一个复数的模数。可能不是最快的解决方案,但我确实认为这种实现简单明了。 简洁是 Divakar 的答案【参考方案2】:

对于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 1InitialPoints 作为1000 x 1 的快速运行时测试:

-------------------- With Original Approach
Elapsed time is 1.299187 seconds.
-------------------- With Proposed Approach
Elapsed time is 0.000263 seconds.

【讨论】:

看起来是正确的,而且速度非常快! +1 也许您可以包含一些每个操作的作用? 另外,您是否有理由使用[real(newPoints).' ; imag(newPoints).']; 而不是[real(newPoints) imag(newPoints)]'; @krisdestruction 认为它会是一样的。添加了一些 cmets,但要了解更多信息,我认为链接必须是实际参考,因为它有很多细节需要真正解释其背后的工作。 @krisdestruction 没错,基本上是平方距离。 @ousamakanawati 如果这是最适合您的解决方案,请不要忘记接受它。谢谢!【参考方案3】:

解决方案非常简单。但是,您确实需要我的 cartprod.m function 来生成笛卡尔积。

首先为每个变量生成随机复数数据。

newPoints = exp(i * pi * rand(4,1));
InitialPoints = exp(i * pi * rand(100,1));

使用cartprod 生成newPointsInitialPoints 的笛卡尔积。

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 );

【讨论】:

以上是关于MATLAB 中复杂向量的高效分类的主要内容,如果未能解决你的问题,请参考以下文章

优化分类基于matlab鲸鱼算法优化支持向量机分类(多输入多分类)含Matlab源码 1557期

优化分类基于matlab灰狼算法优化最小二乘支持向量机分类(多输入多分类)含Matlab源码 1558期

优化分类基于matlab粒子群算法优化支持向量机分类(多输入多分类)含Matlab源码 1559期

LSSVM分类基于matlab最小二乘支持向量机数据分类含Matlab源码 2330期

LSSVM分类基于matlab最小二乘支持向量机数据分类含Matlab源码 2330期

LSSVM分类基于matlab最小二乘支持向量机数据分类含Matlab源码 2330期