Example 2.17 (Kreweras Lattice Walks)
with(gfun):
| > | # The minimal polynomial listed can be proven using the kernel method.
# Here we heuristically guess the minimal polynomial using gfun. # This takes up to 30 seconds. # Generate terms in the counting sequence KrewWalksIJ := proc(n,i,j) option remember: if i < 0 or j < 0 then return 0: elif n=0 and i=0 and j=0 then return 1: elif n=0 then return 0: else return KrewWalksIJ(n-1,i+1,j) + KrewWalksIJ(n-1,i,j+1) + KrewWalksIJ(n-1,i-1,j-1): end if: end: KrewWalks := proc(n) return add(add(KrewWalksIJ(n,i,j),i=0..n),j=0..n): end: # Generate counting sequence LST := [seq(KrewWalks(k),k=0..100)]: P := subs(y(z)=y,listtoalgeq(LST,y(z))[1]); |
| (1) |
| > | # Plot part of the real algebraic curve defined by P
plots[implicitplot](P,z=-10..10,y=-30..30); |
![]() |
| > | # Find potential singularities of the generating function
factor(discrim(P,y)*coeff(P,y,6)); |
| (2) |
| > | # Solutions to P(z,y) at the origin
algeqtoseries(P,z,y,3); |
| (3) |
| > | # Solutions to P(z,y) around dominant singularity z = 1/3
algeqtoseries(subs(z=(1-t)/3,P),t,y,3): subs(t=1-3*z,%); |
| (4) |
| > | # There are two real solutions beginning +/- 2*sqrt(2)*(1-3*z)^(-1/4) + ...
# Thus f(z) ~ 2*sqrt(2)*(1-3*z)^(-1/4), giving dominant asymptotics ASM := 3^n * 2*sqrt(2) * n^(-3/4) / GAMMA(1/4); |
![]() |
(5) |
| > | # Heuristically check that our asymptotic is close to the actual sequence value
PR := rectoproc(listtorec(LST,u(n))[1],u(n)): evalf(PR(1000)/subs(n=1000,ASM)); |
| (6) |
| > |