matlab: быстрая функция, которая может генерировать NaN, если x> 1 - PullRequest
7 голосов
/ 04 октября 2010

Я ищу однострочную функцию f = @(x) {something}, которая выдает NaN, если x> = 1, и либо 0, либо 1, если x <1. </p>

Есть предложения?

Ответы [ 4 ]

5 голосов
/ 04 октября 2010

Вот модификация решения Джейсона, которая работает для массивов.Обратите внимание, что последние версии MATLAB не генерируют предупреждения деления на ноль.

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

Обновление : коллега указал мне, что оригинальный ответ Джейсона прекрасно работает для массивов.

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

f = 

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

>> f(0:.3:2)

ans =

     0     0     0     0   NaN   NaN   NaN
5 голосов
/ 04 октября 2010

Ага, я понял:

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

дает 0 для x <1 и NaN для x> = 1.

2 голосов
/ 04 октября 2010

Вот менее очевидное решение (тем не менее, векторизованное):

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

По сути, оно эквивалентно:

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

+0 в конце всегда состоит в форсировании вывода,даже если f вызывается без выходных аргументов (возвращается в ans).Пример:

>> f(-2:2)
ans =
     0     0     0   NaN   NaN
2 голосов
/ 04 октября 2010

Вот решение, которое не рискует выдавать какие-либо предупреждения деления на ноль, поскольку оно не включает никакого деления (только функции ONES и NAN ):

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


РЕДАКТИРОВАТЬ: Приведенное выше решение сделано для скалярных входов.Если требуется векторизованное решение (что не ясно на 100% из вопроса), вы можете изменить f следующим образом:

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

Или применить ARRAYFUN при вызове первоговерсия функции f:

y = arrayfun(f,x);
...