Structures

Bits and steps on one frame

The size falls from ninety-nine per cent to eighty-six as the sampling thins, and the walk to a sampled position rises from two and a half steps to sixty-four. Neither line is the answer; the answer is a point on the pair.

A self-index’s sampling rate is one number and it moves two things in opposite directions.

Sample densely and the index is large and a locate is fast. Sample sparsely and the index is small and a locate walks.

Every result in this strand is a function of that dial, so the strand’s last plate is both quantities against it.

Bits paid and steps spent, against the one dial that moves bothThe whole structure's size as a share of the plain bidirectional index, and the LF steps one occurrence costs, on the same frame and against the same parameter. The size falls from 78.0% to 84.7% as the sampling thins, and the walk to a sampled position rises from 1.5 steps to 67.5. Neither line is the answer on its own: a reader choosing a sampling rate is choosing a point on this pair, and a plate showing only the first reports a structure that gets better forever. The two operation savings this strand measures move neither line, which is what "orthogonal" means here and is why they compose with this and not with each other.020406080255075100125one sampled position in every …of the plain index, per centsize: 84.7%67.5 steps16,384 characters · 8-character patternssize falls, the walk lengthens
Fig. 1 The structure’s size as a share of the plain bidirectional index, and the LF steps one occurrence costs, on one frame and against the same parameter.

The two lines

Size, as a share of the plain bidirectional index at the same rate: 99.5% at one in four, falling to 86.3% at one in a hundred and twenty-eight.

Steps to a sampled position, per occurrence: 2.5 at one in four, rising to 63.6 at one in a hundred and twenty-eight.

The size falls by 13 percentage points and the walk lengthens by a factor of twenty-five.

Why the size line is nearly flat

The share is nearly flat because it is a share of a structure that is also shrinking. Both indexes get smaller as the sampling thins; the improved one gets smaller faster.

In absolute terms the improved index goes from 157,696 bits at one in four to 80,743 at one in a hundred and twenty-eight — a factor of two.

So the plate is showing a relative saving that grows from a half per cent to fourteen, on top of an absolute size that halves. Two different things falling, and the line drawn is the ratio.

That choice is worth defending because the alternative is misleading. A plate of absolute sizes against the sampling rate would show two lines converging steeply and would say nothing about what the improvements are worth — the dominant effect would be the sampling, which is a parameter rather than a result.

Why the step line is exactly what it is

A locate walks a row backwards by LF steps until it reaches a sampled one. The samples are at every s-th text position, so the expected walk is s/2 and the worst is s − 1.

Measured: 2.5 at s = 4, 63.6 at s = 128. Both are close to s/2 and slightly above it, because the measurement averages over occurrences rather than over rows and the occurrences of a pattern are not uniformly distributed in the text.

That the line follows s/2 is a confirmation rather than a finding, and it is worth confirming: a walk that did not follow the sampling gap would mean the sampling is not doing what its account says.

Every occurrence at the same price is where this collection established the per-occurrence cost of a locate, and this is the same measurement inside a different structure.

Bits paid and steps spent, against the one dial that moves bothThe whole structure's size as a share of the plain bidirectional index, and the LF steps one occurrence costs, on the same frame and against the same parameter. The size falls from 78.1% to 84.7% as the sampling thins, and the walk to a sampled position rises from 1.5 steps to 67.5. Neither line is the answer on its own: a reader choosing a sampling rate is choosing a point on this pair, and a plate showing only the first reports a structure that gets better forever. The two operation savings this strand measures move neither line, which is what "orthogonal" means here and is why they compose with this and not with each other.020406080255075100125one sampled position in every …of the plain index, per centsize: 84.7%67.5 steps16,384 characters · 8-character patternssize falls, the walk lengthens
Fig. 2 The same pair on a twenty-six letter alphabet, where the size share is flatter because the wavelet tree is a larger part of the structure.

The alphabet flattens the size line without touching the step line, which is worth a sentence because it says which of the two quantities is about the data.

The steps depend on the sampling gap and on nothing else: s/2, on any text over any alphabet. A locate’s walk is a property of the sampling policy.

The size share depends on how large the locating apparatus is relative to the rest, and the rest is dominated by the wavelet tree, which grows with the alphabet’s entropy. So on a larger alphabet the same apparatus is a smaller share and the improvements are worth less proportionally.

On DNA the reverse holds sharply: a four-symbol wavelet tree is small, the locating apparatus is most of the index, and this plate’s size line would fall much further across the same dial.

The convention

This collection’s habit is stated once and applied here: both currencies on one frame, when a change trades. Two plates several pages apart is how a trade gets reported as a win.

