Reputation: 233
I have a 3D matrix for example a 1000-by-4-by-20 matrix A and I want to select one of the 1-by-20 vectors from each row of A according to a 1000-by-1 index vector B. This index vector includes numbers form 1 to 4. Also, I do not want to use a for loop. How should I do that (with and/or without "sub2ind")?
Thank you.
Upvotes: 1
Views: 118
Reputation: 112689
Here's a another way using bsxfun
:
[r, c, t] = size(A);
result = A(bsxfun(@plus, (1:r).'+r*(B-1), (0:t-1)*r*c));
Upvotes: 1
Reputation: 16801
I'm not sure this is the most elegant way, but it gets the job done:
[r,c,~]=size(A);
Q=reshape(A,r*c,[]);
P=sub2ind([r,c],[1:r]',B);
result=Q(P,:);
This will put each of the 1x1x20 vectors into the appropriate row in a 1000x20 result matrix. You can combine the last two lines if you want.
Here are the first 20 rows of a sample run with the vector B
appended to the front to show which column we were supposed to take. The construction of A
should be pretty obvious (first digit is the column number, next 3 are the row number - 1. All elements of the 1x1x20 vector are the same.)
B result
2 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000 2000
1 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001 1001
4 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002 4002
4 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003 4003
3 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004 3004
4 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005 4005
3 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006 3006
1 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007 1007
3 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008 3008
4 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009 4009
2 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010
4 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011 4011
3 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012 3012
2 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013
4 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014 4014
4 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015 4015
1 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016 1016
2 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 2017
4 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018 4018
3 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019 3019
Upvotes: 1
Reputation: 4310
Say the vector is called A
. You can index it like so:
A(1:1000,B,:)
Where index1 can range from 1 to 1000, and index2 can range from 1 to 4. The colon selects everything at that index level.
Upvotes: 0