The pattern itself

Counting without an index

A person counting spirals on a cone puts a finger on one scale, follows a family round, and counts how many distinct chains there are. That needs no order of arrival — and building it turns out to be strictly more general than the counter the site had, and to find a bug in the counting of a bijugate stem that no assertion would have caught.
17 min read 7 figures Counted, not admiredThe round trip

The counters this site had before this essay all work the same way and all need the same thing.

For each candidate index offset mm, measure the distance from element ii to element i+mi+m over a band; take the median; keep the offsets whose median is shortest. That is parastichy() on a disc, cylCount() on a stem and coneCount() on a cone, and the only difference between them is which metric the distance uses.

The input they need and cannot do without is the index — and as the previous essay sets out, a bijugate plant does not have one. Two primordia are the same age; there is no “the next one”; and the machinery has no question to ask.

So a different instrument is needed. The natural one is the one a person already uses.

Tracing one family: 4 chainsEvery node is joined to the node one repeated displacement away, and the chains that result are drawn separately. There are 4 of them, which is the parastichy number of this family. No index of arrival was used anywhere, which is what lets the same count be made on a pattern where 2 primordia appear at once.4 chains · counted pair 4 and 62-jugate at 69.35° · rise 0.064 chains in this family
Fig. 1 One family of a bijugate stem, traced. Each chain is drawn separately and the count is how many there are. No order of arrival is used anywhere.

What a person does

Someone counting spirals on a pine cone in the hand does not track which scale came after which. They put a thumb on one scale, follow the family of spirals it belongs to around the cone, and count how many distinct spirals there are before the thumb returns to where it started.

That procedure has three steps and each one is implementable.

Find the repeated displacements. A lattice repeats: the vector from a node to a particular neighbour is the same vector everywhere. Taking each node’s nearest neighbours, canonicalising the direction, and clustering the results by rounding to a grid finer than the spacing gives the short lattice vectors, recovered from the point set rather than derived from a rule.

Follow one. For a candidate displacement v\mathbf v, link each node to the node nearest p+v\mathbf p + \mathbf v, if there is one within a fraction of v|\mathbf v|. That links the whole set into chains.

Count them. A chain begins where nothing sits one displacement below it, so the number of chains is the number of nodes with no predecessor. For a lattice on a cylinder that is exactly the parastichy number of the family.

Nowhere in that does the arrival order appear. What appears instead is a count of objects — how many chains there are — which is what a parastichy number has always meant and which the index-offset method was only ever a proxy for.

The check that makes it an instrument

An index-free counter that returns numbers is a second opinion. What makes it an instrument is that it must agree with the first one wherever both can be run.

On single-jugate lattices at four different divergences and rises, the chain counter and dominantPair() are required to return the same pair. They do: 2 and 3 at a rise of 0.09, 3 and 5 at 0.035, 3 and 4 at the Lucas angle, 2 and 5 at 151.14°.

That agreement is what licenses the multijugate answers. Without it the chain counter would be a new method producing numbers nobody could check; with it, the numbers it returns on a bijugate stem are the same measurement applied to a pattern the older instrument cannot be pointed at.

The second check runs the other way. On kk-jugate lattices at four jugacies, the chain counter is required to return exactly kk times what the ordinary lattice at (kδ,kh)(k\delta, kh) returns — the scaling identity the previous essay derives. It does, at k=1,2,3k = 1, 2, 3 and 44.

Two bugs it found, and how

Neither of the two defects this counter went through was announced by an error. Both produced a well-formed number that was wrong, which is the failure mode this site keeps meeting and keeps recording.

The lookup grid did not wrap. The counter needs “is there a node near here”, and the obvious implementation is a hash on a grid: bucket a node by x/cell\lfloor x/\text{cell}\rfloor and y/cell\lfloor y/\text{cell}\rfloor and look in the neighbouring buckets. On a cylinder that is wrong, because a node at x=0.998x = 0.998 and a node at x=0.002x = 0.002 are next to each other and land in buckets a whole turn apart.

The symptom was a count. A chain whose predecessor was across the seam failed to find it and started a new chain, so a bijugate family with eight parastichies was reported as having thirty-one. About nine per cent of a lattice lies within one cell of the seam, and the seam is exactly where a spiral pattern’s neighbours are.

It was caught by the scaling identity — the chain counter’s answer disagreed with kk times the ordinary lattice’s — and it would not have been caught by anything else, because thirty-one is a perfectly plausible parastichy number and every assertion in the drawing passed.

Two families can trace the same number of chains. On a bijugate stem the displacement v\mathbf v and the displacement v\mathbf v minus the half-turn between a whorl’s two members both climb one whorl, and both leave two chains. Taking the two shortest displacements outright therefore reported the pair as 2 and 2 — one family counted twice.

The fix is the classical definition rather than a patch: the parastichy pair is the two conspicuous families, and what makes a second family conspicuous is that it is a different count from the first. Requiring that also guarantees the returned pair spans the lattice rather than lying along one direction of it.

Both are the same shape as the site’s founding bug — a counter returning the two smallest offsets rather than the two shortest — and both were found downstream, by a cross-check, rather than by looking at the output.

Same counts, different patternsBoth are counted 2 and 4 by machinery shown only their positions. Rotating the left one by half a turn maps it onto itself and rotating the right one does not, so the left is bijugate and the right is not — and no count could have said so.two at a time68.75°, bijugatecounted 2 and 4half a turn maps it onto itselfone at a time180.5°, ordinarycounted 2 and 4half a turn does notboth counted 2/4symmetry order 2 against 1
Fig. 2 The two patterns the counter has to keep apart, and cannot: both are counted 2 and 4 from their positions alone. What separates them is the rotation, not the count.

Recovering a multijugate lattice

With the counter in place the round trip can be run on patterns the ordinary machinery refuses.

The refusal is genuine and the previous essay explains it: two families whose counts share a factor are parallel, so their two hop lengths are one measurement and cannot pin two unknowns. Nothing about the counting fixes that; the data is degenerate.

What breaks the deadlock is a measurement of a different kind — the order of rotational symmetry, read off the positions by rotating the set and requiring every rotated node to land on an existing one. Given that order kk:

  1. divide both counts by kk;
  2. multiply both hop lengths by kk;
  3. recover the ordinary lattice exactly, by the method that already closes to 101310^{-13};
  4. divide the recovered divergence and rise by kk.

Run on four patterns at four jugacies, the worst error in the recovered divergence is a few parts in 101310^{13} of a degree, and in the rise a few parts in 101410^{14}. The closure is as hard as the ordinary one, which it must be, since it is the ordinary one with a change of variable on each side.

The round trip, for every jugacyEach pattern is built from a divergence, the divergence is thrown away, the families are counted by tracing chains, the jugacy is read off the symmetry, and the divergence is recovered. The worst error over the four is 2.3e-13 degrees — and each answer is modulo the pattern's own period, 360/k, because adding that leaves the point set identical.jugacycountedperiodaskedrecoverederrork = 12 and 3360.0°138.4078°138.4078°1e-13k = 24 and 6180.0°69.6539°69.6539°2e-13k = 36 and 9120.0°46.7359°46.7359°0e+0k = 48 and 1290.0°35.2769°35.2769°3e-14200 whorls each · counted by tracing chainsworst error 2.3e-13°
Fig. 3 Four patterns built, forgotten, counted from positions, and recovered. The period column is the part that is not a technicality: a k-jugate pattern’s divergence is only defined modulo 360/k.

The period is not an apology

The recovered angle comes back modulo 360/k360/k, and it is worth insisting that this is a property of the pattern rather than a limitation of the method.

Adding 360/k360/k to a kk-jugate divergence produces the identical set of coordinates — not a congruent pattern, the same numbers. So there is no measurement on the point set that could distinguish them, and a method that returned one of the two would be returning an arbitrary choice dressed as a result.

This is the same discipline the ordinary recovery already follows for a different ambiguity: δ\delta and 360δ360 - \delta are mirror images and produce identical hop lengths, so the cylindrical recovery reports both roots rather than picking one, on the grounds that a photograph of a stem does not say which way the plant was facing.

Reporting the period is the multijugate version of the same sentence.

