nx_arousal_profile.nx
buildroot/runtime/nx_arousal_profile.nx
about
nx_arousal_profile.nx -- estimate a dual-control profile from OBSERVED sessions, and refuse the
part of it that the data cannot support.
This closes the loop the lane was missing: nx_arousal_fit recovers tau from a trajectory and
nx_arousal_clinical diagnoses from a profile, but nothing turned OBSERVATIONS into a PROFILE. A
therapy app watches sessions; nobody hands it SES/SIS1/SIS2.
★★THE IDENTIFIABILITY BOUNDARY IS THE WHOLE POINT. The drive law is
drive = (SES*stim)/1000 - (SIS1*stim)/1000 - SIS2
= ((SES - SIS1) * stim)/1000 - SIS2
SES and SIS1 BOTH scale with stimulus, so stimulus-response data can only ever recover their
DIFFERENCE. SIS2 is the intercept and separates cleanly. No amount of extra sessions fixes this --
it is structural, not a sampling problem. Separating SES from SIS1 requires the SIS/SES
questionnaire, a different instrument measuring a different thing.
⇒ this organ reports net = SES-SIS1 and SIS2, and reports SES/SIS1 as UNIDENTIFIABLE. An estimator
that returned three numbers here would be inventing one of them.
★SATURATED OBSERVATIONS CARRY NO SLOPE. drive is clamped to [0,1000]; a session that pinned at
either end tells you the drive was "at least" or "at most" something, not what it was, so fitting
through it manufactures a slope from a clamp. Those points are refused, not down-weighted.
usage: nx_arousal_profile fit <stim1> <drive1> <stim2> <drive2>
nx_arousal_profile selftest
license_tier: ORIGINAL expect_exit: 0
dependencies 1 imports · 0 importers
imports: nx_arousal_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| none |
functions
| 27 | func main(argc: i64, argv: *i64) -> i64 |