Нужно упростить вывод уравнения симпы - PullRequest
0 голосов
/ 29 октября 2019

Я начинающий программист на Python без опыта работы с sympy - просто для удовольствия. Я пытаюсь сгенерировать формулы для сумм степеней целых чисел, как описано в последнем видео Mathologer (Power Sums). Следующая программа генерирует следующий набор уравнений. Хотя это и правильно, я бы хотел, чтобы полиномы в числителе были учтены в соответствующих случаях, а отдельные термины суммировались (т. Е. Общий знаменатель). Я перепробовал много «упрощателей», но, похоже, ничего не работает. Есть идеи?

Программа :

from sympy import S, Matrix, Symbol, simplify, pprint
import math

def bn(n, k):

    sign = n%2+k%2  # used to negate odd (0 based) diagonals
    n = n+1         # shift triangle up and left
    bc = math.factorial(n)//math.factorial(k)//math.factorial(n-k)
    if sign == 1: bc = -bc
    return bc


if __name__ == "__main__": 

    N = 5

    n = Symbol('n')
    v = Matrix([n**i for i in range(1,N+1)])

    M = [[bn(i,k) for k in range(0,i+1)]+(N-i-1)*[S(0)] for i in range(0,N)]
    eqs = simplify(Matrix(M).inv()*v)
    print(eqs.__repr__())
    # pprint(eqs, use_unicode=True)      

Вывод (примечание; пришлось заменить двойные * на ^):

Matrix([[                           n],
        [                 n*(n + 1)/2],
        [       n*(2*n^2 + 3*n + 1)/6],
        [       n^2*(n^2 + 2*n + 1)/4],
        [n^5/5 + n^4/2 + n^3/3 - n/30]])

Ответы [ 2 ]

1 голос
/ 29 октября 2019

Делает ли это то, что вы хотите?

In [8]: eqs.applyfunc(factor)                                                                                                                                 
Out[8]: 
⎡                 n                  ⎤
⎢                                    ⎥
⎢             n⋅(n + 1)              ⎥
⎢             ─────────              ⎥
⎢                 2                  ⎥
⎢                                    ⎥
⎢        n⋅(n + 1)⋅(2⋅n + 1)         ⎥
⎢        ───────────────────         ⎥
⎢                 6                  ⎥
⎢                                    ⎥
⎢             2        2             ⎥
⎢            n ⋅(n + 1)              ⎥
⎢            ───────────             ⎥
⎢                 4                  ⎥
⎢                                    ⎥
⎢                    ⎛   2          ⎞⎥
⎢n⋅(n + 1)⋅(2⋅n + 1)⋅⎝3⋅n  + 3⋅n - 1⎠⎥
⎢────────────────────────────────────⎥
⎣                 30                 ⎦
0 голосов
/ 29 октября 2019

Обратите внимание, что в качестве альтернативы и для проверки формул Mathologer вы также можете рассчитать эти суммы как:

from sympy import symbols, Sum, factor, expand, Poly

j, n = symbols("j n", integer=True, positive=True)
for k in range(11):
    print(k, ":", factor(Sum(j**k, (j, 1, n)).doit()))

, что дает:

 0 : n
 1 : n*(n + 1)/2
 2 : n*(n + 1)*(2*n + 1)/6
 3 : n**2*(n + 1)**2/4
 4 : n*(n + 1)*(2*n + 1)*(3*n**2 + 3*n - 1)/30
 5 : n**2*(n + 1)**2*(2*n**2 + 2*n - 1)/12
 6 : n*(n + 1)*(2*n + 1)*(3*n**4 + 6*n**3 - 3*n + 1)/42
 7 : n**2*(n + 1)**2*(3*n**4 + 6*n**3 - n**2 - 4*n + 2)/24
 8 : n*(n + 1)*(2*n + 1)*(5*n**6 + 15*n**5 + 5*n**4 - 15*n**3 - n**2 + 9*n - 3)/90
 9 : n**2*(n + 1)**2*(n**2 + n - 1)*(2*n**4 + 4*n**3 - n**2 - 3*n + 3)/20
10 : n*(n + 1)*(2*n + 1)*(n**2 + n - 1)*(3*n**6 + 9*n**5 + 2*n**4 - 11*n**3 + 3*n**2 + 10*n - 5)/66

Если вы подставите factor()на expand() вы получаете все полномочия:

 0 : n
 1 : n**2/2 + n/2
 2 : n**3/3 + n**2/2 + n/6
 3 : n**4/4 + n**3/2 + n**2/4
 4 : n**5/5 + n**4/2 + n**3/3 - n/30
 5 : n**6/6 + n**5/2 + 5*n**4/12 - n**2/12
 6 : n**7/7 + n**6/2 + n**5/2 - n**3/6 + n/42
 7 : n**8/8 + n**7/2 + 7*n**6/12 - 7*n**4/24 + n**2/12
 8 : n**9/9 + n**8/2 + 2*n**7/3 - 7*n**5/15 + 2*n**3/9 - n/30
 9 : n**10/10 + n**9/2 + 3*n**8/4 - 7*n**6/10 + n**4/2 - 3*n**2/20
10 : n**11/11 + n**10/2 + 5*n**9/6 - n**7 + n**5 - n**3/2 + 5*n/66

С Poly(Sum(j**k, (j, 1, n)).doit()).all_coeffs() вы можете получить только коэффициенты:

 0 : [1, 0]
 1 : [1/2, 1/2, 0]
 2 : [1/3, 1/2, 1/6, 0]
 3 : [1/4, 1/2, 1/4, 0, 0]
 4 : [1/5, 1/2, 1/3, 0, -1/30, 0]
 5 : [1/6, 1/2, 5/12, 0, -1/12, 0, 0]
 6 : [1/7, 1/2, 1/2, 0, -1/6, 0, 1/42, 0]
 7 : [1/8, 1/2, 7/12, 0, -7/24, 0, 1/12, 0, 0]
 8 : [1/9, 1/2, 2/3, 0, -7/15, 0, 2/9, 0, -1/30, 0]
 9 : [1/10, 1/2, 3/4, 0, -7/10, 0, 1/2, 0, -3/20, 0, 0]
10 : [1/11, 1/2, 5/6, 0, -1, 0, 1, 0, -1/2, 0, 5/66, 0]
...