朱莉娅:一起添加匿名功能

时间:2017-06-14 16:53:34

标签: recursion julia anonymous-function

如果我将一些匿名函数a(x)b(x)定义为

a = x -> x^2
b = x -> 2x

将递归问题添加到一起会有所帮助,比如在某个循环的持续时间内:

for i=1:5
    a = x -> a(x) + b(x)
end

其中的目标是将每个循环迭代内部表示为

a = x -> x^2 + 2x
a = x -> x^2 + 2x + x^2 + 2x
a = x -> x^2 + 2x + x^2 + 2x + x^2 + 2x
...

但是,这会失败并返回一些错误。我假设是因为调用新的a(x)被解释为:a(2) = 2 -> x^2 + x^2 + ... + x^2 + 2x

julia> a(2)
ERROR: StackOverflowError:
 in (::##35#36)(::Int64) at ./REPL[115]:0
 in (::##35#36)(::Int64) at ./REPL[115]:1 (repeats 26666 times)

这有什么办法吗?

3 个答案:

答案 0 :(得分:7)

您可以使用the let keyword完成您正在寻找的内容:

a = x -> x^2
b = x -> 2x

for i=1:5
  a = let a = a; x -> a(x) + b(x); end
end

a(2) # returns 24

<强>解释

let关键字允许您创建具有本地范围的块,并将块中的最后一个语句返回其调用范围。 (与例如begin关键字形成鲜明对比,不引入新范围)。

如果将一系列“赋值”传递给let关键字,则这些变量将成为块的本地变量(因此,允许您重新使用工作空间中已存在的变量名称)。声明let a = a完全有效,意味着“创建一个局部变量a,它是从外部范围的a变量初始化的”---但是如果我们想要真的清楚,我们可以这样写它:

for i=1:5
  a = let a_old = a
        x -> a_old(x) + b(x); 
      end
end

<小时/> 然后再次,如果你愿意使用a_old变量,你可能只是这样做了:
for i=1:5; a_old = a; a = x-> a_old(x) + b(x); end

let是一个非常有用的关键字:它非常便于创建现场闭包;事实上,这正是我们在这里所做的:我们已经返回了一个闭包,其中“局部变量a”基本上变成了一个闭合变量。

<子> PS。由于提到了matlab,当你在matlab中评估a = @ (x) a(x) + b(x)时你正在做的事实上是创建一个闭包。在matlab中,您可以使用functions命令检查所有已关闭的变量(即闭包的“工作空间”)

<子> PPS。 利文斯通博士,我猜?

答案 1 :(得分:5)

使用Polynomials包可能是一种方式。这将是:

julia> using Polynomials   # install with Pkg.add("Polynomials")

julia> x = Poly([0,1])
Poly(x)

julia> a = x^2
Poly(x^2)

julia> b = 2x
Poly(2*x)

julia> a = a+b
Poly(2*x + x^2)

julia> a(2.0)
8.0

这是有效的原因是因为你想要的行为本质上是对函数的符号操作。 Julia不是这样工作的(它是编译器 - 或者提前编译(AOT)编译器),但它很灵活。如果需要比多项式更高级的函数,可能有一个符号数学包会有所帮助(有SymPy,但我还没有使用它)。

答案 2 :(得分:1)

此:

x^2

是一个没有停止条件的递归调用。它与朱莉娅无关。一旦定义了这个,之前的定义(a(2) = a(2)+2*2 = (a(2)+2*2)+2*2 = ((a(2)+2*2)+2*2)+2*2 = ... )就被覆盖了,并且对于堆栈或结果没有任何意义。它不再存在。你要做的是:

c = x -> a(x) + b(x)

等。 2 * 2甚至不会被替换,我只是写得很清楚。您可能想要定义

concatFuncs => f1,f2 -> (x->f1(x)+f2(x))

修改

我现在看到来自MATLAB,你期望语法意味着别的东西。您在几乎所有语言中编写的内容都是递归调用,您不需要。你想要的是:

x

这段代码将接受summed = concatFuncs(a,b) 的任何函数,并在结果调用之间生成一个+。这适用于'+'使用的任何内容。所以:

app/design/frontend/base/default/layout/poll.xml

是您需要的功能。