views:

100

answers:

4

I am looking for a one-line function f = @(x) {something} that produces NaN if x >= 1, and either 0 or 1 if x < 1.

Any suggestions?

+4  A: 

Aha, I got it:

f = @(x) 0./(x<1)

yields 0 for x < 1 and NaN for x>=1.

Jason S
+2  A: 

Here's a solution that won't risk throwing any divide-by-zero warnings, since it doesn't involve any division (just the functions ONES and NAN):

f = @(x) [ones(x < 1) nan(x >= 1)];


EDIT: The above solution is made for scalar inputs. If a vectorized solution is needed (which isn't 100% clear from the question) then you could modify f like so:

f = @(x) arrayfun(@(y) [ones(y < 1) nan(y >= 1)],x);

Or apply ARRAYFUN when calling the first version of the function f:

y = arrayfun(f,x);
gnovice
@gnovice: neat, but it fails for vector input.
Jonas
@Jonas: True, although it wasn't apparent from the question that a vectorized solution was required. I'll update my answer.
gnovice
@gnovice: But surely, any Matlab function should work on arrays :)
Jonas
@gnovice: Excellent! Now I can give +1 for the most clever solution.
Jonas
+2  A: 

Here's a less obvious solution (vectorized nonetheless):

f = @(x) subsasgn(zeros(size(x)), struct('type','()','subs',{{x>=1}}), nan) + 0

Basically its equivalent to:

function v = f(x)
    v = zeros(size(x));
    v( x>=1 ) = nan;

The +0 at the end is to always force an output, even if f called with no output arguments (returned in ans). Example:

>> f(-2:2)
ans =
     0     0     0   NaN   NaN
Amro
@Amro: no need for `find`. I like this function best, since it is the cleanest implementation that will also work for arrays.
Jonas
that's true, thanks Jonas
Amro
+5  A: 

Here's a modification of Jason's solution that works for arrays. Note that recent versions of MATLAB do not throw divide-by-zero warnings.

>> f = @(x) zeros(size(x)) ./ (x < 1)

f = 

    @(x)zeros(size(x))./(x<1)

>> f(0:.3:2)

ans =

     0     0     0     0   NaN   NaN   NaN

Update: a coworker pointed out to me that Jason's original answer works just fine for arrays.

>> f = @(x) 0./(x<1)

f = 

    @(x)0./(x<1)

>> f(0:.3:2)

ans =

     0     0     0     0   NaN   NaN   NaN
Steve Eddins
Good to know that the newer versions of MATLAB no longer throw DBZ warnings by default. That was always kinda annoying.
gnovice

related questions