use*_*643 6 python recursion python-3.x
考虑以下想法:我想生成一系列函数f_k
,k = 1,...,50
并将它们存储在Python字典中.举一个具体的例子,让我们说
f_k(x) = f_{k-1}(x) * sqrt(x)
Run Code Online (Sandbox Code Playgroud)
这只是一个例子,我遇到的问题更复杂,但这对我的问题无关紧要.因为在我的实际问题f_{k-1}
是非常嘈杂并且包含舍入误差,我不想f_k
直接构建f_{k-1}
,而是我首先f_{k-1}
通过样条近似近似,然后f_k
从该样条逼近来确定.奇怪的是,这会导致错误消息表明超出了最大递归深度.以下是代码示例:
import numpy as np
from scipy.interpolate import interp1d
n = 50 # number of functions I want to create
args = np.linspace(1,4,20) # where to evaluate for spline approximation
fdict = dict() # dictionary that stores all the functions
fdict[0] = lambda x: x**2 # the first function
# generate function f_k as follows: First, take function f_{k-1} and
# approximate it through a spline. Multiply that spline approximation
# by sqrt(x) and store this as function f_k.
for k in range(1,n+1):
spline_approx = lambda x: interp1d( args,fdict[k-1](args) )(x)
fdict[k] = lambda x: spline_approx(x) * np.sqrt(x)
print('test evalutation: ', fdict[n](3))
Run Code Online (Sandbox Code Playgroud)
这导致错误
RecursionError: maximum recursion depth exceeded
Run Code Online (Sandbox Code Playgroud)
我的问题必须是非常具体的Python.它必须与interp1d的插值有关.例如.如果我更换线
spline_approx = lambda x: interp1d( args,fdict[k-1](args) )(x)
Run Code Online (Sandbox Code Playgroud)
通过polyfit
coefs = np.polyfit(args,fdict[k-1](args),10) # polyfit coefficients
spline_approx = lambda x: np.polyval(coefs,x) # approximation of f_{k-1}
Run Code Online (Sandbox Code Playgroud)
代码运行正常.我怀疑问题出现是因为fdict[k-1]
没有直接评估,只是作为参考传递.但是我该如何解决这个问题呢?
引发 的行RecursionError
确实是:
spline_approx = lambda x: interp1d( args,fdict[k-1](args) )(x)
Run Code Online (Sandbox Code Playgroud)
这一行意味着,给定,返回在 中计算的spline_approx
函数。x
interp1d(args, fdict[k-1](args)
x
由于interp1d
返回要放入的函数spline_approx
,因此该行可以简化为:
spline_approx = interp1d( args,fdict[k-1](args) )
Run Code Online (Sandbox Code Playgroud)
这将停止抛出RecursionError
。
为什么你的原始代码会抛出一个RecursionError
?
在原始行中,interp1d(args, fdict[k-1](args))
不求值,因为它位于表达式内部lambda
。此评估被推迟到该表达式的调用lambda
。
换句话说,每次从 调用函数时fdict
,之前的所有函数都必须求值interp1d(args, fdict[k-1](args))
。问题是args
是一个序列,因此fdict[k-1]
被调用的次数与有元素的次数一样多args
。
调用次数当然是指数级的,因为每个函数都必须评估前一个函数的len(args)
次数。这会产生一个RecursionError
.
另一方面,新表达式确实计算interp1d(args, fdict[k-1](args))
。经过此评估后,调用fdict[k]
将不再触发调用fdict[k-1]
。
归档时间: |
|
查看次数: |
149 次 |
最近记录: |