簡體   English   中英

將匿名函數定義為m文件函數的4個輸出中的2個

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

我有一個帶4個輸出的m文件功能。 我想定義一個具有相同輸入的匿名函數,但只生成四個輸出中的兩個。 這可能嗎?

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和#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

然后你可以像往常一樣創建匿名函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM