2015-05-23 1 views
4

В previous question пользователь спросил об итерации по массиву ячеек анонимных функций. Мне интересно, есть ли способ оценить набор функций без явного использования цикла for.Векторизованная или однострочная оценка функционального массива в MATLAB

В качестве примера, следующий код создает массив (простые) функций, оценивает их для фиксированного значения и сохраняет результаты:

fcnList = {@(x) (x+1), @(x) (x+2)}; 
a = 2; 
for i = 1:numel(fcnList) 
    y(i) = fcnList{i}(a); 
end 

Есть ли способ сделать это без зацикливания?

+2

Я думаю, вы можете использовать ['cellfun'] (http://www.mathworks.com/help/matlab/ref/cellfun.html) с помощью [' feval'] (http://www.mathworks.com/help/matlab/ ref/feval.html), но я не совсем уверен, почему в этом случае необходимо избегать цикла 'for'. 'cellfun' также может быть медленнее, но у меня нет MATLAB для тестирования на данный момент. – excaza

+1

Вы правы, что, вероятно, есть мало случаев, когда это значительно ускорит выполнение. Тем не менее, он появился в проекте, и я подумал, что это не помешает спросить. –

+1

Чтобы избежать цикла 'for' или' cellfun' (который более или менее совпадает с циклом), вы можете определить функцию _single_ с выходом _vector_ или _cell array_: 'fcn = @ (x) [x + 1, x + 2]; 'или' fcn = @ (x) {x + 1, x + 2}; '. Затем 'fcn (a)' дает вам вектор или массив ячеек, совпадающих с результатами. –

ответ

5

Для примера, вы можете сделать следующее с помощью функции cellfun:

fcnList = {@(x) (x+1), @(x) (x+2)}; 
a = 2; 
cellfun(@(func) func(a),fcnList) 
ans = 

    3 4 

Где я создал ручку под названием func, который принимает в качестве входных данных функции от переменной fcnList. Затем каждая функция оценивается для a.

Если вам нужно передать вектор вместо скаляра, например b, вам нужно будет установить 'UniformOutput' вариант false:

b=[3 4] 
fcnList = {@(x) (x+1), @(x) (x+2)}; 
cellfun(@(func) func(b),fcnList,'UniformOutput',false) 
ans = 
{ 
    [1,1] = 
    4 5 
    [1,2] = 
    5 6 
} 
3

Чтобы избежать for петли или cellfun (который more or less the same as a loop) , вы можете определить одну функцию с вектором выхода:

fcn = @(x) [x+1, x+2]; 

Тогда fcn(a) дает вектор cointaining результаты:

>> fcn = @(x) [x+1, x+2]; 
>> a = 2; 
>> fcn(a) 
ans = 
    3  4 

Если результаты каждой исходной функции имеют разные размеры, можно определить одну функцию с ячейки выходного массива:

>> fcn = @(x) {x+1, [x+2; x+3]}; 
>> a = 2; 
>> x = fcn(a) 
x = 
    [3] [2x1 double] 
>> celldisp(x) 
x{1} = 
    3 
x{2} = 
    4 
    5 
Смежные вопросы