Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Statistics

The statistics subsystem reads list data, accumulates moments, solves regressions, and writes named results such as x̄, Σx, Sx, a, b, r, and r². This page separates the CALC, STAT-TESTS, and DISTR command families.

The CALC paths read L1–L6 through the VAT and use the BCD floating-point engine. The engine lives on Flash page 3A; raw disassembly supplies indexed-bit and cross-page operations that the decompiler can mis-render.

statVars result block [confirmed]

Every STAT-CALC result is a 9-byte TIFloat (see floating-point.md) written into a fixed RAM table beginning at statVars = 0x8A3A (statVars EQU 8A3Ah in ti83plus.inc). Entries are packed at the 9-byte FPLEN stride. These are the system variables recalled by name ([2nd][STAT] ▸ VARS):

AddrName (.inc)User-facing varMeaning
8A3AStatNnsample count (Σ of frequencies)
8A43XMeanx̄mean of x
8A4CSumXΣxsum of x
8A55SumXSqrΣx²sum of x²
8A5EStdXSxsample std dev of x (÷ n−1)
8A67StdPXσxpopulation std dev of x (÷ n)
8A70MinXminXminimum x
8A79MaxXmaxXmaximum x
8A82MinYminYminimum y (2-Var)
8A8BMaxYmaxYmaximum y (2-Var)
8A94YMeanȳmean of y
8A9DSumYΣysum of y
8AA6SumYSqrΣy²sum of y²
8AAFStdYSysample std dev of y
8AB8StdPYσypopulation std dev of y
8AC1SumXYΣxysum of x·y
8ACACorrrcorrelation coefficient
8AD3MedXMedmedian of x
8ADCQ1Q1first quartile
8AE5Q3Q3third quartile
8AEEQuadAaregression coeff a (highest order)
8AF7QuadBbregression coeff b
8B00QuadCcregression coeff c
8B09CubeDdregression coeff d
8B12QuartEeregression coeff e
8B1B…8B50MedX1/2/3, MedY1/2/3 (8B1B/8B24/8B2D/8B36/8B3F/8B48)Med-Med (×3 partitions)

These 31 consecutive values form the typed prefix used by the Ghidra database:

typedef struct {
    TIFloat StatN, XMean, SumX, SumXSqr, StdX, StdPX, MinX, MaxX;
    TIFloat MinY, MaxY, YMean, SumY, SumYSqr, StdY, StdPY, SumXY;
    TIFloat Corr, MedX, Q1, Q3, QuadA, QuadB, QuadC, CubeD, QuartE;
    TIFloat MedX1, MedX2, MedX3, MedY1, MedY2, MedY3;
} TIStatResultsPrefix; /* 31 × 9 bytes at statVars */

This makes, for example, statVars.XMean and statVars.Corr distinct fields rather than unrelated constants 0x8A43 and 0x8ACA. The address table remains the byte-level evidence for the layout. [confirmed]

Continuing past the table (also .inc): PStat/ZStat/TStat/ChiStat/ FStat/DF/Phat…/MeanX1/StdX1/StatN1/MeanX2/StdX2/StatN2/StdXP2/ SLower/SUpper/SStat — these hold the inferential-stats outputs (the STAT-TESTS menu) and are written by the test commands, not by 1/2-Var Stats. An ANOVA block anovaf_vars (F_DF/F_SS/F_MS/E_DF/E_SS/E_MS) follows.

