Как сохранить количество аргументов дескриптора функции при передаче его какой-либо другой функции в Matlab? - PullRequest
0 голосов
/ 28 октября 2019

Я пытаюсь написать функцию, которая принимает массив ячеек в качестве входных данных и выводит те же функции, но в несколько ином формате.

В частности, я хочу, чтобы вектор строки, скажем,длина N функций fVec = [f1(x, y, z), f2(x,y,z), ..., fn(x, y, z)], которые всегда выводят вектор-столбец одинаковой длины, скажем, M. Теперь я хочу, чтобы оценка fVec(x, y, z) вывела матрицу MXN, где каждый столбец представляет выход соответствующего вектора.

Однако, поскольку Matlab не принимает обычные массивы дескрипторов функций, это должно быть сделано с использованием массивов ячеек. (, верно?)

Более того, я хочу общую функцию, которая работает для нескольких наборов функций, которые не обязательно имеют три входа. То есть мне нужна функция fVec(1, ..., x) = [f1(1, ..., x), f2(1, ..., x), fn(1, ..., x)], означающая, что каждая из функций f1, f2, fn всегда имеет одинаковое количество входов.

Поэтому мне нужна какая-то функция, которая принимает в качестве входных данных массив ячеек функцииобрабатывает {f1(1, ..., x), f2(1, ..., x), fn(1, ..., x)} и выводит некоторую всеобъемлющую функцию fVec(1, ..., x).

Я уже пытался написать функцию, которая, как я думал, должна делать это:

function overArchingFunction = transformFunctionArray(functionArray)
    if length(functionArray) == 1
        if isa(functionArray, 'cell')
            overArchingFunction = functionArray{:};
        else
            overArchingFunction = functionArray;
        end
    else
        disp(cellfun(@(fun) fun(x), functionArray, ...
                'UniformOutput', false))
        overArchingFunction = @(vars) cell2mat(cellfun(@(fun) fun(vars), functionArray, ...
                'UniformOutput', false));
    end
end

Это работает для "массивов длины 1"очевидно. Однако есть проблема с этим кодом. Давайте создадим тестовую функцию, скажем testfun = @(a, b, c, d, e) a(:,3) - a(:,2) (где testfun - это функция b, c, d, e для репликации наиболее общего сценария), и создадим массив этой функции functionArray = {testfun, testfun}.

Теперь мы вызываем нашу функцию overArchingFunction = transformFunctionArray(functionArray). Однако при вызове solution = transfun([[10 1 2]; [3 4 5]], 0, 0, 0, 0) я хочу, чтобы вывод был:

solution =

     1     1
     1     1

Это не так, потому что с помощью операторов @(vars) и fun(vars) я ограничиваю количество входных данных. переменные этой функции только одной переменной, в то время как я пытаюсь передать пять аргументов (а именно [[10 1 2]; [3 4 5]], 0, 0, 0, 0). Хотя я бы исправил это, заменив vars на varargin, но это дает мне ошибку:

Attempt to execute SCRIPT varargin as a function:
/MATLAB/toolbox/matlab/lang/varargin.m

Подводя итог, как мне сохранить исходное количество входных аргументов f1, f2, ..., fn вoverArchingFunction?

1 Ответ

0 голосов
/ 28 октября 2019

Я нашел это. Ответ действительно лежит в использовании varargin. Однако, поскольку varargin передает входные данные структуры ячейки, вам необходимо получить доступ к содержимому этих ячеек, используя varargin{:}. Таким образом, функция должна быть:

function overArchingFunction = transformFunctionArray(functionArray)
    if length(functionArray) == 1
        if isa(functionArray, 'cell')
            overArchingFunction = functionArray{:};
        else
            overArchingFunction = functionArray;
        end
    else
        overArchingFunction = @(varargin) cell2mat(cellfun(@(fun) fun(varargin{:}), 
            functionArray, ...
                'UniformOutput', false));
    end
end

, чтобы следующие команды давали требуемый ответ.

>> testfun = @(a, b, c, d, e) a(:,3) - a(:,2)

testfun =

  function_handle with value:

    @(a,b,c,d,e)a(:,3)-a(:,2)

>> transfun = transformFunctionArray({mytestfun, mytestfun})

transfun =

  function_handle with value:

    @(varargin)cell2mat(cellfun(@(fun)fun(varargin{:}),functionArray,'UniformOutput',false))

>> myans = transfun([[10 1 2]; [3 4 5]], 0, 0, 0, 0)

myans =

     1     1
     1     1
...