Direct algorithm
We can calculate \([p/q](x)\,\) using a direct method. Defining \(N(x)\) and \(D(x)\) as \begin{equation*} N(x)=\sum_{n=0}^{p} c_n\,x^n\,, \qquad D(x)=\sum_{n=0}^{q} b_n\,x^n\,, \end{equation*} we have the following equivalence \begin{equation*} f(x) - \frac{\sum_{n=0}^{p} c_n\,x^n}{\sum_{n=0}^{q} b_n\,x^n}=\mathcal{O}(x^{p+q+1}) \quad \Leftrightarrow \quad \left(\sum_{n=0}^{+\infty}a_n\,x^n\right) \left(\sum_{n=0}^{q} b_n\,x^n\right) - \sum_{n=0}^{p} c_n\,x^n = \mathcal{O}(x^{p+q+1})\,. \end{equation*}
Matching the coefficients of \(N(x)\) and \(f(x)\,D(x)\,\) leads to a system of linear equations
\[\begin{split}\left(\begin{array}{c c c c} a_{p-q+1}&a_{p-q+2}&\dots \dots&a_p\\ a_{p-q+2}&a_{p-q+3}&\dots \dots&a_{p+1}\\ \vdots&\vdots&\ddots&\vdots\\ a_{p}&a_{p+1}&\dots \dots&a_{p+q-1}\\ \end{array}\right) \left(\begin{array}{c} b_q\\ b_{q-1}\\ \vdots\\ b_1\\ \end{array}\right) =\left(\begin{array}{c} -a_{p+1}\\ -a_{p+2}\\ \vdots\\ -a_{p+q} \end{array}\right)\,,\end{split}\]
which can be expressed in a compact form \begin{equation*}\ {\bf A}\,b=a \,. \end{equation*} When possible, there are several ways to solve the above system [1]. A classical approach is to use LU factorization, consisting of expressing \({\bf A}={\bf LU}\), it requires the order of \(q^3\) operations to solve the system. Without loss of generality, assume that is possible to solve
and the denominator coefficients \(b_0\,,b_1\,,b_2\,, \dots\,,b_q\,,\) are well defined. The remaining \(p+1\) equations
gives the numerator coeficients \(c_0\,,c_1\,,c_2\,, \dots\,,c_p\,\) values, and the direct algorithm ends. It requires the order of \(q^3+pq\,\) operations to derive an approximant.
[1] Trefethen, L. N. and Bau, I. I. I. D. (1997). Numerical Linear Algebra. Society for Industrial and Applied Mathematics, Philadelphia.
Examples
[1]:
import sympy as sp
from padepy import direct_algorithm as da
[10]:
var = sp.Symbol("x")
func = sp.exp(var)
p = 3
q = 1
func
[10]:
[11]:
pade = da.pade(p, q, var, func)
pade
[11]:
[13]:
var = sp.Symbol("z")
func = (var + 1) / sp.sqrt(var**2 + 1)
p = 1
q = 7
func
[13]:
[14]:
pade = da.pade(p, q, var, func)
pade
[14]: