Упростить подсчет суммы ряда
def fact(t):
if t == 0:
return 1
else:
return t * fact(t-1)
def fun(x):
k = 0
s = x
final_sum = 0
while abs(s) > e:
k += 1
s *= (-1)**k * x**k/fact(3*k)
final_sum += s
return final_sum
факториал задавал сам, ибо нельзя использовать функцию из библиотеки math
Ответы (1 шт):
Автор решения: Nowhere Man
→ Ссылка
Можно было обойтись без рекурсивного вычисления факториала, вместо этого следовало накапливать отношение x**k/fact(3*k) в цикле, также проще менять знак вместо вычисления -1**k:
EPS = 1e-12
def fun(x):
k = 0
s = x
p = 1
sign = -1
final_sum = 0
while abs(s) > EPS:
k += 1
t = 3 * k # 3, 6, 9..
p *= x / (t * (t - 1) * (t - 2)) # в знаменателе 1*2*3; 4*5*6; 7*8*9..
s *= sign * p
sign *= -1
final_sum += s
return final_sum
Если обязательно требуется рекурсия, то код можно переписать в следующем виде:
def fun2(x):
return rec(x, 0, -1, x, 1, 3) # проинициализировать те же переменные
def rec(x, tot, sign, s, p, t):
if abs(s) <= EPS:
return tot
p *= x / (t * (t - 1) * (t - 2))
s *= sign * p
return rec(x, tot + s, -sign, s, p, t + 3)
Тест
print('цикл : ', fun(100))
print('-----------')
print('рекурсия: ', fun2(100))
цикл : 52190.72272214074
-----------
рекурсия: 52190.72272214074
Дополнение Как заметил MBo в комментарии, параметр sign можно убрать полностью, и код тогда упростится:
EPS = 1e-12
def fun(x):
s = x
p = 1
t = 3
final_sum = 0
while abs(s) > EPS:
p *= -x / (t * (t - 1) * (t - 2))
s *= p
t += 3
final_sum += s
return final_sum
def fun2(x):
return rec(x, 0, x, 1, 3)
def rec(x, tot, s, p, t):
if abs(s) <= EPS:
return tot
p *= -x / (t * (t - 1) * (t - 2))
s *= p
return rec(x, tot + s, s, p, t + 3)