我可以在匿名函数中重用表达式的结果吗?

时间:2019-04-04 10:00:29

标签: matlab anonymous-function

我有一个匿名函数,例如@(x) sqrt(x) + 1./sqrt(x) - 3,我想传递给另一个函数,例如

fsolve(@(x) sqrt(x) + 1./sqrt(x) - 3, 3)

想象一下,sqrt的参数稍微复杂一点,因此sqrt(...)调用的计算量很大-是否有可能创建一个匿名函数进行计算(在此简单示例中)首先sqrt(x),然后将结果res用于计算res + 1/res - 3

还是只能使用常规功能对其进行编程?

2 个答案:

答案 0 :(得分:6)

如果您对嵌套匿名函数的想法进入“没有中间步骤的单个匿名函数中的所有内容”(即中间匿名函数)的方向,那么我想不出解决方案,因为您必须以某种方式“存储”该值以防止重新计算。因此,我的想法如下:

% Original function
orig = @(x) sqrt(x) + 1./sqrt(x) - 3;

% Complicated inner function
inner = @(x) sqrt(x);

% Actual function
func = @(y) y + 1./y - 3;

% Function wrapper
wrapper = @(z) func(inner(z));

% Some small tests
X = 1:10;
orig(X)
wrapper(X)

ans =
  -1.000000  -0.878680  -0.690599  -0.500000  -0.316718  -0.142262   0.023716   0.181981   0.333333   0.478505

ans =
  -1.000000  -0.878680  -0.690599  -0.500000  -0.316718  -0.142262   0.023716   0.181981   0.333333   0.478505

从我的角度来看,复杂的内部函数仅被评估一次。

答案 1 :(得分:2)

是的,您可以这样做(尽管whether this is really a neat solution to your real problem可能会引起争议)。

您本质上想定义一个内部匿名函数,然后通过一些昂贵的函数调用结果立即对其进行求值。

MATLAB完全按照您希望语法允许的方式在匿名函数定义中定义匿名函数。可以使用feval完成“立即评估”位:

@(x) feval(@(res) res + 1./res - 3, sqrt(x))