2011-01-25 12 views
5

Actualmente estoy programando una simulación en MATLAB y necesito ayuda con respecto a un problema que he tenido.MATLAB: Fusionar identificadores de función

Estoy trabajando en un problema en el que tengo n función anónima separada maneja f_i, cada uno de los cuales se almacena en serie de células functions y acepta una matriz numérica x_i 1x1 y devuelve una matriz numérica y_i 1x1.

Estoy tratando de combinar cada una de estas funciones en el anonimato maneja en una sola asa función anónima que acepta una sola n x 1 matriz numérica X y devuelve un solo n x 1 gama -numeric Y. Aquí, X(i) = x_i, Y(i) = y_i = f_i(x_i)

Como ejemplo vamos n = 2 y f_1 y f_2 haber dos funciones se encarga de que la entrada y salida 1x1 matrices y se almacenan en una serie de células de funciones con nombre

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

que básicamente necesita código que haría poder usar n, f_1 y f_2 para construir un controlador de función F que ingresa y saca un conjunto numérico 2x1.

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

Respuesta

5

Es difícil definir una función de este tipo utilizando inline @() sintaxis -Anónimo (a causa de la limitación de requisito en el cuerpo de la función a ser expresión). Aún así es posible definir una función ordinaria (no anónima) que se ejecute sobre los elementos de un vector dado y aplique funciones desde una matriz de celdas dada a esos elementos.

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 

Y cada vez que se necesita para pasar esta función para algún otro, simplemente referencia a su @ -Mango.

F = @apply_funcs 
+0

Gracias por esto! Necesito que el código sea lo más eficiente posible, así que probablemente use su función y quite los argumentos de longitud/afirmación ... Además, ¿sabría usted si feval es más rápido que usar la evaluación del identificador de función en línea?Es decir, sería y (i) = f {i} (x (i)) más rápido que y (i) = feval (f {i}, x (i))> –

2

Esto se puede solucionar utilizando a solution I provided to a similar previous question, aunque habrá algunas diferencias con respecto a cómo dar formato a los argumentos de entrada. Se puede lograr lo que desee mediante las funciones CELLFUN y FEVAL para evaluar sus funciones anónimas en una línea, y la función NUM2CELL para convertir el vector de entrada a una serie de células para ser utilizado por 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(:))); 

en cuenta que yo utilizó el nombre fcnArray para la matriz de celdas de los identificadores de funciones, ya que el nombre functions ya se utiliza para la función incorporada FUNCTIONS. El colon operator (:) se usa para convertir fcnArray y el argumento de entrada x en vectores de columna si no lo están ya. Esto asegura que la salida es un vector de columna.

Y aquí hay algunos casos de prueba:

>> F([2;2]) 

ans = 

    4 
    8 

>> F([1;3]) 

ans = 

    1 
    27 
+0

Gracias de nuevo. Su enfoque es definitivamente más parsimonioso, aunque me pregunto si funcionaría más rápido que el ciclo for descrito por ib. –

+0

k Voy a probar las dos cosas y ver cuál es mejor. ¿Conoces algún tipo de recurso que ilustre las mejores prácticas de MATLAB? Siempre trato de hacer que mi código sea lo más eficiente posible, aunque dado que a menudo hay de 3 a 4 maneras de hacer estas cosas con las funciones incorporadas en MATLAB, me está costando averiguar qué es costoso y qué 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