The floors

The order the column cannot see

A sort of rotations by their first four characters leaves ranges that agree on those four, and the full Burrows–Wheeler transform reads deeper to order them. Given a budget of characters below the transform's, spending it on the ranges whose rotations are preceded by the most different characters was predicted to reach within a hundredth of a bit at two thirds of the transform's reading — and spending it on the longest agreements, as the transform does, to waste it. The price was impossible: the four-character sort alone reads 76% of what the transform reads. The ranking was right on average, and right for a reason that makes the budget unnecessary: a range whose rotations are all preceded by one character writes the same run into the output in any order. Skipping every such range writes the transform's column exactly, on all sixteen streams, and reads 11% less on technical writing — up to 19% on the stream with the longest repeats.

The deepening the sort was already doing tried to save the Burrows–Wheeler transform some of its reading. The transform sorts every rotation of a text completely, reading as many characters of each as it takes to tell it from its neighbours, and its output is the last column of that sorted list: the character before each rotation. A cheaper sort orders rotations by their first kk characters only and leaves rotations that agree on those kk in the order of their positions. The page deepened that cheaper sort only inside ranges whose contexts repeat at twice the depth, and it recovered the transform’s bits on every stream. It read more characters than the transform to do it, 74.5 a symbol against 69.4 on technical writing, because a comparison sort of rotations already reads deep only where rotations agree. The transform was the adaptive sort.

Its closing section changed the question. A sort that must stop somewhere, because its reading is capped or because it runs a fixed number of passes, has a budget, and the question is where to spend it. The transform spends wherever rotations agree, whether or not their order changes the output. But a range of rotations all preceded by the same character writes the same run into the last column whatever order it is in, and reading through it buys nothing. The proposal compared two ways of spending a budget on the ranges a sort by four characters leaves. One takes the ranges whose rotations agree longest, as the transform would. The other takes the ranges whose rotations are preceded by the most different characters, which is what the output’s bits depend on. It predicted that on technical writing the second would reach within a hundredth of a bit of the transform at two thirds of the transform’s reading. It named one way that could fail: counting the preceding characters in a range might cost as much reading as the deepening saves.

Ranges, prices and two orders of spending

Each stream is 8,192 characters, eight streams from a corpus of essays about algorithms and eight from a corpus of technical writing about instrumenting programs, the streams every essay on these sorts has used. Each is first sorted as rotations by their first four characters, ties broken by position. Every maximal run of two or more rotations that share those four characters is a range, about 1,400 of them a stream. Deepening a range means sorting it completely, as the transform would, reading from the fifth character on, and its price is the number of characters that sort reads. A budget is stated as a share of what the transform reads beyond the four-character sort.

Longest agreement first takes ranges in order of how many characters a rotation the transform reads in them, deepest first, and deepens each whose price still fits what is left of the budget. It is told those depths free, which is generous to it: finding out how far a range’s rotations agree is the reading. Most different first takes ranges in order of how many different characters precede their rotations, the largest first, ties by size. It never deepens a range preceded by one character, and it pays one read a rotation to count the preceding characters. That charge is the failure the proposal named.

Bits a symbol are move-to-front followed by zeroth-order entropy, the coder the transform that emits nothing introduced, so the transform’s own bits are the target and the loss is measured above them.

Two ranges, side by side

Two ranges a four-character sort leaves in technical writing: 3 rotations that agree for about 195 characters, all preceded by "m", which write the same run into the last column in any order and cost the transform 1,168 reads to put in order; and 5 rotations preceded by 3 different characters, whose order the output depends onRotations of one stream of the technical corpus, in the transform's order, with the character before each (the one the last column records) and the first thirty characters of the rotation, spaces shown as dots. First range: "m" id j hi if a branch sites merg; "m" id j hi if a branch sites merg; "m" id j hi if a branch sites merg. Second range: "i" s measurable here with a media; "e" s merge a cmp j i buf k a get ; "e" s merge a cmp j i buf k a get ; "e" s merge a cmp j i buf k a get ; "a" s merge in time and differs on.preceded by one character: 3 rotations, 1,168 characters to sortmid·j·hi·if·a·branch·sites·mergmid·j·hi·if·a·branch·sites·mergmid·j·hi·if·a·branch·sites·mergpreceded by 3 characters: 5 rotations, 794 characters to sortis·measurable·here·with·a·mediaes·merge·a·cmp·j·i·buf·k·a·get·es·merge·a·cmp·j·i·buf·k·a·get·es·merge·a·cmp·j·i·buf·k·a·get·as·merge·in·time·and·differs·onleft column: the character the transform writesone stream of technical writing
Fig. 1 Two ranges a four-character sort leaves in one stream of technical writing, in the transform’s order, each rotation shown with the character before it. Three rotations that agree for about 195 characters, every one preceded by “m”, costing the transform 1,168 reads to order. Five rotations preceded by three different characters, costing 794.

