The data that is not a number

The cell nobody filled

Every structure here was measured either on one long repetitive text or on prose cut into short documents. The collection that is both is a two-by-two with one empty corner, and what is in it is not the product of its margins.

Two questions have been asked here about text, and they have never been asked at the same time.

The first is how much does this text repeat, and the structures that answer it — the run-length index, the phrase index — were measured on one long text made of near-identical copies. The second is which documents hold this pattern, and the structures that answer it — the document array, the range minimum, the chain — were measured on prose cut into short pieces.

Those are two cells of a two-by-two. The other two are a single prose text, which is where this collection started, and a repetitive collection of many short documents, which is where a real archive of versioned files actually lives and which nothing here had ever built.

The four cells, and the two measures in eachRuns of the transform and phrases of the parse, per character, on 8,192 characters arranged four ways. The top row is prose and the bottom is 16 near-copies of one base; the left column is one text and the right is that text cut into 16 documents with a separator between them. Everything the repetition strand measured is the bottom left cell and everything the document strand measured is the top right; the bottom right is the one nothing here had filled. Cutting the repetitive text raises r/n from 0.0638 to 0.0768 — 1.20x — and cutting prose raises it from 0.2996 to 0.3053. Those two factors are the subject of the next plate, and they do not come out in the expected order.one text16 short documentsprosecopies of one baseprose, one textr/n 0.2996z/n 0.1273prose, many short documentsr/n 0.3053z/n 0.1301copies of one base, run togetherr/n 0.0638z/n 0.0354one copy per documentr/n 0.0768z/n 0.04188,192 characters throughoutthe outlined cell is the one that was empty
Fig. 1 The same 8,192 characters arranged four ways, with runs of the transform and phrases of the parse per character in each cell. The outlined corner is the one nothing had measured.

What the margins say, and what they cannot

Read across the top row and the effect of cutting prose into documents is small: runs per character move from 0.2996 to 0.3054, phrases from 0.1273 to 0.1302. Read down the left column and the effect of repetition is enormous: runs fall from 0.2996 to 0.0638, phrases from 0.1273 to 0.0354. The first effect is a couple of per cent and the second is a factor of nearly five.

A reader with those two margins would predict the empty cell by multiplying, and would get 0.0651 runs a character. The measured figure is 0.0769. That is 18% over the prediction, which is not a rounding error and is not nothing.

The reason the two effects do not simply compose is that a separator is not a neutral character. It is a symbol that occurs nowhere else in the collection, so it stops a phrase that would have spanned the boundary, and it appears in the transform in a block of its own. Both of those are interactions with the arrangement, and an arrangement is exactly what repetition is.

But the sign of the interaction is not obvious in advance, and this is where the strand stopped being a filling-in exercise. Three effects arrive together and they do not agree about which way to push.

A separator breaks a phrase, which should raise the phrase count on a text whose phrases are long — and a repetitive text is precisely a text whose phrases are long. A separator raises the alphabet, which costs every character of every document a fraction of a bit, and that cost is paid whether the collection repeats or not. And repetition is supposed to be what makes document listing worth doing, because a pattern in the base occurs once in every copy and the whole output-sensitive apparatus exists for patterns that occur far more often than they occur in documents.

Three mechanisms, two of them working against the structures and one of them working for the query. Nothing about the two margins says which wins, and the honest answer is that this had to be built.

The construction is part of the measurement

There is a decision to make before anything can be measured, and making it silently is how a number about one collection becomes a number about collections.

A repetitive collection of many short documents can be built two ways. One is a version history: each document is a near-copy of one base, so the collection is d documents that resemble each other. The other is a long repetitive text cut up: build the copies first, then divide the result into d documents at arbitrary offsets, so a document may straddle a copy boundary and hold a fragment of one copy followed by a fragment of the next.

Those two constructions produce the same characters in a different arrangement. They are not interchangeable, and the repetition measures do not agree about them — which is the reason both are carried through every plate in this strand rather than one being chosen and the choice forgotten.

