nx_ringdown_lib.nx
buildroot/runtime/nx_ringdown_lib.nx
about
nx_ringdown_lib.nx -- ONE damped-oscillator identifier for the whole estate.
WHY THIS EXISTS. The estate has to answer "what is this thing's natural frequency and damping"
about TWO subjects that must be comparable: our own XPBD plant (via nx_dyna_bind_skin's
ringdown) and REAL FOOTAGE (via nx_dynaoracle's optical-flow displacement series). If each
carried its own estimator the comparison would be measuring two rulers, not one subject.
Extracted VERBATIM from nx_dyna_bind_skin.dbs_ringdown_t 2026-08-25 so the two cannot disagree
BY CONSTRUCTION -- the law the jobclaim lane already paid for.
SUBJECT-AGNOSTIC BY DESIGN: it takes a signal, a sample period and a deadband. It knows nothing
about tissue, cages, pixels or cameras. Hair, cloth, camera shake and any damped oscillator are
the same arithmetic.
DOCUMENTED IMPRECISION (carried over, deliberately not silently improved): rd_log2_q16 is a
bit-length plus LINEAR mantissa term, worst error about 0.086 in log2 inside an octave. The
analyser therefore ALWAYS returns the two raw peak amplitudes beside the derived zeta so any
reader can recompute the decrement exactly and is never forced to trust this routine.
license_tier: ORIGINAL
dependencies 1 imports · 3 importers
imports: nx_syscalls.nx
imported by: nx_dynaoracle.nxnx_dynaoracle_gate.nxnx_hairdyn_lib.nx
structs
| none |
consts
| 22 | const RD_Q16: i64 = 65536 |
| 23 | const RD_PERMIL: i64 = 1000 |
| 24 | const RD_US_PER_S: i64 = 1000000 |
| 25 | const RD_MHZ_PER_HZ: i64 = 1000 |
| 27 | const RD_LN2_Q16: i64 = 45426 |
| 28 | const RD_TWOPI_Q16: i64 = 411775 |
| 34 | const RD_LOG2_ERR_PERMIL: i64 = 86 |
| 35 | const RD_LN2_PERMIL: i64 = 693 |
| 36 | const RD_TWOPI_PERMIL: i64 = 6283 |
| 42 | const RD_SPAN_TOL_SAMPLES: i64 = 1 |
| 54 | const RD_SPAN_MIN_INTERVALS: i64 = 3 |
| 57 | const RD_R_NSAMP: i64 = 0 |
| 58 | const RD_R_A1: i64 = 1 |
| 59 | const RD_R_A2: i64 = 2 |
| 60 | const RD_R_PER_US: i64 = 3 |
| 61 | const RD_R_FN_MHZ: i64 = 4 |
| 62 | const RD_R_ZETA: i64 = 5 |
| 63 | const RD_R_PEAKS: i64 = 6 |
| 64 | const RD_R_MAXABS: i64 = 7 |
| 65 | const RD_R_RESID: i64 = 8 |
| 69 | const RD_R_SPAN_HALVES: i64 = 9 // half-periods between the two peaks that were compared |
| 70 | const RD_R_SPAN_A: i64 = 10 // peak of the FIRST closed lobe |
| 71 | const RD_R_SPAN_B: i64 = 11 // peak of the LAST ADMITTED closed lobe |
| 72 | const RD_R_SPAN_ZETA: i64 = 12 // zeta from the generalised decrement, permil |
| 73 | const RD_R_SPAN_ZETA_TOL: i64 = 13 // and the imprecision THIS run can support, permil |
| 74 | const RD_R_SPAN_PER_US: i64 = 14 |
| 75 | const RD_R_SPAN_FN_MHZ: i64 = 15 |
| 76 | const RD_R_SPAN_FN_TOL: i64 = 16 // permil of the frequency |
| 77 | const RD_R_SPAN_LOBES: i64 = 17 // closed lobes seen, admitted or not |
| 78 | const RD_R_SPAN_RC: i64 = 18 // the span estimator's OWN third state, never a bare zero |
| 79 | const RD_R_N: i64 = 19 |
| 84 | const RD_OK: i64 = 0 |
| 85 | const RD_UNOBS_NO_SAMPLES: i64 = 0 - 1 |
| 86 | const RD_UNOBS_NO_CROSSING: i64 = 0 - 2 |
| 87 | const RD_UNOBS_NO_PERIOD: i64 = 0 - 3 |
| 88 | const RD_UNOBS_NO_DECAY: i64 = 0 - 4 |
| 93 | const RD_UNOBS_NO_PERIODIC_SPAN: i64 = 0 - 5 |
| 159 | const RD_HALVES_PER_PERIOD: i64 = 2 |
| 163 | const RD_SPAN_ENDS: i64 = 2 |
functions
| 95 | func rd_reason(r: i64) -> *u8 |
| 105 | func rd_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } called by 1: rd_analyze |
| 107 | func rd_isqrt(n: i64) -> i64 |
| 115 | func rd_log2_q16(x_q16: i64) -> i64 called by 1: rd_ln_q16 |
| 125 | func rd_ln_q16(x_q16: i64) -> i64 { return rd_log2_q16(x_q16) * RD_LN2_Q16 / RD_Q16 } |
| 165 | func rd_zeta_permil_span(a: i64, b: i64, halves: i64) -> i64 |
| 197 | func rd_span_zeta_tol_permil(a: i64, b: i64, halves: i64) -> i64 |
| 211 | func rd_span_fn_tol_permil(per_samples: i64, halves: i64, b: i64) -> i64 called by 1: rd_analyze |
| 230 | func rd_zeta_permil(a1: i64, a2: i64) -> i64 |
| 239 | func rd_analyze(sig: *i64, n: i64, dt_us: i64, quant: i64, out: *i64) -> i64 |
| 378 | func rd_phase_lag_permil(drive: *i64, resp: *i64, n: i64, per_samples: i64, out_lag: *i64) -> i64 |
| 422 | func rd_detrend_from(sig: *i64, n: i64, fit_from: i64, out_a_q16: *i64, out_b_q16: *i64) -> i64 |
| 456 | func rd_detrend(sig: *i64, n: i64, out_a_q16: *i64, out_b_q16: *i64) -> i64 calls 1: rd_detrend_from |
| 463 | func rd_center_on_tail(sig: *i64, n: i64, out_eq: *i64) -> i64 called by 1: main |