The first range is three copies of one line of a program listing, all preceded by “m”, and the transform reads 1,168 characters to put them in an order that writes “mmm” into the last column, which is what any order writes. It is the long repeat that the repeats a context cannot see past found costing the four-character sort its bits on technical writing. A long repeat is exactly where the transform reads deepest, because its rotations agree for so long that a comparison has to go 195 characters before it finds a difference. All of that reading decides the order of three identical characters.

The second range is the other kind. Its rotations begin with “s merge” or “s measurable”, and they are preceded by “i”, “e” and “a”. Here the order matters: it decides whether the three "e"s sit together, where move-to-front codes them as small numbers, or are split by the others. This is the reading that buys bits. The proposal’s ranking says to spend on the second kind first and never on the first, and the plate shows why on one stream before any budget is set.

The prediction’s price, and the curve

At half the transform's deep reading, spending it on the ranges preceded by the most different characters loses 0.0062 bits a symbol on technical writing where spending it on the longest agreements loses 0.0216; the first reaches the transform's bits outright at 62.0 characters a symbol, where the transform reads 69.3Means over eight streams of 8,192 characters for each corpus. Bits a symbol above the full transform's, after move-to-front and zeroth-order entropy, against characters read a symbol including the four-character sort, at budgets of 0%, 10%, 20%, 33%, 50%, 67%, 80%, 100% of the transform's reading beyond the fourth character. the corpus of technical writing: four-character sort 0.0322 bits above at 52.8 characters; longest agreement first 0.0322 at 52.8, 0.0320 at 54.5, 0.0307 at 56.1, 0.0255 at 58.3, 0.0216 at 61.1, 0.0127 at 63.9, 0.0071 at 66.0, 0.0000 at 68.8; most different first 0.0322 at 53.7, 0.0275 at 54.5, 0.0204 at 56.1, 0.0140 at 58.3, 0.0062 at 61.1, 0.0000 at 62.0, 0.0000 at 62.0, 0.0000 at 62.0; the transform reads 69.3. the corpus of essays: four-character sort 0.0148 bits above at 53.5 characters; longest agreement first 0.0148 at 53.5, 0.0145 at 54.6, 0.0141 at 55.6, 0.0112 at 57.0, 0.0067 at 58.8, 0.0020 at 60.6, 0.0002 at 61.9, 0.0000 at 63.7; most different first 0.0148 at 54.3, 0.0146 at 54.6, 0.0138 at 55.6, 0.0103 at 57.0, 0.0041 at 58.8, 0.0001 at 60.3, 0.0000 at 60.4, 0.0000 at 60.4; the transform reads 64.0.the corpus of technical writing0.000.010.020.0355606570the corpus of essays0.000.010.020.03556065characters read a symbolbits a symbol above the transformolive: longest first · dark: most different · green: transformeight streams of 8,192 characters eachrotations first sorted by four characters
Fig. 2 Bits a symbol above the transform against characters read a symbol, at budgets from nothing to all of the transform’s reading past the fourth character. Technical writing: the four-character sort 0.0322 bits above at 52.8 characters; at half the budget, most different first 0.0062 at 61.1 and longest agreement first 0.0216; most different first reaches the transform at 62.0, the transform reads 69.3. Essays: 0.0148 above at 53.5; at half, 0.0041 and 0.0067; most different first reaches it at 60.4 of 64.0.

The four-character sort alone reads 52.8 characters a symbol on technical writing, 76% of the transform’s 69.3, so the prediction’s price of two thirds of the transform’s reading could not be met by any spending. The proposal priced the deep reading as if it were most of the transform’s work. It is a quarter of it. A comparison sort of 8,193 rotations makes about 96,000 comparisons, every one reads at least one character of each rotation, and most read a few. The first four characters of each comparison are three quarters of all the reading. The order inside a tie found a four-character sort reading 63% of the transform’s characters on its streams and coding slightly better than the transform. The deep reading this page is about is the remainder.

