General post

Composition of formal power series

Originally posted 2024-11-22

Last updated 2024-11-22

Background

Note: This is supplemental material originally meant to go with the meetup on classical methods for power series coefficient extraction. I wasn’t able to find a simple, sufficient, self-contained treatment of computational coefficient extraction for power series compositions using iterative methods, so hope this fills that void.1 Understanding integer compositions will make it easier to follow the “composition product terms” discussed below.2

Definition of power series composition

Let h(z)=f(g(z))h(z) = f(g(z)), where ff, gg, and hh are all formal power series. We want to compute the coefficients of h(z)h(z), hn=[zn]h(z)h_n = [z^n] h(z) for all nn. Unfortunately, doing so efficiently (in space and time) is non-trivial. We’ll develop a solution by working with the original series definition and inspecting the coefficients that come out at each step. Start by writing

h(z)=m=0fm(k=0gkzk)mh(z) = \sum_{m=0}^{\infty} f_m \left(\sum_{k=0}^{\infty} g_k z^k\right)^m

and expanding terms. We find that

h0=[z0]m=0fm(k=0gkzk)m=m=0fm[z0](k=0gkzk)m=f0+m=1fm[z0](k=0gkzk)m=f0+m=1fmg0m=m=0fmg0m\begin{aligned} h_0 &= [z^0] \sum_{m=0}^{\infty} f_m \left( \sum_{k=0}^{\infty} g_k z^k \right)^m \\ &= \sum_{m=0}^{\infty} f_m [z^0] \left( \sum_{k=0}^{\infty} g_k z^k \right)^m \\ &= f_0 + \sum_{m=1}^{\infty} f_m [z^0] \left( \sum_{k=0}^{\infty} g_k z^k \right)^m \\ &= f_0 + \sum_{m=1}^{\infty} f_m g_0^m \\ &= \sum_{m=0}^{\infty} f_m g_0^m \end{aligned}

Notice that this is a series that does not converge if g0>0\vert g_0 \vert > 0 (we require all coefficients to be finite; technically, to stabilize). Therefore, we conclude that we must have g0=0g_0 = 0 for the composition hh to converge. This immediately tells us that h0=f0h_0 = f_0, since the only term that contributes a constant is the one with (g(x))0(g(x))^0.

Computing coefficients by brute force

Using similar logic for expansion of the other factors, let’s compute a few coefficients, hnh_n. Recall that g0=0g_0 = 0, so we can start the inner sum at 11. Now, note that [zk](m=1gmzm)n[z^k] \left( \sum_{m=1}^{\infty} g_m z^m \right)^n is essentially asking for the sum of all products gl1gl2glng_{l_1} g_{l_2} \cdots g_{l_n} such that i=0nli=k\sum_{i=0}^{n} l_i = k. Obviously, each 0<lin0 \lt l_i \leq n, but we also know that g0=0g_0 = 0, so only positive indices actually contribute. Let’s put this in context of the total sum for the coefficient of interest:

hn=m=0fm[zn](k=1gkzk)m\begin{aligned} h_n &= \sum_{m = 0}^{\infty} f_m [z^n] \left( \sum_{k=1}^{\infty} g_k z^k \right)^m \end{aligned}

Now it becomes clearer that each fmf_m contributes one term for each (strong) mm-composition of nn.3 Each such integer composition corresponds to a certain product of coefficients of g(z)g(z). For example, g1g3g1g_1 g_3 g_1 is a 33-composition of 55. It has 33 parts and the product of the implied powers of zz is z5z^5, since 1+3+1=51 + 3 + 1 = 5. Consequently this contributes to the coefficient h5h_5 after being multiplied by the outer coefficient f3f_3.

Here are the first few coefficients fully expanded:

h0=f0h1=f1g1h2=f1g2+f2(g1g1)h3=f1g3+f2(g1g2+g2g1)+f3(g1g1g1)h4=f1g4+f2(g1g3+g2g2+g3g1)+f3(g1g1g2+g1g2g1+g2g1g1)+f4(g1g1g1g1)h5=f1g5+f2(g1g4+g2g3+g3g2+g4g1)+f3(g1g1g3+g1g2g2+g1g3g1+g2g1g2+g2g2g1+g3g1g1)+f4(g1g1g1g2+g1g1g2g1+g1g2g1g1+g2g1g1g1)+f5(g1g1g1g1g1)\begin{aligned} h_0 &= f_0 \\ h_1 &= f_1g_1 \\ h_2 &= f_1g_2 + f_2(g_1g_1) \\ h_3 &= f_1g_3 + f_2(g_1g_2 + g_2g_1) + f_3(g_1g_1g_1) \\ h_4 &= f_1g_4 + f_2(g_1g_3 + g_2g_2 + g_3g_1) + f3(g_1g_1g_2 + g_1g_2g_1 + g_2g_1g_1) + f4(g_1g_1g_1g_1) \\ h_5 &= f_1g_5 + f_2(g_1g_4 + g_2g_3 + g_3g_2 + g_4g_1) + f_3(g_1g_1g_3 + g_1g_2g_2 + g_1g_3g_1 + g_2g_1g_2 + g_2g_2g_1 + g_3g_1g_1) + f_4(g_1g_1g_1g_2 + g_1g_1g_2g_1 + g_1g_2g_1g_1 + g_2g_1g_1g_1) + f_5(g_1g_1g_1g_1g_1) \\ \dots \end{aligned}

It may jump out at you that visiting each partition (which grows exponentially in n\sqrt{n}) and multiplying by its corresponding multinomial coefficient would be more efficient than visiting each composition (which grows exponentially in nn). However, this obscures a natural recurrence relation which helps us actually compute the hnh_n “efficiently”.4

Deriving a recurrence

Suppose we’re computing hnh_n where n>0n \gt 0. This will involve a sum of the form

hn=m=0nfmcm,n\begin{aligned} h_n &= \sum_{m=0}^{n} f_m c_{m, n} \end{aligned}

where cm,nc_{m, n} is precisely the sum-of-products of coefficients from g(z)g(z) that we’ve been discussing. In particular, it counts the coefficient products corresponding to each distinct mm-partition of nn. We want an explicit recurrence for cm,nc_{m, n}.

Note that c1,n=gnc_{1, n} = g_n (there’s only one 11-composition of nn) and cn,n=g1nc_{n, n} = g_1^n (there’s only one nn-composition of nn).

Now, consider the “composition product sum”, cm,nc_{m, n} for 1<m<n1 \lt m \lt n. If you look at the row computing hnh_n for a fixed nn, you can see that each composition product sum of mm parts builds off of the product sums of the rows of m1m-1 parts from some row before it. Specifically, consider the operation of prepending a given factor gig_i to any m1m-1 composition of nin-i for all valid gig_i. This generates all valid mm-composition products of nn. Moreover, since we’re prepending a factor to the each term in a given set of composition products (rather than, for example, replacing one of the previous factors with gig_i), this has the effect of scaling the corresponding sub-composition by gig_i.

A concrete example will probably help this stick. Consider the 33-compositions of 44, i.e. the composition terms of the f3f_3 term that go into h4h_4. If we choose g1g_1 as the first factor, then this leaves us with 22-compositions of 33. We read these off of the f2f_2 term of h3h_3: g1g2+g2g1g_1 g_2 + g_2 g_1. Similarly, we could have a first factor of g2g_2 by combining this with the 22-compositions of 22. As before, we read these off of the f2f_2 term of h2h_2: g1g1g_1 g_1. Putting these all together, we have the terms of the f3f_3 term of h4h_4: g1g1g2+g1g2g1+g2g1g1g_1 g_1 g_2 + g_1 g_2 g_1 + g_2 g_1 g_1. As desired, this matches exactly what we found by brute force under h4h_4.

We now have our recurrence relation:

cm,n=i=1nm+1gicm1,nic_{m, n} = \sum_{i=1}^{n-m+1} g_i c_{m - 1, n - i}

Note that the sum is over 1i01 \le i \le 0 because we can only have valid mm-compositions of nn when mnm \le n. Thus we can only have m1m-1-compositions of nin-i if m1niinm+1m-1 \le n-i \Rightarrow i \le n - m + 1.

Space and runtime

The recurrence shown above suggests a direct algorithm for computing each hnh_n:

  • Maintain a ragged array of cm,nc_{m, n} coefficients computed so far.
  • Bootstrap with c0,0=1c_{0, 0} = 1.
  • Compute hnh_n as: m=0nfmi=1nm+1gicm1,ni\sum_{m=0}^{n} f_m \sum_{i=1}^{n-m+1} g_i c_{m-1, n-i}

Note: Each implicit value of cm,nc_{m, n} computed above should be stored in the array to avoid exponentially duplicated work.

If we’re computing coefficient hnh_n, then we effectively have to compute all coefficients hih_i for 0in0 \le i \le n, so we’re using O(n2)O(n^2) storage space for the composition product sum array.5

At each step ii, the double sum costs us O(n2)O(n^2) runtime, for a total of O(n3)O(n^3) to get hnh_n. While this could potentially work fine up to a few thousand (without many deeper levels of composition), it will quickly become unwieldy for larger nn. Unfortunately, I’m not aware of any good solutions in arbitrary precision. You seem to be stuck with lossy DFT-based solutions or asymptotic analysis.

Footnotes

  1. I did, however see many references to advanced or impractical techniques such as those by Brent and Kung, as well as Bell polynomials and Faà di Bruno’s formula.

  2. Any time I use the phrase “integer composition”, this should be understood as a “strong integer composition”, since we do not allow zeros in this context.

  3. To see why, note that we’re taking an infinite multinomial raised to the power mm and, consequently, need to select mm terms in total whose powers of zz sum to nn, i.e., the power of interest.

  4. We will not be using FFT-based methods here because these increase the complexity and prerequisites dramatically, but also because the goal is to compute exact numbers in arbitrary precision. In particular, in the combinatorial classes we will be dealing with, the output coefficients are always intergral (except for some intermediate fractional coefficients as observed in function composition).

  5. We’re also using O(n)O(n) storage for the original fif_is and gig_is since these are reused while computing each sum. While it doesn’t affect the asymptotics, it does mean that you don’t get much benefit in a setting where the coefficients of F(z)F(z) and G(z)G(z) are streamed.