Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selecting elements from an array in MATLAB

I know that in MATLAB, in the 1D case, you can select elements with indexing such as a([1 5 3]), to return the 1st, 5th, and 3rd elements of a. I have a 2D array, and would like to select out individual elements according to a set of tuples I have. So I may want to get a(1,3), a(1,4), a(2,5) and so on. Currently the best I have is diag(a(tuples(:,1), tuples(:,2)), but this requires a prohibitive amount of memory for larger a and/or tuples. Do I have to convert these tuples into linear indices, or is there a cleaner way of accomplishing what I want without taking so much memory?

like image 220
sas4740 Avatar asked Jan 15 '23 06:01

sas4740


2 Answers

Converting to linear indices seems like a legitimate way to go:

indices = tuples(:, 1) + size(a,1)*(tuples(:,2)-1);
selection = a(indices);

Note that this is also implement in the Matlab built-in solution sub2ind, as in nate'2 answer:

a(sub2ind(size(a), tuples(:,1),tuples(:,2)))

however,

a = rand(50);
tuples = [1,1; 1,4; 2,5];

start = tic;
for ii = 1:1e4
    indices = tuples(:,1) + size(a,1)*(tuples(:,2)-1); end
time1 = toc(start);


start = tic;
for ii = 1:1e4
    sub2ind(size(a),tuples(:,1),tuples(:,2)); end
time2 = toc(start);

round(time2/time1)

which gives

ans =   
    38

so although sub2ind is easier on the eyes, it's also ~40 times slower. If you have to do this operation often, choose the method above. Otherwise, use sub2ind to improve readability.

like image 136
Brian L Avatar answered Jan 17 '23 21:01

Brian L


if x and y are vectors of the x y values of matrix a, then sub2und should solve your problem:

a(sub2ind(size(a),x,y))

For example

a=magic(3)

a =

 8     1     6
 3     5     7
 4     9     2
x = [3 1];
y = [1 2];


a(sub2ind(size(a),x,y))

ans =

 4     1
like image 23
bla Avatar answered Jan 17 '23 21:01

bla