我正在尝试编写一个程序,该程序应该重复地将值提升为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或几乎任何东西只会使值远离我想要的值。我正在制作什么初学者错误?
答案 0 :(得分:0)
不清楚究竟smooth_one_times
和smooth_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.00008576
。 smooth_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