2011-01-25 3 views
5

В настоящее время я кодирую симуляцию в MATLAB и нуждаюсь в некоторой помощи в отношении проблемы, которая у меня была.MATLAB: Ручки слияния функций

Я работаю над проблемой, где у меня есть n отдельный анонимная функция обрабатывает f_i, каждый из которых хранится в массиве ячеек functions и принимает 1x1 числовой массив x_i и возвращает 1x1 числовой массив y_i.

Я пытаюсь объединить каждый из этих анонимной функции обращается в одну анонимную функцию ручки, которая принимает один n х 1 числовой массив X и возвращает единственный n х 1 -numeric массив Y. Здесь, X(i) = x_i, Y(i) = y_i = f_i(x_i)

В качестве примера рассмотрим n = 2 и f_1 и f_2 быть две функции ручки, что входные и выходные 1x1 массивов и хранятся в массиве ячеек с именем функции

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

Я в основном нужен код, который будет уметь использовать n, f_1 и f_2 для построения функционального дескриптора F, который вводит и выводит числовой массив 2x1.

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

ответ

5

Трудно определить такую ​​функцию, используя встроенный @() -Anonymous синтаксиса (из-за ограничение требования на теле функции быть выражением). Тем не менее можно определить обычную (не анонимную) функцию, которая пробегает элементы данного вектора и применяет функции из данного массива ячеек к этим элементам.

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 

И каждый раз, когда это необходимо, чтобы передать эту функцию в какой-то другой, только ссылка на его @ -Handle.

F = @apply_funcs 
+0

Спасибо за это! Мне нужен код, чтобы быть максимально эффективным, поэтому я, вероятно, воспользуюсь вашей функцией и удалю аргументы length/assert ... Кроме того, не знаете ли вы, существует ли feval быстрее, чем с помощью оценки дескриптора встроенной функции?То есть y (i) = f {i} (x (i)) быстрее, чем y (i) = feval (f {i}, x (i))> –

2

Это может быть решена с помощью a solution I provided to a similar previous question, хотя будут некоторые различия относительно того, как форматировать входные аргументы. Вы можете добиться того, что вы хотите использовать функции CELLFUN и FEVAL оценить ваши анонимные функции в одной строке, а функция NUM2CELL для преобразования входного вектора в массив ячеек, который будет использоваться по 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(:))); 

Следует заметить, что я использовал имя fcnArray для массива ячеек функций, поскольку имя functions уже используется для встроенной функции FUNCTIONS. colon operator (:) используется для преобразования fcnArray и входного аргумента x в векторы столбцов, если они еще не были. Это гарантирует, что вывод будет вектором столбца.

И вот несколько тестовых примеров:

>> F([2;2]) 

ans = 

    4 
    8 

>> F([1;3]) 

ans = 

    1 
    27 
+0

Еще раз спасибо за это. Ваш подход определенно более экономен, хотя мне интересно, будет ли он работать быстрее, чем цикл for, описанный ib? –

+0

k Я попробую оба и посмотрю, что лучше - знаете ли вы о каком-то ресурсе, который иллюстрирует лучшие практики MATLAB? Я всегда стараюсь сделать мой код максимально эффективным, хотя, поскольку на MATLAB часто есть 3-4 способа сделать это с помощью встроенных функций, мне сложно определить, что дорого, а что нет , –

Смежные вопросы