Упростить подсчет суммы ряда

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)
→ Ссылка