Within that remainder, the ranking is right on average. At half of the deep reading, spending it on the ranges preceded by the most different characters leaves the output 0.0062 bits a symbol above the transform on technical writing. Spending it on the longest agreements leaves it 0.0216 above, three and a half times as much, and a hundredth of a bit is not reached until four fifths of the budget is spent. On the essays, where repeats are fewer and shorter, the two policies are closer, 0.0041 against 0.0067, because there is less long agreement for the transform’s order to waste its reading on. A gap of 0.0026 bits a symbol between two means of eight streams is small beside the spread a result the size of its own noise found between streams of this kind, a standard deviation of 0.011 in one sort’s lead over another, so on the essays the ranking is suggested rather than shown. On technical writing the gap is six times larger.

The most-different policy also stops spending. Past two thirds of the deep reading it has deepened every range preceded by more than one character and has nothing left to buy. It reaches the transform’s bits at 62.0 characters a symbol on technical writing and stays there. The failure the proposal named did not happen: counting the preceding characters costs 0.9 characters a symbol, about a ninth of what skipping saves.

Stream by stream the ranking is a lean, not a law: at half the deep reading, most different first loses less on 5 of eight technical streams and 5 of eight essay streams, and its lead in the means comes from the technical streams with long repeats — 0.0929 against 0.0075 bits a symbol on the most repetitive — where longest first spends the budget on themBits a symbol above the transform on each stream with 50% of the transform's reading past the fourth character spent, longest agreement first against most different first. essays 1: 0.0078 and 0.0071; essays 2: 0.0040 and 0.0068; essays 3: 0.0033 and 0.0043; essays 4: 0.0047 and -0.0007; essays 5: 0.0140 and 0.0073; essays 6: 0.0056 and -0.0015; essays 7: 0.0113 and 0.0060; essays 8: 0.0030 and 0.0037; technical 1: 0.0039 and 0.0102; technical 2: 0.0929 and 0.0075; technical 3: 0.0310 and 0.0023; technical 4: 0.0029 and 0.0038; technical 5: 0.0041 and 0.0040; technical 6: 0.0074 and 0.0096; technical 7: 0.0040 and 0.0036; technical 8: 0.0263 and 0.0087.0.000.020.040.061234567812345678essaystechnical writingbits a symbol above the transformolive: longest agreement first · dark: most different first50% of the deep reading
Fig. 3 Bits a symbol above the transform on each stream at half the deep reading, longest agreement first against most different first. Technical writing: most different first loses less on five streams of eight, and on the second stream 0.0075 against 0.0929. Essays: five of eight; on two essay streams the partly deepened sort codes slightly better than the transform.

Stream by stream the ranking is a lean rather than a law: at half the deep reading, most different first loses less on five of eight technical streams and five of eight essay streams. Its lead in the means comes from three technical streams with long repeats, where longest first spends its whole budget ordering the repeats: on the second stream it is 0.093 bits a symbol above the transform against 0.0075. On the streams without long repeats, the two policies trade places by a few thousandths of a bit. On two essay streams the half-deepened sort even codes a little better than the transform, the effect the order inside a tie found when a sort by four characters beat it: an order that is not the transform’s can cluster the column slightly better by chance, and averages hide it.

What the longest-first policy bought with its first third

The longest-agreement policy is what a sort does when it treats depth as the measure of difficulty, and the plates show what that buys. With a third of the deep reading to spend on technical writing, it deepens the ranges the transform reads deepest, and 55% of what it spends goes on ranges preceded by one character, whose order the output never sees. On the essays the share is 42%. Its curve stays flat at first for exactly that reason: the first characters it buys are the most expensive in the stream and the least useful, three copies of a line of code ordered among themselves.

The most-different policy spends its first third only on ranges whose order can change the column, starting with those preceded by the most different characters, where there are the most arrangements for the order to choose among. Its curve drops fastest there. Whether a range preceded by six characters is really worth more bits a read than one preceded by two was not measured separately; the ranking needs only that a range preceded by one is worth nothing, and that part is exact.

Neither policy is told anything the sort could not find cheaply. The preceding characters of a range are known the moment the range is: they are the characters at one position before each rotation, read once. The depth of a range’s agreement is not known until it has been read. A sort with a budget can rank by the first for less than a character a rotation, and it cannot rank by the second at all without spending the budget it was trying to allocate.

Skipping is exact, not approximate

The curve reaches the transform’s bits, and that is not a coincidence of averages. A range whose rotations are all preceded by the same character contributes one run of that character to the last column, of the range’s length, at the range’s position, whatever order its rotations are put in. The four-character sort has already put the range in the right place among the other ranges, because ranges are separated by their first four characters. So sorting such a range changes nothing the transform outputs. A sort that deepens every range preceded by two or more characters, and leaves every range preceded by one in position order, writes the transform’s last column character for character. On all sixteen streams it does.

What a reordering costs to undo found that a reordering is only worth its clustering if undoing it is free, and the order inside a tie found that whether a cheaper sort is free to undo depends on how it orders its ties. The skipping sort sidesteps both questions. Its column is the transform’s character for character, so the transform’s own inverse reconstructs the text from it, and nothing about its ties has to be undone. The rotations inside a skipped range are out of order, but no character of the output can tell.

Where the transform’s deep reading goes

Half the transform's deep reading is spent ordering rotations that will write the same column in any order: ranges preceded by one character take 48% of its reading past the fourth character on technical writing and 40% on the essays, at every depth — not mainly in the long repeatsFor ranges left by the four-character sort, binned by the characters a rotation the transform reads past the fourth, the transform's reading a symbol in the bin and the share of that reading in ranges preceded by one character. Technical writing: 0–2 characters, 0.27 a symbol, 50% preceded by one; 2–4 characters, 0.87 a symbol, 47% preceded by one; 4–8 characters, 2.59 a symbol, 45% preceded by one; 8–16 characters, 4.13 a symbol, 44% preceded by one; 16–32 characters, 3.18 a symbol, 48% preceded by one; 32+ characters, 4.94 a symbol, 53% preceded by one. Essays: 0–2 characters, 0.30 a symbol, 50% preceded by one; 2–4 characters, 0.99 a symbol, 45% preceded by one; 4–8 characters, 2.85 a symbol, 41% preceded by one; 8–16 characters, 4.55 a symbol, 40% preceded by one; 16–32 characters, 1.48 a symbol, 36% preceded by one; 32+ characters, 0.00 a symbol, 0% preceded by one.characters a symbol the transform reads hereshare of it preceded by one character0–2 deep2–4 deep4–8 deep8–16 deep16–32 deep32+ deep50%upper bar: technical writing · lower: essaysdepth: characters a rotation past the fourth
Fig. 4 The transform’s reading past the fourth character, by how deep it reads in a range, and the share of that reading in ranges preceded by one character. Technical writing: 50%, 47%, 45%, 44%, 48% and 53% from the shallowest bin to the deepest. Essays: 50%, 45%, 41%, 40% and 36%. Overall, 48% on technical writing and 40% on the essays.

Ranges preceded by one character take 48% of the transform’s reading past the fourth character on technical writing and 40% on the essays, and the share is nearly the same at every depth. The proposal’s account said the waste would sit in the long repeats, where rotations agree for dozens of characters and are mostly preceded by one character. It is there, 53% of the reading in ranges read more than thirty-two characters deep, but it is just as much in ranges read two to four characters deep. Half the ranges of every depth are preceded by a single character.

The reason is that most of a text’s four-character contexts are followed by one of a handful of characters and preceded by one of a handful too, and in a stream of 8,192 characters a context that occurs only two or three times is often preceded by the same character every time: " the" after a space, “tion” after “a”. Those ranges are shallow and numerous. A long repeat is a range of the same kind in which the agreement simply goes on longer. The transform cannot tell them apart before reading, because it does not look at the characters before its rotations at all until it writes them.

Where a context stops naming the letter before counted, in one pass and with no sorting, the share of positions whose kk characters fail to decide the character before them. That count was a measurement of exactly these ranges, from the other side. A range whose preceding characters are all one is a context that has already named the letter before it, and no deeper sort of it can change a bit.

Stream by stream

On every one of sixteen streams, skipping the ranges preceded by one character writes the transform's column exactly and reads less: from 5% less to 19% less, the largest on the stream with the longest repeats, where the transform reads 89.5 characters a symbol and the skipping sort 72.4Characters read a symbol on each stream: the four-character sort, the sort that deepens every range preceded by more than one character (including one read a rotation to count the preceding characters), and the full transform. essays 1: 53.8, 61.0, 64.2; essays 2: 53.9, 61.2, 64.7; essays 3: 53.1, 59.7, 63.2; essays 4: 53.8, 61.3, 66.6; essays 5: 53.4, 59.7, 62.7; essays 6: 53.4, 60.0, 63.7; essays 7: 53.4, 60.0, 63.7; essays 8: 53.3, 60.2, 63.5; technical 1: 53.4, 61.4, 67.0; technical 2: 53.3, 72.4, 89.5; technical 3: 52.7, 64.2, 73.9; technical 4: 52.6, 59.9, 65.7; technical 5: 53.0, 60.4, 66.9; technical 6: 52.8, 60.0, 65.6; technical 7: 52.5, 58.4, 62.0; technical 8: 52.6, 59.1, 64.2.03060901234567812345678essaystechnical writingcharacters read a symbolpale: transform · dark: skipping one-preceder ranges · olive tick: four characterssame column, every stream
Fig. 5 Characters read a symbol on each of sixteen streams: the four-character sort, the sort that skips ranges preceded by one character, and the transform. Essays: the skipping sort reads 5% to 8% less than the transform. Technical writing: 6% to 19% less; on the second stream the transform reads 89.5 and the skipping sort 72.4.

