MATLAB: Indexing for 4-D Arrays

indexingmultidimensional arrays

Hello,
I am currently having trouble pulling data from a 4-D array through indexing.
I start with a 3-D array which represents the 3D coordinates of my system. At each point in the 3D matrix I assign a random 3D vector, making it 4-D. I would like to pull the corresponding vector from many different points within the array. The 3D coordinates of the points I want to pull are stored in a 2D array with the columns being the (x,y,z) points.
%% Build array
dim = 40;
totalLocations = dim^3;
randomVec = rand(totalLocations,3);
volume = reshape(randomVec,dim,dim,dim,3);
%% Request data from 4d array

vec = [1 1 1];
ind = [1:3];
vector1 = (volume(vec(:,1),vec(:,2),vec(:,3),ind))
Output:
vector1(:,:,1,1) =
0.4150
vector1(:,:,1,2) =
0.0820
vector1(:,:,1,3) =
0.0865
The above is an example of how I pull the corresponding vector from the position (1,1,1). Since this is only one point I can squeeze out the extra dimensions and end up with the desired vector. My issue is when I try and expand this to multiple (x,y,z) positions by adding additional rows to vec. For example:
%% Build array
dim = 40;
totalLocations = dim^3;
randomVec = rand(totalLocations,3);
volume = reshape(randomVec,dim,dim,dim,3);
%% Request data from 4d array
vec = [1 1 1;1 1 2];
ind = [1:3];
clc
vector1 = volume(vec(:,1),vec(:,2),vec(:,3),ind)
My output is:
vector1(:,:,1,1) =
0.4150 0.4150
0.4150 0.4150
vector1(:,:,2,1) =
0.5320 0.5320
0.5320 0.5320
vector1(:,:,1,2) =
0.0820 0.0820
0.0820 0.0820
vector1(:,:,2,2) =
0.4980 0.4980
0.4980 0.4980
vector1(:,:,1,3) =
0.0865 0.0865
0.0865 0.0865
vector1(:,:,2,3) =
0.7612 0.7612
0.7612 0.7612
Which appears to give me the correct numbers but they all appear (number of rows in vec)^2 times. Can anyone help me with how to pull the vectors from many points in the 3-D space through use of a list of (x,y,z) coordinates. I need to do this without loops due to the size of my arrays.
Please let me know if more clarification is needed.
Thanks.

Best Answer

You could use sub2ind:
%% Build array
dim = 40;
volume = rand(dim,dim,dim,3); % simpler!
%% Request data from 4d array
vec = [1,1,1;1,1,2];
ind = 1:3;
idv = zeros(1,numel(ind));
id4 = repmat(ind,size(vec,1),1);
idx = sub2ind(size(volume),vec(:,1+idv),vec(:,2+idv),vec(:,3+idv),id4);
vector1 = volume(idx)
vector1 = 2×3
0.0996 0.0540 0.8415 0.3888 0.0559 0.9637
Compare:
volume(1,1,1,ind)
ans =
ans(:,:,1,1) = 0.0996 ans(:,:,1,2) = 0.0540 ans(:,:,1,3) = 0.8415
volume(1,1,2,ind)
ans =
ans(:,:,1,1) = 0.3888 ans(:,:,1,2) = 0.0559 ans(:,:,1,3) = 0.9637