Home > Net >  MATLAB indexing by indexes in another matrix
MATLAB indexing by indexes in another matrix

Time:07-05

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

CodePudding user response:

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

CodePudding user response:

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.
  • Related