Подтвердить что ты не робот

Как обернуть функцию с помощью varargin и varargout?

мини-пример:

function varargout = wrapper(varargin)
varargout = someFunction(varargin);

Как бы я это сделал первым. Но, например, если someFunction = ndgrid, это дает ошибку, не определенную для ячеек массивов, поэтому следующая попытка использовала вместо этого someFunction(varargin{:}). Что успешный вызов, но вызов [a,b] = wrapper([1,2], [3,4]) не дает того же результата, что и прямой вызов ndgrid, так что я делаю неправильно?

4b9b3361

Ответ 1

Собственно, ответ Михаила не совсем прав. В случае, когда someFunction является функцией, которая возвращает значение, даже если ни одна из них не запрашивается, то, как функция указывает, что значение должно быть присвоено ans, обертка Михаэля завершится неудачей. Например, если someFunction были заменены на sin, и вы сравнили запущенную обертку и непосредственный запуск греха, вы увидите:

>> wrapper(0)
>> sin(0)

ans =

   0

Правильный способ сделать это -

function varargout = wrapper( varargin )
[varargout{1:nargout}] = someFunction( varargin{:} ); 

Причина, по которой это происходит, объясняется малоизвестным краевым случаем в правилах индексирования MATLAB, которые существовали именно для этого случая, поскольку по крайней мере R2006a (вероятно, дольше). Это что-то вроде бородавки в индексировании MATLAB, но было сочтено необходимым справиться с такими вещами.

Правило:

При выполнении подстрочного присвоения, если

  • subscripted-присваивание неинициализированной переменной, AND
  • неинициализированная переменная индексируется курсивом, AND
  • индекс в фигурных скобках пуст, AND
  • левая часть появляется внутри квадратных скобок, AND
  • правая часть разрешает значение/возвращает вывод

Затем неинициализированной переменной присваивается скалярная ячейка, содержащая значение, возвращаемое правой частью.

Например:

>> clear uninit % just to make sure uninit is uninitialized
>> [uninit{[]}] = sin(0)

uninit = 

    [0]

Ответ 2

function varargout = wrapper( varargin )

if ~nargout
    someFunction( varargin{:} ); 
else
    [varargout{1:nargout}] = someFunction( varargin{:} ); 
end

Ответ 3

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

function varargout = wrapper(varargin)
[varargout{1:nargin}] = someFunction(varargin{:});

Это отлично работает с ndgrid.