Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 跨两种模式的交叉对距离测量_Matlab_Optimization_Vector - Fatal编程技术网

Matlab 跨两种模式的交叉对距离测量

Matlab 跨两种模式的交叉对距离测量,matlab,optimization,vector,Matlab,Optimization,Vector,我有个问题。我试图计算向量之间的成对距离。首先让我解释一下这个问题:我有两组向量X和YX有三个向量x1、x2和x3Y有三个向量y1、y2和y3。注X和Y中的向量长度分别为m和n。将数据集表示为以下图像: 我试图计算一个类似矩阵,如下所示: 。现在解释了不同的颜色编码部分-不需要计算所有标有0的单元格。我有意将其设置为100(它可以是任何值)。必须计算灰色单元格。相似性得分计算为(xi xj)+L2规范的L2规范的(yi yj) 这意味着条目是 M((x_i,y_j), (x_k,y_l)) :

我有个问题。我试图计算向量之间的成对距离。首先让我解释一下这个问题:我有两组向量
X
Y
X
有三个向量
x1
x2
x3
Y
有三个向量
y1
y2
y3
。注
X
Y
中的向量长度分别为
m
n
。将数据集表示为以下图像:

我试图计算一个类似矩阵,如下所示:

。现在解释了不同的颜色编码部分-不需要计算所有标有
0
的单元格。我有意将其设置为
100
(它可以是任何值)。必须计算灰色单元格。相似性得分计算为
(xi xj)
+
L2
规范的
L2
规范的
(yi yj)

这意味着条目是

M((x_i,y_j), (x_k,y_l)) := norm(x_i-x_k,2) + norm(y_j-y_l,2)
为此,我编写了一个基本代码:

clc;clear all;close all;
%% randomly generate data
m=3; n1=4; n2=6;
train_a_mean = rand(m,n1);
train_b_mean = rand(m,n2);
p = size(train_a_mean,1)*size(train_b_mean,1);
score_mean_ab = zeros(p,p);

%% This is to store the index variables 
%% This is required for futu
idx1 = score_mean_ab;
idx2 = idx1; idx3 = idx1; idx4 = idx1;

a=1; b=1;
for i=1:size(score_mean_ab,1)
    c = 1; d = 1;
    for j=1:size(score_mean_ab,2)
        if (a==c)
            score_mean_ab(i,j) = 100;
        else            
            %% computing distances between the different modalities and
            %% summing them up
            score_mean_ab(i,j) = norm(train_a_mean(a,:)-train_a_mean(c,:),2) ...
            + norm(train_b_mean(b,:)-train_b_mean(d,:),2);
        end
        %% saving the indices
        idx1(i,j)=a; idx2(i,j)=b; idx3(i,j)=c; idx4(i,j)=d;        
        %% updating the values of c and d
        if mod(d,size(train_a_mean,1))==0
            c = c + 1;
            d = 1;
        else
            d = d+1;
        end
    end
    %% updating the values of a and b
    if mod(b,size(train_a_mean,1))==0
        a = a + 1;
        b = 1;
    else        
        b = b+1;
    end
end
对于矩阵的干样本运行:我得到以下结果-

score_mean_ab =

  100.0000  100.0000  100.0000    0.6700    1.6548    1.5725    0.8154    1.8002    1.7179
  100.0000  100.0000  100.0000    1.6548    0.6700    1.5000    1.8002    0.8154    1.6454
  100.0000  100.0000  100.0000    1.5725    1.5000    0.6700    1.7179    1.6454    0.8154
    0.6700    1.6548    1.5725  100.0000  100.0000  100.0000    1.3174    2.3022    2.2200
    1.6548    0.6700    1.5000  100.0000  100.0000  100.0000    2.3022    1.3174    2.1475
    1.5725    1.5000    0.6700  100.0000  100.0000  100.0000    2.2200    2.1475    1.3174
    0.8154    1.8002    1.7179    1.3174    2.3022    2.2200  100.0000  100.0000  100.0000
    1.8002    0.8154    1.6454    2.3022    1.3174    2.1475  100.0000  100.0000  100.0000
    1.7179    1.6454    0.8154    2.2200    2.1475    1.3174  100.0000  100.0000  100.0000
然而,我的代码非常慢。我进行了几次样本运行,得到了以下结果:

m=3; n1=3; n2=3;
Elapsed time is 0.000363 seconds.

m=10; n1=3; n2=3;
Elapsed time is 0.042015 seconds.

m=10; n1=1800; n2=1800;
Elapsed time is 0.230046 seconds.

m=20; n1=1800; n2=1800;
Elapsed time is 4.309134 seconds.

