2013-07-02 3 views
6

Функция может быть определена как @(x) x^.2 (для например)Как использовать условие внутри анонимной функции

Но в случае, у нас есть функция, которая принимает различные представления на различных интервалах, например: if abs(x)<3 fun = x^.2 else 0

Как мы можем использовать то же самое (я имею в виду использование @(x)) для определения такой функции.

+1

Возможный дубликат [Как выполнить несколько операторов в анонимной функции MATLAB?] (Http://stackoverflow.com/questions/558478/how-to-execute-multiple-statements-in-a-matlab-anonymous- функция) – Shai

+2

@Shai: не согласен. Этот вопрос касается множественных оценок функций в одном аноне, в то время как об условной оценке в аноне (там * есть * обман, я видел это, но я не нахожу его сейчас ...) –

ответ

16

Существует несколько способов сделать это.

Multiply ложным:

g = @(x) (abs(x)<3) .* x.^2 

или определить правильную функцию (лучший способ на самом деле):

function y = g(x) 

    y = zeros(size(x), class(x)); 

    inds = abs(x)<3; 
    y(inds) = x(inds).^2; 

end 

или сделать грязную уродливую неэффективную но-весело вещь и использовать inline-if:

iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}(); 
g = @(x) iff(... 
    abs(x)<3, x.^2, ... 
     true, 0); 
+2

Больше объяснений : Правильная функция требуется даже тогда, когда вы хотите избежать вычисления другой части, которая не выбрана; например: 'iif (x == 0; 0; 1/x) 'здесь' 1/x' все еще оценивается, даже если 'x == 0'. Это функция, и Matlab все еще хочет передать все аргументы, следовательно, оценку. Единственный способ избежать этого (и именно поэтому это лучший, правильный способ) заключается в использовании отдельной функции, которая позволяет использовать многострочный и нормальный 'if'. –

+0

@GuntherStruyf: true. Добавлен «inefficnet» к описанию метода 'iif()'): –

+0

@GuntherStruyf: ahum. Это «неэффективно». Печатать сложно. –

0

Как @Gunther упоминалось в предыдущих комментариях, общая функция для обработки сим чтобы подражать третичному оператору?: может быть создано для ограничения ограничения, которое Matlab не допускает условных условий внутри анонных функций (если вы не считаете, что запутанная версия - уродливая, неэффективная, но веселая).

Решение было предоставлено по этой ссылке (и, возможно, в нескольких других местах, но SO вернулось к моему поисковому поиску Google, поэтому подумал, что было бы неплохо добавить сюда). http://www.mathworks.co.jp/matlabcentral/newsreader/view_thread/158054

Определим функцию говорят тогда и только тогда или IfElse и добавить его в путь Matlab.

function result = ifelse(condition,trueResult,falseResult) 
    error(nargchk(3,3,nargin)); % check correct number of input args 
    if condition 
     result = trueResult; 
    else 
     result = falseResult; 
    end 

затем использовать как этот

predict = arrayfun(@(x) ifelse(x>=0.5,1,0), inputData); 

В случае с ФП, в чем-то, как это может быть использовано

arrayfun(@(x) ifelse(abs(x)<3,x^.2,0), data) 
0

Это то, что я придумал. У меня есть cases.m функцию со следующим определением:

function [ val ] = cases(table) 
    [rows,~] = size(table); 
    for i = drange(1:rows) 
    condition = table{i,1}; 
    if (ischar(condition) && strcmpi(condition,'else')) || feval(condition) 
     val = feval(table{rows,2}); 
     return 
    end 
    end 
    val={}; 
end 

Функция cases принимает массив ячеек с двумя столбцами. Каждый элемент представляет собой функцию с нулевыми аргументами. Для каждой строки он принимает первый элемент, и если это строка «else» или функция, возвращающая истинное значение, вызывается второй элемент и возвращается его значение. Если строка не соответствует, возвращается пустая ячейка. Элементы являются нулевыми функциями вместо значений, так что ненужные случаи не оцениваются.

Тогда я могу написать тематические выражения, как это:

w=arrayfun(@(j) cases({ ... 
    @() (j==0 || j==n) @() (-1)^j/2; ... 
    'else' @() (-1)^j }), 0:n); 

Это создает массив для значений от 0 до п с первым и последним значением вдвое.

0

Чтобы развернуть ссылку, скрывающуюся в ответе @ RodyOldenhuis, взгляните на Functional Programming Constructs. Этот пакет предоставляет довольно полный набор функциональных конструкций.Автор также сделал серию из guest posts on the Art of MATLAB blog, в которой много деталей за этой библиотекой. Если вы не хотите вытащить весь пакет в свой проект, сообщения в блоге также включают анонимные однострочные элементы некоторых функций в пакете.

Смежные вопросы