How to vectorize this code to eliminate nested For loops

조회 수: 13 (최근 30일)
DaveF
DaveF 2013년 1월 18일
Would like to know how this code be vectorized:
X=zeros(nn);
for i=1:nn
for j=1:nn
X(i,j)=x(i)-x(j);
end
end

답변 (5개)

Sean de Wolski
Sean de Wolski 2013년 1월 18일
X = bsxfun(@minus,x(1:nn).',x(1:nn));

Jan
Jan 2013년 1월 18일
편집: Jan 2013년 1월 19일
This cannot compete with the BSXFUN approach, but it is 32% faster than the original loop:
nn = numel(x);
X = zeros(nn);
for i = 1:nn
for j = i+1:nn
a = x(i) - x(j);
X(i,j) = a;
X(j,i) = -a;
end
end
Using a temporary variable for x(i), which is updated in the outer loop only, is slightly slower.
  댓글 수: 3
Jan
Jan 2013년 1월 19일
편집: Jan 2013년 1월 19일
@Cedric: When you post this as an answer, you get my vote.
Your version does not exploit the symmetry as the other approaches. But this modification is much slower:
X=zeros(nn);
for ii = 1:nn
a = x(ii:nn) - x(ii);
X(ii:nn, ii) = a;
X(ii, ii:nn) = -a;
end
Obviously the overhead for explicit indexing is too high.
Cedric
Cedric 2013년 1월 19일
@Jan : thank you! Knowing that I would get your vote is enough, so I'll keep that as a comment ;-)
I just profiled your last version and it is very interesting indeed, because I would never have expected such an overhead. It might even lead me to review my code in a few projects, so thank you for the comment!

댓글을 달려면 로그인하십시오.


Jan
Jan 2013년 1월 19일
And a C-Mex, which has the same speed as BSXFUN for a [1 x 1e3] vector under Matlab R2009a/64, Win7, MSVC 2008:
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
double *X, *Y;
mwSize i, j, n;
n = mxGetNumberOfElements(prhs[0]);
X = mxGetPr(prhs[0]);
plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL);
Y = mxGetPr(plhs[0]);
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
*Y++ = X[i] - X[j];
}
}
}

Azzi Abdelmalek
Azzi Abdelmalek 2013년 1월 18일
편집: Azzi Abdelmalek 2013년 1월 18일
x=[1 3 4 10 20 30];
X=cell2mat(arrayfun(@(y) y-x,x','un',0))
%or
X=bsxfun(@minus,repmat(x',1,numel(x)),x)
  댓글 수: 2
Cedric
Cedric 2013년 1월 18일
편집: Cedric 2013년 1월 18일
Or
[X, Xt] = meshgrid(x, x) ; Xt-X
More efficient than cell2mat/arrayfun and less efficient than bsxfun. So the latter (bsxfun) should be the winner ;) But Sean's version without repmat beats them all.
Sean de Wolski
Sean de Wolski 2013년 1월 18일
Well the for-loops will smoke arrayfun/cell2mat like a Lambo would smoke bicycle...
bsxfun will be faster than the for-loops some of the time; meshgrid will only be faster if you need to reuse the gridded matrices.

댓글을 달려면 로그인하십시오.


Matt J
Matt J 2013년 1월 19일
y=exp(x(1:nn));
X=log( y * (1./y.') );

카테고리

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