m=30; n1=1800; n2=1800;
Elapsed time is 23.058106 seconds.
我的问题:

  • 通常我的值为
    m~100
    n1~2000
    n2~2000
    。我自己的代码在这一点上崩溃了。有什么优化的方法可以做到这一点吗
  • 内置的matlab函数能否用于此目的

  • 注意:向量实际上是行向量的形式,
    n1
    n2
    的值可能不相等。

    您可以使用以下方法实现此目的:

    m = 3; % Number of vectors in X/Y (must have same number of vectors)
    XD = squareform(pdist(X)); %// == pdist2(X,X) but faster
    YD = squareform(pdist(Y)); %// == pdist2(Y,Y) but faster
    M = kron(XD,ones(m,m)) + repmat(YD,m,m);
    

    请注意,为了使
    pdist
    工作,
    X
    Y
    必须作为行向量给出。另外:忽略对角块。

    这里有一个方法。这将计算所有条目

    m = 3;             %// number of (row) vectors in X and in Y
    n1 = 3;            %// length of vectors in X
    n2 = 3;            %// length of vectors in Y
    X = rand(m, n1);   %// random data: X
    Y = rand(m, n2);   %// random data: Y
    
    [ii, jj] = ndgrid(1:m); 
    U = reshape(sqrt(sum((X(ii,:)-X(jj,:)).^2, 2)), m, m);
    V = reshape(sqrt(sum((Y(ii,:)-Y(jj,:)).^2, 2)), m, m);
    result = U(ceil(1/m:1/m:m), ceil(1/m:1/m:m)) + repmat(V, m, m);
    
    或者您可以使用
    bsxfun
    而不是
    ndgrid

    U = sqrt(sum(bsxfun(@minus, permute(X, [1 3 2]), permute(X, [3 1 2])).^2, 3));
    V = sqrt(sum(bsxfun(@minus, permute(Y, [1 3 2]), permute(Y, [3 1 2])).^2, 3));
    result = U(ceil(1/m:1/m:m), ceil(1/m:1/m:m)) + repmat(V, m, m);
    

    假设
    A
    as
    train\u-mean
    B
    as
    train\u-mean
    易于在代码中访问,您可以在这里使用两种方法到达最终目的地,即输出
    得分\u-mean\u-ab
    行最小索引数组

    方法#1

    该方法的基础是获得
    范数及其
    总和
    ,以及根据问题要求将
    对角线块
    元素设置为所有
    Infs
    的线性指数。下面是实现-

    %// Parameter
    M = m^2; 
    
    %// Get pairwise norms
    nm1 = sqrt(sum(bsxfun(@minus,A,permute(A,[3 2 1])).^2,2));
    nm2 = sqrt(sum(bsxfun(@minus,B,permute(B,[3 2 1])).^2,2));
    
    %// Get sum of norms and the final values
    norm_sum = bsxfun(@plus,nm1,permute(nm2,[2 1 4 3]));
    
    %// Get "diagonal block" elements and set them to all Infs
    ind1 = bsxfun(@plus,[1:m:M]',[0:m-1]*(M+1));  %//'
    ind2 = bsxfun(@plus,ind1(:),[0:m-1]*m^3);
    norm_sum(ind2) = Inf;
    
    [~,min_idx] = min(reshape(norm_sum,m,M,[]),[],2);
    min_idx = reshape(reshape(min_idx,m,[])',[],1);
    
    方法#2

    这种方法ab(使用)用于可能更快的解决方案。下面列出了代码-

    %// Parameters
    nA = size(A,2);
    nB = size(B,2);
    M = m^2;
    
    %// Get the pairwise norms for both A and B
    A_t = A';  %//'
    norm_a = sqrt([-2*A A.^2 ones(m,nA)]*[A_t ; ones(nA,m) ; A_t.^2])
    norm_a(1:m+1:end) = 0;
    B_t = B';  %//'
    norm_b = sqrt([-2*B B.^2 ones(m,nB)]*[B_t ; ones(nB,m) ; B_t.^2])
    norm_b(1:m+1:end) = 0;
    
    %// Norm sums
    norm_sum = reshape(bsxfun(@plus,norm_a(:).',norm_b(:)),m,m,[]) %//'
    
    %// Set the "diagonal blocks" as all Infs
    norm_sum(:,:,1:m+1:M) = Inf
    
    %// Re-arrange into the desired 2D output and get the minimum indices
    out = reshape(permute(reshape(permute(norm_sum,[1 3 2]),M,m,[]),[1 3 2]),M,M);
    [~,min_idx] = min(out,[],2);
    

    请详细说明相似性分数。矩阵
    M((x_i,y_j),(x_k,y_l))的条目是什么?
    ?请将此信息添加到问题中!看起来这可以通过在这些距离上使用一个
    pdist2(…,'euclidean')
    和一个
    pdist2(…,'cityblock')
    来实现。我还不知道细节。另外,您没有指定数据是列向量还是行向量。@roni您的意思是输出大小为
    m^2 X m^2
    ,对吗?如果您只需要索引,我们不需要计算完整矩阵,但at是对称的(使用对称块)。。。另外:Divakar已经提供了删除这些条目的代码,您可以将其用于三种解决方案中的任何一种。@roni您是否能够测试这里列出的各种方法?确定。我看到我们使用的是相同的方法,您避免了
    pdist2
    kron
    。有一段时间我不确定我是否正确理解了这个问题。我尝试使用“更简单”(?)函数来提高速度我在bsxfun上使用了一种稍微不同的方法来获得第四个维度:)@Divakar,当我通过
    bsxfun
    方法写作时,我想到了这一点。我放弃了它,因为它太难了。然后我想:“我知道现在谁在做这个!”-D@roni你能自己测试一下吗?您知道您的数据大小等。您熟悉
    timeit
    功能吗?它比
    tic
    /
    toc
    更好,因为计时可能
    squareform(pdist(…)
    会节省一些时间。我想知道如何从向量生成对称矩阵。什么也找不到。