"Reshaping" matrix
Show older comments
I have a matrix P_ind that is AxB (where each element is an integer in the range 1:C) and a matrix xgrid that is CxDxB. Is there a smart way to create a new matrix xgrid2 that is AxDxB without resorting to the for loop solution below?
xgrid2=NaN(A,D,B);
for i=1:A
for j=1:B
xgrid2(i,:,j)=xgrid(P_ind(i,j),:,j);
end
end
Edit: Since there were comments on the clarity of my question, let me try again. What I want to do is create the array xgrid2 in the code below, but in a more succint and most of all faster way than the nested for loops in my approach.
A=10000; % no. of individuals
B=65; % maximum age
C=30; % gridpoints for P
D=50; % gridpoints for S
P_ind=randi(C,A,B);
xgrid=randi(5000,A,D,B);
xgrid2=NaN(A,D,B);
for i=1:A
for j=1:B
xgrid2(i,:,j)=xgrid(P_ind(i,j),:,j);
end
end
Accepted Answer
More Answers (2)
Kelly Kearney
on 17 Nov 2015
My rule of thumb for this type of problem is to permute and reshape the matrices in such a way that you can access the dimension(s) of interest via linear indexing rather than subscripts.
The data:
A=10000; % no. of individuals
B=65; % maximum age
C=30; % gridpoints for P
D=50; % gridpoints for S
P_ind=randi(C,A,B);
xgrid=randi(5000,A,D,B);
Your way (loops)
tic;
xgrid2=NaN(A,D,B);
for i=1:A
for j=1:B
xgrid2(i,:,j)=xgrid(P_ind(i,j),:,j);
end
end
t(1) = toc;
New way (permute, reshape, index, unreshape, unpermute)
tic;
xgrdtmp = reshape(permute(xgrid, [1 3 2]), [], D);
[ii,jj] = ndgrid(1:A,1:B);
pidx = sub2ind(size(P_ind), ii, jj);
idx = sub2ind([A,B], P_ind(pidx), jj);
xgrid3 = permute(reshape(xgrdtmp(idx(:),:), [A B D]), [1 3 2]);
t(2) = toc;
Check
check = isequal(xgrid2, xgrid3);
fprintf('Time (old): %f\nTime (new): %f\nEqual: %d\n', t,check);
...
Time (old): 2.325150
Time (new): 0.441705
Equal: 1
Nitin Khola
on 3 Nov 2015
0 votes
My understanding is that you want to reshape an array that is of size "CxDxB", xgrid to another array of size "AxDxB". So that you can use "reshape" you need the total number of elements to remain the same i.e. A=C in your case. This implies you will have values repeating (I am assuming A>C). You need to use "repmat" to do it in that particular dimension. Refer to the following documentation for details: http://www.mathworks.com/help/matlab/ref/repmat.html http://www.mathworks.com/help/matlab/ref/reshape.html
1 Comment
Fredrik P
on 17 Nov 2015
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!