I'm a beginning Python programmer with no experience with sympy - just for fun. I'm trying to generate the formulas for sums of powers of integers as described in the latest Mathologer video (Power Sums). The following program generates the set of equations that follow. While correct, I would like the polynomials in the numerator to be factored where appropriate and individual terms to actually be summed (ie, a common denominator). I've tried a lot of "simplifiers", but nothing seems to work. Any ideas?
Program :
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)
Output (note; had to replace double *'s with ^):
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]])
Does this do what you want?
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 ⎦
Note that as an alternative, and to check the Mathologer formulas, you may also calculate these sums as:
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()))
giving:
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
If you substitute factor()
by expand()
, you get all the powers separated:
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
With Poly(Sum(j**k, (j, 1, n)).doit()).all_coeffs()
you can get just the coefficients:
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]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.