简体   繁体   中英

MATLAB indexing by indexes in another matrix

I'm trying to generate a new matrix, based on index values stored in another matrix.

This is trivial to do with a for loop, but this is currently the slowest line in some code I'm trying to optimise, and so I'm looking for a way to do it without the loop, and pulling my hair out. I'm sure this has been answered before, and that I just don't know the right search terms.

n1 = 10;
n2 = 100;

a = randi(n2,[1,n1]);
b = randi(n2,[4,n1]);
c = rand(100,100);

for i = 1:n1
    d(:,i) = c(a(i),b(:,i));
end

I'm assuming the value of n1 in your code is way bigger than in the example you provide, which would explain why it is "slow".

In order to do this without a loop, you can use Linear indexing :

n1 = 1e6;
n2 = 100;

a = randi(n2,[1,n1]);
b = randi(n2,[4,n1]);
c = rand(n2,n2);

% With a loop
d = zeros(4,n1);
tic

for i = 1:n1
    d(:,i) = c(a(i),b(:,i));
end

toc

% A faster way for big values of `n1`
d2 = zeros(4,n1);
tic

a_rep = repmat(a,4,1); % Repeat row indexes to match the elements in b

idx_Lin = sub2ind([n2,n2],a_rep(:),b(:)); % Get linear indexes

d2(:) = c(idx_Lin); % Fill

toc

isequal(d,d2)

Elapsed time is 1.309654 seconds.

Elapsed time is 0.062549 seconds.

ans =

logical

1

Try This:

n1 = 10;
n2 = 100;
a =  randi(n2,[1,n1]);
b =  randi(n2,[4,n1]);
c = rand(100,100);
idx = (1:n1);
tic
d1=(c(a(idx),b(:,idx)))';
[idx,idy]=meshgrid(0:44:400,1:4);
d1=d1(idy+idx);
toc

this is the timeing:

Elapsed time is 0.000517 seconds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM