Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
Function: asympnum Section: sums C-Name: asympnum0 Prototype: GDGp Help: asympnum(expr,{alpha = 1}): asymptotic expansion of expr assuming it has rational coefficients with reasonable height; alpha is as in limitnum. Doc: Asymptotic expansion of \var{expr}, corresponding to a sequence $u(n)$, assuming it has the shape $$u(n) \approx \sum_{i \geq 0} a_i n^{-i\alpha}$$ with rational coefficients $a_i$ with reasonable height; the algorithm is heuristic and performs repeated calls to limitnum, with \kbd{alpha} as in \kbd{limitnum}. As in \kbd{limitnum}, $u(n)$ may be given either by a closure $n\mapsto u(n)$ or as a closure $N\mapsto [u(1),\dots,u(N)]$, the latter being often more efficient. \bprog ? f(n) = n! / (n^n*exp(-n)*sqrt(n)); ? asympnum(f) %2 = [] \\ failure ! ? localprec(57); l = limitnum(f) %3 = 2.5066282746310005024157652848110452530 ? asympnum(n->f(n)/l) \\ normalize %4 = [1, 1/12, 1/288, -139/51840, -571/2488320, 163879/209018880, 5246819/75246796800] @eprog\noindent and we indeed get a few terms of Stirling's expansion. Note that it definitely helps to normalize with a limit computed to higher accuracy (as a rule of thumb, multiply the bit accuracy by $1.612$): \bprog ? l = limitnum(f) ? asympnum(n->f(n) / l) \\ failure again !!! %6 = [] @eprog\noindent We treat again the example of the Motzkin numbers $M_n$ given in \kbd{limitnum}: \bprog \\ [M_k, M_{k*2}, ..., M_{k*N}] / (3^n / n^(3/2)) ? vM(N, k = 1) = { my(q = k*N, V); if (q == 1, return ([1/3])); V = vector(q); V[1] = V[2] = 1; for(n = 2, q - 1, V[n+1] = ((2*n + 1)*V[n] + 3*(n - 1)*V[n-1]) / (n + 2)); f = (n -> 3^n / n^(3/2)); return (vector(N, n, V[n*k] / f(n*k))); } ? localprec(100); l = limitnum(n->vM(n,10)); \\ 3/sqrt(12*Pi) ? \p38 ? asympnum(n->vM(n,10)/l) %2 = [1, -3/32, 101/10240, -1617/1638400, 505659/5242880000, ...] @eprog If \kbd{alpha} is not a rational number, loss of accuracy is expected, so it should be precomputed to double accuracy, say: \bprog ? \p38 ? asympnum(n->log(1+1/n^Pi),Pi) %1 = [0, 1, -1/2, 1/3, -1/4, 1/5] ? localprec(76); a = Pi; ? asympnum(n->log(1+1/n^Pi), a) \\ more terms %3 = [0, 1, -1/2, 1/3, -1/4, 1/5, -1/6, 1/7, -1/8, 1/9, -1/10, 1/11, -1/12] ? asympnum(n->log(1+1/sqrt(n)),1/2) \\ many more terms %4 = 49 @eprog The expression is evaluated for $n = 1, 2, \dots, N$ for an $N = O(B)$ if the current bit accuracy is $B$. If it is not defined for one of these values, translate or rescale accordingly: \bprog ? asympnum(n->log(1-1/n)) \\ can't evaluate at n = 1 ! *** at top-level: asympnum(n->log(1-1/n)) *** ^----------------------- *** in function asympnum: log(1-1/n) *** ^---------- *** log: domain error in log: argument = 0 ? asympnum(n->-log(1-1/(2*n))) %5 = [0, 1/2, 1/8, 1/24, ...] ? asympnum(n->-log(1-1/(n+1))) %6 = [0, 1, -1/2, 1/3, -1/4, ...] @eprog\noindent \synt{asympnum}{void *E, GEN (*u)(void *,GEN,long), GEN alpha, long prec}, where \kbd{u(E, n, prec)} must return either $u(n)$ or $[u(1),\dots,u(n)]$ in precision \kbd{prec}. Also available is \fun{GEN}{asympnum0}{GEN u, GEN alpha, long prec}, where $u$ is a closure as above or a vector of sufficient length.