【问题标题】:Recursive inline anonymous function in script [duplicate]脚本中的递归内联匿名函数[重复]
【发布时间】:2017-06-02 11:13:12
【问题描述】:

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

这里是 MWE:

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

但这会引发以下异常:

未定义的函数或变量'funR'。

这在函数文件中运行时有效,但在脚本中运行时无效。这是因为 Matlab 确实以不同的方式读取这些内容。

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

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

如何做到这一点?

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

【问题讨论】:

  • 我认为你不能定义递归内联匿名函数。我相信这个问题的答案就是:“你不能”。

标签: matlab recursion inline anonymous-function


【解决方案1】:

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

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

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

这对您不起作用,因为您需要在某个时候停止迭代。有一个 great series of articles on functional programming with anonymous functions 由 Loren 在 Mathworks 写的,涵盖了这一点。借用那篇文章,我们可以使用 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)

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

【讨论】:

  • 好简单的主意!我想这确实为我解决了这个问题。
  • @m7913d 查看我刚刚链接的系列文章。第二部分涵盖了这一点。
  • @m7913d 已更新。
  • 哇哦。这太疯狂了
猜你喜欢
  • 2011-10-26
  • 2022-06-20
  • 1970-01-01
  • 2011-07-17
  • 2011-10-24
  • 2015-11-21
  • 2011-01-29
  • 2011-04-22
  • 2020-09-24
相关资源
最近更新 更多