Reassemble matrix in matlab

Viewed 48

I have a matrix x in matlab that has 6*n*n*3 rows and one column representing 6*n*n 3d coordinates of points. The coordinates are arranged such that rows 1:6*n*n are the x coordinates, rows 6*n*n+1:12*n*n are the y coordinates and 12*n*n+1:18*n*n are the z coordinates.

I would like to build 2 new matrices from it, one that simply places the x,y,z coordinates of a given point together and the other whose row i consists of subtracting point i to every other point.

Right now I am doing this using a double for loop which is very slow for n>16. Is there a better/faster way of doing this using matlab vector/matrix capabilities?

Here it is my current code

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 
2 Answers

You can avoid loops using bsxfun, array reshaping and concatenation(assuming that x ,y,z are column vectors of size[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,[]).';

Or in the recent versions of MATLAB you can do:

points = [x y z];
deltax = x.' - x;
deltay = y.' - y;
deltaz = z.' - z;
difs   = reshape([deltax(:) deltay(:) deltaz(:)].',N*3,[]).';

I don't have an idea of how your data looks like, but let's try with simple thing and then I'll eventually expand my answer.

First micro-optimization: always cache your intermediate results in Matlab to improve performance when looping.

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

Second micro-optimization: pre-instantiate your arrays to avoid inline memory reallocation.

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
Related