Ifelse() evalutes both cases

I have encountered an unexpected (for myself) behavior of the ifelse() function. I thought that it would be easier to read if I used ifelse() function instead of an if-block. To see the problem that I had consider the following function and its call:

function foo(x, α)

	ret = ifelse(x < α, log(x), log(-x))

	return ret

end

foo(1.1, 2.0)

The call of this function returns a domain error as it tries to evaluate log(-1.1) which would not be the case if I used a regular if-block. Is it an intended behavior of the ifelse() function? I would prefer to use this function for readability purposes but it is not useful for such instances.

This is intentional. If you want something that is more compact, but behaves like if, then use the ternary operator:

x < α ? log(x) : log(-x)
3 Likes

As ifelse is a function, its arguments are always evaluated first, as with any function.

5 Likes

The ifelse function is useful when both expressions are very cheap to evaluate, so cheap that it’s faster to evaluate both than to use an actual brach, which has a certain cost and might even prevent simd vectorization. So it’s primarily used for performance.

9 Likes