简体   繁体   English

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

[英]define anonymous function as 2 of 4 outputs of m file function

I have an m-file function with 4 outputs. 我有一个带4个输出的m文件功能。 I would like to define an anonymous function that has the same inputs, but only produces 2 of the four outputs. 我想定义一个具有相同输入的匿名函数,但只生成四个输出中的两个。 Is this possible? 这可能吗?

AFAIK, you can't do this with just an inline anonymous function, because that Matlab syntax doesn't provide a way of capturing and indexing in to multiple outputs of a function in a single expression. AFAIK,你不能仅使用内联匿名函数来实现这一点,因为Matlab语法不提供在单个表达式中捕获和索引函数的多个输出的方法。 But you can write a couple reusable helper functions that do so, and then define anonymous functions using them. 但是你可以编写一些可重复使用的辅助函数,然后使用它们定义匿名函数。

Let's say your four argout function is named "f4". 假设您的四个argout函数名为“f4”。

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

Here's a reusable helper function that remaps outputs of a function call. 这是一个可重用的辅助函数,它重新映射函数调用的输出。

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

Now you can make anonymous, argout-remapping functions like this. 现在你可以像这样制作一个匿名的argout重映射函数。 Here, g holds an anonymous function that takes the same inputs as your original function, but just returns 2 of its original 4 outputs. 这里,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
>> 

Using varargin allows you to omit trailing arguments when the resulting function handle is called. 使用varargin可以在调用生成的函数句柄时省略尾随参数。 If you know all argins will always be provided, you can use named argins for readability if you want. 如果您知道将始终提供所有argins,则可以根据需要使用命名argins以提高可读性。

You can get even fancier and do this with a closure. 你可以变得更加漂亮,并通过关闭来做到这一点。

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

This results in simpler code for creating the anonymous function. 这导致创建匿名函数的代码更简单。 And you could compose it with other function wrapper calls. 你可以用其他函数包装器调用来组合它。

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

But closures can be tricky to work with in Matlab and may have performance implications. 但是在Matlab中使用闭包可能很棘手,并且可能会对性能产生影响。 The callandmap approach is probably preferable unless you need the extra power. 除非您需要额外的功率,否则callandmap方法可能更可取。

If the two outputs are #1 and #2, everything is fine, and you don't have to worry about the other two outputs. 如果两个输出是#1和#2,一切都很好,你不必担心其他两个输出。

If the two outputs are any two others, you have two options 如果两个输出是另外两个输出,则有两个选项

(1) Create a wrapper function with two outputs (note that in newer versions of Matlab you can replace the unused outputs dummy by ~ . (1)创建两个输出的包装函数(注意,在Matlab中的较新版本可以更换未使用的输出dummy~

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

(2) Add another input variable that allows you to switch your function's behavior (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

Then you can create the anonymous function as usual. 然后你可以像往常一样创建匿名函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM