开发者

Vectorize call to function of two vectors (treat matrix as array of vector)

开发者 https://www.devze.com 2023-02-08 02:32 出处:网络
I wish to compute the cumulative cosine distance between sets of vectors. The natural representation of a set of vectors is a matrix...but how do I vectorize the following?

I wish to compute the cumulative cosine distance between sets of vectors.

The natural representation of a set of vectors is a matrix...but how do I vectorize the following?

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

I can of course write

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

...so long as I recast my matrices as cell arrays of vectors. Is there a better / entirely numeric way?

Also, will cellfun, arrayfun, etc. take advantage of vector instructions and/or multithreading?

Note probably superfluous in present company but 开发者_开发问答for column vectors v1'*v2 == dot(v1,v2) and is significantly faster in Matlab.


Since P1 and P2 are of the same size, you can do element-wise operations here. v1'*v equals sum(v1.*v2), by the way.

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


@Jonas had the right idea, but the normalizing denominator might be incorrect. Try this instead:

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

You can compare this against the results returned by PDIST2 function:

%# PDIST2 returns one minus cosine distance between all pairs of vectors
d2 = prod( 1-diag(pdist2(P1',P2','cosine')) );
0

精彩评论

暂无评论...
验证码 换一张
取 消