Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52 views

Quick tip: Do you prefer typeset output?

If you are using the show(...) command a lot, you might want to try out switching to typeset output.

matrix([[1,2,3],[4,5,6]])
[1 2 3] [4 5 6]
typeset_mode(True)
matrix([[1,2,3],[4,5,6]])
(123456)\displaystyle \left(\begin{array}{rrr} 1 & 2 & 3 \\ 4 & 5 & 6 \end{array}\right)
pi^2/6
16π2\displaystyle \frac{1}{6} \, \pi^{2}
typeset_mode(False)

Challenge

  • Find an identity kan,k=bn\sum_k a_{n,k} = b_n with hypergeometric terms an,ka_{n,k} (in both nn and kk) and bnb_n such that F(n,k)=an,k/bnF(n,k) = a_{n,k}/b_n does not have a WZ mate.

Loading the packages

  • You need to first download the wz.py file from our website and make it available to Sage by, for instance, copying it into the directory containing the Sage notebook.

  • The ore_algebra package is already installed on the SageMathCloud, but needs to otherwise be installed. See http://arxiv.org/abs/1306.4263v1 for more information, including examples, on this package.

from ore_algebra import * from wz import *

When running commands from these below, you will usually see several DeprecationWarning's pop up in red font. To get rid of these, you can run the command again.

n,k = var('n,k')

Celine's method

Examples from class

Example: k(nk)\displaystyle\sum_k \binom{n}{k}.

celine(binomial(n,k), n, k, 1, 1, output_rec_sum=False)
[-Sn*Sk + Sk + 1]
celine(binomial(n,k), n, k, 1, 1)
Sn - 2

Example: kk(nk)\displaystyle\sum_k k\binom{n}{k}.

celine(k*binomial(n,k), n, k, 1, 1, output_rec_sum=False)
[(-n)*Sn*Sk + (n + 1)*Sk + n + 1]
op = celine(k*binomial(n,k), n, k, 1, 1); op
n*Sn - 2*n - 2
op.parent()
Univariate Ore algebra in Sn over Univariate Polynomial Ring in n over Rational Field

Recall that the sum actually equals n2n1n 2^{n-1}. Let's see a few ways to check that.

op(n*2^(n-1))
-2*2^(n - 1)*(n + 1)*n + 2^n*(n + 1)*n
_.full_simplify()
0
[n*2^(n-1) for n in [0..5]]
[0, 1, 4, 12, 32, 80]
op.to_list([0,1],6)
[0, 1, 4, 12, 32, 80]

Before we continue... note the following very common cause of unexpected trouble: n is no longer the variable it used to be.

(When writing for n in [0..5], n was assigned numerical values.)

n
5
n = var('n')

Exercise

  • Find a recursion for the sum An=kk2(nk)\displaystyle A_n = \sum_k k^2\binom{n}{k}.

  • Prove that An=2n2n(n+1)A_n = 2^{n-2}n(n+1).

  • What about the sums An=kka(nk)\displaystyle A_n = \sum_k k^a\binom{n}{k} for a>2a>2?

No recursion found if we only allow order 1 for the shift operators.

celine(k^2*binomial(n,k), n, k, 1, 1)

Increasing either of the orders, we do find recurrences.

celine(k^2*binomial(n,k), n, k, 2, 1, output_rec_sum=False)
[(n^2 + 2*n + 1)*Sn^2*Sk + (-2*n^2 - 5*n - 2)*Sn*Sk + (-n^2 - 4*n - 4)*Sn + (n^2 + 3*n + 2)*Sk + n^2 + 3*n + 2]
celine(k^2*binomial(n,k), n, k, 1, 2, output_rec_sum=False)
[(-n)*Sn*Sk^2 + (-n^2)*Sn*Sk + (n + 1)*Sk^2 + (n^2 + 3*n + 2)*Sk + n^2 + 2*n + 1]

Which of these two should we prefer?