The version history is the shape a real archive has. A directory of releases, a document under revision, a table of near-duplicate records: in every case the boundary between documents is also the boundary between copies. That coincidence turns out to matter more than anything else in this strand, and it is the subject of two later essays.

The cut-up text is the shape a synthetic benchmark has, because it is what a repetitive corpus taken off a shelf and split becomes. It has no reason to align its boundaries with anything.

Cutting a repetitive text into documents costs it almost nothingRuns per character against the document count, on one fixed text of 8,192 characters cut more and more finely — so nothing moves but the number of separators. The expectation this measurement was made against is that a separator breaks a run, which would make a repetitive collection pay for its document count in the measure it exists to be small in. It does not. Across seven doublings the repetitive line rises by 1.02x and the PROSE line rises by 1.10x — the opposite ordering. In absolute terms the same 127 separators add 19 runs to the repetitive text and 293 to prose. The reason is not in this plate; it is in the characters the documents end with.1101000.1documentsruns of the transform, per characterprose: 1.10xcopies: 1.02x8,192 characters, cutthe control rises further
Fig. 2 One fixed text, cut more and more finely, so nothing moves but the number of separators. The pale line is the same cut applied to prose of the same length.

The cut, with its control beside it

The experiment that isolates the separator is to hold the characters fixed and vary only how many boundaries are dropped into them. Build the repetitive text once; cut it into one document, then two, then four, out to a hundred and twenty-eight; and measure the runs each time.

That design matters and the obvious alternative is wrong. Building a collection of d near-copies at a fixed total length makes the base shorter as d grows, so the text becomes more repetitive and its run count falls — and the plate then shows the cut being free when what it is showing is a different text at every point. A corpus that was not generated records the general version of this: the axis has to be the thing being varied and nothing else.

The control is prose of the same length, cut identically. That is the convention the half of a fall that is the logarithm set: a sweep whose axis could be moving something incidental draws the incidental thing beside it, and the check is two-ended — the control must move, and its movement must account for less than the raw curve.

Across seven doublings the repetitive line rises by a factor of 1.02. The prose line rises by 1.10. The cut costs prose five times what it costs the repetitive collection, which is the opposite of what the phrase-breaking argument predicts, and it is the finding this strand opened with.

The separator is charged where nobody was looking

The mechanism is not in the phrases at all. It is in where a separator’s rows sit.

A separator sorts before every ordinary character, so in the suffix array its d rows are at the very top. The transform characters in those rows are the characters that precede the separators — which is to say the last characters of the documents. Those d characters form a contiguous block of the transform, and a block of the transform costs one run per change inside it.

So the price of cutting a text into documents is the number of distinct characters the documents end with, in the order the separators sort. Not the document count. Not the collection’s size. Not whether the collection repeats.

The separators sort first, so their rows hold the documents' last charactersWhy the cut is nearly free on a repetitive collection. A separator sorts before every ordinary character, so its rows sit at the top of the suffix array — and the transform characters in those rows are the LAST characters of the documents. Those characters form one block of the transform, and a block costs one run per change inside it. At 128 documents a repetitive collection cut at one offset of near-identical copies ends with 6 distinct characters and prose ends with 18. The runs follow: 19 added against 293, which is 0.15 a separator against 2.31. The price of a boundary is the entropy of what precedes it.051015255075100125documentsdistinct characters the documents end with+7+52+162+293+4+-1+9+19prosecopies of one basethe label is the runsthe cut added128 documents0.15 against 2.31 runs a separator
Fig. 3 The characters the documents end with, and the runs the cut added. A repetitive collection cut at one offset of near-identical copies ends with almost one character; prose ends with many.

A version history cut at the same offset of near-identical copies ends every document with almost the same character. At a hundred and twenty-eight documents it ends with six distinct characters, and adds nineteen runs. Prose ends with eighteen, and adds two hundred and ninety-three. That is 0.15 runs a separator against 2.31 — a factor of fifteen — and it explains the whole of the ordering the previous plate showed.

The result is worth stating in the general form, because it is not about documents: the price of a boundary is the entropy of what precedes it. A collection whose documents end predictably pays almost nothing for its boundaries in the run count, and one whose documents end unpredictably pays a run each. That is a property of the collection’s shape rather than of its size, and it is invisible to every account of separators this collection had written down.

The other currency

None of that means the separator is free. It means it is charged somewhere else.

One separator or one for each priced the three joins on prose: running the documents together invents strings no document holds, one shared separator fixes that and raises the alphabet by one symbol, and giving each document its own separator raises the alphabet by d. That third option is what a collection needs if a pattern must not be reported as spanning two documents, and its cost is paid by every character of every document through the width of a packed symbol.

On a repetitive collection the same three joins behave differently in the two currencies, and the gap between them is large.

A separator each is paid in the alphabet, not in the runsThe three joins on a collection of 32 near-copies. Running the documents together costs nothing and invents strings no document contains. One shared separator raises the alphabet from 21 symbols to 22 and the runs by 1.00x — which is to say by nothing. Giving each document its own raises the alphabet to 52, which crosses a power of two and so costs a whole bit on every character of every document: 20.2% on the packed text. It costs 2.9% in runs. The two currencies disagree by more than an order of magnitude, and a collection that needs distinct boundaries should be told which one it is paying in.run together1.00xsigma 21 · 5 bitsone separator1.00xsigma 22 · 5 bitsa separator each1.20xsigma 52 · 6 bitsruns 1.00xruns 1.00xruns 1.03x32 documents of 512 characterspacked bits, against running them together
Fig. 4 The three joins on thirty-two near-copies, priced in packed bits and in runs of the transform. The two currencies disagree by more than an order of magnitude.

One shared separator costs 0.2% in packed bits and nothing at all in runs — the run count actually falls, because the separator’s block is more uniform than the characters it displaced. Distinct separators raise the alphabet from twenty-one symbols to fifty-two, which crosses a power of two, so every character of the collection needs a sixth bit: 20.2% on the packed text. In runs, the same change costs 2.9%.

A collection that needs distinct boundaries should be told which of those two it is paying in, and the answer depends entirely on which structure it is going into. Documents that are not the same length is where the shape of the collection first started deciding a size here rather than merely decorating one. An index built on the entropy of the text pays the first. An index built on the runs pays the second. Quoting one number for “the cost of separators” is quoting a number about a structure that was not named.

What size does to the measures here

The other question this cell was built for is the one about scale. A million characters of the same thing swept size on real prose and found that nearly three quarters of the fall in phrases per character was a logarithm: a shuffle of the same characters — same length, same alphabet, same zeroth-order entropy — fell by 1.70 against the collection’s 2.34, leaving 1.37 that was the arrangement.

That measurement was made on the case the structures are not for. The point of a phrase count is that it is small on a text that repeats, and prose does not repeat in the sense the parse is about.

On a genuinely repetitive collection the fall is the collectionPhrases per character against size, with the axis being the copy count at a fixed base of 2,048 characters — so the arrangement changes and the alphabet does not. The pale line is a shuffle of the same characters: same length, same alphabet, same zeroth-order entropy, no arrangement. It falls by 1.45x across the sweep, which is the logarithm every text pays because z/n is about one over log_sigma n. The collection falls by 4.71x, so what the repetition is actually worth is 3.24x. On real prose the same two-ended measurement left 1.37x; here the control accounts for 30.8% of the raw curve rather than for most of it, which is the difference between a collection that repeats and one that is merely predictable.10⁴0.1charactersphrases of the parse, per charactershuffled: 1.45xthe collection: 4.71x4,111 to 65,551 charactersworth 3.24x after the control
Fig. 5 Phrases per character against the copy count at a fixed base, with a shuffled control. Same length, same alphabet, same zeroth-order entropy, no arrangement.

