Vectoriser l'appel à la fonction de deux vecteurs (traiter la matrice comme un tableau de vecteur)

StackOverflow https://stackoverflow.com/questions/4885524

Question

Je souhaite calculer la distance cumulée en cosinus entre les ensembles de vecteurs.
La représentation naturelle d'un ensemble de vecteurs est une matrice ... mais comment puis-je vectaliser ce qui suit?

function d = cosdist(P1,P2)
    ds = zeros(size(P1,2),1);
    for k=1:size(P1,2)
      %#used transpose() to avoid SO formatting on '
        ds(k)=transpose(P1(:,k))*P2(:,k)/(norm(P1(:,k))*norm(P2(:,k)));
    end
    d = prod(ds);
end

Je peux bien sûr écrire

fz = @(v1,v2) transpose(v1)*v2/(norm(v1)*norm(v2));
ds = cellfun(fz,P1,P2);

... Tant que je refonte mes matrices comme tableaux cellulaires de vecteurs. Y a-t-il une manière meilleure / entièrement numérique?
De plus, CellFun, ArrayFun, etc. profiteront-ils des instructions vectorielles et / ou du multithreading?

Noter Probablement superflu dans la société actuelle mais pour les vecteurs de colonnes v1'*v2 == dot(v1,v2) et est considérablement plus rapide dans Matlab.

Était-ce utile?

La solution

Depuis P1 et P2 sont de la même taille, vous pouvez effectuer des opérations d'élément ici. v1'*v équivaut à sum(v1.*v2), d'ailleurs.

d = prod(sum(P1.*P2,1)./sqrt(sum(P1.^2,1) .* sum(P2.^2,1)));

Autres conseils

@Jonas avait la bonne idée, mais le dénominateur de normalisation pourrait être incorrect. Essayez ceci à la place:

%# matrix of column vectors
P1 = rand(5,8);
P2 = rand(5,8);

d = prod( sum(P1.*P2,1) ./ sqrt(sum(P1.^2,1).*sum(P2.^2,1)) );

Vous pouvez comparer cela avec les résultats renvoyés par PDIST2 fonction:

%# PDIST2 returns one minus cosine distance between all pairs of vectors
d2 = prod( 1-diag(pdist2(P1',P2','cosine')) );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top