繁体   English   中英

如何在Matlab中找到与给定向量最接近的向量?

[英]how to find the closest vector to a given vector in matlab?

我在Matlab中有一组n维代表向量。 我必须将矢量从一组训练矢量到基于代表性的代表性矢量表示的组进行分组。 我该怎么办?

您可以使用dsearchn查找最接近每个点的代表。 我建议先尝试不涉及三角剖分矩阵的版本。 如果内存或CPU性能不够好,请研究三角剖分的内容。

如果通过n维向量表示n维点的有序列表(这是我对所需对象的理解),那么我过去使用平均最接近距离来完成此操作。 基本上,对于矢量一上的每个点,找到到矢量二上一个点的最小距离。 那么,两个向量之间的距离就是所有这些距离的平均值。 但是,这不是对称的,因此您应该对向量2上的每个点执行相同的过程,以找到到向量1的最小距离,然后将两个均值进行汇总,包括最小值,最大值或平均值等。

这是我使用循环(针对3d矢量)制作的一些代码:

function mcd = MCD(fiber1, fiber2, option)

%

%remove NaNs
fiber1(find(isnan(fiber1),1):length(fiber1),:) = [];
fiber2(find(isnan(fiber2),1):length(fiber2),:) = [];

dist = 0;


for k = 1:length(fiber1)

    D = [];

    for j = 1:length(fiber2)
        D = [D distance(fiber1(k,:),fiber2(j,:))];
    end;

    dist = dist + min(D);

end;

mcd = dist / length(fiber1);

if nargin > 2

    dist = 0;

    for k = 1:length(fiber2)

        D = [];

        for j = 1:length(fiber1)
            D = [D distance(fiber2(k,:),fiber1(j,:))];
        end;

        dist = dist + min(D);

    end;

    mcd2 = dist / length(fiber2);

    if strcmp(option,'mean')
        mcd = mean([mcd mcd2]);
    elseif strcmp(option,'min')
        mcd = min([mcd mcd2]);
    end;
end;

但这对我来说太慢了。 因此,这是一个非常快的矢量化版本(但很难遵循):

function mcd = MCD(fiber1, fiber2, option, sampling)

%MCD(fiber1, fiber2)
%MCD(fiber1, fiber2, option)
%MCD(fiber1, fiber2, option, sampling)



%remove NaNs
fiber1(find(isnan(fiber1),1):length(fiber1),:) = [];
fiber2(find(isnan(fiber2),1):length(fiber2),:) = [];

%sample the fibers for speed. Each fiber is represented by "sampling"
%number of points.

if nargin == 4

    freq = round(length(fiber1)/sampling);
    fiber1 = fiber1(1:freq:length(fiber1),:);
    freq = round(length(fiber2)/sampling);
    fiber2 = fiber2(1:freq:length(fiber2),:);

end;

%reshape to optimize the use of distance() for speed
FIBER2 = reshape(fiber2',[1,3,length(fiber2)]);
FIBER1 = reshape(fiber1',[1,3,length(fiber1)]); %this is only used in the symmetrical case, i.e when 'min' or 'mean' option is called


%reshape amd tile filber 1 so as to eliminate the need for two nested for
%loops thus greatly increasing the computational efficiency. The goal is to
%have a 4D matrix with 1 row and 3 columns. Dimension 3 is a smearing of
%these columns to be as long as fiber2 so that each vector (1x3) in fiber1
%can be placed "on top" as in a row above the whole of fiber2. Thus dim 3
%is as long as fiber2 and dim 4 is as long as fiber1.

fiber1 = reshape(fiber1',[1,3,length(fiber1)]); %1x3xF1
fiber1 = repmat(fiber1,[length(FIBER2),1,1]); %F2x3xF1
fiber1 = permute(fiber1,[2,1,3]); %3xF2xF1
fiber1 = reshape(fiber1,[1,3,length(FIBER2),length(FIBER1)]);%1,3,F2,F1

mcd = mean(min(distance(fiber1, repmat(FIBER2,[1,1,1,length(FIBER1)]))));

if nargin > 2

    fiber2 = reshape(fiber2',[1,3,length(fiber2)]); %1x3xF1
    fiber2 = repmat(fiber2,[length(FIBER1),1,1]); %F2x3xF1
    fiber2 = permute(fiber2,[2,1,3]); %3xF2xF1
    fiber2 = reshape(fiber2,[1,3,length(FIBER1),length(FIBER2)]);%1,3,F2,F1

    mcd2 = mean(min(distance(fiber2, repmat(FIBER1,[1,1,1,length(FIBER2)]))));

    if strcmp(option,'mean')
        mcd = mean([mcd mcd2]);
    elseif strcmp(option,'min')
        mcd = min([mcd mcd2]);
    end;
end;

这是我上面使用的distance()函数,在我的情况下,我使用了欧几里得距离,但是只要它可以接受两个向量,就可以将其调整为最适合自己的距离:

function Edist = distance(vector1,vector2)

%distance(vector1,vector2)
%
%provides the Euclidean distance between two input vectors. Vector1 and
%vector2 must be row vectors of the same length. The number of elements in
%each vector is the dimnesionality thereof. 

Edist = sqrt(sum((diff([vector1;vector2])).^2));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM