2011-01-25 14 views
5

Aktualnie koduję symulację w MATLAB i potrzebuję pomocy w odniesieniu do problemu, który miałem.MATLAB: Scalanie uchwytów funkcji

pracuję na problem gdzie mam n oddzielna funkcja anonimowa obsługuje f_i, z których każdy jest przechowywany w macierzy komórkowej functions i akceptuje 1x1 tablicy numerycznej x_i i zwraca tablicę 1x1 numeryczny y_i.

Próbuję połączyć każdy z tych funkcji anonimowej uchwyty w jeden uchwyt anonimowej funkcji, które akceptuje pojedynczy n x 1 tablicę numeryczną X i zwraca pojedynczą n x 1 -numeric tablicę Y. Tutaj X(i) = x_i, Y(i) = y_i = f_i(x_i)

Jako przykład niech n = 2 i f_1 i f_2 być dwa funkcja obsługuje że wejściowych i wyjściowych 1x1 tablic i są przechowywane w tablicy komórek nazwanych funkcji

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

I w zasadzie trzeba kod, który będzie być w stanie użyć n,i f_2 do skonstruowania uchwytu funkcyjnego F, który wprowadza i wyprowadza tablicę numeryczną 2x1.

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

Odpowiedz

5

Trudno jest określić za pomocą takiej funkcji inline @() składni -anonymous (ze względu na ograniczenie wymogu ciała funkcyjnego się wyrażenie). Nadal można zdefiniować zwykłą (nieanonimową) funkcję, która przebiega po elementach danego wektora i stosuje funkcje z danej tablicy komórek do tych elementów.

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 

I za każdym razem jest to potrzebne, aby przekazać tę funkcję do pewnego drugiego, po prostu odniesienie do jego @ -handle.

F = @apply_funcs 
+0

Dzięki za to! Potrzebuję kod, aby być efektywnym, jak to możliwe, więc prawdopodobnie użyję twojej funkcji i usuń argumenty długości/assert ... Czy byłbyś też wiedzieć, czy feval jest szybszy niż przy użyciu oceny funkcji inline?To znaczy, że y (i) = f {i} (x (i)) będzie szybszy niż y (i) = feval (f {i}, x (i))> –

2

ten można rozwiązać stosując a solution I provided to a similar previous question, choć będą pewne różnice dotyczące sposobu formatowania argumentów wejściowych. Można osiągnąć to, czego chcą przy użyciu funkcji CELLFUN i FEVAL ocenić swoje anonimowe funkcje w jednej linii, a funkcja NUM2CELL zamienić wektora wejściowego do tablicy komórki do stosowania przez 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(:))); 

pamiętać, że używa nazwy fcnArray dla tablicy komórek uchwytów funkcji, ponieważ nazwa functions jest już używana dla wbudowanej funkcji FUNCTIONS. Opcja colon operator (:) jest używana do przekształcania fcnArray i argumentu wejściowego x na wektor kolumnowy, o ile jeszcze nie są. Zapewnia to, że wyjście jest wektorem kolumnowym.

A oto kilka przypadków testowych:

>> F([2;2]) 

ans = 

    4 
    8 

>> F([1;3]) 

ans = 

    1 
    27 
+0

Dziękuję za to jeszcze raz. Twoje podejście jest zdecydowanie bardziej oszczędne, ale zastanawiam się, czy działałby szybciej niż pętla for opisana przez ib? –

+0

k. Spróbuję obu i zobaczę, co jest lepsze - czy znasz jakiś zasób ilustrujący najlepsze praktyki MATLABY? Zawsze staram się, aby mój kod był tak wydajny, jak to tylko możliwe, ale ponieważ często są 3-4 sposoby na zrobienie tych rzeczy z wbudowanymi funkcjami na MATLAB, trudno mi jest zorientować się, co jest kosztowne, a co nie. . –

Powiązane problemy