在Python中重复lambda函数n次,错误的值?

时间:2017-01-01 18:33:10

标签: python python-3.x lambda

我正在尝试编写一个程序,该程序应该重复地将值提升为2,使用smoothing_five_times = repeatedly_smooth(lambda x: x**2, 5)调用,其中第二个参数是n次。

def repeatedly_smoothed(func, n):
    return repeat(lambda x: ((func(x-0.001) + func(x) + func(x+0.001)) / 3), n)

def repeat(f, n):
    if n==0:
        return (lambda x: x)
    return (lambda x: f (repeat(f, n-1)(x)))

对于n = 1,它可以正常工作,但是对于更高的x,值会失控。

smooth_one_times(10)
100.00000066666666
smooth_two_times(10)
10000.000134

第二个应该返回100.0000013,我似乎无法让它工作。将重复平滑的一个除以10,n或几乎任何东西只会使值远离我想要的值。我正在制作什么初学者错误?

2 个答案:

答案 0 :(得分:0)

不清楚究竟smooth_one_timessmooth_two_times到底是什么。但我会告诉你我的(原始)定义:

def smooth_one_time(k):
    return repeatedly_smoothed(lambda x: x ** 2, 1)(k)

def smooth_two_time(k):
    return repeatedly_smoothed(lambda x: x ** 2, 2)(k)

如果你做了以下事情(你没有正确地正常化),我认为你会得到你想要的东西:

def smooth_one_time(k):
    return repeatedly_smoothed(lambda x: x ** 2, 1)(k) / repeat(lambda x: x**2, 1)(10) * 100

def smooth_two_time(k):
    return repeatedly_smoothed(lambda x: x ** 2, 2)(k) / repeat(lambda x: x**2, 2)(10) * 100

smooth_two_time(10)的第二个定义根据需要输出100.00000134。自smooth_one_time以来,repeat(lambda x: x**2, 1)(10) * 100 == 1的两个定义在数学上都是等价的,但我出于教学原因将其包含在内,希望您能看到一般模式。如果它不清楚,它可以很好地概括为:

def smooth_n_times(n, k):
    return repeatedly_smoothed(lambda x: x ** 2, n)(k) / repeat(lambda x: x ** 2, n)(10) * 100

但是,要小心。这很快就溢出来了。 smooth_n_times(8, 10)输出100.00008576smooth_n_times(9, 10)在我的机器上溢出。

HTH。

答案 1 :(得分:0)

如果您按如下方式定义smooth

def smooth(f, x):
    return (f(x-0.001) + f(x) + f(x+0.001))/3

然后我认为你想要的smooth_two_times等同于:

In [1]: smooth(lambda y: smooth(lambda x: x**2, y), 10)
Out[1]: 100.0000013333333

然而,它实际上相当于:

repeatedly_smoothed(square, 2)(10)
=> repeat(lambda x: smooth(square, x), 2)(10)
=> smooth_square(repeat(smooth_square, 1)(10))
=> smooth_square(smooth_square(10))
=> smooth_square(100.00000066666666)
=> smooth_square(10000.000134)

我们使用了这些定义:

def square(x): return x**2
def smooth_square(y): return smooth(square, y)

问题是smooth_square是平方函数的平滑版本,并且您不想迭代地应用它(这将或多或少地平方10的平方)。相反,您只想将平滑两次迭代地应用于平方函数。

如果您想使用repeat来完成此操作,可以按如下方式定义smooth_function

def smooth_function(f):
    def smooth_f(x):
        return (f(x-0.001) + f(x) + f(x+0.001))/3
    return smooth_f

这是一个高阶函数,用于平滑给定函数(即返回函数的平滑版本)。因此:

smooth_function(smooth_function(lambda x: x**2))

将是二次函数的双重平滑版本,可以应用于10.但是,smooth_function的这个双重应用可以重写为:

(repeat(smooth_function, 2))(lambda x: x**2)

就是这样,repeat构造一个高阶函数,它将一个函数作为其参数并构造一个双重平滑的版本。然后可以将其应用于值10以提供:

In [2]: ((repeat(smooth_function, 2))(lambda x: x**2))(10)
Out[2]: 100.0000013333333

这里的大多数括号都是多余的,因此您可以定义:

def repeatedly_smoothed(f, n):
    return repeat(smooth_function, n)(f)
def smooth_two_times(x):
    return repeatedly_smoothed(lambda y: y**2, 2)(x)

并获得:

In [3]: smooth_two_times(10) 
Out[3]: 100.0000013333333