The habit came out of the half-index strand, where a saving of bits could be spent on a denser sampling and the two facts were in different essays — so a reader could take away “the structure is a sixth smaller” without the accompanying “or the same size and five times faster”, which is the more useful sentence.

Applying it here has a small cost worth noting. The two quantities are in different units and on different scales, so one of them needs a second axis, and a second axis is a thing that can be misread. The alternative — normalising both to a share of something — makes the step count a share of a maximum nobody chose.

Two axes it is, with the size axis on the left as a percentage and the steps drawn against their own maximum on the right.

There is a third quantity that could have been on the frame and is not, and leaving it off was a decision rather than an oversight: the number of occurrences a query returns.

A locate’s total cost is steps-per-occurrence times occurrences, and the second is a property of the query and the text rather than of the structure. Putting it on the frame would mean choosing a query profile, and the plate would then be about that profile.

So the frame is per-occurrence throughout, and a reader with a workload multiplies. That is the same division every occurrence at the same price settled on, and its reason holds here: a per-unit cost is a property of a structure and a total is a property of a use.

What a system chooses

The plate is a menu and the entries are worth naming, because the dial’s ends are both real configurations.

One in four. Index 157,696 bits, locate 2.5 steps. A read aligner reporting thousands of occurrences per query lives here: the locating cost dominates its runtime and the index fits in memory either way.

One in thirty-two. 89,150 bits, 16 steps. The rate every published size in this collection is quoted at, and a reasonable default.

One in a hundred and twenty-eight. 80,743 bits, 63.6 steps. A structure indexing more text than fits comfortably, where a locate costing a few hundred bit-vector operations is acceptable because most queries are counts.

Between one in thirty-two and one in a hundred and twenty-eight the index falls by nine per cent and the locate lengthens by four times. That is a poor exchange rate and it is the reason the sparse end is less attractive than a size-only plate suggests.

The size ladder, and the last rung spends what the others savedA bidirectional index over 16,384 characters at one sampled position in 32, with each change applied on top of the last. Dropping the reverse half's locating apparatus takes it to 90.4%. Representing the remaining marks as an Elias-Fano array takes it to 84.2% — and that second step is worth 15,570 bits against the first step's 24,080, which is most of a saving that was attributed entirely to the first. The last rung is not a saving at all: it spends the whole of what was saved on sampling the surviving half four times as densely, and lands at 96.4% of where it started with a locate several times faster. That is the trade the strand exists for, and it is one plate rather than two.both halves locate250,584100.0%the reverse half counts only226,50490.4%and its marks are Elias-Fano210,93484.2%the saving spent on sampling241,47596.4%16,384 characters · one in 3284.2% smaller, or the same size and faster
Fig. 3 The size axis on its own, as a ladder of changes at one rate, with the fourth rung being the trade this plate draws.

The exchange rate

Since the fourth rung of the size ladder spends a saving on the sampling, the rate at which bits convert to steps is worth extracting.

Between one in thirty-two and one in eight: the index grows by 30,541 bits and a locate falls from 16 steps to 4. So 12 steps an occurrence cost about 30,000 bits, or 2,500 bits a step.

Between one in a hundred and twenty-eight and one in thirty-two: 8,407 bits for 48 steps, or 175 bits a step.

The rate is fourteen times better at the sparse end, which is the general shape of a hyperbola: the same proportional change in s costs the same proportional change in the samples’ size and the same proportional change in the walk, so the absolute exchange rate improves as s grows.

That says something useful about where to spend a saving. Bits spent moving from one in a hundred and twenty-eight to one in thirty-two buy fourteen times more speed than the same bits spent moving from one in thirty-two to one in eight.

Where the sparse marks change the trade

The plate’s size line is for the improved structure, and it is worth asking what the trade looks like without the improvements — because the improvements change the shape of the trade and not only its level.

With plain marks, the locating apparatus’s share of an index falls from 49% to 18.5% and flattens. So a system turning the sampling dial to save space finds the saving petering out, and stops.

With Elias–Fano marks it falls to 3.8% and keeps falling. The dial keeps paying.

That means the improved structure has a longer usable range on the dial, not merely a smaller size at each point. A system that had settled at one in thirty-two because sparser sampling stopped helping now has a reason to go further — and the reason is that the thing which had stopped it was a badly represented array.

The floor was the marks is where the flattening is diagnosed and what the locating apparatus becomes is where both curves are drawn. What this frame adds is the other currency: going further on the dial costs steps, and the steps were always there — what changed is that the bits now keep falling to pay for them.

