# memory-zeta - The Dirichlet series of a memory rule, `zeta_W(s) = sum_(n in S_W) n^(-s)` over the positive integers whose minimal base-2 string the rule accepts, and the zeros of its matrix Lyndon cofactor `Z_W(s) = det(I - 2^(-s) T) zeta_W(s)`. - `peel.py` is the arbitrary-precision control on the double-precision matrix ladder of `mrlynum::automaton`; `census.py` is the double-precision engine that carries the zero census and reads its own control back. - The peel: with `E_j(w)` the vector whose entry `u` sums `n^(-w)` over the accepted words of exactly `j` digits ending in state `u`, and `G_P = sum_(j >= P) E_j`, splitting a word on its last digit gives `(I - 2^(-w) T) G_P(w) = E_P(w) + sum_(l >= 1) binom(-w,l) 2^(-w-l) Gamma_l G_P(w+l)`, and `zeta_W(w) = 1^T D_(P-1)(w) + 1^T G_P(w)` for the Dirichlet polynomial over the accepted words of at most `P-1` digits. - The cofactor never divides by the vanishing determinant: `Z_W(s) = det(I - 2^(-s) T) D_(P-1)(s) + 1^T adj(I - 2^(-s) T) N(s)` with `N` the right side of that identity, so it reads on the whole `m = 0` pole comb, and the residue at a simple root `x_0` of the determinant is that same lift over `-x_0 log 2 det'(x_0)`. No eigenvector is solved for. - `det(I - x T)` and `adj(I - x T)` are polynomials in `x` with integer matrix coefficients, both taken by Faddeev-LeVerrier from `T`, so the engine runs at any width with no eigen-decomposition anywhere in the loop. ## THE CENSUS - `Z_W` is meromorphic with one simple pole at each level-`m` tooth for `m >= 1` and none on the `m = 0` combs, which the determinant strips all at once, one factor for every eigenvalue. The census counts by the argument principle per cell and adds back the level-`m` poles the cell holds, each named by its exact position, so every printed cell count is a zero count. - Each added-back pole is read and not assumed: its residue is a `48`-point circle mean of `Z_W` at radius `--ring` and again at `0.4` of it, printed with the gap between the two radii, with `(s - s_0) Z_W` at `1e-5` beside it to catch a double pole and a blank point on the same line as the null. - The clearance from every zero to the nearest outer box edge and to the nearest internal cell edge is printed; an internal edge is sampled at the same points and bisected the same way from both sides, so the two cells' phase contributions cancel and only the split between neighbours could move. - The grid is derived and not chosen: the column edges are the midpoints of the comb and pole lines inside the box, subdivided so no column is wider than `0.75`, and the row edges are the midpoints of the tooth and pole heights, so every cell holds at most one tooth. - The phase is accumulated on a contour seeded at step `0.05` and bisected on any step above one radian, and the largest surviving step is printed beside the count. A count is resolved and not certified: nothing here bounds `Z_W'/Z_W` on the contour. - A box of winding one is split along its longer side until it is `0.01` across, then polished by secant, and the largest `abs(Z_W)` at a located zero is printed. - Occupancy at a tooth is read at the radius `0.45` of `lab/py/zeta-family`, with the distance from every tooth to the nearest located zero printed whatever the radius says. - The nonzero eigenvalues are read off the degree of `det(I - x T)`, whose coefficients are integers from the same Faddeev pass, and a root with a relative imaginary part below `1e-9` is snapped real. Reading them off the characteristic polynomial with a magnitude cutoff instead admits numerical debris: the full rule at width `3` has `det = 1 - 2x`, one eigenvalue and one comb, and the cutoff sold it three more near zero and a spurious tooth on the real axis. - The first-order tooth law is `u_1 = -r/R`, `r` the residue of `zeta_W` at the tooth and `R` the regular part, `R` taken as the mean of `Z_W/det` on a circle of radius `0.3`, which is exact for the Laurent tail and needs no fit. - Both verbs print two errors at every tooth and name each one: the modulus miss `abs(d - abs(u_1))`, which is what the occupancy law is stated on, and the vector miss `abs(z - t - u_1)`, which tests the direction too. One word for two quantities is how the weaker of them gets published. - Occupancy is a per-tooth Boolean, so every tooth also prints the number of located zeros inside the radius. At width `3` one tooth of the `50` holds two, and `34` occupied teeth hold `35` zeros. - The truncation bound is carried entrywise as a nonnegative vector through the majorant `sum_k abs(adj_k) abs(x)^k / abs(det)` of the resolvent, which is the adjugate's own coefficients and needs no norm and no primitivity, plus a measured relative allowance of `1e-14` against the largest quantity the ladder carries. The majorant is not certified by a residual, which is the one step short of the crate's left-of-abscissa branch, and the control is what closes it. - The right edge is a proved zero-free wall and not a choice: the least element of `S_W` is `1`, the coefficients are nonnegative, and `zeta_W(2) < 2`, so `abs(zeta_W(s) - 1) < 1` on `Re s >= 2` and the determinant has no root right of the abscissa. ## THE OCCUPANCY CENSUS - `teeth` walks the width-`k` rule classes under `G_(1,k)` at dim 1, keeps the classes whose nonzero eigenvalues carry exactly two distinct moduli and no repeated root, and runs the zero census of `census` on one box for all of them, printing one occupancy row per pole line. - A line is a distinct `abs(lambda)` and not a distinct eigenvalue: a conjugate pair puts two combs on one line, offset by `+-arg lambda / log base`, and the line's teeth are their union. - The box is cut to fit the budget and the cut is printed: `-1.15 < Re s < 2`, `0.02 < Im s < 20`, against the `43.1` of the single-rule census. The left edge holds every radius `0.45` disc of every second line at width `3`, the deepest reaching `Re s = -1.144241913631`, and the height holds two teeth of the first line and two or four of the second. - The left edge is chosen by the contour guard and not by the discs alone. The guard measures every level-`m` pole of the rule against the contour, inside the box and outside it, since a pole just outside is never added back and is the worse neighbour; at `-1.2` codes `54` and `62` carry a pole line `0.002842615688` outside the contour and code `223` one `0.011370462752` inside it, and at `-1.15` every pole clears `0.02`. The floor is exactly `0.02`, the cut `Im s > 0.02` against the level-`m` pole on the real axis. Both boxes read the same occupancy on all nine rules. - Each row prints the rule, its class size, `abs(lambda_2)/rho`, the arguments on the second line, the teeth on each line, the teeth occupied at radius `0.45`, every tooth-to-zero distance, the zeros lying off every tooth, and the zeros and poles within `0.02` of a contour with the least pole clearance. Each row is the argument-principle count of `census`, cell by cell, with the level-`m` poles added back, resolved and not certified. - `bridge` is the control on a new rule. The width-`3` rule `55` forbids exactly `011`, `110` and `111`, which bans an adjacent pair of ones inside every `3`-window, so it accepts the width-`2` rule `7`'s set with the single integer `3` adjoined, the word `11` carrying no window. The verb checks that membership over `1 .. 2^span` and then checks `Z_55(s) = Z_7(s) + det(I - 2^(-s) T) 3^(-s)` at seven points, each against the sum of the two bounds. - That identity crosses widths: the `4`-state ladder, adjugate and peel meet the `2`-state ones that carry `control.json`. It also says the pole data is the same on both rules at every `m >= 0`, orders and residues included, since `zeta_55 - zeta_7 = 3^(-s)` is entire; the determinant vanishing at every `m = 0` tooth is how the census reads that back, and the zero sets are not the same. ## THE DIAL - `dial` is the finite perturbation probe. For a finite `F` of positive integers disjoint from `S_W` the perturbed set `S_W + F` has `zeta_(W+F) = zeta_W + P_F` with `P_F(s) = sum_(n in F) n^(-s)`, so the engine carries it by adding `F` to the Dirichlet polynomial over the short words and changing nothing else: no new ladder level, no new truncation and no new majorant, which is why the perturbation needs no new control. The added term is a finite exact sum and travels inside the same relative allowance as the rest of the polynomial. - The perturbation is entire, so every pole, order and residue of `zeta_W` is shared by `zeta_(W+F)` and only the zero set can move. Two of the three probes that check it are blind by construction and the verb says so: a `48`-point circle mean annihilates every Taylor order below `47`, so an entire addition of any size passes the residue probe, and the determinant vanishes at a tooth, so the tooth probe prints its own floating-point residual. The probe that measures the added part is the identity `Z_(W+F)(s) - Z_W(s) = det(I - base^(-s) A) P_F(s)` read off the teeth, at `t + --rho`, printed beside the modulus of the added part there. - Occupancy is read by the argument principle on the occupancy circle itself and not on a box: the winding of `Z_(W+F)` on a `40`-point circle of radius `--rho` about the tooth, bisected on any step above one radian, plus the level-`m` poles inside the circle, which are read from a pole list padded one unit past the box in both coordinates so that no pole a circle reaches is missed. The verb prints the deepest reach of any circle against the nearest pole line left of the box. - The `0.02` edge rule of the census becomes an annulus: the count is taken at `--rho` minus the guard and again at plus it, and a cell whose two counts differ is printed as a seam, the reported occupancy being the inner one. Both baselines read no seam at all. On the perturbed grid a seam whose inner count is `0` is an undetermined occupancy, and a minimum over a tooth's candidate row is then convention-dependent even when the winning cell is itself off the seam, so each line prints its undetermined count and each tooth prints its smallest occupying singleton and its largest empty candidate on both readings. - The first-order law of the occupancy census moves under the knob through its constant term alone: the principal part is fixed, `R` becomes `R + P_F(t)`, and `u_1(F) = -r/(R + P_F(t))`. The higher Taylor coefficients of the regular part move too, the linear one by `P_F'(t)`, which the first-order law does not read. The verb prints the measured occupancy and that prediction as two bit strings over the printed candidate list, one row per tooth, with the mismatching candidates named. - The scoreboard is printed against a baseline and not alone: each line prints its cells, how many read occupied, how often the first-order law calls a cell right and how often the constant `occupied` predictor does. A law that scores below the constant predictor on a line is not a selector on that line. - `--deep` runs a greedy search for the `F` that drives `abs(R + P_F(t))` to zero at each occupied tooth, one candidate at a time, measuring the disc after every step, which is the attempt to empty a tooth rather than to fill one. A greedy chain is one path, so the verb also runs the exact meet-in-the-middle minimisation over every subset of size at most `--deep` whenever the candidate list is `24` long or less, printing the minimiser, the minimum, the emptying threshold `abs(r)/rho` and the disc measured at the minimiser. ## RUN - `uv run python research/lab/py/memory-zeta/peel.py`, `3.2` seconds, prints the control values. - `uv run python research/lab/py/memory-zeta/peel.py control`, `4.6` seconds, writes `control.json`, the only arbitrary-precision run in the study; the rewrite is byte-identical to the stored file. - `uv run python research/lab/py/memory-zeta/census.py control`, `0.05` seconds, reads `control.json` back through the double-precision engine. - `uv run python research/lab/py/memory-zeta/census.py census`, `8.3` seconds, the golden rule, code `7` at width `2`. - `uv run python research/lab/py/memory-zeta/census.py census --width 3 --code 23 --left -0.75`, `16.3` seconds, the supergolden rule. - `uv run python research/lab/py/memory-zeta/census.py census --left -1.2`, `8.3` seconds, the widened box that holds every occupancy disc of the second comb and reads the same `20` zeros. - `uv run python research/lab/py/memory-zeta/census.py teeth --width 2 --left -1.2 --height 20.0`, `3.3` seconds, the one two-line class at width `2`. - `uv run python research/lab/py/memory-zeta/census.py teeth --width 3 --left -1.15 --height 20.0`, `75.5` seconds, the nine two-line classes of the `88` at width `3`, the occupancy table and the first-order law. - `uv run python research/lab/py/memory-zeta/census.py bridge`, `0.25` seconds, the width-`3` rule `55` against the width-`2` rule `7`. - `uv run python research/lab/py/memory-zeta/census.py census --width 3 --code 55 --left -1.15 --height 20.0`, `7.6` seconds, the four-state ladder's Laurent data against the two-state one. - `uv run python research/lab/py/memory-zeta/census.py dial --width 2 --code 7 --top 40 --height 43.1 --left -1.2 --deep 16`, `16.0` seconds, the nine teeth of the golden rule against the `22` integers of `2 .. 40` outside `S_W`. - `uv run python research/lab/py/memory-zeta/census.py dial --width 3 --code 23 --top 40 --height 43.1 --left -0.75 --deep 0`, `47.0` seconds, the fourteen teeth of the supergolden rule against its `27` candidates. - `--seed`, `--rho`, `--eps`, `--hug`, `--ring`, `--span`, `--top`, `--guard`, `--deep`, `--peel`, `--shift`, `--cut`, `--left`, `--right` and `--height` are the dials. - Halving the seed costs more and not less: `0.025` raises the contour evaluations from `11777` to `21599` and the run from `8.3` to `14.9` seconds, doubling it to `0.1` drops them to `7298` and `5.2`, and the `45` cell rows and the `20` zero rows are identical at all three. - Prints only, writes nothing except under `peel.py control`. ## WITNESSES - The page lines of [beneath](../../../notes/beneath.md), `### The memory zeta`. - `zeta_W(3) = 1.154012963277642016659466`, `zeta_W(2) = 1.415825532884777929125692`, `zeta_W(0.8) = 9.536379694275011510923898` and `zeta_W(1.2 + 9i) = 1.906409024243906069557735 - 0.453243424778265833646527i`, each met by `mrlynum::automaton` inside its own bound, the largest gap `3.0e-15` against a bound of `9.54e-13`. - The six residues at `m = 0`, `j = 0, 1, 2` on both combs. On the comb at `Re s = log_2 phi` the gaps against the crate are `6.0e-16`, `2.6e-15` and `9.3e-16` against bounds near `1.3e-13`; on the comb at `Re s = -log_2 phi`, where the crate reads through its left-of-abscissa branch and bounds near `4.1e-9`, the gaps are `1.1e-12`, `3.7e-12` and `4.3e-12`. - That second comb is the reason this study exists: every crate number on it is produced by one branch and is met here from outside it. - `control.json` carries fourteen rows at `dps 40`, peel `14`, shift `60`, cut `30`, against the census engine at peel `8`, shift `12`, cut `24`: two `zeta_W` values, ten `Z_W` values including five located zeros and the census contour points `-0.95 + 20i` and `30i`, and two residues, one on each comb. The largest gap is `1.134e-11`, on the row `Z` at `-0.95 + 20i` against its bound `7.348e-11`, and no row falls outside its printed bound. - Five of those rows evaluate `Z_W` at a located zero printed to twelve decimals and read `abs(Z_W)` below `9.81e-12` in the other lane. Both lanes run the same peel, the same Faddeev adjugate and the same `l`-cut, so this is a precision control and not a second method; the independent lane is the crate. - The new rule's control is `bridge`: `3` is the only integer of `1 .. 262143` on which the width-`3` rule `55` and the width-`2` rule `7` disagree, and `Z_55 - Z_7 - det(I - 2^(-s) T) 3^(-s)` reads at most `1.168e-13` over seven points including three teeth and one located zero, every point inside its bound. - The occupancy table at width `3` reads `9` two-line classes of `88`, `50` teeth, `34` occupied at radius `0.45` holding `35` zeros, every zero located on every rule, largest residual `3.236e-11`, largest phase step `0.999909` radians, largest bound `9.110e-09`, and no pole within `0.02` of a contour. Two zeros are, `-1.134547677+3.580553251i` on code `127` and `-1.143621954+17.814806003i` on code `63`; the box at `-1.2` reads the same occupancy with the failure on the poles instead. - The first-order law at width `3` reads largest modulus miss `0.739013203` and largest vector miss `1.287895060`, both at code `63`, line `1`, `Im s = 13.597080`, `abs(u_1) = 0.520202113` against a nearest zero at `1.259215316`. - The dial's baseline is the census read back through a different contour: the circle probe reads `4` of `4` and `0` of `5` on code `7` and `3` of `4` and `7` of `10` on code `23`, the same occupancy the cell census prints, with no seam on either baseline and the deepest circle reaching `Re s = -1.164241913631` on code `7` against a nearest excluded pole line at `-1.305758086369`. - The falsification that measures something: the off-tooth identity misses by at most `2.384e-15` at code `7` and `4.003e-16` at code `23` against an added part of up to `1.912203` and `1.708983` in modulus, over three probes. The residue and tooth probes beside it read `1.776e-15` and `1.332e-15` over the `4` level-one poles of each box and `1.250e-13` and `1.789e-14` over the teeth, and both are blind: a `48`-point circle mean annihilates an entire addition, and the determinant vanishes at a tooth, so those two numbers are an aliasing floor and a determinant residual and would print at that magnitude however the addition were implemented. - The dial meets the one cross-width control that exists: `S_7 + {3}` is `S_55`, and the dial's grid row for the added element `3` reads the second comb occupied at `Im s = 4.532360` and empty at `13.597080`, which is the `1` of `2` the four-state ladder prints for code `55`. - The same control measures the Laurent shift on a four-state ladder against a two-state one: at `Im s = 9.064720` code `55` reads `r = 0.210170579-0.581938843i`, digit for digit code `7`'s, and `R = 1.313430833+1.119663028i` against `1.714940435+0.882338583i`, a difference of `-0.401509602+0.237324445i`, which meets `3^(-t) = -0.401509601+0.237324445i` up to one unit in the last place of the two nine-decimal prints it is read from. - Every empty tooth of code `7` is occupied by one added integer, `{3}`, `{6}`, `{7}`, `{11}`, `{11}` at `Im s = 4.532360`, `13.597080`, `22.661801`, `31.726521`, `40.791241`, and on code `23` the empty teeth are occupied by `{7}`, `{5}`, `{7}`, `{15}` while two occupied teeth are emptied, `Im s = 2.678332` by `{6}` and `42.645269` by `{6}` and by `{7}`. - Those least singletons are read on the inner convention and two of each list move on the outer one: code `7` reads `{3}`, `{6}`, `{3}`, `{11}`, `{6}` and code `23` reads `{6}` at `9.064720` and `{11}` at `38.937214`. What does not move is the bound, `11` at code `7` on both readings, the four fillings and the two emptyings, both emptied teeth printing an empty seam list, and so the count `6` of `14`. - Occupancy under the knob is undetermined on `9` of the `110` cells of code `7`'s second comb, `10` of the `108` of code `23`'s abscissa comb and `9` of the `270` of its second line, each a cell whose inner count is `0` and outer count positive. - The exact minimum of `abs(R + P_F)` over all `4158861` subsets of size at most `16` of the `22` candidates is `1.095277075`, `0.784350607`, `1.295268436` and `1.662786204` at code `7`'s four abscissa-comb teeth, the greedy chain attains every one of them, and the disc at each exact minimiser keeps its zero off the seam, `1/1`, `2/2`, `1/1`, `1/1`, the one at `Im s = 18.129441` gaining a second. - That search bounds the first-order proxy and not the occupancy, and at `Im s = 9.064720` the two part company: the minimum `1.095277075` falls below the emptying threshold `abs(r)/rho = 1.374951382`, the law predicts `abs(u_1) = 0.564905571` and an empty disc, and the disc reads `1/1` with no seam. - The scoreboard: code `7` line `1` holds `110` cells, `77` occupied, the first-order law right `75` times against the constant predictor's `77`; code `23` line `1` holds `270` cells, `222` occupied, the law right `218` against `222`; code `23` line `0` holds `108` cells, `84` occupied, the law right `105` against `84`; code `7` line `0` is `88` of `88` on both. - On the outer reading of the seam the subdominant deficits widen and the abscissa-comb margin does not survive: code `7` line `1` reads `80` against `86`, code `23` line `1` `219` against `231`, and code `23` line `0` `95` against `94`, three of whose four teeth are `27` of `27` occupied and score alike, so the whole margin sits on the one tooth carrying `10` undetermined cells. - The four level-one poles of code `7` read residues `-1.990368154340-0.795661945868i`, `-0.350975872907-0.436714265460i`, `-3.135030562964-2.032376530959i` and `-1.028888122837+2.036528502776i`, the two radii agreeing to `7.3e-14` or better, each simple to `5.1e-05` against `(s - s_0) Z_W` at `1e-5`, with a blank point on the same line at `4.6e-16`.