Sweeping the copy count at a fixed base instead — so the arrangement changes and the alphabet does not — the collection’s phrase count per character falls by 4.71 and the control falls by 1.45. What the repetition is worth, after the logarithm is removed, is a factor of 3.24.

That is the number the structures in this field are actually built on, and it is more than twice the 1.37 the same two-ended measurement left on prose. The two are not in conflict; they are answers to different questions. A collection that merely has predictable statistics gives a phrase count a small correction. A collection that contains copies of itself gives it most of what it has.

What the query was supposed to get out of it

The third expectation is the one the deferral naming this cell was mostly about: the one where a compressed index and a large document count meet. The meeting is supposed to be productive. The output-sensitive listing apparatus — the chain, the range minimum, the answer-so-far bitmap — exists because reading every occurrence costs the occurrences, and it wins exactly when a pattern occurs far more often than it occurs in documents.

The crossing that never arrives measured that on a collection of two thousand short captions and found the crossing sitting at 10.8 occurrences a document against a measured 1.04. The apparatus cost 2.64 times the index it sat on and won nothing, because a phrase in prose is rare and a collection of short prose documents holds each phrase about once.

A repetitive collection looks like the opposite case by construction. A pattern in the base occurs once in every copy, so on thirty-two copies it has thirty-two occurrences, and thirty-two is comfortably past the crossing.

Repetition does not give the listing apparatus anything to doOccurrences per document for two patterns, in three collections of 32 documents. The pale bar is the collection's own most frequent 6-character string and the dark bar is a string drawn from one of its documents, which is what a reader asks for. On the drawn pattern all three cells read within a tenth of each other — prose 1.87, one copy per document 1.84, copies cut across documents 1.88. In a collection of versions the copies and the documents are the same partition, so a phrase of the base occurs once in each of d documents: d occurrences and d documents, and a ratio of one. The apparatus needs a pattern that repeats INSIDE a document, and repetition of this kind does not provide one.prose, many short documents2.38 most frequent1.87 drawn from a documentone copy per document4.78 most frequent1.84 drawn from a documentcopies cut across the boundaries2.91 most frequent1.88 drawn from a documentoccurrences per document holding the pattern32 documents · 6-character patternsall three within a tenth on the drawn pattern
Fig. 6 Occurrences per document for two patterns in three collections: the collection’s own most frequent six-character string, and a string drawn from one of its documents.
On many short documents there is nothing to be output-sensitive aboutThe collection's own most frequent 6-character strings, in 2,214 real documents of 132,166 characters. The upper line is what a scan over the occurrences reads and the lower is the size of the answer — and on this collection they are the same line, because a pattern that occurs 543 times occurs in 522 different documents. Occurrences per document is 1.04. Output-sensitive document listing exists to win when a pattern occurs many times inside each of a few documents, which is what a version history looks like and is not what a collection of short documents looks like at all.0200400200400occurrences of the patternrows read, and documents in the answerrows readdocuments in the answertwo thousand short documents · 2,214 documents1.04 occurrences a document
Fig. 7 The crossing the apparatus has to beat, measured on a collection of short prose documents: where reading every occurrence stops being cheaper than walking a range structure.

It is not the opposite case. For a pattern drawn from one of the documents — which is what a reader asks for — prose reads 1.87 occurrences a document, a versioned collection reads 1.84, and copies cut across document boundaries read 1.88. All three within a tenth of each other.

The arithmetic is one line once it is seen. In a collection of versions the copies and the documents are the same partition. A phrase of the base occurs once in each copy, and each copy is one document, so the pattern has d occurrences spread over d documents and the ratio is one. Repetition of that kind cannot make a pattern dense inside a document, because it is repetition between documents and the ratio the apparatus turns on is a ratio within them.

Only the collection’s own most frequent string separates the three cells at all, at 4.78 occurrences a document against prose’s 2.38 — and the most frequent six-character string of an English-like text is a fragment of a common word rather than anything a reader would search for.

