Contents / Information Theory / Arithmetic, Lempel–Ziv and Universal Coding
Chapter 6
Arithmetic, Lempel–Ziv and Universal Coding
Coding a whole message as one interval, learning the dictionary as you go, and what it costs to compress a source you were not told about.
Introduction
Coding a whole message as one interval, learning the dictionary as you go, and what it costs to compress a source you were not told about.
6.1The Core Idea: Messages as Subintervals
Huffman coding is optimal and still leaves up to one bit per symbol on the table, because a codeword is an integral number of bits. Arithmetic coding removes that restriction by refusing to give any symbol a codeword at all: the entire message is mapped to a single number, and only that number is transmitted. The cost is bits for the whole message, so the rounding loss is amortised over the whole file rather than paid per symbol.
Arrange the strings of length in lexicographic order and lay their probabilities end to end along . Each string then owns a subinterval whose length is its probability and whose position identifies it. Naming a message means naming a point in its interval.
Definition 6.1 (Cumulative distribution and the interval of a string). For a distribution on a totally ordered set, the cumulative distribution function is , and the interval assigned to is
of length exactly . Distinct symbols own disjoint intervals, and the intervals tile .
Definition 6.2 (Modified cumulative function and the Shannon–Fano–Elias code). The modified cumulative function is the midpoint of the interval,
The Shannon–Fano–Elias code transmits the first
bits of the binary expansion of ; write for that truncation.
The extra bit in buys prefix-freeness, and the following proof shows exactly where it is spent.
Theorem 6.3 (The Shannon–Fano–Elias code is prefix-free, with ). The code above is a prefix code, and its expected length satisfies
Proof. Prefix-freeness. Truncating a number to bits loses less than , so
A codeword of length stands for the dyadic interval , and by the display this interval contains . Moreover
so the dyadic interval has length at most and contains the midpoint of ; since the midpoint is at distance from each end of , the dyadic interval lies entirely inside . The intervals are disjoint for distinct , so the dyadic intervals are disjoint, and as established in the proof of Kraft's inequality, disjoint dyadic intervals correspond to codewords neither of which is a prefix of the other.
Expected length. Taking expectations of and using ,
Two bits of overhead is worse than Huffman's one — on single symbols. The point is that the construction never mentions the alphabet: apply it to the alphabet of whole messages and the overhead becomes bits per symbol, with no enormous code table, because the interval of can be computed incrementally. That incremental computation is arithmetic coding.
Definition 6.4 (Arithmetic code and tag). An arithmetic code for a model over maps the message to the interval of length obtained by nesting the per-symbol subdivisions, and transmits enough binary digits of a point inside it — the tag — to identify the interval uniquely.
Intuition. The unit interval is a ruler. Every possible message claims a segment of the ruler in proportion to how likely it is: likely messages get wide segments, unlikely ones get slivers.
To send a message you point at a spot inside its segment. Wide segments can be located with few digits of precision, slivers need many — and "number of digits needed" is , which is exactly the ideal codelength. Arithmetic coding is the observation that pointing precisely is the same as compressing.
Example 6.5 (Encoding a three-symbol message). A source emits with and with , with and as the interval bases. Encode AAB.
Solution. Start with , width .
First : , width .
Second : , width .
Then : , width .
Sanity check. The final width is ✓ — the probability of AAB. The ideal codelength is bits, so about bits should suffice. Indeed lies in , and no shorter binary fraction does, since the only -bit candidates are . Three bits for three symbols beats the naive bits only marginally here, but the source entropy is , so on long messages the coder approaches bits per symbol while Huffman is stuck at .□
6.2Interval Narrowing, Renormalization, and Precision
The encoder is one line of arithmetic repeated once per symbol.
Method 6.7 (Arithmetic encoder update). Maintain , initialised to . For each symbol with probability and cumulative base — both allowed to depend on all previously coded symbols — set and
Proposition 6.8 (The final width is the message probability). After encoding the interval has width
so bits suffice to name it, whatever model supplied the conditional probabilities.
Proof. From the update rule, : each step multiplies the width by the probability of the symbol just coded. Starting from width and multiplying across the message gives , which is by the chain rule.∎
This proposition is the reason arithmetic coding is model-agnostic. The coder never sees a table of symbol probabilities; it consumes a conditional distribution per symbol, and whatever model produces them — order-0, order-5 context, a neural network — the output length is plus a constant. Modelling and coding are cleanly separated, which is arithmetic coding's true advantage over Huffman.
The obvious implementation problem is that and converge and would need unbounded precision. The fix is to notice that once the interval lies wholly in one half of , the leading bit of every point in it is decided and can be emitted.
Method 6.9 (Renormalization: E1, E2 and E3 scalings). After each symbol, repeat while one of the conditions holds:
- E1 (): the interval is in the lower half. Output the bit , then map .
- E2 (): the interval is in the upper half. Output the bit , then map .
- E3 (): the interval straddles but is narrow. Increment a counter of pending bits, then map . When the next E1 or E2 finally outputs a bit , emit that bit followed by one copy of per pending count.
Proposition 6.10 (Renormalization is lossless and keeps the width above ). The E1/E2 maps are the affine maps that send the relevant half of onto ; emitting the corresponding bit and rescaling therefore preserves the identity of the final interval. After the loop terminates the width exceeds , so the registers never lose more than two bits of precision.
Proof. The map on and on are exactly "delete the leading bit after the binary point", which is the bit just emitted; so the remaining digits of the tag are unchanged. The loop exits only when none of E1, E2, E3 applies, i.e. when and , or and ; in either case .∎
The E3 rule is the subtle one. An interval such as is tiny but straddles the midpoint, so no bit is yet determined; scaling about the midpoint keeps the registers full while recording that whatever the first undetermined bit turns out to be, the next bits are its complement. Without E3 an implementation with finite registers eventually underflows and the code becomes ambiguous.
Intuition. You keep zooming into a smaller and smaller portion of the ruler. As soon as the whole remaining segment lies to the left of the halfway mark you know the first digit is ; write it down and blow the left half back up to full size, recovering a bit of working precision.
E3 is the "I know the next two bits are either or " case: you cannot name the first bit yet, but you know all the following ones will be its opposite, so you count them and fill them in later.
Example 6.11 (One narrowing step and its renormalization). The current interval is . The next symbol has and . Perform the update and any renormalization.
Solution. Width . The update gives
of width ✓.
Since , rule E1 applies: output the bit and rescale to .
Now , so E2 applies: output the bit and rescale to . No rule applies to , so the loop stops.
Sanity check. Two bits (01) were emitted and the width went from to , a factor of — one doubling per emitted bit, as the proposition requires. And 01 is right: the final interval sits inside , whose points all begin in binary ✓.□
Pitfall (Finite precision needs integer arithmetic, not floating point). Encoder and decoder must agree bit for bit. Floating-point rounding differs across compilers and platforms, so any real implementation keeps low and high as fixed-width integers (say 32 bits), computes with integer multiply-then-divide by the cumulative total, and guarantees that no interval ever becomes empty by keeping the frequency counts below a bound related to the register width. Carry propagation out of low must also be handled — the pending-bit counter of E3 is exactly the mechanism that does it.
6.3Termination, Decoding, and the Coding Theorem for Arithmetic Codes
The interval determines the message; a transmitted tag determines the message only if the decoder also knows where to stop. Two devices are used, and one theorem settles the cost of both.
Theorem 6.12 (Arithmetic coding is within two bits of optimal). Encoding a message with an arithmetic coder driven by the model produces at most
bits, and the resulting code is prefix-free. Consequently the expected rate satisfies
Proof. The final interval has width by Proposition The final width is the message probability. Applying the Shannon–Fano–Elias construction to the alphabet — transmitting the first bits of the midpoint of that interval — gives a prefix code by the Shannon–Fano–Elias theorem, with the stated length. Taking expectations,
Dividing by and letting gives the rate claim, since by definition of the entropy rate.∎
Compare this with Huffman's for blocks: the constant is worse, but Huffman needs a table of size to achieve it while arithmetic coding needs one register and a model. Two bits for the whole file is the practical meaning of the theorem.
Method 6.13 (Termination strategies).
- End-of-file symbol. Reserve a symbol EOF with a small probability, and code it as the last symbol. The decoder stops when it decodes EOF. Cost: bits, plus a tiny dilution of every other symbol's probability.
- Explicit length. Transmit in a header (e.g. with an Elias code) and decode exactly symbols. Cost: about bits.
- Flush bits. Emit enough bits of the tag to pin it inside the final interval — two bits after renormalization, plus any pending E3 bits — and let the container format supply the length.
Method 6.14 (Arithmetic decoding). The decoder mirrors the encoder. Maintain the same and a value register holding the received tag bits.
- Compute , the position of the tag within the current interval.
- Find the unique symbol with ; emit .
- Apply the same narrowing update for , then the same renormalization, shifting new bits into the value register whenever the encoder would have emitted one.
- Repeat until EOF or the known length is reached.
Proposition 6.15 (Decoder correctness). If the transmitted tag lies in , the decoder recovers exactly.
Proof. By induction on . The intervals of the possible first symbols partition , and the tag lies in , so step 2 selects . After the update the decoder's interval is , the encoder's interval after one symbol, and the tag still lies in . The inductive step repeats the argument inside the rescaled interval, and the renormalization maps applied by both sides are identical, so the registers stay synchronised.∎
Intuition. The decoder is the encoder run as a question-answering machine: "given where the pointer is, which segment is it in?" Each answer is one symbol, and narrowing to that segment zooms in to ask the same question again.
Because the two sides apply the same updates in the same order, the decoder needs no information beyond the tag and the model — and if the model is adaptive, it can update it from the symbols it has already decoded, exactly as the encoder did.
Example 6.16 (Cost of the two termination strategies). A file of symbols is coded at bits/symbol. Compare an EOF symbol of probability with an explicit length header.
Solution. EOF symbol. Coding it costs bits once. But giving EOF probability also scales every other symbol's probability by , costing bits per symbol, i.e. bits over the file. Total: about bits.
Explicit length. An Elias delta code for uses about bits.
Flush. Either way, two extra bits pin the tag.
Sanity check. The file itself occupies bits, so the termination overhead is about of the total — utterly negligible, which is why the choice is made on engineering grounds (streaming favours EOF; random access favours an explicit length). The theorem's " bits" is of the same order, confirming that arithmetic coding's inefficiency is a constant, not a rate.□
6.4Parsing a String into Phrases
Every coder so far has been handed a probability model. Real files arrive without one. A universal compressor must learn the structure while coding and still approach the entropy rate of whatever source produced the data. The Lempel–Ziv family does this with no probabilities at all: it compresses by noticing that text repeats itself.
Definition 6.17 (LZ78 parsing). The LZ78 parsing of a string is the greedy decomposition into phrases in which each new phrase is the shortest prefix of the remaining input that has not appeared as an earlier phrase. Each phrase therefore equals some earlier phrase extended by one symbol, and is transmitted as the pair
Write for the number of phrases produced.
Definition 6.18 (LZW dictionary). LZW (Lempel–Ziv–Welch, 1984) is the variant that keeps the phrases in an explicit dictionary initialised with every single symbol of the alphabet, so that only an index — never a raw symbol — is ever transmitted. Encoder and decoder build identical dictionaries from the code stream alone; the dictionary is never sent.
The two descriptions differ only in bookkeeping, and LZW is what GIF and the Unix compress utility implement. The essential point is shared: the code is a sequence of pointers into text the decoder has already reconstructed.
Theorem 6.19 (How many phrases a string can have). If a string of length over an alphabet of size is parsed into distinct phrases, then
for an absolute constant and all ; that is, .
Proof. The phrases are distinct strings whose lengths sum to , so is at least the smallest possible total length of distinct non-empty strings — which is attained by taking the shortest ones.
First count the short strings. The number of non-empty strings of length at most is
using for .
Let be the largest integer with . Then at most of the phrases have length , so at least of them have length greater than , and since the lengths sum to ,
Maximality of gives , hence . Substituting,
using and . Now split on the size of . If then , and the display gives . If instead , then because for all . Either way the bound holds with .∎
The theorem is the engine of the whole method: it says the number of pointers grows like , so the total cost grows like — a constant number of bits per symbol — and the entire question is what that constant turns out to be.
Intuition. The first time you meet the phrase the you must spell it out. After that you can say "entry 300". The dictionary grows, so later pointers are longer, but the phrases they name grow faster — and that race is what compression is.
A string cannot have too many distinct phrases, because distinct strings have to get longer: there are only strings of length to go around.
Example 6.20 (LZW encoding of a repetitive string). The alphabet is with initial dictionary , ; the next free code is . Encode ABABABA.
Solution. The encoder holds a phrase cur and emits a code only when cur + c is not yet in the dictionary.
cur = "A", read B: "AB" unknown output 1 ("A"), add "AB" , set cur = "B".
cur = "B", read A: "BA" unknown output 2 ("B"), add "BA" , set cur = "A".
cur = "A", read B: "AB" known extend, cur = "AB".
cur = "AB", read A: "ABA" unknown output 3 ("AB"), add "ABA" , set cur = "A".
cur = "A", read B: "AB" known cur = "AB".
cur = "AB", read A: "ABA" known cur = "ABA".
End of input: output 5 ("ABA").
Output stream: — four codes for seven characters.
Sanity check. Every dictionary addition is the phrase just emitted followed by the next input symbol (AB, BA, ABA), so the decoder, which sees the same emitted phrases, can replay every addition. Note the last code, , names a phrase the algorithm learned during this very string — the mechanism by which LZW discovers structure it was never told about.□
6.5Encoding, Decoding, and the Self-Referential Case
Method 6.21 (LZW encoding).
- Initialise the dictionary with the single symbols; set
curto the first input symbol. - For each subsequent symbol
c: ifcur + cis in the dictionary, setcur = cur + c; otherwise output the code ofcur, addcur + cto the dictionary, and setcur = c. - At the end of the input, output the code of
cur.
Method 6.22 (LZW decoding).
- Read the first code and emit its phrase; call it
prev. - For each subsequent code : if is in the dictionary, let
curbe its phrase; otherwise letcurprevprev. Emitcur, addprevcurto the dictionary, and setprevcur.
The decoder runs one step behind the encoder — it adds an entry only after seeing the next code — and that one-step lag creates the only subtlety in the algorithm.
Proposition 6.23 (The exceptional code). A decoder can receive a code that is not yet in its dictionary. This happens exactly when the encoder used an entry it created on the immediately preceding step, and in that case the missing phrase is
so the decoder can always continue.
Proof. Suppose the encoder emits code for a phrase that it added one step earlier. By the encoding rule, the entry added at the previous step was , where is the phrase emitted at the previous step (so at the decoder) and is the input symbol that followed it. But the encoder emits next only if cur grew to , which starts from cur : the symbol immediately after is , and begins with that same symbol only if starts with — i.e. starts with , so . Hence , which the decoder already knows.
No other code can be missing: any emitted for an older entry was added at least two steps earlier, and the decoder is only one step behind.∎
Example 6.24 (Decoding the stream and meeting the exception). Decode with initial dictionary , , next free code .
Solution. Receive 1 emit "A"; nothing to add yet. prev = "A".
Receive 2 phrase "B"; emit "B", add "A"+"B" = "AB" . prev = "B".
Receive 3 phrase "AB"; emit "AB", add "B"+"A" = "BA" . prev = "AB".
Receive 5 not in the dictionary. By the exceptional-code rule the phrase is prev + prev[0] = "AB" + "A" = "ABA". Emit "ABA", add "AB"+"A" = "ABA" . prev = "ABA".
Output: A + B + AB + ABA = ABABABA.
Sanity check. The reconstruction equals the original input ✓, and the decoder's dictionary (AB, BA, ABA) is identical to the encoder's ✓ — built from the code stream alone, with no dictionary transmitted. The exception fired exactly where the proposition predicts: code was created by the encoder one step before it was used.□
Theorem 6.25 (Codelength of LZ78). Transmitting the phrases of an LZ78 parsing, each as an index into the phrases so far plus one symbol, costs at most
which is bits: by the phrase-count theorem , while , so the product is bounded by a constant multiple of . The code therefore spends a bounded number of bits per symbol, and the content of the optimality theorem below is that the constant is exactly .
Proof. There are phrases; the index of the earlier phrase referenced by phrase is at most and so fits in bits if a fixed width is used, and the appended symbol costs bits. Summing over the phrases gives the bound.∎
Theorem 6.26 (Asymptotic optimality of Lempel–Ziv). For any stationary ergodic source with entropy rate , the LZ78 codelength satisfies
Lempel–Ziv therefore attains the source coding bound without being told the distribution: it is universal over the class of all stationary ergodic sources on a finite alphabet.
Proof. We only sketch the argument; the full proof is in Cover and Thomas and is beyond the scope of this chapter. Two ingredients do the work.
Lower bound. is the converse to the source coding theorem: no uniquely decodable code beats the entropy rate.
Upper bound. The key step is Ziv's inequality: for any distinct parsing of into phrases, and for any -th order Markov measure on the source,
with depending only on and . Combining it with the phrase-count theorem shows is asymptotically bounded by the -th order conditional entropy ; the ergodic theorem lets , and that conditional entropy decreases to . Since the codelength is up to lower-order terms, the limsup is at most .∎
Intuition. LZ never estimates a probability. It nevertheless converges to the entropy rate, because repetition is exactly what low entropy means: a source with entropy rate produces about typical strings of length , so within a long enough window, phrases must start repeating, and the repetition rate is governed by .
The dictionary is an empirical model that gets richer the longer you look. It is slower to converge than a well-chosen parametric model — its redundancy decays like rather than — but it needs no choosing.
6.6Limits, Variants, and What Is Used in Practice
The optimality theorem is asymptotic in with an unbounded dictionary. Every real implementation departs from it, and the departures are what distinguish the formats.
- Bounded dictionary. GIF uses -bit codes, i.e. entries. Once full, an implementation either freezes the dictionary (and stops adapting) or emits a CLEAR code that resets it, paying the cost of relearning. Neither matches the theorem, whose conclusion needs .
- LZ77 instead of LZ78. LZ77 (Ziv–Lempel 1977) emits triples (distance back, match length, next symbol) into a sliding window rather than indices into a dictionary of phrases. It is also universal, adapts faster to local statistics, and is what gzip (DEFLATE), zstd, LZMA and Brotli use, always with an entropy coder — usually Huffman or ANS — applied to the literals, lengths and distances.
- Expansion on incompressible data. On a string with no repeats every phrase is new, so and the output is bits, longer than the input. Formats therefore include a "stored" (uncompressed) block type, which caps the expansion at a few bytes per block.
- Convergence speed. LZ's redundancy over the entropy rate decays roughly like , so on a kB file it may be several tenths of a bit per symbol away from . Context-model-plus-arithmetic compressors converge much faster and win decisively on small inputs; LZ wins on speed.
Theorem 6.27 (LZW cannot compress a memoryless uniform source). If are i.i.d. uniform on an alphabet of size , then and every lossless code — Lempel–Ziv included — has expected length at least bits, so the expected compression ratio is at most .
Proof. Uniformity gives and independence gives . The entropy lower bound for uniquely decodable codes applied to the block gives . Since the raw encoding also costs bits, no scheme can do better on average, and any scheme that shortens some inputs lengthens others by the no-free-lunch theorem.∎
Example 6.28 (Why GIF is a poor choice for photographs). A -colour icon with large flat areas and a -colour dithered photograph are both stored as GIF. Explain the difference in file size using the phrase-count bound.
Solution. Icon. Flat runs mean the parsing quickly builds long phrases: a run of identical pixels is covered by phrases of lengths , so phrases cover about pixels and . The cost is about bits instead of — a ratio that improves as the file grows.
Dithered photograph. Dithering deliberately randomises neighbouring pixels, so repeats are rare, or worse, and the cost approaches bits: LZW expands it, and only the stored-block escape keeps the file near its raw size.
Sanity check. The two cases bracket the theorem: the icon is a low-entropy-rate source where repetition is abundant, the dithered image an engineered high-entropy one where the incompressibility theorem applies with . The right tools are respectively PNG (LZ77 + Huffman, with a pixel predictor) and JPEG (lossy, escaping the entropy bound altogether).□
6.7What Universality Means
Every code so far has needed a model: Huffman needs the probabilities, arithmetic coding needs a conditional distribution per symbol, and only Lempel–Ziv managed without. A universal code is one that works for a whole class of sources at once, paying a price that vanishes per symbol. This last part makes the notion precise, exhibits the standard constructions, and proves that the price cannot be driven to zero at finite length.
Definition 6.29 (Redundancy of a code). Let be a class of sources and let be a code on with lengths . For the pointwise redundancy on is
the excess over the ideal codelength for , and the expected redundancy is .
Definition 6.30 (Universal code). A sequence of codes is weakly universal for the class if for every
the entropy rate of ; equivalently for every . It is strongly universal (or minimax) if the convergence is uniform over :
A code is pointwise universal if almost surely under each .
Notice what universality is not. It is not "optimal for the unknown source at finite " — no code is — and it is not a claim about any particular file. It is a statement that the per-symbol overhead of not knowing the source vanishes.
Theorem 6.31 (Codes are probability distributions). Given any uniquely decodable code with lengths , the assignment with is a probability distribution, and . Conversely, for any distribution the lengths define a prefix code.
Consequently designing a universal code is designing a single distribution that is close to every in the class simultaneously, and the redundancy is
Proof. The first claim is Kraft–McMillan plus normalisation; the second is Kraft's converse, as used for the Shannon code. For the redundancy formula, take , so that , and average under :
by the cost-of-the-wrong-model identity. Subtracting gives , and the matching lower bound follows from the entropy bound applied to the code's own induced distribution.∎
This duality is the organising idea of the whole subject: a universal compressor is a single distribution over files that hedges across a class of sources, and its worst-case cost is a divergence.
Intuition. A universal compressor is a packing service that is not told what is in your luggage. It watches the first few items, forms a theory, and keeps revising. The theory is wrong at first, which costs bits — but the number of wasted bits grows like , not like , so the per-item waste goes to zero.
The formal version of "forming a theory" is Bayesian: put a prior on the class of sources, let be the resulting mixture, and the redundancy becomes the cost of the prior.
Example 6.32 (Weak universality of Lempel–Ziv). Which class is LZ78 universal for, in which sense, and what is known about its redundancy?
Solution. Class. All stationary ergodic processes on a finite alphabet.
Sense. Pointwise: almost surely, by the LZ optimality theorem. Pointwise convergence implies weak universality by dominated convergence, the codelength being bounded by per symbol.
Redundancy. Slow. For an i.i.d. or finite-order Markov source the LZ78 redundancy is of order in total, i.e. about per symbol; for that is roughly bits per symbol.
Sanity check. Compare with the total redundancy of a mixture code for a parametric class: at that is about bits in total, versus LZ's . The comparison is fair only where the parametric model is right — LZ pays for covering a vastly larger class, and for asking nothing of the user.□
6.8The Standard Constructions
Three families of universal code recur, and they cover the practical ground.
Integer codes. These are universal for the class of all distributions on with decreasing probabilities, and are the building block for headers, lengths and dictionary indices.
Definition 6.33 (Elias gamma and delta codes). The Elias gamma code writes a positive integer as zeros, followed by the bits of in binary. The Elias delta code replaces the unary prefix by the gamma code of .
Proposition 6.34 (Lengths of the Elias codes). Gamma uses bits and delta uses bits; both are prefix codes, and delta is within of the ideal bits.
Proof. For gamma, the unary prefix of zeros terminated by the leading of the binary expansion tells the decoder how many further bits to read, so the code is prefix-free, and the total is . For delta, the same argument applies with the unary prefix replaced by a gamma-coded length, whose own length is ; the payload contributes the remaining bits. The ratio of the delta length to tends to , since .∎
Mixture and plug-in codes. These are universal for parametric classes, and achieve the best possible redundancy.
Definition 6.35 (Krichevsky–Trofimov estimator). For a binary i.i.d. source of unknown bias, the KT estimator predicts the next symbol after zeros and ones by
and feeding these predictions to an arithmetic coder produces the KT code. It is the Bayesian mixture over the bias with a (Jeffreys) prior.
Theorem 6.36 (KT redundancy). For every , the KT code applied to an i.i.d. binary source of bias has total redundancy
uniformly in — a total overhead, not a per-symbol one, so the per-symbol overhead is .
Proof. We sketch the standard argument. The KT probability of a string with zeros and ones is the mixture with the Jeffreys prior . Laplace's method applied to this integral gives
where is the maximum-likelihood bias, and the first term is at most for the true because maximises the likelihood. Taking expectations under and adding the arithmetic coder's two bits gives the claim. The full argument evaluates the Beta integral exactly; it is carried out in the source-coding literature and we do not reproduce it.∎
Context models. Context Tree Weighting (CTW) mixes KT estimators over all tree-structured context models up to a depth , achieving redundancy for any tree source with states — again a logarithmic total. Prediction by Partial Matching (PPM) is the heuristic cousin that dominated text compression benchmarks before context mixing (PAQ, cmix) and, more recently, neural predictors.
Example 6.37 (Counting the cost of not knowing the bias). A binary file of symbols comes from an i.i.d. source of unknown bias . Compare the ideal length, the KT length, and the length produced by wrongly assuming .
Solution. Ideal. bits/symbol, so bits.
KT. At most bits. The overhead is bits — about bits per symbol.
Wrong fixed model. Assuming a fair coin costs bit per symbol, i.e. bits.
Sanity check. The wrong fixed model throws away bits; the universal coder recovers all but of them. Twelve bits against half a megabit is the practical case for universal coding in one line.□
6.9The Price of Universality
Universality is not free, and the cost has an exact asymptotic form. The intuition is a counting one: a code that must be ready for essentially different sources has to reserve short codewords for the typical set of each, and typical sets of different sources are disjoint.
Definition 6.38 (Minimax redundancy). The minimax redundancy of a class at block length is
the least worst-case excess achievable by any single coding distribution .
Theorem 6.39 (Rissanen's bound for parametric classes). For the class of i.i.d. distributions on an alphabet of size — a parameter family — the minimax redundancy satisfies
More generally, for a smooth -parameter class the minimax redundancy is : every parameter costs half a logarithm. No universal code for such a class can do better, and mixture codes such as KT and CTW attain it.
Remark (On the proof). The upper bound is the mixture argument sketched for the KT estimator, applied with Jeffreys' prior in dimensions; the constant in is the logarithm of the volume of the parameter space in the Fisher metric. The lower bound is Rissanen's theorem, proved by a counting argument: the parameter space contains about distributions that are statistically distinguishable at sample size , and no single can be close to all of them at once. Both halves are beyond the scope of this chapter; we state the result and use it.
Corollary 6.40 (Half a bit per parameter per doubling). Doubling the file length adds bits to the minimax redundancy — so for fixed the per-symbol cost of universality decays like , and vanishes.
Proof. Replace by in the theorem: the redundancy changes by bits. Dividing the total by gives the per-symbol claim.∎
Theorem 6.41 (Most strings are incompressible by any code). For any uniquely decodable code on and any , fewer than a fraction of the inputs receive codewords shorter than bits. In particular, no universal code — however clever, however adaptive — compresses more than a negligible fraction of all files.
Proof. This is the no-free-lunch theorem applied to the encoder, which is injective by unique decodability: at most binary strings have length less than , so at most that many inputs can receive them.∎
The two theorems together delimit the subject. Universality is possible because real data is not uniform over — it lives in the typical set of some low-entropy source — and the only cost of not knowing which source is logarithmic. But the moment the data really is uniform, no amount of adaptivity helps, because the obstruction is counting, not ignorance.
Remark (Kolmogorov complexity: the ultimate universal code). One can define the complexity of a string as the length of the shortest program that prints it on a fixed universal machine. This is universal in the strongest sense — for every computable code — and for a computable source . It is also uncomputable: no algorithm computes , by a diagonal argument closely related to the halting problem. Kolmogorov complexity is therefore the correct theoretical endpoint of this chapter and useless as an engineering target. The practical hierarchy — Huffman, arithmetic, LZ, CTW — is a sequence of computable approximations to an ideal that cannot be reached.
Example 6.42 (Sizing the minimax penalty for a real alphabet). A compressor must handle an unknown memoryless source over the byte values. How many extra bits must it pay on a MB file, and on a kB file?
Solution. Here , so parameters.
1 MB. The symbols are bytes, so . The penalty is
or of the file.
1 kB. : bits bytes, which is of the file.
Sanity check. The penalty grows only logarithmically in while the file grows linearly, so the relative cost falls by a factor of about between the two sizes — which is precisely why compressors have a minimum useful file size, and why archive formats compress many small files as one stream ("solid" archives) rather than separately.□
- Waiting until the end to emit bits. Renormalization emits each bit as soon as it is determined, so memory use is constant and the coder streams. An implementation that computes the exact final interval in rational arithmetic is correct but useless.
- Omitting the E3 (underflow) rule. Without it an interval straddling shrinks below the register precision and encoder and decoder diverge.
- Blaming the coder for poor compression. Arithmetic coding is within two bits of *for the model it is given*. All remaining compression performance is the model's; this is why modern compressors put their effort into context mixing, not into the coder.
- Forgetting to allocate probability to termination. Without an EOF symbol or an explicit length the decoder cannot know when to stop and will happily decode arbitrarily many further symbols.
- Using floating point. Encoder and decoder must perform bit-identical arithmetic; fixed-point integers with a controlled total frequency are mandatory.
- Assuming arithmetic coding is always the right choice. It has higher per-symbol cost than a canonical Huffman decoder, and for nearly uniform alphabets the one-bit Huffman penalty is negligible. ANS (asymmetric numeral systems) now occupies much of this ground, achieving arithmetic-coding compression at table-driven speeds.
- Confusing LZ77 with LZ78/LZW. LZ77 points backwards into the raw text with (distance, length) pairs; LZ78/LZW points into a dictionary of previously created phrases. The distinction matters for memory, for seeking, and for patent history.
- Believing the dictionary is transmitted. It is rebuilt by the decoder from the code stream. Sending it would defeat the purpose.
- Mishandling the exceptional code. An implementation that assumes every received code is already in the dictionary fails on inputs as short as `ABABABA`.
- Expecting compression of random data. The incompressibility theorem forbids it; LZ on random data expands by roughly bits per phrase.
- Forgetting the CLEAR mechanism. With a bounded dictionary and no reset, a compressor that has finished learning one file's statistics carries them, uselessly, into the next region of a heterogeneous file.
- Quoting LZ's optimality without its hypotheses. It is asymptotic, requires an unbounded dictionary, and holds for stationary ergodic sources. None of the three is exactly true of a real file on a real implementation.
- Thinking a universal code achieves the entropy exactly on every file. It achieves ; on short files the term dominates and compression can be negative.
- Confusing universal with optimal-for-the-unknown-source. Rissanen's bound says a strictly positive minimax redundancy is unavoidable at every finite .
- Assuming Lempel–Ziv is the best universal code. It is universal over a far larger class than CTW, and correspondingly slower to converge: against total redundancy on parametric classes.
- Forgetting that the class must be specified. A code universal for i.i.d. sources need not be universal for sources with long memory; "universal" without a class is meaningless.
- Restricting the term to integer codes. Elias codes are the classic examples, but in modern usage a universal *compressor* is the whole model-plus-coder pipeline.
- Believing adaptivity defeats the counting bound. The incompressibility theorem quantifies over every injective encoder. Adaptive, neural or otherwise, almost all strings stay incompressible.