我在matlab中有一个矩阵x,它有6 * n * n * 3行和一列代表点的6 * n * n 3d坐标。坐标排列为行1:6 * n * n为x坐标,行6 * n * n + 1:12 * n * n为y坐标,12 * n * n + 1:18 * n * n是z坐标。
我想从它构建2个新矩阵,一个简单地将给定点的x,y,z坐标放在一起,另一个i的行包括将点i减去每个其他点。
现在我正在使用双循环执行此操作,对于n> 16,这非常慢。使用matlab矢量/矩阵功能有更好/更快的方法吗?
这是我目前的代码
x=x(1:6*n*n);
y=y(6*n*n+1:12*n*n);
z=z(12*n*n+1:18*n*n);
N=6*n*n;
points=[];
difs=[];
for i=1:N
difrow=[];
points=[points;x(i) y(i) z(i)];
for j=1:N
deltax=x(i)-x(j);
deltay=y(i)-y(j);
deltaz=z(i)-z(j);
difrow=[difrow deltax deltay deltaz];
end
difs=[difs;difrow];
end
答案 0 :(得分:4)
您可以使用bsxfun,数组重新整形和连接来避免循环(假设x ,y,z
是大小为[N x 1]
的列向量):
points = [x y z];
deltax = bsxfun(@minus,x.' , x);
deltay = bsxfun(@minus,y.' , y);
deltaz = bsxfun(@minus,z.' , z);
difs = reshape([deltax(:) deltay(:) deltaz(:)].',N*3,[]).';
或者在MATLAB的最新版本中,您可以这样做:
points = [x y z];
deltax = x.' - x;
deltay = y.' - y;
deltaz = z.' - z;
difs = reshape([deltax(:) deltay(:) deltaz(:)].',N*3,[]).';
答案 1 :(得分:1)
我不知道你的数据是怎么样的,但让我们尝试简单的事情,然后我最终会扩展我的答案。
首次微优化:始终在Matlab中缓存您的中间结果,以提高循环时的性能。
x = x(1:6*n*n);
y = y(6*n*n+1:12*n*n);
z = z(12*n*n+1:18*n*n);
points = [];
difs = [];
for i=1:N
difrow = [];
x_i = x(i);
y_i = y(i);
z_i = z(i);
points = [points; x_i y_i z_i];
for j=1:N
deltax = x_i - x(j);
deltay = y_i - y(j);
deltaz = z_i - z(j);
difrow = [difrow deltax deltay deltaz];
end
difs=[difs; difrow];
end
第二次微优化:预先实例化数组以避免内联内存重新分配。
x = x(1:6*n*n);
y = y(6*n*n+1:12*n*n);
z = z(12*n*n+1:18*n*n);
points = NaN(N,1);
difs = [];
for i=1:N
x_i = x(i);
y_i = y(i);
z_i = z(i);
points(i) = [x_i y_i z_i];
difrow = NaN(N,1);
for j=1:N
deltax = x_i - x(j);
deltay = y_i - y(j);
deltaz = z_i - z(j);
difrow(j) = [deltax deltay deltaz];
end
difs = [difs; difrow];
end