将匿名函数定义为m文件函数的4个输出中的2个

时间:2010-09-09 02:34:34

标签: matlab

我有一个带4个输出的m文件功能。我想定义一个具有相同输入的匿名函数,但只生成四个输出中的两个。这可能吗?

2 个答案:

答案 0 :(得分:4)

AFAIK,你不能只使用内联匿名函数来实现这一点,因为Matlab语法不提供在单个表达式中捕获和索引函数的多个输出的方法。但是你可以编写一些可重复使用的辅助函数,然后使用它们定义匿名函数。

假设您的四个argout函数名为“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

现在你可以制作这样的匿名,argout重映射功能。这里,g包含一个匿名函数,它接受与原始函数相同的输入,但只返回其原始4个输出中的2个。

>> 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可以在调用结果函数句柄时省略尾随参数。如果您知道将始终提供所有argins,您可以根据需要使用命名argins以便于阅读。

你可以变得更加漂亮,并通过闭合来做到这一点。

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方法可能更可取。

答案 1 :(得分:3)

如果两个输出是#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

然后你可以像往常一样创建匿名函数。