2013-07-02 8 views
6

Una funzione può essere definita come @(x) x^.2 (per esempio)Come utilizzare condizioni all'interno di una funzione anonima

Ma nel caso, abbiamo una funzione che prende diversa rappresentazione su intervalli diversi per esempio: if abs(x)<3 fun = x^.2 else 0

Come possiamo usare allo stesso modo (voglio dire usare @(x)) per definire tale funzione.

+1

possibile duplicato di [Come eseguire più istruzioni in una funzione anonima MATLAB?] (Http://stackoverflow.com/questions/558478/how-to-execute-multiple-statements-in-a-matlab-anonymous- funzione) – Shai

+2

@Shai: non sono d'accordo. Quella domanda riguarda le valutazioni di più funzioni in un singolo anon, mentre si tratta di valutazione condizionale in un anon (c'è * un * dupe, l'ho visto, ma non lo trovo ora ...) –

risposta

16

Ci sono alcuni modi per farlo.

Moltiplicare per falso:

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

o definire un corretto funzionamento (il modo migliore in realtà):

function y = g(x) 

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

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

end 

o fare la cosa disordinato-ugly-inefficiente-ma-divertimento e utilizzare un inline-if:

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

Altre spiegazioni : È necessaria persino una funzione appropriata quando si desidera evitare il calcolo dell'altra parte che non viene selezionata; es: 'iif (x == 0; 0; 1/x) 'qui' 1/x' viene ancora valutato, anche se 'x == 0'. È una funzione e MATLAB ancora vuole passare tutti gli argomenti, quindi la valutazione. L'unico modo per evitarlo (ed è per questo che è il modo migliore, corretto) consiste nell'utilizzare una funzione separata, che consente una multilinea e un normale 'if'. –

+0

@GuntherStruyf: true. Aggiunto "inefficnet" alla descrizione del metodo 'iif()' :) –

+0

@GuntherStruyf: ahum. Questo è "inefficiente". La digitazione è difficile. –

0

Come @Gunther menzionato nei commenti di cui sopra, una funzione generica per gestire sim condizioni per imitare l'operatore terziario?: può essere creato per circumnavigare la limitazione che Matlab non consente condizionali all'interno di funzioni anon (se non si contano quella versione inline disordinata, inefficiente ma divertente :).

La soluzione è stata presentata tramite questo link (e forse pochi altri posti ma SO è tornato in cima alla mia ricerca su google, quindi ho pensato che sarebbe bello aggiungere qui). http://www.mathworks.co.jp/matlabcentral/newsreader/view_thread/158054

definiscono una funzione dire sse o IfElse e inserirlo al percorso 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 

quindi utilizzare come questo

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

Nel caso del PO, qualcosa di simile potrebbe essere utilizzato

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

Questo è quello che mi è venuta. Ho cases.m funzione con la seguente definizione:

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 

La funzione cases prende una matrice di celle con due colonne. Ogni elemento è una funzione con argomenti zero. Per ogni riga prende il primo elemento e se è la stringa 'else' o una funzione che restituisce un valore true, viene chiamato il secondo elemento e viene restituito il valore. Se nessuna riga è idonea, viene restituita una cella vuota. Gli elementi sono funzioni nullarie anziché valori, quindi i casi non necessari non vengono valutati.

Allora posso scrivere espressioni case simili:

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

Questo produce una matrice di valori da 0 a n con il primo e l'ultimo valore dimezzato.

0

Per espandere il collegamento nascosto nella risposta di @RodyOldenhuis, dare un'occhiata a Functional Programming Constructs. Questo pacchetto fornisce un insieme piuttosto completo di costrutti funzionali.L'autore ha anche fatto una serie di guest posts on the Art of MATLAB blog mostrando molti dei dettagli dietro questa libreria. Se non vuoi inserire l'intero pacchetto nel tuo progetto, i post del blog includono anche one-liner anonimi di alcune delle funzioni del pacchetto.

Problemi correlati