Repository navigation
analog: linear_zoh.t27 -- exact zero-order-hold constants for the linear cell, and the h/2 convergence check (Closes #10503) - #10528
Merged
Conversation
…ear cell, and the h/2 convergence check (Closes #10503) M1c of #10486 (weaknesses W1 and W10 of docs/analog/competitors.md). specs/analog/linear_zoh.t27 `use`s the M1 cell (linear.t27) and adds a second constant set for the same step x' = x + rnd(D x + N u): the exact zero-order hold, M = exp(A_c dt), N = A_c^-1 (M - I) B_c, computed in the tests in f64 (scaling and squaring, Pade (6,6), M1's Gauss-Jordan eliminate for the solves) and quantized to Q.24 like M1. No hardware change. Circuits: M0's RC, the series RLC of M1 (Q = 1), the same with R = 5 Ohm (Q = 20) and R = 0.5 Ohm (Q = 200, the LC tank). Every stored integer is asserted equal to round(value * 2^24); M agrees with the closed form of the series RLC, with exp of the augmented matrix and with det M = exp(tr(A_c) dt). Convergence (h, h/2, h/4 against the analytic step response): backward Euler measures order 0.985/0.993 (RC), 0.975/0.988 (RLC Q 1), 0.915/0.957 (RLC Q 20); the exact scheme is within 1e-12 relative of the analytic solution at every grid point. The Q = 20 circuit leaves the asymptotic regime over 400 steps (0.84), and a test pins that. The three errors are reported apart; the model error is stated as not applicable. Stability: ||M_q^256||_inf < 1 for the RC, the RLC and the Q = 20 circuit; the Q = 200 tank needs K = 4096 (0.83; 1.17 at K = 256), asserted both ways. LC tank after 100 periods: the exact scheme keeps the amplitude to 1.00000000000006 (f64) and 1.0003 (Q.24 constants); backward Euler keeps 1.78e-7 of it. Negative controls are tests (Pade order 1 and 2, wrong dt, negative resistance, dropped integral, BE constants offered as exact); eight mutations of the file make t27c test-report fail, and t27c seal --verify refuses a mutated copy. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
October 18, 2026 16:41
Contributor
gHashTag
added a commit
that referenced
this pull request
Oct 18, 2026
… with another type named Ring and moved the types ratchet 107 -> 108 (Closes #10503) (#10539) PR #10528 merged specs/analog/linear_zoh.t27 with `pub struct Ring`. The corpus-ratchet job ran `tri types ratchet` and failed: ledger 107 names, observed 108, "+ Ring NEW conflict" -- a type name with two definitions in the corpus. The job is not a required check, so the merge went through; master is red on it until this lands. The struct holds the peak amplitude of the scheme and the analytic one in the tank test. Renamed to RingPeak (no other definition of that name). Nothing else changes: the same 15 tests pass with 0 vacuous, the seal is re-saved (15/15), `tri types ratchet` is CLEAN at 107/107, dupe_scan says ok. Co-authored-by: Claude <claude@anthropic.com> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
4 of 14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #10503
M1c of #10486 (weaknesses W1 and W10 of
docs/analog/competitors.md). New specspecs/analog/linear_zoh.t27uses the M1 cell (specs/analog/linear.t27) and copies nothing from it. It adds a second constant set for the same stepx' = x + rnd(D x + N u): the exact zero-order hold,M = exp(A_c dt),N = A_c^-1 (M - I) B_c, computed in the tests in f64 (scaling and squaring, Pade (6,6), M1's Gauss-Jordaneliminatefor both solves) and quantized to Q.24 like M1. No hardware change. Files: the spec and its seal, nothing else (t27b_expectations.jsonuntouched).What was measured
Circuits: M0's RC; the series RLC of M1 (R = 100, Q = 1); the same with R = 5 (Q = 20); the same with R = 0.5 (Q = 200, the LC tank). States are v_C and i_L * sqrt(L/C), as M1 scales them. Every stored integer is asserted equal to
round(value * 2^24)with no value within 1e-4 of a tie; M also agrees with the closed form of the RLC, with exp of the augmented matrix, and withdet M = exp(-R dt / L).Convergence, step response against the analytic solution, dt / dt/2 / dt/4, horizon 200 steps at dt (largest error over both states and all grid points):
All BE orders are in [0.9, 1.1]; the exact scheme beats the issue's 1e-9 by more than four orders. Boundary stated and pinned by a test: the Q = 20 order is a statement about its horizon. Over 400 steps the first pair measures 0.84, so at dt = 5 ns that circuit is not in the asymptotic regime for three periods (W10's rule applies).
The three errors, apart (FR-001):
Discretization is the table above. Model error is stated as not applicable (the reference is the analytic solution of the same equations; ngspice joins at M3). For the RLC, backward Euler's arithmetic error is 5.0e-7 V and its discretization error 1.89e-2 V, about 37000 times larger: a bit-exact comparison with float64 could not see it.
LC tank (Q = 200), after 100 periods (12566 steps; amplitude = largest |1 - v_C| over the last 127 steps; analytic 0.211153):
The closed form
(lam2 / exp(-R dt / L))^(K/2)gives 1.54e-7, within 15 % of the run. Numerical damping per step of BE is ten times the tank's physical damping at 125 steps per period.Stability (FR-002):
||M_q^256||_inf < 1holds for the exact RC (< 1e-5), RLC (0.0030) and Q = 20 circuit (0.877). The Q = 200 tank does not certify at K = 256 (1.17: its memory is 8000 steps) and does at K = 4096 (0.83); both are asserted. A lossless tank and a negative resistance are not certified.Gates
t27c test-report specs/analog/linear_zoh.t27: 15 of 15 pass,vacuous passes 0 of 15.tri test specs/analog/linear_zoh.t27: exit 0, 15/15.t27c seal --savethen--verify: all hashes MATCH; the seal records 15/15 and M1 in its closure.python3 tools/dupe_scan.py: ok, no new duplicate body.t27c frontier --only specs/analog/linear.t27 --list: M1's sealed verdict is reused, so its tests were not re-run.Negative controls
In the spec, as tests: Pade order 1 changes the stored integers and misses 1e-9 by five orders; Pade order 2 rounds to the same integers for the Q = 1 RLC and is caught only by the f64 grid test (error 6e-9), so both checks are kept; wrong dt (x0.5, x2), negative resistance, the input term without the integral, a damping row divided by C instead of L, and BE constants offered as exact each fail. On scratch copies of the file, eight mutations make
test-reportfail: squaring loop removed (1 test fails), PADE_ORDER 2 (8), PADE_ORDER 1 (10), one stored D digit (4), dt x1.01 (7), damping sign (8),M - Idropped from the N formula (9), one pinned fold digit (1).t27c seal --verifyreports MISMATCH on a mutated copy.Notes for the reviewer
t27b testcannot run this spec: the JIT does not support@sin,@cos,@exp,@log2(the analytic solution needs them).test-reportandtri testare the gates used.🤖 Generated with Claude Code