Ordinary Generating Functions
Learn to encode sequences as power series and solve counting problems algebraically.
Introduction
Generating functions transform counting problems into algebra. Instead of counting directly, we encode sequences as power series, manipulate them algebraically, and extract answers by reading coefficients. It's a powerful technique that solves problems beyond basic combinatorics.
Learning Objectives:
- Understand ordinary generating functions (OGFs)
- Convert counting problems into power series
- Extract coefficients to solve counting questions
- Perform basic operations on generating functions
What Is a Generating Function?
For a sequence , the ordinary generating function is the formal power series:
The coefficient of is , written as .
Key insight: The GF "generates" the sequence by encoding it in polynomial form.
Example 1: Constant Sequence
Sequence: (all terms equal 1)
Closed form (geometric series):
Verification: Multiply both sides by :
import numpy as np
import matplotlib.pyplot as plt
# Demonstrate geometric series approximation
def partial_sum_geometric(n_terms, x_val):
"""Compute partial sum of geometric series"""
return sum(x_val**n for n in range(n_terms))
def closed_form(x_val):
"""Closed form: 1/(1-x)"""
if abs(x_val) < 1:
return 1 / (1 - x_val)
else:
return float('inf')
# Test for x = 0.5
x = 0.5
terms_list = [5, 10, 20, 50]
print(f"Geometric series for x = {x}:")
print(f"Closed form: 1/(1-x) = 1/(1-{x}) = {closed_form(x):.6f}")
print(f"\nPartial sums:")
for n in terms_list:
partial = partial_sum_geometric(n, x)
print(f" {n} terms: {partial:.6f} (error: {abs(partial - closed_form(x)):.6f})")
# Show coefficients
print(f"\nFirst 10 coefficients (all = 1):")
coefficients = [1] * 10
print(f" {coefficients}")Extracting Coefficients
The power of GFs: solve for algebraically, then extract the coefficient of .
Example 2: Powers of 2
Sequence: (i.e., )
Factor out powers of 2:
Check: โ
# Verify coefficient extraction
def extract_coefficient_geometric(a, n):
"""
For G(x) = 1/(1-ax), the coefficient of x^n is a^n
"""
return a**n
# Test: G(x) = 1/(1-2x)
a = 2
test_n = [0, 1, 2, 3, 4, 5, 10]
print("G(x) = 1/(1-2x)")
print("\nCoefficient of x^n (equals 2^n):")
for n in test_n:
coef = extract_coefficient_geometric(a, n)
print(f" [x^{n}]: {coef}")
# Verify with polynomial expansion (first few terms)
print("\nExpanded form (first 6 terms):")
expansion = [2**n for n in range(6)]
print(f" {' + '.join(f'{c}x^{i}' if i > 0 else str(c) for i, c in enumerate(expansion))}")Operations on Generating Functions
Addition
If and , then:
Example: GF for and :
Multiplication (Convolution)
The coefficient of is the convolution: .
Binomial Series
The binomial series generalizes to non-integer exponents:
where (generalized binomial coefficient).
Key cases:
-
(coefficients: all 1)
-
(coefficients: )
-
from scipy.special import comb
# Verify 1/(1-x)^2 = sum of (n+1)x^n
def verify_binomial_series(k, max_n):
"""
Verify that coefficient of x^n in 1/(1-x)^k is C(n+k-1, k-1)
"""
print(f"Coefficients of 1/(1-x)^{k}:")
print(f"Formula: C(n+k-1, k-1) = C(n+{k-1}, {k-1})\n")
for n in range(max_n):
coef = int(comb(n + k - 1, k - 1, exact=True))
print(f" [x^{n}]: C({n + k - 1}, {k - 1}) = {coef}")
return
# Test for k=2: 1/(1-x)^2
print("Case 1: 1/(1-x)^2")
verify_binomial_series(k=2, max_n=8)
print("\n" + "="*50)
print("\nCase 2: 1/(1-x)^3")
verify_binomial_series(k=3, max_n=8)Solving a Counting Problem
Example 3: Number of Non-Negative Integer Solutions
How many solutions to where ?
GF approach: Each variable can be 0, 1, 2, 3, ..., so:
Same for and . The product gives solutions:
Coefficient of :
For : โ (matches stars and bars!)
from scipy.special import comb
def count_solutions_gf(n, k):
"""
Count non-negative integer solutions to x1 + x2 + ... + xk = n
using generating functions
"""
# Coefficient of x^n in 1/(1-x)^k
return int(comb(n + k - 1, k - 1, exact=True))
# Test: x1 + x2 + x3 = 5
n = 5
k = 3
result = count_solutions_gf(n, k)
print(f"Solutions to x1 + x2 + x3 = {n} (xi โฅ 0):")
print(f"\nGenerating function: (1/(1-x))^{k} = 1/(1-x)^{k}")
print(f"Coefficient of x^{n}: C({n}+{k}-1, {k}-1) = C({n+k-1}, {k-1}) = {result}")
print(f"\nVerification with stars and bars: {result}")Key Takeaways
- OGF: Encodes sequence as
- Geometric series:
- Extraction: gives the -th coefficient
- Operations: Add GFs (term-wise), multiply (convolution)
- Binomial series:
Next Lesson: Applications to integer partitions, coin change, and more!
GF | Sequence | Closed Form |
|---|---|---|
| $\sum x^n$ | $1, 1, 1, ...$ | $\frac{1}{1-x}$ |
| $\sum 2^n x^n$ | $1, 2, 4, 8, ...$ | $\frac{1}{1-2x}$ |
| $\sum (n+1) x^n$ | $1, 2, 3, 4, ...$ | $\frac{1}{(1-x)^2}$ |
| $\sum \binom{n+k-1}{k-1} x^n$ | Stars & bars | $\frac{1}{(1-x)^k}$ |