Six stems built, forgotten and recoveredEach row is a lattice built from a divergence and a rise, counted by machinery shown only the coordinates, and reconstructed from the counts and the two hop lengths. The worst error in the recovered angle is 3.0e-13°.137.51°, rise 0.098.5e-14°counted 2/3137.51°, rise 0.032.0e-13°counted 3/5137.51°, rise 0.0122.8e-14°counted 5/899.50°, rise 0.083.0e-13°counted 1/3151.14°, rise 0.071.1e-13°counted 2/399.50°, rise 0.021.1e-13°counted 4/7error in the recovered divergence anglecounts and hop lengths onlyworst 3.0e-13°
Fig. 4 The ordinary closure the multijugate one reduces to. Six stems built from a divergence and a rise, counted blind, and reconstructed from the counts and the two hop lengths.

Recovering the lattice vectors, in detail

The first step is the one doing the real work and it is worth setting out, because it is where an index-free method could most easily smuggle an assumption back in.

For a sample of nodes — a few hundred is enough, and sampling rather than using all of them keeps the cost linear — take each node’s ten nearest neighbours on the cylinder, with the wrap. Each gives a displacement (Δx,Δy)(\Delta x, \Delta y). Canonicalise by flipping any displacement with Δy<0\Delta y < 0, so that a family and its reverse are one entry rather than two. Round each to a grid one fifth of the local spacing and tally.

A lattice’s displacements pile up: the same handful of vectors appear from almost every node, and everything else appears from one or two. Keeping the clusters supported by at least a third of the sampled nodes, and averaging within each cluster, gives the short lattice vectors with their multiplicity.

Three things about this are worth noticing.

It uses the local spacing to set every threshold, so the answer does not depend on the scale of the pattern. The spacing is itself measured — the median nearest-neighbour distance — rather than supplied.

It uses no ordering, which is the point, but it also uses no model: nothing in the clustering knows that the vectors ought to form a lattice, or that their counts ought to be Fibonacci numbers, or that there ought to be exactly two of them. If a point set has five short repeated displacements the clustering finds five, and the pair reported is a choice made afterwards.

And it fails loudly on a non-lattice. If fewer than two clusters clear the support threshold, the counter refuses with the message that the point set does not repeat a displacement often enough to be a lattice. That refusal is what stops the method from returning a confident number for a scatter of points, which the index counter will happily do.

What a chain is, exactly

The count is the number of chains, and “chain” is doing enough work to deserve pinning down, because the natural alternative definitions give different answers.

A chain is a maximal path under the linking map: from each node, go to the node nearest one displacement away, if there is one close enough. The map is a partial function, so the graph it produces is a disjoint union of paths — and the number of paths equals the number of nodes with no incoming edge.

Two edge cases decide whether that number is the parastichy count.

The top of the pattern. Nodes near the top have no successor, so their chains end there. That does not affect the count, which is about starts rather than ends.

The bottom. Nodes in the lowest few rows have no predecessor, and those are the chain starts. For a family of offset mm on a lattice of NN nodes, exactly the first mm nodes have no predecessor, so the count is mm — which is the parastichy number, obtained without ever mentioning mm.

There is a third case that has to be excluded rather than counted. A displacement that goes purely around the cylinder — the half-turn between the two members of a bijugate whorl, for instance — links each node into a closed cycle, so every node has a predecessor and the count is zero. Zero is not a parastichy number and such families are dropped, which is a rule rather than a threshold and is stated as one.

A round trip on four heads of 600 primordia: the divergence angle recovered from eachThe counter is shown the points and nothing else. The worst recovery across the four is 0.007°.the first of the four — 200 of its 599 pointsused to buildcountsrecovered137.508°34 · 55137.515°99.502°29 · 4799.500°151.100°31 · 81151.100°77.960°37 · 6077.955°worst error 0.007°counts in, angle outthe recovery never sees the angle
Fig. 5 The disc’s round trip, for comparison. It returns an interval several degrees wide because a range of angles gives the same two offsets; the cylindrical closure the multijugate recovery reduces to is exact instead.

What the chain counter cannot do

Three limits, each of which is a real constraint rather than an implementation detail.

It needs a lattice. The first step recovers repeated displacements by clustering, and a point set with no repeated displacements has none to find. A disordered pattern — a Poisson set, or the rim of a real head where packing has taken over — gives clusters that no threshold separates, and the counter refuses rather than guessing. The refusal is correct and it means the instrument is narrower than the index counter, which will return something for any indexed point set.

It needs enough rows. The count is the number of chains, and a chain is identified by having no predecessor. A pattern only two or three whorls tall has almost every node at an edge, and the count degenerates. Forty nodes is the floor here and it is a floor rather than a recommendation.

It does not distinguish handedness by itself. A family and its mirror both trace the same number of chains, and which of the two is drawn depends on which displacement the clustering happened to find first. Handedness is reported separately, from the sign of the displacement, and it is a separate measurement rather than a consequence of the count.

The symmetry test, and its one piece of care

The recovery needs the jugacy and the jugacy comes from the symmetry, so the symmetry test is load-bearing and deserves the same scrutiny as the counting.

It is simple: for each candidate kk from 2 upwards, rotate every node by 1/k1/k of a turn and require it to land within a fraction of the local spacing of an existing node. The largest kk that passes is the order.

The one piece of care is the boundary. The top and bottom whorls of a finite pattern have nothing to rotate onto in the sense that matters — a node at the very top is fine, but the pattern as a whole is a truncated one and the truncation is not symmetric under an arbitrary rotation unless the ends are excluded. Without excluding them every pattern reports order 1, because the extreme rows always fail, and the test would be useless while looking like a result.

That is the same class of error as the sixty boundary cells that inverted Lewis’s law: a population at the edge of a finite sample, answering a different question from the one asked, and numerous enough to decide the outcome. It is worth stating in the same words each time it appears, because it is the commonest way a measurement on a finite sample goes wrong, and it never announces itself.

The control that makes the test a test is the awkward case. An ordinary single-jugate lattice at a divergence of 180.5° has a counted pair of 2 and 4 — a pair sharing a factor — and a symmetry order of 1. If the test returned 2 there it would be reporting the counts back rather than measuring the positions, and the whole distinction the previous essay is built on would collapse.

A whorl and a spiral, from one lattice at two divergencesAt 90° the nodes fall on 4 rows and the two counts share a factor: the elements of each turn are level with one another. At 137.51° they never are.90° — a quarter of a turn4 and 8 — whorled137.51°3 and 5 — Fibonaccirise 0.030 in both panelsthe counts decide, not the eye
Fig. 6 The pattern the chain counter has to be careful about. Rows are what a lattice near a rational divergence produces, and they are counted the same way a genuine whorl is.
five limit divergences, all of them 137.5078 over a whole numberThe golden angle is the k = 1 member of a family. Real bijugate plants — teasel, *Cephalaria* — are reported near 68.75°, which is exactly half of it, and the pairs they are counted at are the Fibonacci pairs doubled.1-jugate137.5078°counts 3/52-jugate68.7539°counts 6/103-jugate45.8359°counts 9/154-jugate34.3769°counts 12/205-jugate27.5016°counts 15/25limit divergence5 jugacies137.5078 / k
Fig. 7 What the recovery returns for each jugacy, once the symmetry has supplied k. Each is modulo its own period, and each is the golden angle over k.

Why the more general instrument is the better one anyway

There is an argument for using the chain counter even where the index counter works, and it is not about multijugacy.

The index counter’s answer is an offset — “the 34-family” means “join every 34th element”. That is a statement about the order of arrival, and it is only a statement about the picture because on a single-jugate lattice the two coincide. The chain counter’s answer is a number of chains, which is a statement about the picture directly.

Where they coincide, nothing is gained. Where they do not — a multijugate pattern, a pattern whose order of arrival is unknown, a photograph of something dead — only one of them is available, and it is the one that matches what the word “parastichy number” has always meant.

That is the general form of a preference this site keeps arriving at. The measurement that uses less about the object is the measurement worth having, because the extra information is usually the thing being claimed. The counting is done blind because a count that had been shown the divergence angle would be a restatement. Counting without an index is the same move, one step further along: a count that has been shown the order of arrival is a count that has been shown a piece of the plant’s history, and the history is not in the photograph.