STAT-TESTS are separate command handlers. [confirmed] Z-Test/T-Test/χ²-Test/ 2-SampFTest/ANOVA( etc. come in as their own 2-byte t2ByteTok (0xBB)-prefixed command tokens — e.g. LinRegTTest=34h in the STAT command token map — and are not dispatched through _OneVar (whose token map is only F2–FF). They fill the PStat…SStat/anovaf_vars block above directly. Test handlers and helpers appear alongside accumulation, variance, median, and regression code within 3A:4A00–3A:7E60; that span also contains coefficients and UI data, not one continuous test engine. See STAT-TESTS engine. The per-test entry addresses are not exposed as named routines and remain [hypothesis].

A scratch byte stat_calc_command (0x8A36, immediately below statVars) holds the stat-command discriminator (the model index set from the command token) for the duration of the computation. Working list/element pointers used by the loop live in the OP-scratch RAM 0x84AF…0x84DB (84D3=median data ptr, 84D5/84D7=current x/y element ptr, 84D9=sums matrix base, 84DB=freq list ptr, 84B1/84B2=loop counters, 84B3=element count). [confirmed]

Recall by name: _Rcl_StatVar (00:2149, id 0x42DC) is a page-0 bcall wrapper (CALL 0x3E07, then RST 20h) that loads the named statVar into OP1; the VAT-level recall (_RclVarSym/rcl_var_push, see sub-vat-archive.md) routes the stat-var name tokens (tRegEq 0x01, tStatN 0x02, tXMean 0x03, … tCorr 0x12, the STATVARS token group) to it. The name-token values are in ti83plus.inc (tStatN=02h … tSumXY=11h, tCorr=12h, tMedX=13h, regression coefficients via tokens 16h–1Ah). [standard]


_OneVar STAT-CALC entry [confirmed]

bcall(_OneVar) enters the shared 1-Var, 2-Var, and polynomial/transformed regression path. Separate nonlinear regression entries require their own caller analysis. The parser invokes it after pushing the list arguments; the normalized selector derived from the command token selects the behavior.

_OneVar (3A:6420):
  SET 5,(IY+9)            ; statFlags: "stat computation active"
  LD B,0                  ; arg counter
  RES 1,(IY+0)
  RES 1,(IY+1a)
  LD (9817),0             ; clear a status byte
  LD HL,8499
  CALL 1b33  ; stage the parsed arg descriptor at 8499
  LD A,0FF
  LD (84af),A
  CALL _CkOP1Real (1942-ish) / arg-class checks …
  ; ---- argument parsing (6442..64de) ----
  ;   walks the parser argument list, accepting list-name tokens (0x24 list,
  ;   0x2A list-element, 0x1C/0x25/0x19 = freq/list variants); validates count;
  ;   _JError(0x8A) ARGUMENT / 0x88 SYNTAX on a bad arg list.
  ; ---- set up the data pointers (64e1..6503) ----
  LD HL,847a
  LD DE,8d2a
  CALL 1a9a  ; resolve the x-list (and y/freq) → 84D3..84DB
  POP AF
  LD (8a36),A          ; *** save the command code → model discriminator ***
  LD HL,6352
  CALL 27da        ; install an on-error cleanup frame
  CALL 6572                     ; accumulation pass
  CALL 2800
  CALL 6345         ; tear down frame
  ; ---- coefficient ordering (6506..652f) ----
  LD A,(8a36)
  CP 4
  JR NC,..  ; other selectors take further ordering checks
       ; A<4: exchange coefficient slots through IDs 16h and 17h
       LD HL,8aee      ; read the first coefficient
  …
  SET 7,(IY+9)                  ; mark results valid
  CALL 67c1 …                   ; finalize / median

Key facts read from the disassembly:

  • The command byte is saved in stat_calc_command and steers everything afterward.
  • LD HL,0x8AEE (= QuadA) is the regression coefficient destination; the solver writes a,b,c,d,e there in descending order of power.
  • _ErrStat (00:2741, id 0x44C2, code 0x15 “STAT”) and _ErrStatPlot (00:2759, code 0x1B) are the STAT-specific error raisers; the _OneVar body jumps to 0x2741 on e.g. fewer than the required data points. _ErrDimMismatch (0x2715) is raised if L1 and L2/freq lengths differ (the 21bb length compare at 6584/658a).

STAT command token map [confirmed]

The parser normalizes command selectors before the calculation path stores them in stat_calc_command (0x8A36). The source token bytes below must not be used directly as model indices. From ti83plus.inc:

TokenValueCommandModel
tOneVarF21-Var Statsone variable
tTwoVarF32-Var Statstwo variable
tLRF4LinReg(a+bx)degree-1 (a+bx form)
tLRExpF5ExpRegy=a·bˣ (log-linear)
tLRLnF6LnRegy=a+b·ln x (log-x)
tLRPwrF7PwrRegy=a·xᵇ (log-log)
tMedMedF8Med-Medresistant line
tQuadF9QuadRegdegree-2
tLR1FFLinReg(ax+b)degree-1 (ax+b form)

CubicReg/QuartReg use single-byte tokens FAh/FBh; SinReg=32h, Logistic=33h, LinRegTTest=34h are 2-byte t2ByteTok (0xBB)-prefixed tokens (their 32h/33h/34h values are the second byte after 0xBB). The stored model selector is not the polynomial degree: the dimension setup at 3A:65A8–3A:65C1 handles special selectors before subtracting two from the selected value. The coefficient fan-out depends on the resulting matrix dimensions. [confirmed]

SortA(/SortD( are separate tokens (tSortA=E3h, tSortD=E4h) with their own command handler — not _OneVar. The sort used here, stat_sort (3A:7935), is stat-internal: its only callers are stat_median_quartile (3A:79B9) and medmed_partition (3A:760F) (xref-confirmed), so it powers the 1-Var median/ quartile and Med-Med paths in Median, quartiles, extrema, and sorting. The SortA(/SortD( command sort is a different routine on page 0x02 (≈02:5939, comparator _CpOP1OP2) — see Matrices and lists.


Accumulation pass [confirmed]

This builds the power-sums for 1/2-Var Stats and the regression sum-setup. It makes a single pass over the data list(s), accumulating the power-sums needed for the mean, variance, and least-squares normal equations. Read from disassembly:

6572: CALL 6f90/6f7d         ; default freq = 1 if no freq list given
6584: CALL 21bb              ; if freq list present, length-check vs x-list
                             ;   → _ErrDimMismatch (2715) on mismatch
658a: LD HL,(84d3)          ; HL = first element ptr; DE = element count
6590: LD A,(8a36)           ; dispatch on command:
   CP 8 (Med-Med) → jump to the resistant-line path (760f/75e4 → 79b9)
   else compute the matrix dimension from the degree:
        CP 1c/25/19/9 → dim=4
        CP 5 (CubicReg) NC → dim+? ; default
   65c1: A = dim
   SUB 2
   PUSH AF
65cd: set up x/y element pointers (84d5/84d7/84db)
65f0: ---- per-element accumulator init ----
   LD DE,8a3a ; … CALL 1a92  ; StatN slot
   LD DE,8a94                ; YMean/Σy slots
   CALL 110f                 ; allocate the sums matrix (84d9 = base)
6646..66fe: ---- per-element loop ----
   6f6a  : conditionally logarithm-transform the current operand
   28e4/2297 : loop bound (RST FPSub / compare)
   6567  : helper = (RST 8: OP1→OP2)
   LD HL,(84af)
   CALL 6f7d ; _FPMult (238b)
           → forms the running power x^k · freq
   238a  : _FPSquare (Σx²)
   238b  : _FPMult   (Σxy, Σx^(i+j))
   RST 30: _FPAdd    → accumulate into the matrix cell / Σ-slot
   2999/29db/29a2 : guard-clear / OP-shuffle helpers
   66fe: JP C,6655  ; loop while elements remain

So one pass builds, for a degree-d fit, the symmetric moment matrix of power-sums Σxⁱ (i = 0 … 2d) and the right-hand side Σxⁱy, stored as a small 2-D array reached by the RAM trampoline helpers 00:3A8F/3AA1/3AA7/3AAD/3AB9 (matrix-element get/set by (row B, col C)). StatN, SumX, SumXSqr, SumY, SumYSqr, SumXY, MinX/MaxX/MinY/MaxY are filled here directly. [confirmed]

Non-polynomial regressions transform first [confirmed]: the front-end at 658a+ checks the command code and, for ExpReg/PwrReg (ln y), LnReg/PwrReg (ln x), pre-applies the logarithm to each element before accumulating, then exponentiates the resulting linear coefficients off page 0x3A. The per-element ln is selected by the transform helper at 3A:6F6A:

LD A,(8A36)
CP 4
RET NC
AND B
RET Z

It bcalls _LnX at 3A:6F72 only when the model code is below four and its intersection with the caller’s mask in B is nonzero. This helper neither loads an element nor advances a data pointer. The back-transform _EToX/_TenX lives on page 02; see Transcendentals. This is the standard “linearize, fit a line, transform back” method; r is the correlation of the transformed data.

Mean and standard deviation [confirmed]

After the pass, _OneVar finalizes the moments (3A:6762+):

6762: LD DE,8a67
CALL 6984   ; σx  (population) from Σx², Σx, n
6786: LD DE,8a5e
CALL 6989   ; Sx  (sample), via _Minus1 (n→n-1) at 677c
6798: LD DE,8a55
CALL 6998   ; Σx² slot
67a7: LD DE,8aa6
CALL 6998   ; Σy²   (2-Var)

The variance helpers (3A:6984/6989/6998) implement the one-pass formula var = (Σx² − n·x̄²)/N then √:

6998: _FPSquare(x̄) ; recall Σx² (15da) ; _FPMult ; (RST 30 _FPAdd / subtract) ; …
6989: CALL _FPDiv (2541)
CALL 3939 (_SqRoot wrapper) ; store

The only difference between σx (population) and Sx (sample) is the divisor: the population path divides by n, the sample path first does _Minus1 (00:2294, n−1) — confirmed at 3A:677C. x̄ = Σx / n via _FPDiv. [confirmed]


Regression solver [confirmed]

For a polynomial fit the moment matrix from the accumulation pass is the augmented normal-equations matrix [ M | Σxⁱy ]. _OneVar solves it in place by Gauss-Jordan elimination (not a closed-form determinant), then writes the coefficients to QuadA…QuartE.

67c6: build/copy the augmented matrix; 84d9 = base
67d4..67e3: scale the pivot row
67ec: LD BC,0202
CALL 3aad        ; pivot element (2,2)
67f7: CALL 212d                     ; zero guard -> _ErrDomain (84h)
67fa: RST 8 ; …                     ; pivot reciprocal
6804: CALL 2541 (_FPDiv)            ; divide row by pivot
680d..6815: elimination loop

The 3A:6845–6891 cluster, byte by byte:

6845  CALL 3939  (cross_page_jump)   ; OP1 = √OP1 (_SqRoot at 02:6E38)
6848  RST 08h   (_OP1ToOP2)          ; OP2 = √…
6849  CALL 1674  (_CpyTo1FPST)       ; OP1 ← FPS−9 (the saved numerator sum)
684C  CALL 2541  (_FPDiv)            ; OP1 = numerator/denominator = r
684F  LD A,0x12 ; CALL 213D          ; _Sto_StatVar(tCorr): Corr (8ACA) ← r
6854  CALL 1BA4  (_OP1Set0)          ; accumulator = 0
6857  POP BC / PUSH BC               ; BC = augmented-matrix row count
685B  LD B,2                         ; start at row 2 (first data column)
685D  loop:
        CALL 19EC (_OP1ToOP4); CALL 150A (_PopRealO2)   ; OP2 ← popped FPS value
        CALL 3AA7 (cross_page_jump)  ; matrix element (col B) → OP1
        CALL 238B (_FPMult)          ; element · value
        CALL 19FE; RST 30h (_FPAdd)  ; accumulate into OP4/OP1
        INC B until B = H            ; walk the column
6878  CALL 2903 (fp_st_slot7_op3)    ; stash the column sum
687B  CALL 1DEE  (_CkOP2FP0)         ; denominator zero?
687E  JR Z,6891                      ; yes → skip r² store
6880  CALL 2541  (_FPDiv)            ; ratio for r²/R²
6885  LD A,B; CP 2                   ; model order == 2 (linear)?
6888  LD A,0x35 / 0x36               ; id 0x35 = r² (slot 8C05), 0x36 = R² (8C0E)
688E  CALL 213D  (_Sto_StatVar)

The region forms r = num/den and stores it to Corr at 0x8ACA. It then accumulates a column-weighted residual sum over the augmented matrix. When the denominator is nonzero, it stores r² for linear fits or R² for higher-order fits in separate statVar slots at 0x8C05 and 0x8C0E. [confirmed]

68d6..6953: back-substitution — each coeff = (rhs − Σ known·M) / pivot
   (3aa7/3aa1 matrix access, 238b _FPMult, RST 30/RST 8 accumulate,
    24bd _InvOP1S to subtract, 2541 _FPDiv)
   each solved coefficient is stored via 69af → CALL 3ab9 (matrix set)
       then copied out to the QuadA..QuartE statVars block.
  • The zero guard at 3A:67F7 calls ram:212D. That helper calls _CkOP1FP0 and jumps to _ErrDomain on zero; this site raises DOMAIN (0x84), not SINGULAR MAT. Other matrix/regression guards must be classified separately. [confirmed]

  • The solver is dimension-generic: LinReg (2×2) → a,b; QuadReg (3×3) → a,b,c; CubicReg (4×4) → a,b,c,d; QuartReg (5×5) → a,b,c,d,e. The coefficients land in QuadA(8AEE) downward. [confirmed]

  • Correlation r and r² are computed for the linear models from the centred sums: $$r=\frac{\sum (x-\bar x)(y-\bar y)}{\sqrt{\sum (x-\bar x)^2\,\sum (y-\bar y)^2}}=\frac{n\sum xy-\sum x\sum y}{\sqrt{\big(n\sum x^2-(\sum x)^2\big)\big(n\sum y^2-(\sum y)^2\big)}}$$

    assembled with _FPMult/_FPSub/_SqRoot/ _FPDiv (the 6845/684c cluster) and stored to Corr (8ACA). The store offset is pinned: at 3A:684F the code does LD A,0x12
    CALL 0x213D, and 0x213D is _Sto_StatVar (the store counterpart of _Rcl_StatVar 00:2149 — both funnel through the 0x3E07 statVar dispatcher with the name id in A). Id 0x12 = tCorr = the Corr slot, so this single sequence is exactly r → Corr (8ACA). The preceding 3A:6845 _SqRoot/_FPDiv cluster forms the ratio; r² (and R² for higher-order fits) is the coefficient of determination derived by the following column-weighted pass. It is stored separately through IDs 0x35 and 0x36, at 0x8C05 and 0x8C0E respectively. [confirmed]

  • The fitted equation is also written to RegEQ (the Y=-style regression equation system var, recalled via token tRegEq=0x01) so RegEQ can be pasted or graphed. [standard]

The Med-Med model (F8) takes the resistant-line branch (3A:760F/79B9): it sorts, splits the x-sorted data into three equal partitions, takes the median (x,y) of each (MedX1/2/3, MedY1/2/3 at 8B1B…), and fits the line through the outer two summary points adjusted toward the middle — classic Tukey median-median. [standard]


Median, quartiles, extrema, and sorting [confirmed]

For 1-Var Stats the five-number summary needs the data sorted:

  • MinX/MaxX are tracked during the accumulation pass with running min/max compares.
  • The median/quartile path (3A:79B9 → 7A0B …) sorts a working copy via the internal sort stat_sort (3A:7935), then:
    • Med (MedX, 8AD3) = middle element (or mean of the two middle for even n),
    • Q1 (8ADC) = median of the lower half, Q3 (8AE5) = median of the upper half (TI’s “exclude the overall median when n is odd” convention), with frequency-weighted positions (the 7B30/7B4C/7B6E helpers walk the cumulative-frequency index, and 198d/238b interpolate the rank). The ROM path is [confirmed]. The quartile rule is [standard].

The five-number summary (minX, Q1, Med, Q3, maxX) is what the MED/box-plot stat plot reads back out of statVars.


Worked two-variable statistics and regression flow [hypothesis]

  1. Parser pushes the list args, sets A = command token, bcall(_OneVar).
  2. _OneVar parses args → x-list ptr (84D3), y-list (84D5), freq (84DB); saves the model code to stat_calc_command.
  3. Accumulation pass: one walk of L1/L2 building n, Σx, Σx², Σy, Σy², Σxy and minX/maxX/minY/maxY into statVars, plus the 2×2 moment matrix.
  4. Moments: $\bar x=\tfrac{\sum x}{n}$, $\bar y=\tfrac{\sum y}{n}$; the sample/population spreads $S_x,\sigma_x,S_y,\sigma_y$ via the variance helper (divide by $n-1$ vs $n$).
  5. Solve: Gauss-Jordan on the normal equations $\left[\begin{array}{cc|c}\sum 1&\sum x&\sum y\\\sum x&\sum x^2&\sum xy\end{array}\right]$ → b=slope, a=intercept → QuadA/QuadB; r → Corr, r² → its separate stat-variable slot; equation → RegEQ, pasted into Y1.
  6. Results displayed by the STAT-CALC report screen; all of x̄/Σx/…/a/b/r persist in statVars for later recall by name (_Rcl_StatVar).

Stat plots [standard]

Stat plots (Scatter tScatter=FE, xyLine FD, Histogram tHist=FC, box plots tBoxIcon, normal-prob) are drawn by the graphing subsystem, reading the five-number summary and the raw L1/L2 lists. _ErrStatPlot (00:2759, code 0x1B) guards an invalid/undefined plot configuration; _ZmStats (33:65DC, id 0x47A4) is the ZoomStat routine that auto-scales the window to the plotted list data (sets Xmin/Xmax/Ymin/Ymax from minX/maxX/minY/maxY). See sub-graphing.md. [standard]


DISTR functions

Distribution functions use the BB token family. For example, BB 0F is normalcdf( and BB 1B is normalpdf(; they are expression functions rather than _OneVar commands. The complete numerical caller paths remain open on this page. [standard]

The macro tools/macros/distr-normalcdf.macro enters normalcdf(0,1) through the interactive UI. Its visits to 39:4A02–39:4F5B belong to the MathPrint editor/layout family documented in Equation display. Whole-run coverage of those routines does not identify the distribution calculation. A reduced trace anchored around numeric evaluation is needed.

The coefficient table at 3A:554F below directly establishes a normal-tail approximation in the statistics code. Which DISTR entries use that approximation, and which use other integration or special-function routines, remains [hypothesis].


STAT-TESTS engine on page 3A [confirmed]

The inferential-statistics commands execute in their own engine on page 3A, sharing the bank with _OneVar but distinct from it. Three byte-pinned structures locate it:

Candidate PStat–SStat references. A ROM-wide byte-pattern scan (tools/ti84re/rom/scan_stat_writers.py, immediate or absolute operands landing in 0x8B5A–0x8C37) finds about 50 opcode-shaped candidates on page 3A (3A:4B15–3A:6BDC) plus candidates on pages 06, 35, 37, and 39. Because the scan does not recover instruction boundaries, these hits locate a search cluster but do not by themselves establish a writer count or exclude references on other pages. [hypothesis]

A TStat output stage at 3A:54C0–3A:54D9. The code loads StdX (0x8A5E) at 3A:54C1, divides through _FPDiv at 3A:54C5, and calls the subtraction/division helper at 3A:544C through 3A:54D4. It stores the result with LD A,24h at 3A:54D7 followed by _Sto_StatVar at 3A:54D9. The common resolver at 38:618A maps ID 24h to TStat at 0x8B6C. This pins a result-store stage, not every command caller. 3A:5500 instead belongs to the normal-tail arithmetic below. [confirmed]

The normal p-value coefficient table at 3A:554F. [confirmed] Nine-byte TIFloat constants, byte-verified in sequence:

AddrValueRole
3A:554F0.2316419threshold p
3A:55581.330274429coefficient b5
3A:5561-1.821255978coefficient b4
3A:556A1.781477937coefficient b3
3A:5573-0.356563782coefficient b2
3A:557C0.319381530coefficient b1

For nonnegative $z$, this coefficient set gives the Zelen–Severo upper-tail approximation $Q(z)\approx\varphi(z),(b_1t+b_2t^2+b_3t^3+b_4t^4+b_5t^5)$, where $Q(z)=1-\Phi(z)$ and $t=1/(1+pz)$. The loop at 3A:551F evaluates the five coefficients in descending order by Horner steps; LD HL,554Fh at 3A:550E pins the table start. The type bytes at 3A:5561 and 3A:5573 are 0x80, which supplies the negative signs on b4 and b2. The routine evaluates the polynomial using the absolute standardized argument (3A:550A). After multiplying by the normal density, it tests the saved argument’s sign at 3A:553F and conditionally calls 3A:447A to replace the result with 1-Q(|z|). Thus the returned tail has the correct symmetry for negative arguments. Caller-level conversion to a test’s PStat must be checked separately. [confirmed]

UI descriptor tables at 3A:7D00–3A:7E60. [confirmed] The same bank carries the test editor’s data. It includes alternative-hypothesis strings for the 1-PropZTest and 2-PropZTest menus, plus the F-test tail strings. It also contains SinReg and Logistic formula templates, three-byte dispatch stubs into fixed page 0 vectors, and an ascending handler-pointer array at 3A:7DF4–3A:7E1E. The mapping from array slots to menu items remains open.


Subsystem integration

  L1..L6 lists (VAT data)                 statVars (0x8A3A)  ← results, recall-by-name
        │ (VAT element access)                 ▲
        ▼                                       │ (_Rcl_StatVar 00:2149)
   _OneVar (3A:6420, id 0x4BA3)  ──►  per-element accumulation pass (3A:6572)
        │  cmd code → stat_calc_command          │  uses FP engine:
        │                                        │   RST30 _FPAdd, 238B _FPMult,
        ├─ moments / Sx,σx (3A:6984..)           │   238A _FPSquare, 2541 _FPDiv,
        ├─ Gauss-Jordan solve (3A:67C6..) ───►   │   3939 _SqRoot, 2294 _Minus1
        │     → QuadA..QuartE, Corr, RegEQ       │
        └─ sort + median/quartile (3A:7935/79B9) ┘
  errors: _ErrStat 00:2741 (0x15), _ErrStatPlot 00:2759 (0x1B),
          _ErrSingularMat 0x83, _ErrDimMismatch 00:2715 (0x8B)

The STAT subsystem is a thin data-driven front-end on page 0x3A that reads list data via the VAT, drives the page-0/page-02 BCD FP engine to build power-sums, then either finalizes the moments or runs an in-place Gauss-Jordan solve of the normal equations, depositing every output as a named TIFloat in the statVars block.


Routine index

space:addrnamewhat
3A:6420_OneVarShared 1/2-Var and regression entry, id 0x4BA3
3A:6572onevar_accumulateone-pass power-sum accumulation loop
3A:6567onevar_powmulrunning power·freq product (OP1→OP2, ×)
3A:6345onevar_frame_teardownrestore stat error frame
3A:6352onevar_frame_teardown_tailon-error tail calling onevar_frame_teardown
3A:6984stat_stddev_poppopulation variance/σ finalize (÷ n)
3A:6989stat_stddev_sampsample variance/S finalize (÷ n−1)
3A:6998stat_var_core(Σx²−n·x̄²) variance core + √
3A:67C6reg_gauss_solveGauss-Jordan solve of normal equations
3A:69AFreg_store_coeffwrite a solved coefficient (matrix set)
00:3A8F/3AA1/3AA7/3AAD/3AB9stat_mtx_index/get/setRAM trampolines for sums-matrix element access by (row,col)
3A:6F6Aconditional logarithm helperapply _LnX when the model selector and caller mask require it
3A:6F7D/6F90stat_freq_defaultdefault frequency = 1
3A:7935stat_sortstat-internal data sort (median/quartile, Med-Med)
3A:79B9stat_median_quartilemedian/Q1/Q3 + Med-Med medians
3A:760F/75E4medmed_partitionMed-Med 3-partition setup
3A:54C0–54D9TStat output stagearithmetic through StdX, _FPDiv, and 544C; _Sto_StatVar ID 24h at 54D9
3A:54FD–554Dnormal-tail arithmeticstandardize an operand and evaluate the coefficient polynomial
3A:554Fnormal_tail_coef_tblZelen–Severo coefficients (p, b5…b1) for the normal upper-tail approximation
00:2385fp_mult_constOP1 ×= (HL)-pointed float constant
00:2532fp_div_constOP1 ÷= (HL)-pointed float constant
00:2149_Rcl_StatVarrecall a named statVar into OP1, id 0x42DC
00:2741_ErrStatraise STAT error (code 0x15), id 0x44C2
00:2759_ErrStatPlotraise STAT PLOT error (0x1B), id 0x44D1
00:2294_Minus1OP1 − 1 (n→n−1 for sample stddev)
33:65DC_ZmStatsZoomStat — fit window to plotted data, id 0x47A4
00:2715_ErrDimMismatchlist length mismatch (0x8B)

RAM: statVars=0x8A3A, stat_calc_command=0x8A36, work pointers 0x84AF–0x84DB (84D3 x/median ptr, 84D5/84D7 element ptrs, 84D9 sums-matrix base, 84DB freq ptr, 84B1/84B2 loop counters, 84B3 element count). FP engine reused: RST 30h=_FPAdd, RST 08h=OP1→OP2, 00:238B=_FPMult, 00:238A=_FPSquare, 00:2541=_FPDiv, 00:2294=_Minus1, 02:6E38 via the fixed-page stub ram:3939 =_SqRoot, 24BD=_InvOP1S.

Remaining questions

  • Correlation stores. 3A:684F does LD A,0x12
    CALL 0x213D (_Sto_StatVar, ID 0x12 = tCorr), i.e. r → Corr (0x8ACA); r²/R² is the coefficient of determination from the following column-weighted pass, stored through IDs 0x35/0x36 at 0x8C05/0x8C0E. See the annotated 3A:6845–3A:6891 listing under Regression solver. [confirmed]
  • DISTR numerical cores. The interactive normalcdf( trace visits MathPrint UI routines, but its numerical evaluator has not been isolated. The normal-tail coefficients on page 3A are decoded; the complete DISTR caller graph and algorithms remain open.
  • STAT-TESTS (Z/T/χ²/F/ANOVA) fill PStat…SStat/anovaf_vars from their own engine on page 3A. A pinned TStat store, the normal-tail coefficient table, and the UI descriptor area provide separate anchors. See STAT-TESTS engine. The per-test entry addresses and the slot-to-menu mapping for the 3A:7DF4 pointer array remain [hypothesis]. The _Sto_StatVar/_Rcl_StatVar stubs (ram:213D/ram:2149) funnel through the stub at ram:3E07. Its descriptor 8A 61 78 selects the common stat-variable address resolver at 38:618A; the variable ID in A selects a RAM slot, not a separate cross-page descriptor.
  • stat_sort (3A:7935) is a 49-byte setup that validates/counts the elements then dispatches the compare-swap via rst 28h (the bcall site isn’t fully analyzed in the DB). The SortA(/SortD( command sort is a different routine (page 0x02, comparator _CpOP1OP2) — its complex-list ordering is documented in Matrices and lists.