【发布时间】:2021-08-10 11:42:53
【问题描述】:
我正在尝试编写一个 Maxima 函数来迭代作为参数提供的另一个函数。目标基本上是……
iter(f,0) ........ gives the identity function lambda([x],x)
iter(f,1) ........ gives f
iter(f,2) ........ gives lambda([x],f(f(x))
iter(f,3) ........ gives lambda([x],f(f(f(x)))
原因是试图弄清楚迭代多项式的行为方式 - 类似于 Robert May 人口方程,但多项式不同。
无论如何,我对 Maxima 还是很陌生(至少对于看起来更像是简单编程而不是仅仅寻求解决方案的事情)并且经过一段时间试图找出我做错了什么之后,我想我已经消除了所有愚蠢的错误,我必须对 Maxima 的工作原理有一个更根本的误解。
我有什么...
iter(f,n) := if is (n=0)
then lambda ([x], x)
else block ([n2: floor (n/2),
nr: is (n2*2#n),
ff: iter (f,n2) ], if nr then lambda ([x],f(ff(ff(x))))
else lambda ([x], ff(ff(x)) ));
千里马接受这一点。现在作为一个简单的示例函数进行迭代...
inc(x):=x+1;
还有一些测试——首先是基本情况……
iter(inc,0);
这行得通 - 它按预期提供lambda([x],x)。接下来,“迭代”一次……
iter(inc,1);
我期待与inc 等效的内容,但由于其编写方式,更像lambda([x],inc(identity(identity(x))),但更混乱。我实际上得到的是堆栈溢出......
Maxima encountered a Lisp error:
Control stack exhausted (no more space for function call frames).
This is probably due to heavily nested or infinitely recursive function
calls, or a tail call that SBCL cannot or has not optimized away.
...
我不明白为什么is (n=0) 基本情况检查无法在递归调用中发现这一点,所以我不明白为什么n=1 的这个iter 函数会被输入两次以上 -耗尽堆栈似乎非常极端。
当然,一旦我有了基本的想法,我可能会将特殊情况 n=1 作为有效的另一个基本情况来提高效率(结果函数定义不太混乱)并添加更多检查,但我只想要一些不t 堆栈溢出现在在微不足道的情况下。
我误会了什么?
【问题讨论】: