Conditional element replacement using cellfun
Asked Answered
A

2

6
vec = randi(10,10,1)
vec(vec < 5) = 0

func = @(x) x(x < 5) = 0    % This isn't valid

How am I supposed to translate the second line of code into a function handle that I can use in conjunction with cellfun?

Amara answered 17/5, 2018 at 14:15 Comment(1)
Do the different vectors have different sizes? In case the size is the same (i.e. they're just stored as a cell for convenience), and assuming their total size is not too large in terms of memory - the cell array can be converted to a numeric matrix, the substitution performed, then the numeric matrix converted back to a cell array.Behre
A
9

You can use multiplication, since if your condition is satisfied you have 1 and 0 otherwise.

Multiplying by the inverse of the condition therefore gives you either an unchanged value (if condition is not satisfied) or your desired substitution of 0!

func = @(x) x .* (~(x < 5)) % Replace values less than 5 with 0

If you had a different substitution, you could expand the same logic

func = @(x) x .* (~(x < 5)) + 10 * (x < 5) % replace values less than 5 with 10
Alvinaalvine answered 17/5, 2018 at 14:24 Comment(3)
@Behre I left the condition as ~(x<5) instead of x>=5 to show that you need to negate whatever condition you're using, assuming x<5 is a simplification in the question! Sticking ~ in front means you don't have to think through the logical negation for more complex statements. Of course in this case the two are equivalent...Alvinaalvine
This seems to be a suitable solution. One question: Am I correct in saying that the equal sign (=) won't work in anonymous functions?Amara
@Amara Please see my above comment about using ~, it is the logical negation ("not") of the condition, i.e. ~true==false. You are correct that you can't use = within anonymous functions. The only way around this is when setting properties of handle objects when you can use the set command instead of an = statement, however that doesn't apply for matrixes like this example.Alvinaalvine
D
2

How about not using an anonymous function, but a function handle instead?

vec = randi(10,10,1);
vec_cell = num2cell(vec);
vec_cell_out = cellfun(@func, vec_cell);

function x = func(x)
    x(x<5) = 0;
end
Downhearted answered 17/5, 2018 at 14:21 Comment(1)
Yes, a function handle is working. However, in my view this one-liner screams for an anonymous function.Amara

© 2022 - 2024 — McMap. All rights reserved.