op = celine(k^2*binomial(n,k), n, k, 2, 1); op
(n + 1)*Sn^2 + (-3*n - 6)*Sn + 2*n + 4
op = celine(k^2*binomial(n,k), n, k, 1, 2); op
n*Sn - 2*n - 4

Note that we want a recursion for the sum of least possible order (from the answer, we know that there is one of order 1, but Celine's method is not guaranteed to find the one of least order). Therefore, we should increase the order in SkS_k before increasing the order in SnS_n. In this example, we succeeded and actually found a first-order recursion for the sum.

From there, we can derive the formula 2n2n(n+1)2^{n-2}n(n+1) ourselves.

op = celine(k^3*binomial(n,k), n, k, 1, 3); op
(n^3 + 3*n^2)*Sn - 2*n^3 - 12*n^2 - 18*n - 8

This is again a first order operator, so we can immediately express the sum as a hypergeometric term.

Here is a less inspired way to find the solution. Just to expose some more advanced possibilities...

Can you figure out what is going on?

op.parent()
Univariate Ore algebra in Sn over Univariate Polynomial Ring in n over Rational Field
op.parent().0
Sn
Sn = op.parent().0 op.symmetric_product(Sn-1/2)
(n^3 + 3*n^2)*Sn - n^3 - 6*n^2 - 9*n - 4
_.polynomial_solutions()
[(1/3*n^3 + n^2,)]

WZ method

n,k = var('n,k')

Example: k(nk)=2n\displaystyle\sum_k \binom{n}{k} = 2^n.

Why is it fully expected that we don't find a WZ mate for F(n,k)=(nk)F(n,k)=\binom{n}{k}?

wz_mate(binomial(n,k),n,k)
wz_mate(binomial(n,k)/2^n,n,k)
2^(-n - 1)*k*binomial(n, k)/(k - n - 1)
wz_mate_rat(binomial(n,k)/2^n,n,k)
1/2*k/(k - n - 1)

Example: kk(nk)=n2n1\displaystyle\sum_k k\binom{n}{k} = n 2^{n-1}.

wz_mate_rat(k*binomial(n,k)/(n*2^(n-1)),n,k)
1/2*(k - 1)/(k - n - 1)

Example: k(nk)xk=(1+x)n\displaystyle\sum_k \binom{n}{k}x^k = (1+x)^{n}.

This example illustrates that we can work with symbolic parameters.

x= var('x')
wz_mate_rat(x^k*binomial(n,k)/(1+x)^n,n,k)
k/((k - n - 1)*(x + 1))

Exercise

  • Give a WZ proof of k(nk)2=(2nn)\displaystyle \sum_k \binom{n}{k}^2 = \binom{2n}{n}.

  • Give a WZ proof of kk2(nk)=n(n+1)2n2\displaystyle \sum_k k^2\binom{n}{k} = n(n+1) 2^{n-2}.

  • What about the sums An=kka(nk)\displaystyle A_n = \sum_k k^a\binom{n}{k} for a>2a>2?

wz_mate_rat(binomial(n,k)^2/binomial(2*n,n),n,k)
1/2*(2*k - 3*n - 3)*k^2/((k - n - 1)^2*(2*n + 1))
wz_mate_rat(k^2*binomial(n,k)/(n*(n+1)*2^(n-2)),n,k)
1/2*(k*n + 2*k - n - 1)*(k - 1)/((k - n - 1)*k*(n + 2))

Gosper's algorithm

Example: sums of powers

gosper(n, n)
1/2*(n - 1)*n

Recall what this means: if f(n)=nf(n)=n, then g(n)=n(n1)/2g(n)=n(n-1)/2 is a discrete antiderivate, that is, f(n)=g(n+1)g(n)f(n) = g(n+1)-g(n).

In particular, k=0n1f(k)=g(n)g(0)\displaystyle \sum_{k=0}^{n-1} f(k) = g(n)-g(0).

gosper(n^2, n)
1/6*(2*n - 1)*(n - 1)*n

Exercise

  • Does f(n)=n!f(n)=n! have a hypergeometric term discrete antiderivative? What about f(n)=nn!f(n)=n \cdot n!?

  • Evaluate the sum n=0N1(n+1)42n(2nn)2\displaystyle\sum_{n=0}^{N} \frac{1}{(n+1)4^{2n}} \binom{2n}{n}^2.

  • Discover the geometric sum.

  • Determine n=0N(nk)\displaystyle\sum_{n=0}^{N} \binom{n}{k}.

  • Compute a WZ pair for F(n,k)=(nk)/2nF(n,k) = \binom{n}{k}/2^n directly by using Gosper's algorithm.

gosper(factorial(n), n)
gosper(n*factorial(n), n)
factorial(n)
gn = gosper(binomial(2*n,n)^2/((n+1)*4^(2*n)), n); gn
4*n*binomial(2*n, n)^2/4^(2*n)
gn.subs(n=0)
0
N = var('N') gn.subs(n=N+1)
x^(N + 1)/(x - 1)
gn = gosper(x^n ,n); gn
x^n/(x - 1)
gn.parent()
Symbolic Ring
gn.subs(n=N+1)
x^(N + 1)/(x - 1)
(gn.subs(n=N+1)-gn.subs(n=0)).factor()
(x^(N + 1) - 1)/(x - 1)
gn = gosper(binomial(n,k), n); gn
-(k - n)*binomial(n, k)/(k + 1)
bin_sum = (gn.subs(n=N+1) - gn.subs(n=0)); bin_sum
k*binomial(0, k)/(k + 1) + (N - k + 1)*binomial(N + 1, k)/(k + 1)

Simplifying symbolic expressions is not yet one of Sage's strong points...

bin_sum.full_simplify()
(k*factorial(N - k + 1) + (N*factorial(-k) - (k - 1)*factorial(-k))*factorial(N + 1))/((k^2 + k)*factorial(N - k + 1)*factorial(-k)*factorial(k - 1))
(gn.subs(n=N+1) - binomial(N+1,k+1)).full_simplify()
0
gosper(binomial(n,k)/2^n, k)
Gnk = gosper(binomial(n+1,k)/2^(n+1) - binomial(n,k)/2^n, k); Gnk
-k*(binomial(n + 1, k)/2^(n + 1) - binomial(n, k)/2^n)/(2*k - n - 1)

Let's check that we get the same answer as from WZ:

wz_mate(binomial(n,k)/2^n, n, k)
2^(-n - 1)*k*binomial(n, k)/(k - n - 1)
(Gnk - _).full_simplify()
0

Why are the rational functions slightly different?

gosper_rat(binomial(n+1,k)/2^(n+1) - binomial(n,k)/2^n, k)
-k/(2*k - n - 1)
wz_mate_rat(binomial(n,k)/2^n, n, k)
1/2*k/(k - n - 1)

Ore Algebra Basics

Working with derivative operators

R.<x> = QQ[] A.<Dx> = OreAlgebra(R)
Dx*x
x*Dx + 1
(x*Dx)^2
x^2*Dx^2 + x*Dx
(x*Dx)^3
x^3*Dx^3 + 3*x^2*Dx^2 + x*Dx
(x*Dx)^8
x^8*Dx^8 + 28*x^7*Dx^7 + 266*x^6*Dx^6 + 1050*x^5*Dx^5 + 1701*x^4*Dx^4 + 966*x^3*Dx^3 + 127*x^2*Dx^2 + x*Dx

Finding power series solutions to differential equations

Just one example of the things we can do. Explore more yourself by going through the properties of operators.

op = (Dx-1)*(Dx-2)
op
Dx^2 - 3*Dx + 2
op.power_series_solutions(n=5)
[x + 3/2*x^2 + 7/6*x^3 + 5/8*x^4 + O(x^5), 1 - x^2 - x^3 - 7/12*x^4 + O(x^5)]

Find all solutions to the Bessel differential equation

op_bessel = x^2*Dx^2+x*Dx+x^2
op_bessel.power_series_solutions(n=10)
[1 - 1/4*x^2 + 1/64*x^4 - 1/2304*x^6 + 1/147456*x^8 + O(x^9)]

This is the Bessel J0J_0 function. Let's compare with the builtin function.

y = var('y') bessel_J(0,y).taylor(y, 0, 8)
1/147456*y^8 - 1/2304*y^6 + 1/64*y^4 - 1/4*y^2 + 1

One of the inconsistencies... the following should work, too, but doesn't simplify yet.

bessel_J(0,y).series(y, 2)
(bessel_J(0, 0)) + (-1/2*bessel_J(1, 0) + 1/2*bessel_J(-1, 0))*y + Order(y^2)

The Bessel function is the unique analytic solution the second-order differential equation. Here is the second solution.

Check out the Frobenius method if you are interested in learning how to find all these solutions.

op_bessel.generalized_series_solutions(n=6)
[1 - 1/4*x^2 + 1/64*x^4 + O(x^6), (1 - 1/4*x^2 + 1/64*x^4 + O(x^6))*log(x) + 1/4*x^2 - 3/128*x^4 + O(x^6)]

We made x a variable in a polynomial ring over Q. Let's revert it to a symbolic variable before confusing ourselves later on.

x = var('x')

Working with shift operators

R.<n> = QQ['n']; A.<Sn> = OreAlgebra(R, 'Sn')
Sn*n
(n + 1)*Sn
(Sn*n)^6
(n^6 + 21*n^5 + 175*n^4 + 735*n^3 + 1624*n^2 + 1764*n + 720)*Sn^6

Playing with the Fibonacci recurrence

op_fib = Sn^2-Sn-1

Depending on the initial values, we get Fibonacci or Lucas numbers

op_fib.to_list([0,1],10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
op_fib.to_list([2,1],10)
[2, 1, 3, 4, 7, 11, 18, 29, 47, 76]

Guessing recurrences

With only a few values, you can try to guess a recurrence.

[catalan_number(n) for n in [0..10]]
[1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796]
guess([catalan_number(n) for n in [0..10]], A)
(-n - 2)*Sn + 4*n + 2

Of course, we could have done that by hand, too.

But the guessing works for any sequence, as soon as you have a way to compute sufficiently many terms.

Exercise

  • In different ways, obtain an operator which annihilates an=n!a_n=n!.

  • Find an operator which annihilates the square of the Fibonacci numbers.

  • Find an operator which annihilates both an=n!a_n=n! and the Fibonacci numbers.

op_factorial = Sn - (n+1)

Let's find a recurrence for squares of Fibonacci numbers by guessing.

(This is actually a perfectly rigorous way of finding the recurrence, because we know from class that there has to be a recurrence of order 3 with constant coefficients.)

R.<n> = QQ['n']; A.<Sn> = OreAlgebra(R, 'Sn')
[fibonacci(m)^2 for m in [0..10]]
[0, 1, 1, 4, 9, 25, 64, 169, 441, 1156, 3025]
guess(_, A)
-Sn^3 + 2*Sn^2 + 2*Sn - 1

Here is an advanced alternative:

op_fib = Sn^2-Sn-1 op_fib.symmetric_power(2)
Sn^3 - 2*Sn^2 - 2*Sn + 1
_.to_list([0,1,1],10)
[0, 1, 1, 4, 9, 25, 64, 169, 441, 1156]
op_factorial.lclm(op_fib)
(n^2 + 2*n)*Sn^3 + (-n^3 - 6*n^2 - 9*n - 3)*Sn^2 + (n^3 + 4*n^2 + 5*n + 3)*Sn + n^3 + 5*n^2 + 7*n + 3
guess([factorial(n)+fibonacci(n) for n in [0..20]], A)
(n^2 + 2*n)*Sn^3 + (-n^3 - 6*n^2 - 9*n - 3)*Sn^2 + (n^3 + 4*n^2 + 5*n + 3)*Sn + n^3 + 5*n^2 + 7*n + 3

Conversion between shift and derivative operators

Rx.<x> = QQ['x']; Ax.<Dx> = OreAlgebra(Rx, 'Dx') Rn.<n> = QQ['n']; An.<Sn> = OreAlgebra(Rn, 'Sn')

From a recurrence to a differential equation (for the ogf)

op_fib = Sn^2-Sn-1
de_fib = op_fib.to_D(Ax); de_fib
(-x^2 - x + 1)*Dx^2 + (-4*x - 2)*Dx - 2
de_fib.rational_solutions()
[(1/(x^2 + x - 1),), (x/(x^2 + x - 1),)]
de_fib.to_S(An)
(n^2 + 3*n + 2)*Sn^2 + (-n^2 - 3*n - 2)*Sn - n^2 - 3*n - 2
_.normalize()
Sn^2 - Sn - 1

From a differential equation to a recurrence

de_bessel = x^2*Dx^2+x*Dx+x^2
de_bessel.to_S(An)
(n^2 + 4*n + 4)*Sn^2 + 1

Zeilberger's algorithm

n,k = var('n,k')
celine(binomial(n,k)^2,n,k,2,2)
(n + 2)*Sn^2 + (-4*n - 6)*Sn
zeilberger(binomial(n,k)^2,n,k)
(n + 1)*Sn - 4*n - 2
celine(binomial(n,k)^3,n,k,3,3)
(n^3 + 22/3*n^2 + 17*n + 12)*Sn^3 + (-6*n^3 - 38*n^2 - 232/3*n - 148/3)*Sn^2 + (-15*n^3 - 80*n^2 - 419/3*n - 80)*Sn - 8*n^3 - 104/3*n^2 - 136/3*n - 56/3
zeilberger(binomial(n,k)^3,n,k)
(n^2 + 4*n + 4)*Sn^2 + (-7*n^2 - 21*n - 16)*Sn - 8*n^2 - 16*n - 8

Given a hypergeometric term F(n,k)F(n,k), Zeilberger's algorithm determines an operator P(n,N)P(n,N) such that P(n,N)F(n,k)=G(n,k+1)G(n,k)P(n,N) \cdot F(n,k) = G(n,k+1)-G(n,k) for some G(n,k)G(n,k).

This computation can be certified with a rational function R(n,k)R(n,k) such that G(n,k)=R(n,k)F(n,k)G(n,k)=R(n,k)F(n,k).

zeilberger(binomial(n,k),n,k,certificate=True)
(Sn - 2, k/(k - n - 1))
zeilberger(binomial(n,k)/2^n,n,k,certificate=True)
(Sn - 1, 1/2*k/(k - n - 1))

Exercise

  • Find a recursion for An=k=0n(nk)4\displaystyle A_n = \sum_{k=0}^n \binom{n}{k}^4.

  • Prove that $$\sum_k \binom{2 k}{k} \binom{2 n - 2 k}{n - k} \binom{n + k}{n - k} \binom{n

  • k}{k} = \sum_k \binom{n}{k}^4.$$

zeilberger(binomial(n,k)^4,n,k)
(n^3 + 6*n^2 + 12*n + 8)*Sn^2 + (-12*n^3 - 54*n^2 - 82*n - 42)*Sn - 64*n^3 - 192*n^2 - 188*n - 60
zeilberger(binomial(2*k,k)*binomial(2*(n-k),n-k)*binomial(n+k,n-k)*binomial(n-k,k),n,k)
(n^3 + 6*n^2 + 12*n + 8)*Sn^2 + (-12*n^3 - 54*n^2 - 82*n - 42)*Sn - 64*n^3 - 192*n^2 - 188*n - 60

It only remains to check at least two initial values (note that the leading coefficient in the recurrence doesn't vanish for n0n\ge0).

[sum(binomial(n,k)^4 for k in [0..n]) for n in [0..5]] [sum(binomial(2*k,k)*binomial(2*(n-k),n-k)*binomial(n+k,n-k)*binomial(n-k,k) for k in [0..n]) for n in [0..5]]
[1, 2, 18, 164, 1810, 21252] [1, 2, 18, 164, 1810, 21252]