That is a retraction of the sentence that named this cell, and it is worth as much as a number would have been. It also says where to look instead: the apparatus needs a pattern that repeats inside a document, which is a third collection shape and not this one.

What each index notices

The last thing this cell is for is the comparison the field exists to make. Three compressed indexes are built here, and they are proportional to three different things.

One index does not notice the repetition and two of them are made of itThree compressed indexes on 8,192 characters, against how many near-copies the text is made of — which in this cell is also the document count, because each document is one copy. The entropy-bounded FM-index is flat at about 6.4 bits a character throughout: the transform is a permutation, so its zeroth-order entropy is the text's, and no amount of repetition changes it. The run-length index falls from 18.5 to 3.4 and the phrase index from 9.1 to 1.6. At one copy the two repetition-aware structures are the LARGEST of the three, by a factor of 2.88x; the crossing is what decides which structure a collection wants, and it is a property of the collection rather than of the field.051015204060documents, which here is also the copy countbits a characterFM-indexrun-length indexphrase index8,192 characters throughout2665 runs down to 427
Fig. 8 Bits a character for three indexes over the same 8,192 characters, against how many near-copies the text is made of — which in a versioned collection is also the document count.

The entropy-bounded FM-index is flat at about 6.4 bits a character however many copies the collection holds. That is not a defect and it is not a surprise: the Burrows–Wheeler transform is a permutation of the text, so its zeroth-order entropy is the text’s, and a structure whose size is n·H₀ cannot see a copy. The entropy that cannot see a copy is the essay that measured that to fifteen decimal places, and what is still proportional to n is the one that found which parts of a run-length structure keep a term in the text’s length anyway.

The run-length index falls from 18.5 bits a character to 3.4 and the phrase index from 9.4 to 1.6. Both are made of the repetition rather than merely tolerant of it.

And at one copy — an ordinary text with no repetition in it at all — the two repetition-aware structures are the largest of the three, the run-length index by a factor of 2.9. The collection decides which index is small made that argument on one long text; it holds here with the document count folded in, and the crossing is a property of the collection rather than of the field.

The three lines cross, and where they cross is the decision. That crossing is the reason the collection decides which index is small is a sentence about a corpus rather than about a data structure, and it is the reason this cell had to be measured at several document counts rather than at one.

There is one further thing the plate says that is easy to read past. The document count and the copy count are the same axis here only because the collection is a version history. Cut the copies across the boundaries instead and the two come apart: the copy count stays where it was and the document count moves freely, and the index sizes follow the first and not the second. A structure proportional to the runs does not know how many documents there are; it knows how much of the text is a copy of earlier text. That is a nice property and it is also a warning, because a plate that sweeps documents on a versioned collection is sweeping two things at once and can be read as saying either.

What this cell turned out to be

The two-by-two is filled, and the corner is not what its margins predicted in any of the three respects the header of this strand expected.

The separator does not break the repetition, because its cost is the entropy of the document endings and a versioned collection’s endings are nearly constant. The alphabet cost is real, is large, and is paid in a currency that has nothing to do with repetition. And the third expectation — that repetition would finally give the document-listing apparatus something to do — is the subject of one copy per document is one occurrence per document, and it comes out against the sentence that named it.

What survives is a rule about measurement rather than about text. A two-by-two whose margins are known is not a two-by-two whose cells are known, and the interaction is where the mechanism is. Every one of the three effects above turned out to be charged somewhere other than where the argument for it put it, and in each case the relocation was found by building the cell rather than by reasoning about the edges.

What this makes readable

Essays that name this one as a prerequisite.

Named alongside this one

Essays reaching for the same objects. Nobody chose these; they are what the concept index makes visible.

What links here

Every essay whose body links to this one.

The objects this essay names

Each one links to every other essay that touches it.

Alphabet sizeBurrows-wheeler runsCorpusDocument arrayDocument collectionMeasurement designOutput-sensitivePhrase countRepetitionSelf-indexSeparator