The size ladder, and the last rung spends what the others savedA bidirectional index over 16,384 characters at one sampled position in 128, with each change applied on top of the last. Dropping the reverse half's locating apparatus takes it to 88.1%. Representing the remaining marks as an Elias-Fano array takes it to 80.8% — and that second step is worth 18,217 bits against the first step's 29,840, which is most of a saving that was attributed entirely to the first. The last rung is not a saving at all: it spends the whole of what was saved on sampling the surviving half four times as densely, and lands at 84.2% of where it started with a locate several times faster. That is the trade the strand exists for, and it is one plate rather than two.both halves locate250,584100.0%the reverse half counts only220,74488.1%and its marks are Elias-Fano202,52780.8%the saving spent on sampling210,93484.2%16,384 characters · one in 12880.8% smaller, or the same size and faster
Fig. 4 The size ladder at the sparse end of the dial, where the mark representation is worth more than the deletion and the fourth rung buys most.

What the operation savings do to this plate

Nothing, and that is the point of drawing them elsewhere.

The compound walk and the interval enumeration change what a search costs. Neither touches the marks or the sampled positions, so neither moves either line on this plate — checked as an equality: 12,486 ranks whether the marks are plain or sparse.

So the strand has two independent trades. This one, between bits and locate steps, parameterised by the sampling rate. And the operation savings, which are free in bits and split by the query’s shape rather than trading against anything.

Three savings on one structure is where that independence is established and two factors that do not multiply is where the two operation savings turn out to be one.

Three ways to extend an interval, on the same searchA search for 8-character patterns within 1 error over 8,192 characters of a 21-symbol alphabet, 6 patterns, counted in bit-vector ranks. The published shape asks about every character of the alphabet at every node: 1,478,400. The compound walk makes each of those questions cheaper by returning the rank and the smaller-count from one descent, which is 11x. Enumerating the interval's symbols removes the questions instead, which is 78x — and the 55.8% of extensions that found nothing are what it removed. All three visit the same live intervals in the same order and report the same occurrences; that is the check, and it is what makes this a plate about cost.a loop over the alphabet1,478,400the compound walk, inside the loop134,40011xone descent per node18,91678x6 patterns · 1 error · sigma 2155.8% of the extensions were dead
Fig. 5 The other axis entirely: three ways to extend an interval on a branching search, none of which appears on the size-and-steps frame.

The trade in one sentence, twice

Two summaries of this frame, one for each direction a reader might come from.

Coming from size: an index sampling one position in a hundred and twenty-eight is half the size of one sampling one in four, and its locates cost twenty-five times as many steps. The improvements in this strand take a further fourteen per cent off the sparse end and half a per cent off the dense end, so they widen the range rather than shifting it.

Coming from speed: a locate costs about s/2 LF steps whatever else is done to the structure, and the only way to make it faster is to sample more densely, which costs bits at 175 to 2,500 bits a step depending on where on the dial the change is made. The improvements in this strand supply about 39,650 bits at one in thirty-two, which is enough to quadruple the sampling.

Those are the same plate read twice and neither summary follows from the other. A reader with a size budget and a reader with a latency budget are choosing different points and want the curve read in opposite directions, which is the argument for drawing it rather than quoting either end.

On an exact search the enumeration is the more expensive of the twoThe same three machines on a search that knows which character it wants at every step: 16 exact patterns of 12 characters, in bit-vector ranks per step. The loop costs 107.9, the compound walk 10.0 — 11x, and one walk per step is all an exact search needs. The descent costs 19.0, which is 1.90x the walk, because it reports every symbol present in order to hand back one of them. So the two operation savings are a choice rather than a stack, and what chooses is the shape of the search: a branch wants the descent and a known character wants the walk.a loop over the alphabet107.9the compound walk10.0the cheapest hereone descent per step19.016 exact patterns of 12ranks per step · sigma 21
Fig. 6 A cost this frame does not include and a reader adding up a query needs: what an exact search spends per step, which is independent of the sampling.

What a one-currency plate would have said

It is worth writing out the essay this plate prevents.

The improvements to a bidirectional index are worth 15.8% of its size at one sampled position in thirty-two, and the saving grows as the sampling thins — reaching 18.4% at one in a hundred and twenty-eight.

Every number correct, and the implication — that the sparse end is better — is what a reader takes away.

The sparse end has a locate costing sixty-four LF steps an occurrence, which on a query returning ten thousand occurrences is several million bit-vector operations. Whether that is acceptable is the whole decision and it is absent from the sentence.

The rule this collection follows is not “report the other currency somewhere”. It is that a plate about a change that trades draws both, because the two facts are only useful together and prose linking two plates is how a reader ends up with one of them.

Three plates, three axes, one structure

The strand ends with three plates and it is worth saying what each is for, because between them they are the whole of what has been measured and none is a summary of the others.

The size ladder is a bar chart of cumulative changes at one sampling rate. It says what each change is worth and it holds the dial fixed.

This frame is two curves against the dial. It says what the dial does and holds the changes fixed.

The branching plate is three machines on one search. It says what the operation savings are worth and it holds everything else fixed.

Three plates, three axes, and every one of them holds two of the three things fixed. That is the discipline this collection settles on wherever a result has more than one parameter: sweep one, hold the rest, and draw as many plates as there are parameters.

The alternative — one plate with everything on it — is a plate a reader cannot read, and the alternative to that is a single number, which is a number about one configuration.

One saving is flat in the budget and the other is notThe two savings against the error budget, on 8-character patterns over 8,192 characters of a protein alphabet. The compound walk is flat at 11x — it makes each extension cheaper by a factor that is a property of the alphabet, and the budget does not change the alphabet. The enumeration moves with the budget, because what it removes is the extensions that find nothing and the share of those rises from 64.5% at no errors to 74.7% at 2. The two lines never cross here, and that is the finding rather than a limitation: on a branching search the descent wins at every budget, and the crossing is on the other axis entirely — whether the search branches at all.025507510000.50011.502errors permittedfactor against the published loop64.5%55.8%74.7%the walk: 11xthe descentthe label is the shareof dead extensions6 patterns · sigma 2198x to 105x
Fig. 7 The fourth axis, which the other three hold fixed: the two operation savings against the error budget, where one is flat and one is not.

There is a fourth axis and a fourth plate, which is the budget sweep. So the strand’s parameter space is four-dimensional — sampling rate, alphabet, error budget, and which savings are applied — and four plates cut it four ways.

Whether that is enough is a fair question and the answer is that it covers the axes a system chooses. The alphabet is given by the data; the other three are decisions, and each has a plate.

Why the second axis is drawn against its own maximum

A small drawing decision is worth recording because it is the kind of thing that quietly makes a plate say the wrong thing.

The two quantities are a percentage and a step count, so the second needs its own scale. Scaling it against its own maximum — sixty-four steps at the sparsest point — puts the two curves in the same visual range and makes their opposition legible.

It also means the step curve’s height carries no absolute information: a reader cannot read a step count off it without the axis label. That is a real loss and the alternative is worse — a shared axis would put a 63.6 against a 99.5 and make the size curve look flat, which it nearly is and not that flat.

The convention this settles for future plates of this kind: two currencies, two scales, and the second normalised to its own range with its endpoint labelled. The endpoints are where the numbers are, and the shape between them is what the plate is for.

Two savings that do not multiply, and the amount by which they do notThe compound walk is 11x and the enumeration is 78x against the same baseline, so a reader with both numbers computes 860x for an index that has both. The measured figure is 78x, and the shortfall is 11x — which is the compound walk's own factor, exactly. It is not an interaction, an overhead or a rounding: one descent over an interval returns each present symbol's sub-interval, which IS the walk's rank, and running-summing the counts gives the walk's smaller-count for every symbol at once. Taking both is taking the second one twice.factor against the published loopthe compound walk11xthe enumeration78xthe two, multiplied860xnothing measures thisan index with both78xthe shortfall is 11x, and the walk's factor is 11x6 patterns · 1 error · sigma 21the larger of the two, not the product
Fig. 8 A plate that had to break a different convention: the product a reader would compute from two factors, drawn as an unmeasured bar because the plate’s subject is that the arithmetic is wrong.

What is still missing from the frame

Two quantities that belong on a complete picture and are not here.

Construction time, which grows as the sampling densifies — more samples to compute and store — and which nothing in this strand measures.

The search’s cost, which is on a different plate for the good reason that it is independent of this dial. A reader wanting a total query cost needs to add a search and a locate, and the two are functions of different parameters.

That second is worth stating as a limitation rather than as a virtue. A query is a search followed by a locate, and the two are drawn separately because they depend on different things — so the composition is arithmetic a reader has to do, and this collection does not do it for any specific workload.

What can be said in general: as the error budget rises, the search’s cost multiplies faster than the occurrence count does, so the search dominates at loose budgets; and as the sampling thins, the locate’s cost per occurrence rises linearly, so the locate dominates on queries with many occurrences. Where the two cross is a property of the workload.

The search that spends a budget is where the first half of that was measured and the branches that find nothing is where the enumeration’s effect on it was, and neither is on this frame because neither depends on the sampling rate. A complete query-cost model would compose four measurements from four plates, and this collection has the four and has not composed them for any named workload — which is honest and is a gap.

The reason it is a gap rather than a decision is that composing them requires a workload, and a workload is a corpus and a query distribution. A corpus that was not generated is where this collection stopped trusting a made-up one, and a made-up query distribution would be the same failure on the other side of the interface.

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.

Bidirectional indexElias fanoIndex sizeLocatingSpace accountingSuffix array samplingTrade