5

My question is: How could I perform something like List comprehension in Matlab similar to Haskell or Python? To accomplish the function in Matlab like below:

for xxx 
    if condition
        expression1;    
    else 
        expression2;
     end 
end 

My original aim is to make use of the vectorized operations and reduce the for-loop in my code to make it running faster.

EDIT: My expect to the answer is not necessary something related to the arrayfun, the vectoried operation method is more welcomed.

There is another question related to this question (through the function named "arrayfun"). The anonymous function in Matlab seams to be only 1 line, then how could I write the if-else expression in it ?

Thanks everyone ~~

freealbert
  • 53
  • 1
  • 5
  • Faster to type, or faster to execute? Because the details of whether for loops, list comprehensions, or vectorized operations execute faster very much depends on the individual language. – Marius Jul 05 '13 at 06:11
  • 1
    If it is a matter of performance you should definitely benchmark both solutions. `for` is generally much faster than `arrayfun`. – Mohsen Nosratinia Jul 05 '13 at 07:46
  • 1
    similar questions: http://stackoverflow.com/q/16555724/97160, http://stackoverflow.com/q/8327013/97160, http://stackoverflow.com/q/9993189/97160, http://stackoverflow.com/q/10918404/97160 – Amro Jul 05 '13 at 12:45
  • 1
    wrt to performance, here is a question about it: http://stackoverflow.com/q/12522888/97160 . Another difference is that `arrayfun` supports running on the GPU with `gpuArray` – Amro Jul 05 '13 at 12:50
  • @freealbert: regarding your question about anonymous functions, you might find this series of articles to be of interest: http://blogs.mathworks.com/loren/category/functional-programming/ – Amro Jul 05 '13 at 12:55
  • @Amro Thanks, You are so nice. Xie Xie (in Chinese). – freealbert Jul 05 '13 at 13:03

2 Answers2

2

You cannot use if in anonymous functions in Matlab. However, you could work around this a bit using arrayfun, by defining your own function that will execute the statements and conditions, e.g.

function result = iff(condition, v1, v2)
  if condition
    result = v1;
  else
    result = v2;
  end

Then in arrayfun you can do something such as this:

arrayfun(@(x) iff(mod(x,2)==0, x , 0), [1:10])

results in:

0     2     0     4     0     6     0     8     0    10

This is based on the answer to similar question here.

Marcin
  • 215,873
  • 14
  • 235
  • 294
1

arrayfun doesn't actually get rid of the loops, it just means you don't have to type them out explicitly. That said, in new Matlabs loops aren't that slow anymore. But there might be a fully vectorized way to do what you want, I'm not saying it will necessaruly be faster (but I think it will in older matlabs):

You can take advantage of the way Matlab will automatically cast logicals to double, i.e. false to 0 and true to one. For example

A = rand(10,1);

lets say you want value above 0.7 to be multiplied by 2, otherwise you must subtract 5 then you can go

(A*2).*(A>0.7) + (A-5).*(A<=0.7);

of course in such a simple example you can also just use logical indexing:

I = A > 0.7;
A(I) = A(I)*2;
A(~I) = A(~I) - 5;

Which is also fully vectorized.

Dan
  • 45,079
  • 17
  • 88
  • 157
  • Thank you so much! You not only tell me a method that could save my problem without write another function file, but also give more information than I had expected. Sorry for lacking the reputation to vote. – freealbert Jul 05 '13 at 11:31
  • @freealbert I'm glad it helped. You should choose an answer to accept though, by clicking the arrow in the top left of the question. Whichever you feel is more correct for you, but they are both right so you should def pick one. – Dan Jul 05 '13 at 11:43
  • Thanks Dan, I am a newbie here. As you said that " new Matlabs loops aren't that slow anymore", where could I find the information?", does it mean that there is no need to use the vectorized operations for effience and "for" can got work done as fast as vectorized operations in new Matlab ? – freealbert Jul 05 '13 at 12:04
  • @freealbert I suggest you always check using `tic` and `toc` to see if vectorizing gives you a performance increase. But google matlab's JIT optimization for more – Dan Jul 05 '13 at 12:57