freealbert
freealbert

Reputation: 53

How could I perform something like List comprehension in Matlab?

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 ~~

Upvotes: 5

Views: 3619

Answers (2)

Dan
Dan

Reputation: 45752

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.

Upvotes: 1

Marcin
Marcin

Reputation: 238199

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.

Upvotes: 2

Related Questions