sdhub
writeup onlyStructural dynamics solver on a TI-84 Evo. Closed-form vibration response with every step shown, 1,457 checks, and three memory failures found with on-device probes.
Python
SDHUB is a structural dynamics solver that runs on a TI-84 Evo and solves single-degree-of-freedom vibration problems with every step shown. It is verified by 1,457 checks across 14 test suites, including a numerical oracle that integrates 72 random systems independently. The constraint is the whole story, and the failure inside it is that the calculator ran out of memory three different ways before it ran out of problems to solve.
I built it on the same base as my DiffEq toolkit, in the Python subset a TI-84 Evo accepts. That target takes away f-strings, typing, dataclasses and the cmath and fractions modules. Every line of output and every prompt must fit in 28 characters. The two toolkits share one library file and live on the calculator side by side.
The failure: RAM on the real device
The calculator gives Python about 105 KB of working memory, and every desktop test passed while the device kept failing. I stopped guessing and wrote small probe programs that load one module at a time and print free memory after each. Those readings found three separate failures, each with a different repair.
| Failure on the device | What the probe showed | Repair |
|---|---|---|
| MemoryError at startup | The hub imported every module at once, about 124 KB of code against a 105 KB heap | Load each topic module only while its menu is open, and unload it on the way out |
| MemoryError while loading the library | The library loaded fine alone, but failed when compiled while two other modules already sat in RAM | Import the leaf modules first, so the biggest compile happens with the least in memory |
| MemoryError in PEAK and SETTLE | A 1 KB request failed with 54 KB free, because sample lists of 400 to 2,000 numbers need one unbroken block | Stream the samples one at a time, which cut peak use from up to 63 KB to under 4 KB |
A fourth problem looked like a crash but was silence. The calculator runs a program the way Python imports a module, so the usual main-guard never fired and nothing appeared. The hub is now a three-line launcher that always starts the menu. The lazy loading reads like a design decision. It was a repair, and the probes are how I knew which one.
How it solves
One engine solves m x’’ + c x’ + k x = F(t) in closed form for every damping case, including unstable and spring-less systems. Unlike DiffEq, it works in floating point, because natural frequencies are square roots and are almost never rational. It prints work in a fixed order: parameters, classification, roots, the homogeneous form, the particular solution, then constants.
- Particular solution: undetermined coefficients, with resonance detected by root multiplicity, so the guess gains a t or t² factor only when the forcing matches a characteristic root.
- Initial conditions: always applied to the total solution, never to the homogeneous part alone.
- Impulses, delayed steps and ramps: time-shifted segments, each solved from rest and added after its start time.
- Typed numbers: a damping value or forcing rate typed to five significant figures is recognised as the exact critical value or root it was copied from.
What it covers
It covers free response in all damping cases, step response and dynamic amplification, viscous and hysteretic frequency response, the total solution under sinusoidal forcing, impulse response and Duhamel’s integral, force transmissibility, base excitation and isolation design. It also identifies damping from decaying peaks and finds equivalent viscous damping from loop energy, quadratic drag and Coulomb friction.
When a problem leaves the initial conditions or force amplitude as letters, the tool keeps them as letters, solving each with a value of 1 and scaling, since the response is linear in them. Damping can be entered as c or as zeta. A teaching mode annotates each step with why it happens, and result tools find peaks, settling times and tables, or draw the response with the calculator’s own plotting module.
How it is verified
I verified it with 1,457 checks across 14 suites, checked against independent computation and worked references.
| Check | What it proves |
|---|---|
| RK4 oracle, 370 checks | The closed-form engine matches a separate numerical integration on 72 random systems across every damping case and forcing mix |
| Worked examples | Every numeric answer from 26 worked examples reproduces |
| Keystroke walkthrough | 21 reference problems solved by typing into the real menu, each answer re-derived by hand |
| Width and paging sweep | Every menu path, with teaching mode on and off, stays within 28 characters and pages correctly |
Two independent code reviews found real bugs the tests had missed, including one that turned an unstable system into a stable one. Each fix shipped with a test that failed first. The memory fixes were confirmed on the calculator itself, not just on the desktop.