Two months ago I implemented the computation of Puiseux series expansions of places of plane algebraic curves as well as integral bases of algebraic functions fields. These two tools are necessary for computing Riemann matrices associated with plane algebraic curves but have plenty of applications in other computations.

Puiseux Series

A Puiseux series is like a Laurent series but with fractional exponents. Laurent series are used to locally represent a complex-valued function whereas Puiseux series are used to locally represent the sheets of the Riemann surface corresponding to a plane algebraic curve. For example, the curve $ f(x,y) = y^3 + 2x^3y - x^7 $ admits the following three Puiseux series expansions at $x=0$

\[ y_1(x) = \cdots + \frac{3}{128} x^{14} - \frac{1}{16} x^{9} + \frac{1}{2} x^{4}, \\ y_2(x) = \cdots - \frac{1}{4} x^{4} + \frac{3}{64} \sqrt{2} \left(-x\right)^{\frac{13}{2}} - \sqrt{2} \left(- x\right)^{\frac{3}{2}}, \\ y_3(x) = \cdots -\frac{1}{4} x^{4} - \frac{3}{64} \sqrt{2} \left(- x\right)^{\frac{13}{2}} + \sqrt{2} \left(- x\right)^{\frac{3}{2}}. \]

In other words, each $ (0, y_i(0)) $ describes a point on the curve, $f$, and each $y_i(x)$ parameterizes one sheet of the corresponding Riemann surface in a small neighborhood around $x=0$. In fact, note that $f(x, y_1(x)) = 0 + O(x^{15})$.

Here is some example usage of abelfunctions in order to compute Puiseux series:

$ ipython

In [1]: import sympy; from sympy.abc import x,y
In [2]: from abelfunctions import puiseux
In [3]: f = y**3 + 2*x**3*y - x**7
In [4]: P = puiseux(f,x,y,0,nterms=3,parametric=False)
In [5]: for Pj in P: sympy.pretty_print(Pj)
   14    9    4
3*x     x    x 
----- - -- + --
 128    16   2 
      ___    13/2                   4
  3*\/ 2 *I*x         ___    3/2   x 
- --------------- - \/ 2 *I*x    - --
         64                        4 
    ___    13/2                   4
3*\/ 2 *I*x         ___    3/2   x 
--------------- + \/ 2 *I*x    - --
       64                        4 

In [6]: g = f.subs(y,P[0]).expand()
In [7]: sympy.pretty_print(g)
     42       37      32       27      22
 27*x     27*x     9*x     19*x     3*x  
------- - ------ + ----- - ------ + -----
2097152   262144    8192    4096     128 

Puiseux series of a complex plane algebraic curve at the roots of the curve when considered as a polynomial in $y$ over $\mathbb{C}[x]$. That is, polynomials in $\mathbb{C}[x][y]$ factor completely in the field of Puiseux series.

In [8]: f_approx = (y-P[0]) * (y-P[1]) * (y-P[2])
In [9]: f_approx = f_approx + sympy.O(x**12) + sympy.O(y**12)
In [10]: sympy.pprint( f_approx.expand() )
                    9  2                  
 3      3      7   x *y     / 12\    / 12\
y  + 2*x *y - x  + ----- + O\y  / + O\x  /
                     16    

(Were we to use more terms in the Puiseux series expansions there would be more cancellation in the product. Note that the order of the term $x^9y^2$ is greater than any of the terms in $f$.)

Puiseux series will play a central role in many of the algebraic computations involved in abelfunctions. My implementation is based on the algorithm of Duval [1].

Integral Bases

One such application of Puiseux series is in the calculation of integral bases of algebraic function fields $\mathbb{C}[x,y] / f(x,y)$. That is, the "integral basis" is a set of elements $b_0, \ldots, b_{n-1} \in \mathbb{C}(x,y)$ such that

\[ \overline{\mathbb{C}[x,y] / f(x,y)} = b_0 \mathbb{C}[x] + \cdots + b_{n_1} \mathbb{C}[x]. \]

In applications to Riemann surfaces and algebraic curves this means that any element of the integral closure of $\mathbb{C}[x,y]$ within the field of meromorphic functions defined on the curve $\Gamma : f(x,y) = 0$ can be written as a linear combination of $b_0, \ldots, b_{n-1}$ whose coefficients are in $\mathbb{C}[x]$.

Continuing from the code above, here is an example of computing integral bases in abelfunctions.

In [11]: from abelfunctions import integral_basis
In [12]: b = integral_basis(f,x,y)
In [13]: sympy.pprint(b)
        2 
    y  y  
[1, -, --]
    x   3 
       x  

We show that each of these integral basis elements are, indeed, algebraic over $\mathbb{C}[x,y] / (f(x,y))$.

In [14]: g1 = b[1]**3 + 2*x*b[1] - x**4
In [15]: sympy.pprint( g1.factor(f) )
 / 7      3      3\
-\x  - 2*x *y - y /
-------------------
          3        
         x   

In [16]: g2 = b[2]**2 + 2*b[2] - x*y
In [17]: sympy.pprint( g2.factor(f) )
   / 7      3      3\
-y*\x  - 2*x *y - y /
---------------------
           6         
          x  

The polynomial $f$ appears as a factor in each of the resulting expressions. Therefore, $g_1$ and $g_2$ are zero in $\mathbb{C}[x,y] / (f(x,y))$. My implementation is based on the algorithm of van Hoeij [2].

  1. [1] Duval, Dominique. "Rational Puiseux Series." Compositio Mathematica 70 (1989): 119-154.
  2. [2] Van Hoeij, Mark. "An algorithm for computing an integral basis in an algebraic function field." J. Symbolic Computation 18, no. 4 (1994): 353-364.