1

I've got a big array, say A, with values in {1,...,n}, and another array B of the same size.

I want to get all of the following:

B(A==1)
B(A==2)
...
B(A==n)

and then do something else with the results (not so important for now).

I tried things like:

[x,y] = B(A==[1:n])

and

[x,y] = [B(A==1), B(A==2), ..., B(A==n)]

Of course to no avail.

The for loop approach

for ii=1:n
    dummy=B(A==1)
    other stuff
end

works, but I'm convinced I can avoid for loops for everything in MATLAB! Stuck here, though. Any suggestions? Perhaps some sort of inline anonymous function call?

MichaelChirico
  • 33,841
  • 14
  • 113
  • 198

2 Answers2

2

arrayfun is your friend for things like this, hopefully you can see how to modify this for your own use:

A=randi(5,10,10)
B=rand(10)
C=arrayfun(@(i) B(A==i),1:5,'UniformOutput',false)
C{1} % for example, gives B(A==1)

C is a cell array.

Beware that the for loop may be faster for larger problems. It would be a good idea to do some tests to see whether arrayfun is actually faster. Look at this question and its answers to learn a bit more about this. There may be some way to do this without using arrayfun, but I can't think of it!

Community
  • 1
  • 1
David
  • 8,449
  • 1
  • 22
  • 32
  • Yes, it actuall does seem to be a bit slower. Great function to add to my arsenal though! Thank you. – MichaelChirico May 21 '14 at 03:42
  • There seems to be no right answer for speed nowadays with Matlab. Before JIT compilation, vectorisation was always faster, but now it is often not necessary, and sometimes slower than using loops. There are a few functions like arrayfun, bsxfun and cellfun are two others that do similar jobs, they could be worth playing around with and learning. – David May 21 '14 at 04:08
1

Assuming A to be a vector array, you can create a binary matrix of comparisons for each element in A to a vector of [1:n], where n is the maximum element in A -

indx_mat = bsxfun(@eq,A,1:max(A))

Next, whenever you need to access some elements in B based on the comparisons, you may use specific columns in indx_mat instead. For example, if you need to access elements for B(A==2), use B(indx_mat(:,2)).

Divakar
  • 218,885
  • 19
  • 262
  • 358