3
votes

I have a matrix of x,y,z matrix coordinates as well as a matrix of row vectors corresponding to timeseries associated with these coordinates. E.g.

coordinates = [1 2 3; 57 89 22]; % Where the column 1 = x, column 2 = y, column 3 = z
timeseries = rand(2,200); % where each row corresponds to the timeseries of the coordinates in the same row in the coordinates matrix.

I want to build a 4D matrix containing these timeseries. Any unassigned coordinate should default to a vector of zeros. Currently I do this as follows:

M = zeros(100,100,100,200); 
for ii = 1:size(coordinates,1)
    M(coordinates(ii,1),coordinates(ii,2),coordinates(ii,3),:) = timeseries(ii,:);
end

This works, but I was wondering if there is a (more readable/efficient) method to write the for-loop in a single step. I've tried using logical arrays and indices, but it always fails because I'm assigning vectors, not scalars.

1

1 Answers

2
votes

Here's a way using sub2ind. I haven't timed it:

sz = [100 100 100 200];
M = zeros(sz(1)*sz(2)*sz(3), sz(4));
ind = sub2ind(sz([1 2 3]), coordinates(:,1), coordinates(:,2), coordinates(:,3));
M(ind(:),:) = timeseries;
M = reshape(M, sz);

You can increase speed a little replacing sub2ind by manual computation:

sz = [100 100 100 200];
M = zeros(sz(1)*sz(2)*sz(3), sz(4));
ind = coordinates(:,1) + sz(1)*(coordinates(:,2)-1) + sz(1)*sz(2)*(coordinates(:,3)-1);
M(ind(:),:) = timeseries;
M = reshape(M, sz);