The polynomial dream, and where it breaks
Start from something you have trusted since school. A polynomial of degree n with roots a_1, ..., a_n can be written as a constant times (z - a_1)(z - a_2)...(z - a_n). The roots are not just clues about the polynomial — they are the polynomial, once you multiply the factors back together. In the last guide on factoring a function by its zeros we asked the obvious follow-up: an entire function like sin z or e^z - 1 also has zeros, often infinitely many of them, so can we write it as a product over its zeros in the same way? The dream is to pull every zero out as a factor (z - a_n) and be done.
It breaks immediately. Suppose the zeros a_1, a_2, a_3, ... march off to infinity, as they must for any entire function with infinitely many zeros — they cannot accumulate at a finite point, or the zeros would not be isolated. Form the naive product (z - a_1)(z - a_2)(z - a_3).... For this to converge at a fixed z, the factors must tend to 1. But (z - a_n) does the opposite: as a_n runs off to infinity, |z - a_n| grows without bound. Multiplying together infinitely many numbers that are getting larger and larger does not settle to a finite value — it diverges to infinity. The factors are pointing the wrong way.
There is a cheap first fix: normalize each factor. Instead of (z - a_n), use (1 - z/a_n), which equals 1 when z = 0 and still vanishes exactly at z = a_n. Now each factor at least heads toward 1 as a_n grows, since z/a_n shrinks to 0. From the earlier guide on the convergence of infinite products you know the real test: the product converges precisely when the sum of |z/a_n| converges. So if the zeros run off fast enough — say sum 1/|a_n| converges — we are already done. The trouble is the zeros that crawl, not sprint, to infinity.
Weierstrass's trick: a built-in correction factor
When the zeros crawl — for example a_n roughly n, so that sum 1/|a_n| is the harmonic series and diverges — the normalized product (1 - z/a_n) still fails to converge, because each factor differs from 1 by about z/a_n, and those differences add up to a divergent sum. Weierstrass's idea is gorgeous: do not throw away the factor, fix it from the inside by multiplying it by an exponential whose only job is to cancel the slowly-decaying part of log(1 - z/a_n). Recall log(1 - w) = -(w + w^2/2 + w^3/3 + ...). The term that refuses to die is the leading -w. So multiply by e^w to kill it.
This gives the Weierstrass elementary factor. Define E_0(w) = 1 - w, and for p = 1, 2, 3, ..., E_p(w) = (1 - w) times exp(w + w^2/2 + ... + w^p/p). Each E_p still has its single zero exactly at w = 1, because the exponential is never zero — it only reshapes the factor away from there. The genius is in what the exponential does to the logarithm: log E_p(w) = log(1 - w) + (w + ... + w^p/p) = -(w^(p+1)/(p+1) + w^(p+2)/(p+2) + ...). The first p terms have been surgically removed; the factor now differs from 1 only by something of size |w|^(p+1). Raise p and you make every factor hug 1 as tightly as you like.
E_0(w) = 1 - w E_p(w) = (1 - w) * exp( w + w^2/2 + w^3/3 + ... + w^p/p ) for |w| <= 1/2 : | E_p(w) - 1 | <= |w|^(p+1) (single zero at w = 1; exp factor never vanishes)
Assembling the theorem
Now the pieces snap together. Given any sequence of nonzero points a_n running off to infinity, we want a product of factors E_(p_n)(z/a_n), each contributing exactly one zero at a_n. Near a fixed z, the n-th factor differs from 1 by about |z/a_n|^(p_n + 1). If we are clever about choosing the integers p_n — letting them grow if the zeros are stubbornly slow — we can always force the sum of these tiny differences to converge. That is the whole game: pick p_n large enough that sum |z/a_n|^(p_n + 1) converges on every disk, and then the infinite product converges uniformly on compact sets to an entire function.
That is the constructive heart of the Weierstrass factorization theorem. The clean statement runs: every entire function f can be written as f(z) = z^m e^(g(z)) times the product over n of E_(p_n)(z/a_n), where m is the order of the zero at the origin (zero if f(0) is nonzero), the a_n are the remaining zeros listed with multiplicity, and g is some entire function. Read it slowly. The product manufactures exactly the right zeros; the factor z^m handles a possible zero at the origin (which has no 1 - z/a_n form); and e^(g(z)) is a zero-free fudge factor — the exponential is never zero — that carries everything about f that the zeros alone cannot see.
The canonical product and a worked sine
Weierstrass lets the p_n vary freely, which is generous but messy. In practice you want one fixed integer p that works for all the factors at once, giving the tidiest product. If there is a smallest nonnegative integer p with sum 1/|a_n|^(p+1) convergent, take that single p for every factor; the result is the canonical product, the most economical Weierstrass product the given zeros allow. That uniform exponent p is called the genus of the product, and it pins down a function as tightly as the zeros ever can — Hadamard's deeper theorem then shows that for functions of finite growth the leftover e^(g(z)) is just e^(polynomial), not a wild entire g.
Let us actually build one. Take f(z) = sin(pi z). Its zeros are exactly the integers 0, plus/minus 1, plus/minus 2, ..., each simple. The zero at the origin needs a bare z factor. Pair up plus n and minus n: the two factors (1 - z/n) and (1 + z/n) multiply to (1 - z^2/n^2), and once paired this way the sum of 1/n^2 already converges, so we need no exponential correction at all — the genus is effectively handled by the pairing. This produces sin(pi z) = pi z times the product over n >= 1 of (1 - z^2/n^2). Plug in a value and you recover Euler's celebrated infinite product for the sine.
Why this matters: building functions to order
Step back and see what you have gained. Before this theorem, you could only analyze entire functions handed to you. Now you can commission one. Hand me any sequence of points with no finite accumulation, together with a multiplicity for each, and Weierstrass hands back an entire function whose zeros are precisely those points to those multiplicities — the prescribed-zeros theorem. The zeros of an entire function are not some delicate accident; they are completely free to choose, subject only to the one unavoidable constraint that they cannot pile up at a finite point.
This is also the gateway to building meromorphic functions. A meromorphic function is a quotient of two entire functions, so once Weierstrass lets you construct an entire function with whatever zeros you want for the numerator and another for the denominator, you can prescribe both zeros and poles. The very next guide, on the Mittag-Leffler theorem, does the dual construction directly in terms of poles and their principal parts; together the two theorems say you can sculpt a meromorphic function from its singular data almost at will. The infinite product and the partial-fraction sum are the two halves of one sculptor's toolkit.
- List the desired zeros a_1, a_2, ... (with repeats for multiplicity), and peel off any zero at the origin as a separate factor z^m.
- Find the smallest nonnegative integer p making sum 1/|a_n|^(p+1) converge — that is your genus, the exponent for every elementary factor.
- Form the canonical product z^m times the product of E_p(z/a_n); it converges on every disk to an entire function with exactly those zeros.
- If you have a target function in mind, fix the leftover e^(g(z)) by matching a value, a derivative, or a growth rate — for finite-order functions g is only a polynomial.