Reputation: 53
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
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
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