определить анонимную функцию как 2 из 4 выходов m файловой функции - PullRequest
5 голосов
/ 09 сентября 2010

У меня есть функция m-файла с 4 выходами.Я хотел бы определить анонимную функцию, которая имеет те же входы, но производит только 2 из четырех выходов.Возможно ли это?

Ответы [ 2 ]

4 голосов
/ 09 сентября 2010

AFAIK, вы не можете сделать это только с помощью встроенной анонимной функции, потому что этот синтаксис Matlab не обеспечивает способ захвата и индексации нескольких выходов функции в одном выражении.Но вы можете написать пару вспомогательных функций многократного использования, которые делают это, а затем определить анонимные функции, используя их.

Допустим, ваша функция из четырех аргументов называется "f4".

function varargout = f4(x)
%F4 Dummy function that returns 4 argouts holding identifying indexes
varargout = num2cell(1:4);

Вотмногоразовая вспомогательная функция, которая перераспределяет выходные данные вызова функции.

function varargout = callandmap(fcn, ix, varargin)
%CALLANDMAP Call a function and rearrange its output arguments

tmp = cell(1,max(ix));        % Capture up to the last argout used
[tmp{:}] = fcn(varargin{:});  % Call the original function
varargout = tmp(ix);          % Remap the outputs

Теперь вы можете создавать анонимные функции переопределения аргументов, подобные этой.Здесь g содержит анонимную функцию, которая принимает те же входные данные, что и ваша исходная функция, но просто возвращает 2 из своих исходных 4 выходных данных.

>> g = @(varargin) callandmap(@f4, [2 4], varargin{:})
g = 
    @(varargin)callandmap(@f4,[2,4],varargin{:})
>> [a,b] = g('dummy') % gets argouts 2 and 4 from original f4() function
a =
     2
b =
     4
>> 

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

Вы можете стать еще интереснее и сделать это с закрытием.

function fcn = mapargout(fcnIn, ixArgout)
%MAPARGOUT Create wrapper function that selects or reorders argouts
%
% fcn = argoutselector(fcnIn, ixArgout)
%
% Wraps a given function handle in a function that rearranges its argouts.
% This uses closures so it may have performance impacts.
%
% FcnIn is a function handle to wrap.
%
% IxArgout is a list of indexes in to the original functions argout list
% that should be used as the outputs of the new function.
% 
% Returns a function handle to a new function.

fcn = @extractor;

    function varargout = extractor(varargin)
    n = max(ixArgout);
    tmp = cell(1,n);
    % Call the wrapped function, capturing all the original argouts
    [tmp{:}] = fcnIn(varargin{:});
    % And then select the ones you want
    varargout = tmp(ixArgout);
    end

end

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

>> g = mapargout(@f4, [2 4])
g = 
    @mapargout/extractor
>> [a,b] = g('dummy')
a =
     2
b =
     4
>> 

Но с замыканиями может быть сложно работать в Matlab, что может сказаться на производительности.Подход callandmap, вероятно, предпочтительнее, если вам не нужна дополнительная мощность.

3 голосов
/ 09 сентября 2010

Если два выхода # 1 и # 2, все в порядке, и вам не нужно беспокоиться о двух других выходах.

Если два выхода являются любыми двумя другими, у вас есть две опции

(1) Создайте функцию-оболочку с двумя выходами (обратите внимание, что в более новых версиях Matlab вы можете заменить неиспользуемые выходы dummy на ~.

function [out1,out2] = wrapperFunction(in1,in2,in3)
   [dummy,out1,dummy,out2] = mainFunction(in1,in2,in3);

(2) Добавьте еще одну входную переменную, которая позволит вам переключать поведение вашей функции

function varargout = mainFunction(in1,in2,in3,outputSwitch)
   %# make output switch optional
   if nargin < 4 || isempty(outputSwitch)
      outputSwitch = 0;
   end

   %# calculation here that creates out1-4

   if outputSwitch
       %# the special case where we only want outputs 2 and 4
       varargout = {out2,out4};
   else
       %# return all four outputs
       varargout = {out1,out2,out3,out4}
   end

Затем вы можете создать анонимную функцию как обычно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...