Avoiding for loops problem

1 次查看(过去 30 天)
Kilian
Kilian 2013-2-26
What I want to do is the following:
Given a matrix A of size [M,N] (rows are vectors) and another matrix B of size [Q,N] (rows are vectors) I want to construct a matrix with the squared distance between each vector of A with all the vectors of B and put it in matrix D. So D(i,j) = sum(((A(i,:)-B(j,:)).^2)
I want to avoid using a double for loop over i and j for creating this because I want to speed up the process. If matrix A would be of size [1,N] I'd think I could transform it into a matrix C of size [Q,N] with on every row the same vector and just go D = sum((C-A).^2) . I'm not sure if this would be a good idea and then I'd still need a for loop to go over the other vectors if A wasn't a [1,N] matrix.
Is there any logical solution or should I just stick to for loops?

回答(4 个)

Teja Muppirala
Teja Muppirala 2013-2-27
If you have the Statistics Toolbox, you can use the PDIST2 function. It is very fast.
A = rand(200,100);
B = rand(300,100);
pdist2(A,B).^2

Honglei Chen
Honglei Chen 2013-2-26
sum(bsxfun(@minus,permute(A,[1 3 2]),permute(B,[3 1 2])).^2,3)

Matt J
Matt J 2013-2-26
There are also some generalizations of this capability on the FEX, e.g.,

Matt J
Matt J 2013-2-26
If you organize your vectors column-wise instead of row-wise, you can do this without PERMUTE operations, using the utility below. Permute operations are slow.
function Graph=interdists(A,B)
%Finds the graph of distances between point coordinates
%
% (1) Graph=interdists(A,B)
%
% in:
%
% A: matrix whose columns are coordinates of points, for example
% [[x1;y1;z1], [x2;y2;z2] ,..., [xM;yM;zM]]
% but the columns may be points in a space of any dimension, not just 3D.
%
% B: A second matrix whose columns are coordinates of points in the same
% Euclidean space. Default B=A.
%
%
% out:
%
% Graph: The MxN matrix of separation distances in l2 norm between the coordinates.
% Namely, Graph(i,j) will be the distance between A(:,i) and B(:,j).
%
%
% (2) interdists(A,'noself') is the same as interdists(A), except the output
% diagonals will be NaN instead of zero. Hence, for example, operations
% like min(interdists(A,'noself')) will ignore self-distances.
%
% See also getgraph
noself=false;
if nargin<2
B=A;
elseif ischar(B)&&strcmpi(B,'noself')
noself=true;
B=A;
end
N=size(A,1);
B=reshape(B,N,1,[]);
Graph=l2norm(bsxfun(@minus, A, B),1);
Graph=squeeze(Graph);
if noself
n=length(Graph);
Graph(linspace(1,n^2,n))=nan;
end

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by