2011-01-25 9 views
5

Attualmente sto programmando una simulazione in MATLAB e ho bisogno di aiuto in relazione a un problema che ho riscontrato.MATLAB: funzioni di unione Maniglie

Sto lavorando su un problema in cui ho n funzione anonima separata gestisce f_i, ognuno dei quali è memorizzato in array di celle functions e accetta un 1x1 array numerico x_i e restituisce un array numerico 1x1 y_i.

Sto cercando di coniugare ciascuno di questi funzione anonima gestisce in un unico manico funzione anonima che accetta un singolo n x 1 matrice numerica X e restituisce singola n x 1 serie -numeric Y. Qui, X(i) = x_i, Y(i) = y_i = f_i(x_i)

Come esempio n = 2 e f_1 e F_2 tramite due funzione gestisce che ingresso e uscita 1x1 array e sono memorizzati in una matrice di celle di funzioni con nome

f_1 = @(x_1) x_1^2 
f_2 = @(x_2) x_2^3 
functions = {f_1,f_2} 

Io fondamentalmente bisogno di codice che avrebbe essere in grado di utilizzare n, f_1 e f_2 per costruire un handle di funzione F che immette e restituisce un array numerico 2x1.

F = @(x) [f_1(x(1,1));f_2(x(2,1))] 

risposta

5

È difficile definire tale funzione utilizzando linea @() sintassi -Anonimo (a causa della limitazione requisito sul corpo della funzione per essere espressione). Tuttavia è possibile definire una funzione ordinaria (non anonima) che gira sugli elementi di un dato vettore e applica le funzioni da un determinato array di celle a tali elementi.

function y = apply_funcs(f, x) 
    assert(length(f) == length(x)); 
    y = x; 
    for i = 1 : length(f) 
     y(i) = feval(f{i}, x(i)); 
    end 
end 

E ogni volta che è necessario per passare questa funzione per qualche altro uno, basta fare riferimento alla sua @ Maniglia a.

F = @apply_funcs 
+0

Grazie per questo! Ho bisogno che il codice sia il più efficiente possibile, quindi probabilmente userò la tua funzione e rimuoverò gli argomenti lunghezza/asserzione ... Inoltre, ti capiterà di sapere se feval è più veloce dell'utilizzo della funzione di gestione della funzione inline?Vale a dire, y (i) = f {i} (x (i)) è più veloce di y (i) = feval (f {i}, x (i))> –

2

Questo può essere risolto utilizzando a solution I provided to a similar previous question, anche se ci saranno alcune differenze per quanto riguarda come si formatta gli argomenti di input. È possibile ottenere ciò che si desidera utilizzare le funzioni CELLFUN e FEVAL per valutare le funzioni anonime in una linea, e la funzione NUM2CELL per convertire il vostro vettore di input a un array di celle per essere utilizzato da CELLFUN:

f_1 = @(x_1) x_1^2;  %# First anonymous function 
f_2 = @(x_2) x_2^3;  %# Second anonymous function 
fcnArray = {f_1; f_2}; %# Cell array of function handles 
F = @(x) cellfun(@feval,fcnArray(:),num2cell(x(:))); 

Nota che ho utilizzato il nome fcnArray per l'array di celle di handle di funzione, poiché il nome functions è già utilizzato per la funzione incorporata FUNCTIONS. Il colon operator (:) viene utilizzato per trasformare fcnArray e l'argomento di input x in vettori di colonne se non lo sono già. Ciò garantisce che l'output sia un vettore di colonna.

e qui ci sono un paio di casi di test:

>> F([2;2]) 

ans = 

    4 
    8 

>> F([1;3]) 

ans = 

    1 
    27 
+0

Grazie ancora per questo. Il tuo approccio è decisamente più parsimonioso, anche se mi chiedo se sarebbe più veloce del ciclo for descritto da ib? –

+0

k Proverò entrambi e vedrò quale è meglio - conosci qualche tipo di risorsa che illustra le migliori pratiche di MATLAB? Cerco sempre di rendere il mio codice il più efficiente possibile, anche se spesso ci sono 3-4 modi per fare queste cose con le funzioni integrate in MATLAB, sto avendo difficoltà a capire cosa è costoso e cosa no . –

1
#you can try 
[email protected](x)[x(1)^2;x(2)^3] 
>>f([1,2]) 
ans = 
    1 
    8 
>>f([2,3]) 
ans = 
    4 
    27 
Problemi correlati