On every one of the sixteen streams the skipping sort writes the transform’s column and reads less: 5% to 8% less on the essays, 6% to 19% less on technical writing, the most on the stream with the longest repeats, where the transform reads 89.5 characters a symbol and the skipping sort 72.4. That stream is the one the first plate’s two ranges came from, where a line of a program occurs three times over, and its repeats are the deepest reading in the study. A repeated line is preceded each time by whatever came before it, and when the repeat is long the thing before it is usually repeated too.

The saving tracks repetition, as the earlier page’s loss did. Where the four-character sort lost most to the transform, the transform read most past the fourth character, and the skipping sort saves most of that reading. Where text barely repeats, as in the essays, the transform’s deep reading is small to begin with, and skipping half of it saves a twentieth of the whole.

What a budget was for

The proposal treated a budget as the constraint and the ranking as the answer. The measurement found the ranking more useful than the budget. With the ranking alone, the budget question for half the ranges is settled before any reading: preceded by one character, spend nothing. For the other half the budget question remains, and there the ordering by preceding diversity still helps, as the curve’s first half shows. But a sort with no budget at all gets the transform’s column for 89% of its reading on technical writing and 94% on the essays, and needs no knob.

That is the shape of several results about this transform. The deepening the sort was already doing found that a cleverer stopping rule could not beat the comparison sort, because the comparison sort’s own reading already adapted to the text. This page finds that the comparison sort adapts to the wrong thing. It reads until it can tell two rotations apart, which is a question about the rotations, while the output only asks a question about the characters before them. A sort that asks the output’s question once per range reads less and writes the same.

Three things the counts assume

Reading as the cost. Every number here is characters compared, which is the cost model of a comparison sort over rotations. The transform is usually computed from a suffix array, the structure an index larger than what it indexes priced at nearly four times its text, built by doubling or by induced sorting, whose costs are passes over the text rather than comparisons. A doubling construction could skip a range preceded by one character at any round, which would save rounds rather than reads. That was not built.

One depth for the test. The preceding characters are counted once, at four characters. A range preceded by three different characters that is deepened splits into sub-ranges, and many of those will be preceded by one character each. A sort that applied the test again at every split would skip more. The measurement applied it only at the top.

Move-to-front and entropy. The column is identical to the transform’s, so its bits under any coder are identical too; the exactness does not depend on the coder. The budgeted curves do, since a column that differs from the transform’s in a few places can cost more or less under another second stage.

Still open: the test applied at every split

The skipping sort asks its question once, of the ranges a four-character sort leaves, and then sorts every remaining range completely. But a range that is deepened becomes a set of smaller ranges at each further character, and each of those can be asked the same question. A range of twelve rotations preceded by “e”, “e”, “e”, “i” and eight "s"s splits at the fifth character into, perhaps, a sub-range of eight all preceded by “s” and a few others, and the eight need no further reading. A multikey sort that partitions on one character at a time could ask at every partition whether the characters before its rotations are all one, and stop the moment they are.

The measurement that follows builds that sort, a three-way partition on one character at a time that drops any partition whose preceding characters agree, and counts its reading against the transform’s and against the skipping sort’s on the same sixteen streams. The prediction is that it reads 20% less than the transform on technical writing and 12% less on the essays. Every deep range that is not preceded by one character at the top still contains sub-ranges that are, and those sub-ranges hold most of its deep reading. It could fail on the partitioning itself. A multikey sort reads each character once per partition rather than once per comparison, and if its reading on the shallow ranges is greater than the comparison sort’s, the stopped sub-ranges may only pay for the change of sort. The question is how much of the transform’s reading is spent on order that its output cannot see, once the question is asked everywhere rather than once.

Named alongside this one

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

The objects this essay names

Each one links to every other essay that touches it.

Bits per symbolBurrows-wheeler transformContext modelCorpusEntropyHonest limitMeasurement designMove to front