脚本中的递归内联匿名函数

时间:2017-06-02 11:13:12

标签: matlab recursion inline anonymous-function

我尝试在Matlab脚本中编写递归内联匿名函数。

这是一个MWE:

funR = @(x) [x(1) funR(x(2:end))];
funR(0:5);

但这引发了以下异常:

  

未定义的功能或变量' funR'。

当它在函数文件中运行但在脚本中运行时不起作用。这是因为Matlab确实以不同的方式阅读了这些内容。

我对这个MWE的预期结果是:

[0, 1, 2, 3, 4, 5]

如何做到这一点?

目标是将funR定义为内联函数,因此两行或多行解决方案不是我想要的。如果这个或MWE有意义,请忽略,这不是这个问题的重点。

1 个答案:

答案 0 :(得分:5)

您不能这样做,因为必须在创建时定义匿名函数内部使用的函数和变量,而不是执行时,并且直到赋值后才定义匿名函数本身。

编写递归匿名函数的正确方法是为匿名函数提供第二个输入,这是匿名函数本身,以便匿名函数可以使用该函数句柄调用自身。

funR = @(x, funR) [x(1) funR(x(2:end), funR)];
funR(0:5, funR)

这对您不起作用,因为您需要在某个时刻停止迭代。 Loren在Mathworks上写了great series of articles on functional programming with anonymous functions,涵盖了这一点。借用那篇文章,我们可以使用iif匿名函数来允许我们的匿名函数在它到达数组末尾时正确终止。

% From the article linked above
iif = @(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();

% Recurse as long as there is more than one element in x 
funR = @(x,funR)iif(numel(x) > 1,   @()[x(1), funR(x(2:end), funR)], ...
                    true,            x);

funR(0:5, funR)

除此之外,从绩效角度来看,这可能会产生糟糕的结果。可能有一种处理这个问题的矢量化方法,不需要递归的匿名函数。