繁体   English   中英

Python中的迭代函数生成

[英]Iterative function generation in Python

考虑以下想法:我想生成一系列函数f_k ,对于k = 1,...,50并将它们存储在Python字典中。 举一个具体的例子,让我们说

f_k(x)  = f_{k-1}(x) * sqrt(x)

这只是一个例子,我遇到的问题更复杂,但这对我的问题无关紧要。 因为在我的实际问题中f_{k-1}非常嘈杂并且包含舍入误差,我不想直接从f_{k-1}构建f_k ,而是我首先通过样条近似逼近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))

这导致错误

RecursionError: maximum recursion depth exceeded

我的问题必须是非常具体的Python。 它必须与interp1d的插值有关。 例如。 如果我更换线

spline_approx = lambda x: interp1d( args,fdict[k-1](args) )(x)

通过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} 

代码运行正常。 我怀疑问题出现是因为fdict[k-1]没有直接评估,只是作为参考传递。 但是我该如何解决这个问题呢?

引发RecursionError的行确实是:

spline_approx = lambda x: interp1d( args,fdict[k-1](args) )(x)

这一行意味着spline_approx是给定x的函数,它返回在x计算的interp1d(args, fdict[k-1](args)

由于interp1d返回要放入spline_approx ,因此该行可简化为:

spline_approx = interp1d( args,fdict[k-1](args) )

这会停止抛出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]的调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM