Counting without an index
The counters this site had before this essay all work the same way and all need the same thing.
For each candidate index offset , measure the distance from element to element 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.
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 , link each node to the node nearest , if there is one within a fraction of . 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 -jugate lattices at four jugacies, the chain counter is required to return exactly times what the ordinary lattice at returns — the scaling identity the previous essay derives. It does, at and .
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 and and look in the neighbouring buckets. On a cylinder that is wrong, because a node at and a node at 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 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 and the displacement 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.
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 :
- divide both counts by ;
- multiply both hop lengths by ;
- recover the ordinary lattice exactly, by the method that already closes to ;
- divide the recovered divergence and rise by .
Run on four patterns at four jugacies, the worst error in the recovered divergence is a few parts in of a degree, and in the rise a few parts in . 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 period is not an apology
The recovered angle comes back modulo , and it is worth insisting that this is a property of the pattern rather than a limitation of the method.
Adding to a -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: and 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.
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 . Canonicalise by flipping any displacement with , 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 on a lattice of nodes, exactly the first nodes have no predecessor, so the count is — which is the parastichy number, obtained without ever mentioning .
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.
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 from 2 upwards, rotate every node by of a turn and require it to land within a fraction of the local spacing of an existing node. The largest 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.
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.