我正在编写一个近似e的数学值的函数。
我们被告知使用上面的factorial
函数和inverse
函数。还建议使用map
。
到目前为止,我有这个,但它给我一个错误说:ValueError: factorial() only accepts integral values
。
def inverse(n):
"""Returns the inverse of n"""
return 1 / n
def e(n):
"""Approximates the mathematical value e"""
lst = range(1, n+1)
lst2 = map(inverse, lst)
lst3 = map(math.factorial, lst2)
return sum(lst3)
有人能指出我正确的方向吗?
答案 0 :(得分:1)
现在这对我有用。我需要将范围从(1, n+1)
更改为(0, n+1)
并反转先执行factorial
然后执行inverse
的顺序。
def inverse(n):
"""Returns the inverse of n"""
return 1 / n
def e(n):
"""Approximates the mathematical value e"""
lst = map(math.factorial, range(0, n+1))
return sum(map(inverse, lst))
答案 1 :(得分:1)
e 可以用Σ(1 / k!)定义,其中k = 0..∞。
所以,对于每个k,
看起来你在阶乘之前而不是之后进行反演,从1而不是0开始。
请注意,这不是执行此计算的最有效方法,因为不必为每个k从头开始计算阶乘。
答案 2 :(得分:0)
正如其他人所指出的那样:
1/2 == 0
。你需要这样的东西:
def inverse(n):
"""Returns the inverse of n"""
# Using 1 as a float makes the division return a float value.
return 1. / n
def e(n):
"""Approximates the mathematical value e"""
lst = range(1, n+1) # k=1...n
lst2 = map(math.factorial, lst)
return 1 + sum(map(inverse, lst2))
您可以将近似值与math.exp
:
>>> abs(math.exp(1) - e(20)) < 1e-10
True
答案 3 :(得分:0)
我对这个问题很开心,使用生成器和装饰器。首先,您可以创建一个生成器yield
连续更精确的e
值:
def compute_e():
currentFactorial = 1
currentSum = 1
for i in itertools.count(start=1):
currentFactorial *= i
currentSum += 1/currentFactorial
yield currentSum
然后,我创建一个装饰器来找到一个固定点(具有最大迭代次数和所需精度):
def getFixedPoint(gen, maxiter=10000, precision=0):
def mywrap(*args, **kwargs):
instanceGen = gen(*args, **kwargs)
prevValue = next(instanceGen)
for n, value in enumerate(instanceGen):
if (value - prevValue < precision) or (n > maxiter):
return value
else:
prevValue = value
return mywrap
给了我这样的东西:
In [83]: getFixedPoint(compute_e)()
Out[83]: 2.7182818284590455
In [84]: getFixedPoint(compute_e, maxiter=5)()
Out[84]: 2.71827876984127
In [85]: getFixedPoint(compute_e, precision = 0.001)()
Out[85]: 2.7182539682539684
现在,我可以改变计算e
的每个连续值的方式,例如使用from decimal import Decimal
:
@getFixedPoint
def compute_e():
currentFactorial = Decimal(1)
currentSum = Decimal(1)
for i in itertools.count(start=1):
currentFactorial *= i
currentSum += 1/currentFactorial
yield currentSum
compute_e()
Out[95]: Decimal('2.718281828459045235360287474')