我尝试在Matlab脚本中编写递归内联匿名函数。
这是一个MWE:
funR = @(x) [x(1) funR(x(2:end))];
funR(0:5);
但这引发了以下异常:
未定义的功能或变量' funR'。
当它在函数文件中运行但在脚本中运行时不起作用。这是因为Matlab确实以不同的方式阅读了这些内容。
我对这个MWE的预期结果是:
[0, 1, 2, 3, 4, 5]
如何做到这一点?
目标是将funR定义为内联函数,因此两行或多行解决方案不是我想要的。如果这个或MWE有意义,请忽略,这不是这个问题的重点。
答案 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)
除此之外,从绩效角度来看,这可能会产生糟糕的结果。可能有一种处理这个问题的矢量化方法,不需要递归的匿名函数。