{
 "schema_version": "0.40",
 "paper": {
  "title": "Admissibility of lagged single-source-of-error state space models: the per-lag eigenvalue check, the cancelled ARIMA form of the whole model, the step-down test and their implementation in smooth, for ETS, GUM and ETS+ARIMA",
  "contributions": [
   "C3",
   "C25",
   "C4",
   "C16",
   "C26",
   "C1",
   "C24",
   "C22"
  ],
  "highlights": [
   "C1",
   "C3",
   "C22",
   "C24",
   "D10"
  ],
  "autonomy": "human_supervised",
  "contribution_record": "complete",
  "origin": "native",
  "exploration": {
   "lab_record": "A9",
   "questions": 2,
   "hypotheses": {
    "total": 9,
    "supported": 9,
    "not_supported": 0,
    "inconclusive": 0,
    "revised": 0,
    "abandoned": 0,
    "open": 0
   },
   "tests": {
    "total": 9,
    "supported": 9,
    "not_supported": 0,
    "inconclusive": 0
   },
   "runs": {
    "total": 69,
    "confirmatory": 9,
    "exploratory": 60,
    "failed": 8
   }
  },
  "classification": {
   "keywords": [
    "exponential smoothing",
    "state space models",
    "admissible parameter space",
    "invertibility",
    "ARIMA reduced form",
    "Schur-Cohn stability test",
    "cyclotomic polynomials",
    "time series forecasting",
    "ARIMA",
    "forecastability"
   ],
   "subfield": "openalex:subfields/1703",
   "topics": [
    "openalex:T10142",
    "openalex:T11321",
    "openalex:T10217"
   ]
  },
  "licence": "CC-BY-4.0",
  "declarations": {
   "funding": [],
   "competing_interests": "None declared."
  },
  "study": "adam-admissible-bounds",
  "id": "entrylib:2026.000002",
  "version": 1,
  "date": "2026-11-10",
  "status": "active"
 },
 "contributors": [
  {
   "id": "P1",
   "type": "human",
   "name": "Ivan Svetunkov",
   "positions": [
    "supervisor",
    "guarantor"
   ],
   "orcid": "0000-0001-7826-0281",
   "credit_roles": [
    "conceptualization",
    "supervision"
   ]
  },
  {
   "id": "P2",
   "type": "agent",
   "name": "Claude Code research agent",
   "positions": [
    "author"
   ],
   "models": [
    {
     "model": "M1",
     "role": "sole"
    }
   ],
   "run_period": {
    "start": "2026-10-21",
    "end": "2026-10-22"
   },
   "tools": [
    "code_execution",
    "file_access",
    "web_search"
   ],
   "record_source": "harness",
   "credit_roles": [
    "conceptualization",
    "methodology",
    "software",
    "formal_analysis",
    "investigation",
    "writing_original_draft"
   ],
   "ai_tasks": [
    {
     "task": "ideation",
     "extent": "substantial"
    },
    {
     "task": "analysis",
     "extent": "full"
    },
    {
     "task": "code",
     "extent": "full"
    },
    {
     "task": "writing",
     "extent": "full"
    },
    {
     "task": "literature_search",
     "extent": "assisted"
    },
    {
     "task": "json_preparation",
     "extent": "full"
    }
   ],
   "system": {
    "name": "Claude Code",
    "version": "2.1.306"
   }
  },
  {
   "id": "P3",
   "type": "agent",
   "name": "Independent checker agent",
   "positions": [
    "contributor"
   ],
   "models": [
    {
     "model": "M2",
     "role": "sole"
    }
   ],
   "credit_roles": [
    "validation"
   ],
   "ai_tasks": [
    {
     "task": "review",
     "extent": "full"
    }
   ],
   "tools": [
    "code_execution",
    "file_access"
   ],
   "record_source": "self_reported",
   "run_period": {
    "start": "2026-10-21",
    "end": "2026-10-21"
   },
   "system": {
    "name": "Claude Code"
   }
  },
  {
   "id": "P4",
   "type": "agent",
   "name": "Independent checker of Q2 (ETS+ARIMA)",
   "positions": [
    "contributor"
   ],
   "models": [
    {
     "model": "M2",
     "role": "sole"
    }
   ],
   "run_period": {
    "start": "2026-10-22",
    "end": "2026-10-22"
   },
   "tools": [
    "code_execution",
    "file_access"
   ],
   "record_source": "self_reported",
   "credit_roles": [
    "validation"
   ],
   "ai_tasks": [
    {
     "task": "review",
     "extent": "full"
    }
   ],
   "system": {
    "name": "Claude Code"
   }
  }
 ],
 "models": [
  {
   "id": "M1",
   "provider": "Anthropic",
   "name": "Claude Opus",
   "version": "5.5",
   "identifier": "claude-opus-5-5",
   "accessed": "2026-10-21",
   "weights": "api_only"
  },
  {
   "id": "M2",
   "provider": "Anthropic",
   "name": "Claude Sonnet",
   "version": "5.5",
   "identifier": "claude-sonnet-5-5",
   "weights": "api_only",
   "accessed": "2026-10-21"
  }
 ],
 "definitions": [
  {
   "id": "D1",
   "term": "lagged SSOE model",
   "definition": "A pure additive single-source-of-error state space model $y_t = w' v_{t-l} + \\epsilon_t$, $v_t = F v_{t-l} + g \\epsilon_t$ with $k$ components, in which component $j$ of $v_{t-l}$ enters with its own lag $l_j$; its discount matrix is $D = F - g w'$ and its lag matrix is $L(B) = \\mathrm{diag}(B^{l_1}, \\dots, B^{l_k})$ for the backshift operator $B$; $\\Lambda(\\lambda) = \\mathrm{diag}(\\lambda^{l_1}, \\dots, \\lambda^{l_k})$ for a complex number $\\lambda$.",
   "kind": "method"
  },
  {
   "id": "D2",
   "term": "expanded discount matrix",
   "definition": "The transition matrix $\\tilde D$ of size $\\sum_j l_j$ of the lag-1 system equivalent to $v_t = D v_{t-l}$, in which component $j$ carries itself and its $l_j - 1$ lagged copies; $\\tilde F$, $\\tilde g$ and $\\tilde w$ are expanded in the same way, so that $\\tilde D = \\tilde F - \\tilde g \\tilde w'$.",
   "kind": "concept"
  },
  {
   "id": "D3",
   "term": "decaying weights",
   "definition": "A lagged SSOE model has decaying weights when the weights $\\tilde w' \\tilde D^j \\tilde g$ of the past observations in its fitted values tend to zero, that is, when every eigenvalue $\\lambda$ of its expanded discount matrix that is reachable from $\\tilde g$ and observable through $\\tilde w$ has $|\\lambda| < 1$; the largest such $|\\lambda|$ is its largest mode modulus. A mode that $\\tilde g$ does not reach but $\\tilde w$ sees carries an initial state whose effect is not covered: with $|\\lambda| > 1$ it grows.",
   "kind": "concept"
  },
  {
   "id": "D4",
   "term": "per-lag check",
   "definition": "The test applied by smoothEigens() of smooth 4.6.0 and of its repository until commit 4a44c1c (src/headers/eigenCalc.h) to models without adaptive regressors: every eigenvalue of every diagonal block of $D$, one block per unique lag, has modulus below 1; reimplemented in numpy as per_lag_max().",
   "kind": "method"
  },
  {
   "id": "D5",
   "term": "PBH reference",
   "definition": "The largest modulus among the eigenvalues $\\lambda$ of the expanded discount matrix for which the smallest singular values of $[\\lambda I - \\tilde D;\\ \\tilde w']$ and of $[\\lambda I - \\tilde D,\\ \\tilde g]$ both exceed $10^{-7}(\\|\\tilde D\\|_2 + \\|\\tilde g\\| + \\|\\tilde w\\|)$ (Popov-Belevitch-Hautus rank tests), computed with numpy as pbh_max().",
   "kind": "method"
  },
  {
   "id": "D6",
   "term": "cyclotomic cancellation",
   "definition": "The procedure that computes the coefficients of $\\theta(B) = \\det(I - D L(B))$ and $\\phi(B) = \\det(I - F L(B))$ by an inverse discrete Fourier transform of their values at the $N$-th roots of unity ($N$ the smallest power of 2 above $\\sum_j l_j$), and divides both by every cyclotomic polynomial $\\Phi_n(B)$, $n$ dividing one of the lags, for as long as it divides both with a remainder at most $10^{-9}$ times the sum of absolute coefficients; the quotient of $\\theta$ is the cancelled MA polynomial $\\theta^*(B)$.",
   "kind": "method"
  },
  {
   "id": "D7",
   "term": "step-down test",
   "definition": "The Levinson-Durbin step-down (Schur-Cohn) recursion on $1 + c_1 B + \\dots + c_n B^n$: for $j = n, \\dots, 1$, $\\kappa_j = c_j$ and $c_i \\leftarrow (c_i - \\kappa_j c_{j-i}) / (1 - \\kappa_j^2)$; the test passes when every $|\\kappa_j| < 1$, which holds if and only if all roots lie outside the unit circle (the $\\kappa_j$ are the partial autocorrelations of the autoregression with this polynomial).",
   "source": "B2",
   "kind": "method"
  },
  {
   "id": "D8",
   "term": "GUM",
   "definition": "Generalised Univariate Model of the smooth package: a lagged SSOE model whose $F$, $g$ and $w$ are all estimated.",
   "source": "B3",
   "kind": "method"
  },
  {
   "id": "D9",
   "term": "ETS(A,N,A)",
   "definition": "Exponential smoothing with additive error, no trend and additive seasonality of period $m$; here in the lagged form with a level of lag 1 and one seasonal state of lag $m$, $F = I$, $w = (1, 1)'$, $g = (\\alpha, \\gamma)'$.",
   "source": "B1",
   "kind": "method"
  },
  {
   "id": "D10",
   "term": "check of the whole model",
   "kind": "method",
   "definition": "Admissibility of a lagged SSOE model from the MA polynomial $\\theta(B) = \\det(I - D L(B))$ of its ARIMA form: $\\theta$ is divided by its common factors with $\\phi(B) = \\det(I - F L(B))$ by [[D6:cyclotomic cancellation]], and the model is accepted when the cancelled polynomial $\\theta^*$ has no root in $|B| \\le 1$ and, for a model with ARIMA components, the AR polynomial of its ARIMA part is stationary; its largest mode modulus is $1/\\min|B|$ over the roots of $\\theta^*$. In the numpy prototype (admissibility.py, confirm.py, ets_arima.py) the roots come from numpy; in smooth the [[D7:step-down test]] decides and bisection gives the modulus."
  },
  {
   "id": "D11",
   "term": "bisection for the largest root modulus",
   "kind": "method",
   "definition": "Bisection on $r$ over the [[D7:step-down test]] applied to $\\theta^*(B/r)$, which passes exactly when $1/|B| < r$ for every root $B$ of $\\theta^*$, so that the smallest such $r$ is the largest mode modulus; run to a width of 1e-10 in the prototype and to a tolerance of 1e-6 in smooth.",
   "part_of": [
    "D10"
   ]
  },
  {
   "id": "D12",
   "term": "smoothEigensCpp()",
   "kind": "method",
   "definition": "The [[D10:check of the whole model]] as implemented in smooth (src/headers/eigenCalc.h, shared by R and Python): the coefficients of $\\theta$ and $\\phi$ by inverse discrete Fourier transform, cyclotomic cancellation, the step-down test and bisection with tolerance 1e-6; called in R through smoothEigensR().",
   "broader": [
    "D10"
   ]
  },
  {
   "id": "D13",
   "term": "check of the parts apart",
   "kind": "method",
   "definition": "The check that adam() applied with bounds=\"admissible\" to models combining ETS and ARIMA before this study: the ETS part by the [[D4:per-lag check]], and the AR and MA polynomials of the ARIMA part for stationarity and invertibility, each apart from the others."
  },
  {
   "id": "D14",
   "term": "bounds checker of adam()",
   "kind": "method",
   "definition": "adam_bounds_checker() of adam(), om() and omg() in R (R/utils-adam.R) and of ADAM, OM and OMG in Python, with bounds=\"admissible\" after this study: smoothEigensCpp() on the whole model, with a shortcut that accepts a pure ARIMA model (without ETS and adaptive regressors) whose MA factors are invertible without running it; the penalty is zero, or 1e100 times the largest root modulus.",
   "broader": [
    "D10"
   ]
  },
  {
   "id": "D15",
   "term": "roots by numpy",
   "kind": "method",
   "definition": "The roots of a polynomial by numpy's roots (the eigenvalues of its companion matrix), and the admissibility decision and largest modulus $1/\\min|B|$ they give."
  },
  {
   "id": "D16",
   "term": "stability condition of the ADAM monograph",
   "kind": "method",
   "definition": "The condition of Section 5.4 of the ADAM monograph (eqs 5.20-5.22): every nonzero eigenvalue of each per-lag discount matrix $D_{m_i} = F_{m_i} - g_{m_i} w_{m_i}'$ has modulus below 1.",
   "source": "B4"
  },
  {
   "id": "D17",
   "term": "ETS(A,N,A) grid",
   "kind": "data",
   "definition": "The 3042 [[D9:ETS(A,N,A)]] models with $m = 4$ and $m = 12$ and $\\alpha$ and $\\gamma$ on the grid 0.05, 0.10, ..., 1.95 (confirm.py, plan PL1)."
  },
  {
   "id": "D18",
   "term": "random GUM models with lags (1, 12)",
   "kind": "data",
   "definition": "200 [[D8:GUM]] models with lags (1, 12): entries of $F$ normal with mean 0 and standard deviation 0.35, of $g$ with mean 0 and standard deviation 0.175, of $w$ with mean 1 and standard deviation 0.175 (confirm.py, seed 2026)."
  },
  {
   "id": "D19",
   "term": "random additive ETS and GUM models",
   "kind": "data",
   "definition": "The 500 models of plan PL3 (confirm.py --test cancel --seed 2026 --n 200): 200 additive ETS models (level; no, additive or damped trend with $\\phi$ in (0.8, 0.99); 0 to 2 seasonal lags from {4, 7, 12, 24, 52}; a constant with probability 0.3; $\\beta = 0$ with probability 0.1 and each $\\gamma = 0$ with probability 0.15; $\\alpha$ in (0.01, 1.9)), 100 GUM models with $F = I$, lags from {1, 4, 12}, $g$ uniform on (-0.3, 0.6) and $w$ normal with mean 1 and standard deviation 0.3, and 200 GUM models with lags from {1, 4, 12, 24} and normal $F$ (standard deviation 0.35).",
   "part_of": [
    "D20"
   ]
  },
  {
   "id": "D20",
   "term": "random additive ETS and GUM models with long seasonal lags",
   "kind": "data",
   "definition": "The 575 models of plan PL4 (confirm.py --test stepdown --seed 2026 --n 200): the 500 models of plan PL3 generated afresh, 50 additive ETS models with seasonal lags from {24, 168, 365} and 25 GUM models with lags (1, 24, 168) and normal $F$ (standard deviation 0.3). The generator allows MA polynomial degrees up to 536 (level, trend, seasonal lags 168 and 365, constant)."
  },
  {
   "id": "D21",
   "term": "four model families of the implementation test",
   "kind": "data",
   "definition": "200 models in each of four families (cpp_check.py --seed 2027 --n 200, plan PL6): additive ETS with 0 to 2 seasonal lags from {4, 7, 12, 24, 52}; additive ETS with 0 to 2 seasonal lags from {24, 168, 365}; GUM with $F = I$ and lags from {1, 4, 12}; GUM with normal $F$ (standard deviation 0.35) and lags from {1, 4, 12, 24}."
  },
  {
   "id": "D22",
   "term": "random ETS+ARIMA models",
   "kind": "data",
   "definition": "Random ADAM models combining additive ETS with ARIMA (ets_arima.py), 500 with ARIMA at lag 1 and 500 with seasonal ARIMA per seed (seed 2 for plans PL7 and PL8, seed 3 for plan PL9): ETS with a level; no, additive or damped trend; no or one seasonal lag $m$ in {4, 12}; smoothing parameters drawn from wide ranges, some fixed at 0; ARIMA with a stationary AR polynomial, differences and MA up to order 2 at lag 1 and 1 at lag $m$, 15% over-differenced (an MA root at one on the unit circle of a differenced lag); built in ADAM's state space form (one state per lag of the ARI and MA polynomials)."
  },
  {
   "id": "D23",
   "term": "ETS+ARIMA models of the checker's generator",
   "kind": "data",
   "definition": "Random ADAM ETS+ARIMA models from the generator of the checker P4 (code/checker/exact_oracle.py with lib.py), wider than the [[D22:random ETS+ARIMA models]]: 250 models for each of seeds 21-23 and 31-34."
  },
  {
   "id": "D24",
   "term": "ETS(A,N,A,A) with seasonal lags 24 and 168",
   "kind": "data",
   "definition": "The additive ETS model with a level and two seasonal states of lags 24 and 168, $\\alpha = 0.3$ and $\\gamma = (0.1, 0.05)$, in the lagged form."
  },
  {
   "id": "D25",
   "term": "starting point of gum()",
   "kind": "data",
   "definition": "The default starting point of gum() with orders (2, 2) and lags (1, 12): $F = I$, $g = 0.1$, $w = 1$."
  },
  {
   "id": "D26",
   "term": "comparison with a reference",
   "kind": "design",
   "definition": "Each model's admissibility decision, and its largest mode modulus where both find it inadmissible, computed by the method studied and by a reference on the same model (the [[D5:PBH reference]], the roots by numpy, the numpy prototype of the check of the whole model or an exact oracle); the result is the number of models whose decisions differ and the largest absolute difference of the modulus. In the planned tests, models whose reference modulus lies within 1e-8 of 1 are left out and counted."
  },
  {
   "id": "D27",
   "term": "timing benchmark",
   "kind": "design",
   "definition": "The time of a computation as the mean over 50 repeated calls (timing.py), or the time of a fit with bounds=\"admissible\" as the median over five or seven repeated fits of the package installed at -O2 from a worktree of each version (bench_eigens.R, timing_ets_arima.R), on one x86_64 machine."
  },
  {
   "id": "D28",
   "term": "discount recursion over 2400 periods",
   "kind": "design",
   "definition": "The full discount recursion $v_t = D v_{t-l}$ of a lagged SSOE model run for 2400 periods, from initial states set to one with no data and from zero states with one unit observation, its growth per period measured over the second half (book_check.py)."
  },
  {
   "id": "D29",
   "term": "admissibility decision",
   "kind": "variable",
   "definition": "Whether a method accepts a model as admissible ([[D3:decaying weights]]); compared between a method and a reference as the number of models on which the two differ."
  },
  {
   "id": "D30",
   "term": "largest mode modulus",
   "kind": "variable",
   "definition": "The largest modulus of the modes that decide admissibility: for the [[D5:PBH reference]] the largest $|\\lambda|$ of the reachable and observable eigenvalues of the [[D2:expanded discount matrix]], for the check of the whole model $1/\\min|B|$ over the roots $B$ of the cancelled MA polynomial, for the per-lag check the largest $|\\lambda|$ of its blocks; a model is admissible when it is below 1."
  },
  {
   "id": "D31",
   "term": "time of a computation",
   "kind": "variable",
   "definition": "The time of one call of a computation, as the mean over repeated calls.",
   "unit": "ms"
  },
  {
   "id": "D32",
   "term": "time of a fit",
   "kind": "variable",
   "definition": "The time of one fit, as the median over repeated fits.",
   "unit": "s"
  },
  {
   "id": "D33",
   "term": "log-likelihood of a fit",
   "kind": "variable",
   "definition": "The log-likelihood of a fitted model at its estimates."
  },
  {
   "id": "D34",
   "term": "growth per period",
   "kind": "variable",
   "definition": "The growth per period, over the second half of the recursion, of the effect $|w' v_{t-l}|$ of initial states set to one on the fitted value, and of the weight of one unit observation."
  },
  {
   "id": "D35",
   "term": "ETS(A,N,A) with m = 12",
   "kind": "data",
   "definition": "[[D9:ETS(A,N,A)]] with $m = 12$ at $(\\alpha, \\gamma) = (0.1, 0.1)$ and $(1.2, 0.9)$ (book_check.py)."
  },
  {
   "id": "D36",
   "term": "AirPassengers",
   "kind": "data",
   "definition": "Monthly totals of international airline passengers, 1949-1960 (144 observations): the AirPassengers series of R's datasets package."
  },
  {
   "id": "D37",
   "term": "BJsales",
   "kind": "data",
   "definition": "The sales series BJsales of R's datasets package (150 observations)."
  },
  {
   "id": "D38",
   "term": "synthetic hourly series",
   "kind": "data",
   "definition": "1008 hourly observations $100 + 10 \\sin(2\\pi t/24) + 5 \\sin(2\\pi t/168)$ plus standard normal noise, generated by bench_eigens.R after set.seed(41), as a ts of frequency 24, fitted with seasonal lags 24 and 168."
  },
  {
   "id": "D39",
   "term": "exact gcd oracle",
   "kind": "method",
   "definition": "Admissibility by rational determinants and the exact greatest common divisor of $\\theta$ and $\\phi$, which cancels any shared factor (code/checker/exact_oracle.py of the checker P4)."
  },
  {
   "id": "D40",
   "term": "random GUM models with lags (1, 24, 168)",
   "kind": "data",
   "definition": "GUM models with lags (1, 24, 168) and normal $F$ (standard deviation 0.3), as generated by confirm.py and timing.py."
  }
 ],
 "claims": [
  {
   "id": "C1",
   "statement": "The [[D4:per-lag check]] accepted all [[D17:3042 ETS(A,N,A) grid models]], 1482 of which do not have [[D3:decaying weights]], and 193 of [[D18:200 random GUM models with lags (1, 12)]], 10 of which do not have decaying weights.",
   "about": {
    "subject": "D4",
    "relation": "accepts models without",
    "object": "D3",
    "comparator": null,
    "conditions": [
     "D17",
     "D18"
    ]
   },
   "type": "descriptive",
   "role": "principal",
   "novelty": "refutation",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E1",
     "artefacts": [
      "A1",
      "A3"
     ],
     "results": [
      "E1.R1",
      "E1.R3",
      "E1.R4",
      "E1.R6"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H1",
    "outcome": "supported"
   },
   "planning": "confirmatory",
   "planned_at": "2026-10-21T15:21:29Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "seed": 2026,
     "edge_band": 1e-08,
     "pbh_tolerance": 1e-07,
     "cancellation_tolerance": 1e-09,
     "sample": "3042 ETS grid models and 200 random GUM models, fixed; no interim analysis"
    },
    "quantities": {
     "ets_bad": {
      "variable": "models accepted by the per-lag check that do not forget their initial states",
      "conditions": {
       "family": "ETS(A,N,A)"
      }
     },
     "gum_bad": {
      "variable": "models accepted by the per-lag check that do not forget their initial states",
      "conditions": {
       "family": "GUM"
      }
     }
    },
    "supported": "ets_bad > 0 and gum_bad > 0",
    "not_supported": "ets_bad == 0 and gum_bad == 0",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL1"
   },
   "scope": {
    "population": "pure additive lagged SSOE models",
    "conditions": [
     "ETS(A,N,A) with m = 4 and m = 12, alpha and gamma on the grid 0.05, 0.10, ..., 1.95",
     "GUM with lags (1, 12) and normal random F, g and w (standard deviations 0.35, 0.175, 0.175; mean of w 1)",
     "largest mode modulus from the PBH reference, band of 1e-8 around 1"
    ],
    "excludes": [
     "models with adaptive regressors",
     "multiplicative models"
    ]
   },
   "assumptions": [
    "C13",
    "C14"
   ],
   "limitations": [
    "L1",
    "L2"
   ],
   "relations": [
    {
     "type": "contradicts",
     "reference": "B3",
     "locator": "gum(), documentation of the argument bounds",
     "self": true,
     "note": "The documentation of gum() states that bounds = \"admissible\" guarantees the stability of the model."
    }
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "moderate",
     "rationale": "Deterministic counts on a fixed grid and one seeded GUM sample, resting on a numpy reimplementation of the per-lag check and a reference written by the same agent."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Re-ran confirm.py --test perlag --seed 2026 --n 200: ETS 1482 of 3042 and GUM 10 of 200 reproduced; per_lag_max implements D4 and pbh_max implements D5; counts unchanged with PBH tolerances 1e-9 to 1e-3 and with the cancelled-theta roots as reference. Noted that the earlier wording 'accepted 1482 of 3042' was ambiguous because all 3042 were accepted; the statement was reworded."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Reworded statement checked against a re-run at seed 2026: 3042 ETS accepted, 1482 of them not forgetting; 193 GUM accepted, 10 of them not forgetting."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C2",
   "statement": "The [[D4:per-lag check]] rejected 1 of [[D18:200 random GUM models with lags (1, 12)]] that have [[D3:decaying weights]].",
   "about": {
    "subject": "D4",
    "relation": "rejects models with",
    "object": "D3",
    "comparator": null,
    "conditions": [
     "D18"
    ]
   },
   "type": "descriptive",
   "role": "secondary",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E2",
     "artefacts": [
      "A1",
      "A3"
     ],
     "results": [
      "E2.R5"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H2",
    "outcome": "supported"
   },
   "planning": "confirmatory",
   "planned_at": "2026-10-21T15:21:33Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "seed": 2026,
     "edge_band": 1e-08,
     "pbh_tolerance": 1e-07,
     "cancellation_tolerance": 1e-09,
     "sample": "200 random GUM models, fixed; no interim analysis"
    },
    "quantities": {
     "gum_rej": {
      "variable": "models rejected by the per-lag check that forget their initial states",
      "conditions": {
       "family": "GUM"
      }
     }
    },
    "supported": "gum_rej > 0",
    "not_supported": "gum_rej == 0",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL2"
   },
   "scope": {
    "population": "GUM models",
    "conditions": [
     "GUM with lags (1, 12) and normal random F, g and w (standard deviations 0.35, 0.175, 0.175; mean of w 1)",
     "PBH reference below 1 - 1e-8"
    ],
    "excludes": [
     "models with adaptive regressors"
    ]
   },
   "assumptions": [
    "C13",
    "C14"
   ],
   "limitations": [
    "L2",
    "L3"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "low",
     "rationale": "One model out of 200 in one seeded sample; how far that model's reference lies from 1 was not recorded."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "1 of 200 reproduced; the cancellation-based reference gives the same model."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C3",
   "statement": "On [[D19:500 random additive ETS and GUM models]], the [[D29:admissibility decision]] from [[D10:the roots of the MA polynomial after cyclotomic cancellation]] differed from the [[D5:PBH reference]] on 0 models, and on the 172 models that both found inadmissible the [[D30:largest mode modulus]] differed from the reference by at most 4.4e-13.",
   "about": {
    "subject": "D10",
    "relation": "gives the same admissibility decision and largest mode modulus as",
    "object": [
     "D29",
     "D30"
    ],
    "comparator": "D5",
    "conditions": [
     "D19"
    ]
   },
   "type": "methodological",
   "role": "principal",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E3",
     "artefacts": [
      "A1",
      "A3"
     ],
     "results": [
      "E3.R1",
      "E3.R2"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H3",
    "outcome": "supported"
   },
   "planning": "confirmatory",
   "planned_at": "2026-10-21T15:21:36Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "seed": 2026,
     "edge_band": 1e-08,
     "pbh_tolerance": 1e-07,
     "cancellation_tolerance": 1e-09,
     "sample": "500 models, fixed; no interim analysis"
    },
    "quantities": {
     "mism": {
      "variable": "admissibility decisions that differ from the PBH reference"
     },
     "diff": {
      "variable": "max abs difference of max |lambda| from the PBH reference, inadmissible models"
     }
    },
    "supported": "mism == 0 and diff < 0.000001",
    "not_supported": "mism > 0 or diff >= 0.000001",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL3"
   },
   "scope": {
    "population": "pure additive lagged SSOE models",
    "conditions": [
     "additive ETS: level; no, additive or damped trend; 0 to 2 seasonal lags from {4, 7, 12, 24, 52}; optional constant; some persistence fixed at 0",
     "GUM with F = I and lags from {1, 4, 12}",
     "GUM with random F and lags from {1, 4, 12, 24}",
     "numpy prototype",
     "models within 1e-8 of the unit circle excluded (none occurred)"
    ],
    "excludes": [
     "ARIMA components",
     "CES",
     "adaptive regressors",
     "multiplicative models",
     "seasonal harmonics with non-integer periods (TBATS)",
     "the largest mode modulus of admissible models, where a common factor that is not cyclotomic can remain in the cancelled MA polynomial",
     "an eigenvalue of modulus above 1 shared by a reachable and observable mode and an unreachable or unobservable one"
    ]
   },
   "depends_on": [
    "C6",
    "C8",
    "C17"
   ],
   "assumptions": [
    "C14"
   ],
   "limitations": [
    "L2",
    "L3"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "moderate",
     "rationale": "A planned test on 500 seeded models with exact agreement, against a reference written by the same agent with the same numerical libraries."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "0 mismatches, 172 inadmissible models, max difference 4.39648e-13 reproduced; D6 implemented as defined; seeds 1-5 with n = 400 (1000 models each) also gave 0 mismatches and maximum differences from 2.4e-13 to 5.3e-12."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C4",
   "statement": "On [[D20:575 random additive ETS and GUM models]], including ETS models with up to two seasonal lags from {24, 168, 365} whose generator allows MA polynomial degrees up to 536, the [[D7:step-down test]] on the MA polynomial after [[D6:cyclotomic cancellation]] gave an [[D29:admissibility decision]] different from [[D15:the roots of that polynomial]] on 0 models.",
   "about": {
    "subject": "D7",
    "relation": "gives the same admissibility decision as",
    "object": [
     "D29"
    ],
    "comparator": "D15",
    "conditions": [
     "D20"
    ]
   },
   "type": "methodological",
   "role": "principal",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E4",
     "artefacts": [
      "A1",
      "A3"
     ],
     "results": [
      "E4.R1",
      "E4.R3"
     ]
    },
    {
     "kind": "cited",
     "reference": "B2"
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H4",
    "outcome": "supported"
   },
   "planning": "confirmatory_with_deviations",
   "planned_at": "2026-10-21T15:21:39Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "seed": 2026,
     "edge_band": 1e-08,
     "pbh_tolerance": 1e-07,
     "cancellation_tolerance": 1e-09,
     "sample": "575 models, fixed; no interim analysis"
    },
    "quantities": {
     "mism": {
      "variable": "step-down decisions that differ from the decision by the roots"
     }
    },
    "supported": "mism == 0",
    "not_supported": "mism > 0",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL4"
   },
   "limitations": [
    "L3",
    "L4",
    "L5",
    "L8"
   ],
   "scope": {
    "population": "pure additive lagged SSOE models",
    "conditions": [
     "additive ETS: level; no, additive or damped trend; 0 to 2 seasonal lags from {4, 7, 12, 24, 52}; optional constant; some persistence fixed at 0",
     "GUM with F = I and lags from {1, 4, 12}",
     "GUM with random F and lags from {1, 4, 12, 24}",
     "additive ETS with up to two seasonal lags from {24, 168, 365}",
     "GUM with random F and lags (1, 24, 168)",
     "numpy prototype"
    ],
    "excludes": [
     "ARIMA components",
     "CES",
     "adaptive regressors",
     "multiplicative models",
     "seasonal harmonics with non-integer periods (TBATS)"
    ]
   },
   "depends_on": [
    "C3"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "moderate",
     "rationale": "A planned test on 575 seeded models with exact agreement; the reference roots at high degree were not checked by a second method."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "disputed",
     "extent": "partial",
     "notes": "On the earlier statement 'MA polynomials of degree up to 366': 0 step-down mismatches on 575 models reproduced, but the statement's description 'degree up to 366' was false: instrumented runs reached degree 535 before cancellation and 533 after.",
     "resolution": "The statement was reworded to the generator's bound of 536, the departure from the plan's text was recorded as a deviation (limitation L5), and the recheck confirmed the reworded statement."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "partial",
     "notes": "0 mismatches on 575 models reproduced; the bound of 536 holds by construction (1 + 1 + 168 + 365 + 1), with 535 measured before cancellation and 533 after, but no recorded result holds the realised degree."
    }
   ],
   "assumptions": [
    "C19"
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C5",
   "statement": "On the 198 models among [[D20:575 random additive ETS and GUM models]] whose cancelled MA polynomial $\\theta^*$ has a root inside the unit circle, [[D11:bisection on $r$ with the step-down test applied to $\\theta^*(B/r)$]] gave [[D30:$1/\\min|B|$ over the roots $B$ of $\\theta^*$]] within 5.8e-11 of the value from [[D15:numpy's roots]].",
   "about": {
    "subject": "D11",
    "relation": "gives the same largest mode modulus as",
    "object": [
     "D30"
    ],
    "comparator": "D15",
    "conditions": [
     "D20"
    ]
   },
   "type": "methodological",
   "role": "secondary",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E5",
     "artefacts": [
      "A1",
      "A3"
     ],
     "results": [
      "E5.R1"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H5",
    "outcome": "supported"
   },
   "planning": "confirmatory_with_deviations",
   "planned_at": "2026-10-21T15:21:42Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "seed": 2026,
     "edge_band": 1e-08,
     "pbh_tolerance": 1e-07,
     "cancellation_tolerance": 1e-09,
     "sample": "the inadmissible models among 575, fixed; no interim analysis"
    },
    "quantities": {
     "diff": {
      "variable": "max abs difference of max |lambda|, bisection against roots"
     }
    },
    "supported": "diff < 0.00000001",
    "not_supported": "diff >= 0.00000001",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL5"
   },
   "limitations": [
    "L3",
    "L4",
    "L5"
   ],
   "scope": {
    "population": "inadmissible pure additive lagged SSOE models",
    "conditions": [
     "additive ETS: level; no, additive or damped trend; 0 to 2 seasonal lags from {4, 7, 12, 24, 52}; optional constant; some persistence fixed at 0",
     "GUM with F = I and lags from {1, 4, 12}",
     "GUM with random F and lags from {1, 4, 12, 24}",
     "additive ETS with up to two seasonal lags from {24, 168, 365}",
     "GUM with random F and lags (1, 24, 168)",
     "bisection to a width of 1e-10",
     "numpy prototype"
    ],
    "excludes": [
     "ARIMA components",
     "CES",
     "adaptive regressors",
     "multiplicative models",
     "seasonal harmonics with non-integer periods (TBATS)"
    ]
   },
   "assessments": [
    {
     "by": "author",
     "strength": "low",
     "rationale": "The difference is bounded by the bisection width of 1e-10 once the step-down decisions on the scaled polynomials are right, so the test checks those decisions and the bisection logic rather than an independent accuracy."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "198 inadmissible models and 5.8137e-11 reproduced; the difference is bounded by the 1e-10 bisection width by construction, so the result checks the bisection logic, and the values are not compared with the PBH reference."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "partial",
     "notes": "198 models and 5.8137e-11 reproduced and the rewording as 1/min|B| matches the bisection; the scope then omitted two of the four model families, since added."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C16",
   "statement": "On [[D21:800 random additive ETS and GUM models in four families]], [[D12:the implementation of the check in smooth (smoothEigensCpp() through smoothEigensR())]] gave the same [[D29:decision]] as [[D10:the numpy prototype]] on every model, a [[D30:largest root modulus]] within the bisection tolerance of it on the models both found inadmissible, and the same modulus and MA polynomial on three consecutive calls with each model.",
   "about": {
    "subject": "D12",
    "relation": "gives the same admissibility decision and largest mode modulus as",
    "object": [
     "D29",
     "D30"
    ],
    "comparator": "D10",
    "conditions": [
     "D21"
    ]
   },
   "type": "methodological",
   "role": "principal",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E13",
     "artefacts": [
      "A5",
      "A8"
     ],
     "results": [
      "E13.T1.r1",
      "E13.T1.r2",
      "E13.T1.r3",
      "E13.T1.r4"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H6",
    "outcome": "supported"
   },
   "planning": "confirmatory",
   "planned_at": "2026-10-22T10:03:01Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "seed": 2027,
     "tolerance": 1.1e-06,
     "sample": "800 models, fixed; no interim analysis"
    },
    "quantities": {
     "m1": {
      "variable": "admissibility decisions of the C++ core that differ from the prototype",
      "conditions": {
       "family": "ETS"
      }
     },
     "d1": {
      "variable": "max abs difference of the largest root modulus on inadmissible models, C++ core against prototype",
      "conditions": {
       "family": "ETS"
      }
     },
     "r1": {
      "variable": "max abs difference between three calls of the C++ core on the same model",
      "conditions": {
       "family": "ETS"
      }
     },
     "m2": {
      "variable": "admissibility decisions of the C++ core that differ from the prototype",
      "conditions": {
       "family": "ETS high degree"
      }
     },
     "d2": {
      "variable": "max abs difference of the largest root modulus on inadmissible models, C++ core against prototype",
      "conditions": {
       "family": "ETS high degree"
      }
     },
     "r2": {
      "variable": "max abs difference between three calls of the C++ core on the same model",
      "conditions": {
       "family": "ETS high degree"
      }
     },
     "m3": {
      "variable": "admissibility decisions of the C++ core that differ from the prototype",
      "conditions": {
       "family": "GUM identity"
      }
     },
     "d3": {
      "variable": "max abs difference of the largest root modulus on inadmissible models, C++ core against prototype",
      "conditions": {
       "family": "GUM identity"
      }
     },
     "r3": {
      "variable": "max abs difference between three calls of the C++ core on the same model",
      "conditions": {
       "family": "GUM identity"
      }
     },
     "m4": {
      "variable": "admissibility decisions of the C++ core that differ from the prototype",
      "conditions": {
       "family": "GUM random"
      }
     },
     "d4": {
      "variable": "max abs difference of the largest root modulus on inadmissible models, C++ core against prototype",
      "conditions": {
       "family": "GUM random"
      }
     },
     "r4": {
      "variable": "max abs difference between three calls of the C++ core on the same model",
      "conditions": {
       "family": "GUM random"
      }
     }
    },
    "supported": "m1 == 0 and d1 < 0.0000011 and r1 == 0 and m2 == 0 and d2 < 0.0000011 and r2 == 0 and m3 == 0 and d3 < 0.0000011 and r3 == 0 and m4 == 0 and d4 < 0.0000011 and r4 == 0",
    "not_supported": "m1 > 0 or d1 >= 0.0000011 or r1 > 0 or m2 > 0 or d2 >= 0.0000011 or r2 > 0 or m3 > 0 or d3 >= 0.0000011 or r3 > 0 or m4 > 0 or d4 >= 0.0000011 or r4 > 0",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL6"
   },
   "scope": {
    "population": "pure additive lagged SSOE models",
    "conditions": [
     "additive ETS: level; no, additive or damped trend; 0 to 2 seasonal lags from {4, 7, 12, 24, 52}; optional constant; some persistence fixed at 0",
     "additive ETS with 0 to 2 seasonal lags from {24, 168, 365}",
     "GUM with F = I and lags from {1, 4, 12}",
     "GUM with random F and lags from {1, 4, 12, 24}",
     "R 4.3.3, -O0 build of pkgload"
    ],
    "excludes": [
     "ARIMA components",
     "CES",
     "adaptive regressors",
     "multiplicative models",
     "seasonal harmonics with non-integer periods (TBATS)"
    ]
   },
   "depends_on": [
    "C3",
    "C4",
    "C18",
    "C20"
   ],
   "assumptions": [
    "C19"
   ],
   "limitations": [
    "L2",
    "L3",
    "L4",
    "L8"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "moderate",
     "rationale": "A planned test on 800 seeded models with exact agreement of the decisions, against a prototype written by the same agent."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "cpp_check.py --seed 2027 --n 200 reproduced E13 to the last digit (0 mismatches; 9.4885e-7, 9.5266e-7, 9.4058e-7, 9.4854e-7; three-call differences 0); smoothEigensR() wraps the polynomial check of eigenCalc.h; 720 more ETS models sharing F in groups of 12 gave 0 mismatches. Noted that 9.5e-7 is the bisection resolution and that the three calls cover the modulus and the MA polynomial only; the statement was reworded."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C6",
   "statement": "For a [[D1:lagged SSOE model]], ignoring the initial states, $\\det(I - D L(B))\\, \\epsilon_t = \\det(I - F L(B))\\, y_t$, so the model has the ARIMA form with AR polynomial $\\phi(B) = \\det(I - F L(B))$ and MA polynomial $\\theta(B) = \\det(I - D L(B))$.",
   "about": {
    "subject": "D1",
    "relation": "has the ARIMA form with",
    "object": "AR polynomial det(I - F L(B)) and MA polynomial det(I - D L(B))",
    "comparator": null,
    "conditions": [
     "initial states ignored"
    ]
   },
   "type": "formal",
   "role": "supporting",
   "novelty": "extension",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E6"
    },
    {
     "kind": "consensus"
    },
    {
     "kind": "simulation",
     "evidence": "E10",
     "artefacts": [
      "A1",
      "A2"
     ]
    }
   ],
   "scope": {
    "population": "pure additive lagged SSOE models",
    "conditions": [
     "identity of lag-operator polynomials, initial states ignored"
    ]
   },
   "relations": [
    {
     "type": "extends",
     "reference": "B1",
     "locator": "Chapter 11",
     "self": false,
     "note": "Hyndman, Koehler, Ord and Snyder relate the reduced forms of linear innovations state space models to ARIMA models."
    }
   ],
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Steps S1-S7 of E6 re-derived; simulated residual of the identity on 40 random GUMs at late t at most 1.7e-15 relative; the identity holds after start-up (initial states ignored), which was then in the scope only and is now in the statement."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "The statement now carries the condition on initial states."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C7",
   "statement": "If the discount matrix $D$ of a [[D1:lagged SSOE model]] is block-diagonal with one block $D_{ll}$ per unique lag $l$, every eigenvalue of the [[D2:expanded discount matrix]] has modulus $|\\mu|^{1/l}$ for an eigenvalue $\\mu$ of some $D_{ll}$, so all of them lie inside the unit circle exactly when the [[D4:per-lag check]] passes.",
   "about": {
    "subject": "D4",
    "relation": "passes exactly when every eigenvalue lies inside the unit circle of",
    "object": "D2",
    "comparator": null,
    "conditions": [
     "discount matrix block-diagonal across lags"
    ]
   },
   "type": "formal",
   "role": "secondary",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E7"
    }
   ],
   "scope": {
    "population": "lagged SSOE models whose discount matrix is block-diagonal across lags"
   },
   "verification": "agent_checked",
   "depends_on": [
    "C15"
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Re-derived by a Schur complement; 50 random block-diagonal D with lags from {1, 3, 4} gave moduli |mu|^(1/l) and agreeing decisions. Noted that the RN2 example labelled block-diagonal is lower-triangular, and that the claim does not cover ETS or GUM, whose D is not block-diagonal."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "E7.S1 now rests on C15 for a general M; S2 needs the components grouped by lag, which a simultaneous permutation allows; the claim does not cover ETS or GUM, whose D is not block-diagonal."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C8",
   "statement": "An eigenvalue $\\lambda \\neq 0$ of the expanded transition matrix $\\tilde F$ with an eigenvector unobservable through $\\tilde w$ or a left eigenvector unreachable from $\\tilde g$ is an eigenvalue of the [[D2:expanded discount matrix]], and $1/\\lambda$ is a common root of $\\phi(B) = \\det(I - F L(B))$ and $\\theta(B) = \\det(I - D L(B))$.",
   "about": {
    "subject": "a nonzero eigenvalue of the expanded transition matrix that is unobservable or unreachable",
    "relation": "is an eigenvalue of",
    "object": "D2",
    "comparator": null,
    "conditions": []
   },
   "type": "formal",
   "role": "supporting",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E8"
    }
   ],
   "scope": {
    "population": "pure additive lagged SSOE models"
   },
   "depends_on": [
    "C15"
   ],
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Steps re-derived and checked on 5 random GUMs with a constructed unobservable mode (residuals about 1e-14). Noted that step S3 rested on the general identity of the expansion rather than on C7; the dependency now points to C15."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "E8.S3 now cites C15 in its lambda != 0 form; S4 follows with M = F and M = D."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C9",
   "statement": "For [[D9:ETS(A,N,A)]] with any period $m$ and any $\\alpha$ and $\\gamma$, $B = 1$ is a root of both $\\theta(B) = (1 - (1-\\alpha)B)(1 - (1-\\gamma)B^m) - \\alpha\\gamma B^{m+1}$ and $\\phi(B) = (1 - B)(1 - B^m)$, so the [[D2:expanded discount matrix]] has an eigenvalue equal to 1.",
   "about": {
    "subject": "D9",
    "relation": "has an eigenvalue equal to 1 in its",
    "object": "D2",
    "comparator": null,
    "conditions": [
     "any period m",
     "any alpha and gamma"
    ]
   },
   "type": "formal",
   "role": "secondary",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E9"
    }
   ],
   "scope": {
    "population": "ETS(A,N,A) models"
   },
   "depends_on": [
    "C15"
   ],
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "theta matches the closed form; det(I - D~) about 1e-17 for m = 1, 2, 4, 7, 12, 24; noted that step S5 needs the identity of the expansion, now cited as C15."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "E9.S5 now cites C15 at lambda = 1, giving det(I - D~) = theta(1) = 0."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C10",
   "statement": "For [[D24:ETS(A,N,A,A) with seasonal lags 24 and 168, $\\alpha = 0.3$ and $\\gamma = (0.1, 0.05)$]], [[D6:cyclotomic cancellation]] removed a common factor from the MA polynomial, and the [[D30:largest mode modulus]] after cancellation, just below one, equalled the [[D5:PBH reference]] to within rounding error.",
   "about": {
    "subject": "D6",
    "relation": "gives the same value of",
    "object": [
     "D30"
    ],
    "comparator": "D5",
    "conditions": [
     "D24"
    ]
   },
   "type": "descriptive",
   "role": "secondary",
   "novelty": "no_prior_found",
   "planning": "exploratory",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E10",
     "artefacts": [
      "A1",
      "A2"
     ],
     "results": [
      "E10.T1.r1"
     ]
    }
   ],
   "scope": {
    "population": "ETS(A,N,A,A) with seasonal lags 24 and 168",
    "conditions": [
     "alpha = 0.3, gamma = (0.1, 0.05)",
     "numpy prototype"
    ]
   },
   "assumptions": [
    "C14"
   ],
   "limitations": [
    "L2"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "low",
     "rationale": "Exploratory single case, chosen by the agent while designing the method."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Degree 193, shared factor 25, 0.9999965469723225 against PBH 0.9999965469723241."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C11",
   "statement": "For [[D25:the default starting point of gum() with orders (2, 2) and lags (1, 12)]] ($F = I$, $g = 0.1$, $w = 1$), [[D6:cyclotomic cancellation]] removed a common factor from the MA polynomial, and the [[D30:largest mode modulus]] after cancellation equalled the [[D5:PBH reference]] to within rounding error.",
   "about": {
    "subject": "D6",
    "relation": "gives the same value of",
    "object": [
     "D30"
    ],
    "comparator": "D5",
    "conditions": [
     "D25"
    ]
   },
   "type": "descriptive",
   "role": "secondary",
   "novelty": "no_prior_found",
   "planning": "exploratory",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E10",
     "artefacts": [
      "A1",
      "A2"
     ],
     "results": [
      "E10.T1.r2"
     ]
    }
   ],
   "scope": {
    "population": "GUM with orders (2, 2) and lags (1, 12)",
    "conditions": [
     "F = I, g = 0.1, w = 1",
     "numpy prototype"
    ]
   },
   "assumptions": [
    "C14"
   ],
   "limitations": [
    "L2"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "low",
     "rationale": "Exploratory single case, chosen by the agent while designing the method."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Degree 26, shared factor 14, 0.9829371631611427 against PBH 0.9829371631611421."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C12",
   "statement": "For an admissible and an inadmissible [[D40:random GUM model with lags (1, 24, 168)]] and the cancelled MA polynomial of [[D24:an ETS(A,N,A,A) model with seasonal lags 24 and 168]], the [[D7:step-down test]] was more than twenty times faster than [[D15:all roots by numpy's companion-matrix eigenvalues]].",
   "about": {
    "subject": "D7",
    "relation": "takes less time than",
    "object": null,
    "comparator": "D15",
    "conditions": [
     "D40",
     "D24"
    ]
   },
   "type": "descriptive",
   "role": "secondary",
   "novelty": "no_prior_found",
   "planning": "exploratory",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E12",
     "artefacts": [
      "A1",
      "A4"
     ],
     "results": [
      "E12.T1.r1",
      "E12.T1.r2",
      "E12.T1.r3"
     ]
    }
   ],
   "scope": {
    "population": "GUM with lags (1, 24, 168) and ETS(A,N,A,A) with seasonal lags 24 and 168",
    "conditions": [
     "numpy, Python 3.13, one x86_64 machine with 4 CPUs, mean of 50 repeats",
     "step-down recursions of 193, 170 and 168 steps"
    ]
   },
   "assessments": [
    {
     "by": "author",
     "strength": "low",
     "rationale": "Exploratory timings on one machine for three polynomials, in Python, where the interpreter's overhead dominates the step-down recursion."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "disputed",
     "extent": "partial",
     "notes": "Checked an earlier statement based on run RN2 (step-down 0.007 ms, roots 22 ms, coefficients 4.7 ms): the order of magnitude and ranking reproduced, but the timed polynomial was inadmissible and the step-down stopped after 1 of 193 steps; a full recursion took about 0.5 ms.",
     "resolution": "The claim was replaced by timings from run RN13 with full recursions (193, 170 and 168 steps), which the recheck reproduced."
    },
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "timing.py --seed 3 --repeats 50: 193, 170 and 168 steps; step-down 0.90, 0.57 and 0.43 ms against roots 24.5, 19.7 and 17.9 ms; same order and ranking, with load noise of 30 to 40 percent in the step-down times, so the times should not be read finer than a factor of two."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C13",
   "statement": "The numpy function per_lag_max() returns the same largest eigenvalue modulus as smoothEigensCpp() of smooth 4.6.0 (replaced in commit 4a44c1c) for models with a constant measurement vector and without adaptive regressors.",
   "type": "methodological",
   "role": "supporting",
   "support": [
    {
     "kind": "assumption"
    }
   ],
   "assumption_category": "methodological",
   "check": "unchecked",
   "verifiability": "not_applicable",
   "verifiability_flags": []
  },
  {
   "id": "C14",
   "statement": "The [[D5:PBH reference]] with relative rank tolerance 1e-7 classifies every eigenvalue of modulus at least 1 of the [[D2:expanded discount matrix]] of the tested models correctly as both reachable and observable or not.",
   "type": "methodological",
   "role": "supporting",
   "support": [
    {
     "kind": "assumption"
    }
   ],
   "assumption_category": "methodological",
   "check": "unchecked",
   "verifiability": "not_applicable",
   "verifiability_flags": []
  },
  {
   "id": "C15",
   "statement": "For the lag-1 expansion $\\tilde M$ of $v_t = M v_{t-l}$ in a [[D1:lagged SSOE model]], $\\det(\\lambda I - \\tilde M) = \\det(\\Lambda(\\lambda) - M)$, which equals $\\lambda^{\\sum_j l_j} \\det(I - M L(1/\\lambda))$ for $\\lambda \\neq 0$.",
   "about": {
    "subject": "D1",
    "relation": "has as characteristic polynomial of its lag-1 expansion",
    "object": "det(Lambda(lambda) - M)",
    "comparator": null,
    "conditions": [
     "any square matrix M of size k"
    ]
   },
   "type": "formal",
   "role": "supporting",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E11"
    }
   ],
   "scope": {
    "population": "pure additive lagged SSOE models",
    "conditions": [
     "any square matrix $M$ of size $k$"
    ]
   },
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Steps S1-S6 of E11 re-derived; on 200 random models with lags from {1, 2, 3, 5} at complex lambda the identities of S2, S3, S5 and S6 held to relative errors of at most 7.3e-15; the rule of S6 was corrected to factor Lambda on the right."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C17",
   "statement": "For a [[D1:lagged SSOE model]] with $\\theta(B) = \\det(I - D L(B))$ and $\\phi(B) = \\det(I - F L(B))$, the roots of $\\theta(B) / \\gcd(\\theta(B), \\phi(B))$ are exactly the reciprocals $1/\\lambda$ of the nonzero eigenvalues $\\lambda$ of the reachable and observable part of the [[D2:expanded discount matrix]] (its Kalman decomposition), with their multiplicities.",
   "about": {
    "subject": "D2",
    "relation": "has, in its reachable and observable part, the reciprocals of the roots of",
    "object": "theta(B) / gcd(theta(B), phi(B))",
    "comparator": null,
    "conditions": []
   },
   "type": "formal",
   "role": "supporting",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E14"
    },
    {
     "kind": "consensus"
    }
   ],
   "scope": {
    "population": "pure additive lagged SSOE models",
    "conditions": [
     "the definition D3 agrees with this part unless an eigenvalue is shared by the reachable and observable part and the rest"
    ]
   },
   "depends_on": [
    "C6",
    "C15"
   ],
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Re-derived S1-S5; exact rational arithmetic against the Kalman decomposition on 300 random lagged models (159 with an unreachable or unobservable part) agreed; noted that S5 needed the reversal, the normalisation and the coprimality under reversal spelled out, since added."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C18",
   "statement": "For a polynomial $c$ with $c(0) \\neq 0$ and $r > 0$, the [[D7:step-down test]] passes on $c(B/r)$ if and only if $1/|B| < r$ for every root $B$ of $c$.",
   "about": {
    "subject": "D7",
    "relation": "passes on c(B/r) exactly when every root B of c has 1/|B| below",
    "object": "r",
    "comparator": null,
    "conditions": [
     "c(0) nonzero",
     "r > 0"
    ]
   },
   "type": "formal",
   "role": "supporting",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E15"
    },
    {
     "kind": "cited",
     "reference": "B2"
    }
   ],
   "scope": {
    "population": "real polynomials with a nonzero constant term"
   },
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "The scaling is correct and the equivalence rests on D7 and B2; noted the missing division by c(0) and the citation of D7 for a substitution in E15, since corrected."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C19",
   "statement": "In additive ETS models, and in GUM models with an identity transition or with transition, persistence and measurement in general position, every factor shared by $\\theta(B)$ and $\\phi(B)$ with a root in $|B| \\le 1$ is a product of cyclotomic polynomials $\\Phi_n(B)$ with $n$ dividing a lag of the model.",
   "type": "methodological",
   "role": "supporting",
   "support": [
    {
     "kind": "assumption"
    }
   ],
   "assumption_category": "theoretical",
   "check": "unchecked",
   "verifiability": "not_applicable",
   "verifiability_flags": []
  },
  {
   "id": "C20",
   "statement": "For a square matrix $M$ of size $k$ and lags $l_1, \\dots, l_k$, $\\det(I - M L(B)) = \\sum_{S \\subseteq \\{1, \\dots, k\\}} (-1)^{|S|} \\det(M_{SS})\\, B^{\\sum_{j \\in S} l_j}$, with $\\det(M_{\\emptyset\\emptyset}) = 1$.",
   "about": {
    "subject": "det(I - M L(B))",
    "relation": "is the signed sum over subsets of",
    "object": "the principal minors of M",
    "comparator": null,
    "conditions": [
     "M square of size k",
     "positive integer lags"
    ]
   },
   "type": "formal",
   "role": "supporting",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E16"
    },
    {
     "kind": "consensus"
    }
   ],
   "scope": {
    "population": "square matrices and positive integer lags"
   },
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Steps of E16 re-derived; against the determinant at random complex B the relative error was at most 3.0e-15 for real M (200 cases) and complex M (100 cases)."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C21",
   "statement": "The per-lag discount matrices $D_{m_i} = F_{m_i} - g_{m_i} w_{m_i}'$ of [[D16:Section 5.4 of the ADAM monograph]] have as nonzero eigenvalues those of the diagonal block of $D = F - g w'$ for the lag $m_i$ (the [[D4:per-lag check]]), and their sum is $D + \\sum_{i \\neq j} g_{m_i} w_{m_j}'$, which differs from $D$ whenever $g w'$ links components of distinct lags.",
   "about": {
    "subject": "D16",
    "relation": "checks the same eigenvalues as",
    "object": null,
    "comparator": "D4",
    "conditions": [
     "more than one distinct lag"
    ]
   },
   "type": "formal",
   "role": "supporting",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "formal_proof",
     "evidence": "E17"
    }
   ],
   "scope": {
    "population": "pure additive lagged SSOE models with more than one distinct lag",
    "conditions": [
     "F split by the columns, and g and w by the components, of each lag, as in Section 5.2 of the monograph, which writes g_{m_i} and w_{m_i} without defining their split; with g kept whole the first part holds and the sum equals D"
    ]
   },
   "verification": "agent_checked",
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "500 random models with lags in {1, 3, 12}: the nonzero eigenvalues of each D_{m_i} equal those of the diagonal block of D, and the sum equals D plus the cross terms, never D with distinct lags. Noted the missing step for 'differs from D', the 'distinct lags' wording and the monograph's undefined split of g, since added to the evidence and the scope."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C22",
   "statement": "For [[D35:ETS(A,N,A) with $m = 12$]], $\\alpha = 1.2$ and $\\gamma = 0.9$, the [[D16:stability condition of Section 5.4 of the ADAM monograph]] holds, while in the full discount recursion the effect of the initial states on the fitted values and the weight of a past observation both grow from period to period, and the largest root modulus of the cancelled MA polynomial exceeds one.",
   "about": {
    "subject": "D16",
    "relation": "holds for a model that is not admissible",
    "object": null,
    "comparator": null,
    "conditions": [
     "D35",
     "alpha = 1.2, gamma = 0.9"
    ]
   },
   "type": "descriptive",
   "role": "principal",
   "novelty": "refutation",
   "planning": "exploratory",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E18",
     "artefacts": [
      "A1",
      "A6"
     ],
     "results": [
      "E18.T1.r2"
     ]
    }
   ],
   "scope": {
    "population": "ETS(A,N,A) with m = 12",
    "conditions": [
     "alpha = 1.2, gamma = 0.9",
     "initial states set to one or one unit observation, 2400 periods"
    ]
   },
   "depends_on": [
    "C21"
   ],
   "limitations": [
    "L6"
   ],
   "relations": [
    {
     "type": "contradicts",
     "reference": "B4",
     "locator": "Section 5.4, equations 5.20 to 5.22",
     "self": true,
     "note": "The monograph states that the model is stable when all the nonzero eigenvalues of the per-lag discount matrices D_{m_i} are below one in absolute value, and forecastable when the effect of the initial states through each D_{m_i} tends to a constant (eq. 5.22)."
    }
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "moderate",
     "rationale": "An exploratory but deterministic counterexample, with the growth of the recursion and the root of the polynomial computed separately and agreeing; one parameter pair, chosen from the planned grid test of the per-lag check."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "book_check.py reproduced E18 (0.2, 1.016393, 1.016457); the roots of the cancelled polynomial and the expanded matrix confirm several modes above one; suggested adding the growth of the observation weights (measured at about 1.01642 per period) and naming the forecastability condition in the note, since done with run RN44."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C23",
   "statement": "Over five fits with bounds=\\\"admissible\\\", the median time of a fit with [[D12:the polynomial check]] was comparable to that with [[D4:the per-lag check]], also for adam() with seasonal lags 24 and 168 on [[D38:hourly data]], with optimisation paths that differ between the checks.",
   "about": {
    "subject": "D12",
    "relation": "takes about as long per fit as",
    "object": null,
    "comparator": "D4",
    "conditions": [
     "D38"
    ]
   },
   "type": "descriptive",
   "role": "secondary",
   "novelty": "no_prior_found",
   "planning": "exploratory",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E19",
     "artefacts": [
      "A7"
     ],
     "results": [
      "E19.T1"
     ]
    }
   ],
   "scope": {
    "population": "fits of gum(), adam() and ces() on AirPassengers and a synthetic hourly series",
    "conditions": [
     "R 4.3.3, -O2, one x86_64 machine with 4 CPUs, median of seven fits"
    ]
   },
   "limitations": [
    "L7"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "low",
     "rationale": "Exploratory timings on one machine with a run-to-run noise of about 10%, and optimisation paths that differ between the checks."
    }
   ],
   "checks": [
    {
     "by": "P3",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "The ratios matched the table of E19 (0.8247 to 1.1963, hourly 1.0833); noted that the earlier metric, fit time divided by the calls of one check, mixed time and call counts; the claim now reports the ratio of the fit times with both call counts in the table."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C24",
   "statement": "On [[D22:1,000 new random ADAM ETS+ARIMA models]] (500 with ARIMA at lag 1, 500 with seasonal ARIMA), [[D13:checking the ETS part and the ARIMA polynomials apart]], as adam() did with bounds=\\\"admissible\\\", gave an [[D29:admissibility decision]] different from the [[D5:PBH reference]] of the whole model on about a third of the models in each family, accepting models that are not forecastable and rejecting models that are.",
   "about": {
    "subject": "D13",
    "relation": "gives admissibility decisions different from",
    "object": [
     "D29"
    ],
    "comparator": "D5",
    "conditions": [
     "D22"
    ]
   },
   "type": "descriptive",
   "role": "principal",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E20",
     "results": [
      "E20.T1.r1",
      "E20.T1.r3"
     ],
     "artefacts": [
      "A10",
      "A1"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H7",
    "outcome": "supported"
   },
   "planning": "confirmatory",
   "planned_at": "2026-10-22T15:55:32Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "sample": "500 models per family, one run, no stopping rule",
     "threshold": 25
    },
    "quantities": {
     "s1": {
      "variable": "models whose admissibility decision differs from the PBH reference",
      "conditions": {
       "family": "ETS+ARIMA",
       "check": "split"
      }
     },
     "s2": {
      "variable": "models whose admissibility decision differs from the PBH reference",
      "conditions": {
       "family": "ETS+SARIMA",
       "check": "split"
      }
     }
    },
    "supported": "s1 > threshold and s2 > threshold",
    "not_supported": "s1 <= 5 and s2 <= 5",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL7",
    "flags": [
     "code_changed_after_plan"
    ]
   },
   "scope": {
    "population": "random ADAM models that combine additive ETS with ARIMA",
    "conditions": [
     "ETS: level; no, additive or damped trend; no or one seasonal lag m in {4, 12}; smoothing parameters drawn from wide ranges, some fixed at 0",
     "ARIMA: AR stationary, differences and MA up to order 2 at lag 1 and 1 at lag m, 15% over-differenced (an MA root at one on the unit circle of a differenced lag)",
     "ADAM's state space form of ARIMA (one state per lag of the ARI and MA polynomials), checked against the matrices of adam() on 20 of the models"
    ],
    "excludes": [
     "regressors",
     "constant",
     "multiplicative models",
     "several seasonal lags",
     "CES",
     "GUM"
    ]
   },
   "assumptions": [
    "C28"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "high",
     "rationale": "Planned test on new models with a fixed rule; the counts are far from the threshold of 25 per family. The share depends on the generator (wide ranges of the smoothing and MA parameters, 15% over-differenced models, some of which are among those rejected by the parts apart); the models accepted by the parts apart and rejected by the reference alone, 104 and 128, exceed the threshold."
    }
   ],
   "limitations": [
    "L12"
   ],
   "checks": [
    {
     "by": "P4",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Re-derived and reran. Formal: for ADAM's ARIMA part F = -a 1', g = ma - a, w = 1 (a = ari coefficients per state lag), so phi = det(I + 1' L a) = ari polynomial and D = F - g w' = -ma 1', theta = ma polynomial; checked numerically on 57 and 238 matrices built by adam() itself (AC3.RN3, AC3.RN11: max abs gap of det(I-FL) and det(I-DL) to ari and ma polynomials 1.4e-14). Cross terms: ETS(A,N,N) alpha=1.9 + MA(1) theta=0.1 has whole theta = 1 + B - 0.1 B^2 (exact fractions), the product of the parts' thetas is 1 + B + 0.09 B^2, smallest root modulus 0.916 against 1.111 (AC3.RN3), so the parts-apart check accepts a model that does not forget its states (package modulus 1.0916 whole, 0.9 ETS part alone). Reproduction with new seeds, script unchanged: seed 11 n=200 (AC3.RN1): split check differs from PBH on 65/200 ETS+ARIMA and 71/200 ETS+SARIMA; seed 12 n=200 (AC3.RN2): 67/200 and 58/200; author's RN49 166/500 and 159/500; all far above the 5% rule (25/500). Both directions occur (AC3.RN1: split accepts and PBH rejects 42 and 64; reverse 23 and 7). Review of ets_arima.py: the split baseline matches the old admissible branch of adam_bounds_checker (git 094b76f4~1: smoothEigens on ETS/constant/regressors apart, AR and MA reflections for the ARIMA); generators, AR via reflection coefficients, over-differencing, structure check against adam() (30 models, max gap 4.9e-15, AC3.RN1) are correct. Caveats, not disputes: (1) the percentage depends on the generator (alpha up to 1.9, MA reflection up to 1.5, 15% over-differenced by design), so '>5%' says the parts-apart check is wrong on a non-negligible share of such models, not on real fits; (2) over-differenced MA unit roots that cancel with a difference make the split check reject models PBH accepts, a mechanism other than the ETS-ARIMA cross terms (the cross-term direction alone is 104/500 and 128/500 in RN49 and still above 25); (3) RN49 and RN50 are the same command with the same results.json hash, so they are one data set tested under two plans; (4) the 'code changed after plan' flag is benign: git diff 397f255f..acb23120 touches only lab files."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C25",
   "statement": "On the same [[D22:1,000 random ETS+ARIMA models]], [[D10:the check of the whole model]], the criterion of [[C3]] applied to the whole model (the MA polynomial of the ARIMA form of the whole lagged SSOE after [[D6:cyclotomic cancellation]], with the AR polynomial of the ARIMA part stationary), gave the same [[D29:admissibility decision]] as the [[D5:PBH reference]] on every model, and the same [[D30:largest modulus]] to within rounding error on the models both found inadmissible.",
   "about": {
    "subject": "D10",
    "relation": "gives the same admissibility decision and largest mode modulus as",
    "object": [
     "D29",
     "D30"
    ],
    "comparator": "D5",
    "conditions": [
     "D22"
    ]
   },
   "type": "methodological",
   "role": "principal",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E21",
     "results": [
      "E21.T1.r2",
      "E21.T1.r4",
      "E21.T2.r1",
      "E21.T2.r2"
     ],
     "artefacts": [
      "A10",
      "A1"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H8",
    "outcome": "supported"
   },
   "planning": "confirmatory",
   "planned_at": "2026-10-22T15:55:35Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "sample": "500 models per family, one run, no stopping rule",
     "threshold": 1e-06
    },
    "quantities": {
     "j1": {
      "variable": "models whose admissibility decision differs from the PBH reference",
      "conditions": {
       "family": "ETS+ARIMA",
       "check": "joint"
      }
     },
     "j2": {
      "variable": "models whose admissibility decision differs from the PBH reference",
      "conditions": {
       "family": "ETS+SARIMA",
       "check": "joint"
      }
     },
     "d1": {
      "variable": "max abs difference of the largest modulus, check of the whole model against the PBH reference, on models both find inadmissible",
      "conditions": {
       "family": "ETS+ARIMA"
      }
     },
     "d2": {
      "variable": "max abs difference of the largest modulus, check of the whole model against the PBH reference, on models both find inadmissible",
      "conditions": {
       "family": "ETS+SARIMA"
      }
     }
    },
    "supported": "j1 == 0 and j2 == 0 and d1 <= threshold and d2 <= threshold",
    "not_supported": "j1 > 0 or j2 > 0 or d1 > threshold or d2 > threshold",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL8",
    "flags": [
     "code_changed_after_plan"
    ]
   },
   "scope": {
    "population": "random ADAM models that combine additive ETS with ARIMA",
    "conditions": [
     "ETS: level; no, additive or damped trend; no or one seasonal lag m in {4, 12}; smoothing parameters drawn from wide ranges, some fixed at 0",
     "ARIMA: AR stationary, differences and MA up to order 2 at lag 1 and 1 at lag m, 15% over-differenced (an MA root at one on the unit circle of a differenced lag)",
     "ADAM's state space form of ARIMA (one state per lag of the ARI and MA polynomials), checked against the matrices of adam() on 20 of the models"
    ],
    "excludes": [
     "regressors",
     "constant",
     "multiplicative models",
     "several seasonal lags",
     "CES",
     "GUM"
    ]
   },
   "assumptions": [
    "C28"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "high",
     "rationale": "Planned test on new models with a fixed rule; the reference is exact for these models under the assumption C28. The same run and data as C24, tested under a second plan."
    }
   ],
   "limitations": [
    "L12"
   ],
   "checks": [
    {
     "by": "P4",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Reran with new seeds (script unchanged). Whole-model check (cancelled MA polynomial of the ARIMA form, AR stationary) against the PBH reference: seed 11 n=200 (AC3.RN1) 0 differing decisions in 200 ETS+ARIMA and 200 ETS+SARIMA models, max abs difference of the largest modulus 2.9e-13 and 1.5e-12; seed 12 n=200 (AC3.RN2) 0 and 0, max differences 7.9e-13 and 5.7e-9; author's RN50: 0, 0, 4.3e-13, 1.6e-11. Threshold 1e-6 met each time. Stronger test with an independent oracle (AC3.RN4-RN10, 1750 models, 7 seeds): a wider generator (constant state, ETS with two seasonal lags, AR up to 3, I up to 2, MA up to 3 including factors on the unit circle 1+-B, 1+B+B^2, 1+B^2, 1-B+B^2, rational parameters, exact Fraction determinants and exact gcd(theta, phi) instead of cyclotomic-only cancellation): the cyclotomic-cancelled check (the author's functions) disagrees with the exact gcd oracle on 0 of 1750 models, so cancelling only Phi_n is enough here; models whose unit-circle MA factor cancels and which are admissible were 3 to 7 per 250. Limitation of the reference, not of the claim: PBH (tolerance 1e-7 on singular values) accepted one model whose theta* keeps a double root at -1 (AC3.RN9, oracle and cancellation reject it), because repeated unit-circle eigenvalues are defective and the rank tests fail numerically; the author's generator never produces such a case (0 of 2000 differ in RN49/RN50/RN53), but PBH should not be treated as ground truth for repeated unit roots. Formal side (AS1): theta and phi of the whole model share no root inside the circle, so the cyclotomic-only cancellation is complete."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C26",
   "statement": "On [[D22:1,000 further random ETS+ARIMA models]], [[D14:the bounds checker of adam() in R and of ADAM in Python]] with bounds=\\\"admissible\\\", which run smoothEigensCpp() on the whole model, gave the same [[D29:admissibility decision]] as [[D10:the prototype check of the whole model]] on every model, and a penalty slope ([[D30:the largest root modulus]]) within the bisection tolerance of it in both families.",
   "about": {
    "subject": "D14",
    "relation": "gives the same admissibility decision and largest mode modulus as",
    "object": [
     "D29",
     "D30"
    ],
    "comparator": "D10",
    "conditions": [
     "D22"
    ]
   },
   "type": "methodological",
   "role": "principal",
   "novelty": "no_prior_found",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E22",
     "results": [
      "E22.T3.r1",
      "E22.T3.r2",
      "E22.T3.r3",
      "E22.T3.r4"
     ],
     "artefacts": [
      "A10",
      "A1",
      "A12",
      "A13",
      "A14"
     ]
    }
   ],
   "provenance": "author_stated",
   "hypothesis": {
    "lab_event": "H9",
    "outcome": "supported"
   },
   "planning": "confirmatory",
   "planned_at": "2026-10-22T17:19:52Z",
   "planned_at_anchor": "git_remote",
   "test": {
    "framework": "deterministic",
    "parameters": {
     "sample": "500 models per family, one run, no stopping rule",
     "threshold": 1.1e-06
    },
    "quantities": {
     "r1": {
      "variable": "admissibility decisions of the package's bounds checker that differ from the prototype check of the whole model",
      "conditions": {
       "family": "ETS+ARIMA",
       "language": "R"
      }
     },
     "r2": {
      "variable": "admissibility decisions of the package's bounds checker that differ from the prototype check of the whole model",
      "conditions": {
       "family": "ETS+SARIMA",
       "language": "R"
      }
     },
     "p1": {
      "variable": "admissibility decisions of the package's bounds checker that differ from the prototype check of the whole model",
      "conditions": {
       "family": "ETS+ARIMA",
       "language": "Python"
      }
     },
     "p2": {
      "variable": "admissibility decisions of the package's bounds checker that differ from the prototype check of the whole model",
      "conditions": {
       "family": "ETS+SARIMA",
       "language": "Python"
      }
     },
     "dr1": {
      "variable": "max abs difference of the largest modulus, package's bounds checker against the prototype, on models both find inadmissible",
      "conditions": {
       "family": "ETS+ARIMA",
       "language": "R"
      }
     },
     "dr2": {
      "variable": "max abs difference of the largest modulus, package's bounds checker against the prototype, on models both find inadmissible",
      "conditions": {
       "family": "ETS+SARIMA",
       "language": "R"
      }
     },
     "dp1": {
      "variable": "max abs difference of the largest modulus, package's bounds checker against the prototype, on models both find inadmissible",
      "conditions": {
       "family": "ETS+ARIMA",
       "language": "Python"
      }
     },
     "dp2": {
      "variable": "max abs difference of the largest modulus, package's bounds checker against the prototype, on models both find inadmissible",
      "conditions": {
       "family": "ETS+SARIMA",
       "language": "Python"
      }
     }
    },
    "supported": "r1 + r2 + p1 + p2 == 0 and dr1 <= threshold and dr2 <= threshold and dp1 <= threshold and dp2 <= threshold",
    "not_supported": "r1 + r2 + p1 + p2 > 0 or dr1 > threshold or dr2 > threshold or dp1 > threshold or dp2 > threshold",
    "verdict": "computed",
    "runs": 1,
    "lab_plan": "PL9",
    "flags": [
     "code_changed_after_plan"
    ]
   },
   "scope": {
    "population": "random ADAM models that combine additive ETS with ARIMA",
    "conditions": [
     "ETS: level; no, additive or damped trend; no or one seasonal lag m in {4, 12}; smoothing parameters drawn from wide ranges, some fixed at 0",
     "ARIMA: AR stationary, differences and MA up to order 2 at lag 1 and 1 at lag m, 15% over-differenced (an MA root at one on the unit circle of a differenced lag)",
     "ADAM's state space form of ARIMA (one state per lag of the ARI and MA polynomials), checked against the matrices of adam() on 20 of the models",
     "the checkers called on the matrices of each model, R through pkgload::load_all of the repository"
    ],
    "excludes": [
     "regressors",
     "constant",
     "multiplicative models",
     "several seasonal lags",
     "CES",
     "GUM"
    ]
   },
   "assumptions": [
    "C28"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "high",
     "rationale": "Planned test of the code in the package on new models; the decisions are exact and the moduli agree within the bisection tolerance. The shortcut for pure ARIMA, added after this run, was tested only by the checker P4. Two later changes of the checkers (decision DC8) are not covered by the run: the margin of 1e-10 below one, and the penalty of a rejected pure ARIMA, which stays that of its MA factors."
    }
   ],
   "limitations": [
    "L11"
   ],
   "checks": [
    {
     "by": "P4",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "Reran the implementation test with another seed: seed 12 n=200 --impl in the project venv (AC3.RN2): R adam_bounds_checker() and Python adam_bounds_checker() both 0 differing decisions against the prototype in 200 ETS+ARIMA and 200 ETS+SARIMA models; max abs difference between penalty/1e100 and the prototype modulus 9.35e-7 (ETS+ARIMA, 118 inadmissible) and 9.53e-7 (ETS+SARIMA, 167 inadmissible), R and Python equal to 8 digits; author's RN53 0 differences and 9.5e-7; all within the 1.1e-6 threshold (the C++ bisection returns the upper end, tolerance 1e-6). Script review: R positional call of adam_bounds_checker() matches its signature, Python dict arguments match, AR reflection computed as in C++; matrices are the author's builder verified against adam() on 30 models (AC3.RN1, gap 4.9e-15), not matrices from adam() fits. Limitations to state with the claim: (1) the prototype decides with a 1e-6 margin (modulus < 1 - 1e-6) and the package with modulus > 1 + 1e-50, so for a root exactly on the unit circle that does not cancel the package's answer is set by roundoff: simple cases (MA(1) theta=+-1, 1 - B + B^2, 1 + B^2) are rejected with modulus 1.00000095 (AC3.RN13), but in 3 of 1750 models of the wider generator the package accepted a model whose theta* keeps a cyclotomic factor, with moduli 0.9999999999999969 (AC3.RN4), 0.9999999999999993 (AC3.RN9) and 0.9999999999970864 (AC3.RN10; the specs are printed in their stdout), while the cancelled-polynomial prototype and the exact oracle reject them. The generator of RN53 has no such models (the only unit-circle MA roots are over-differenced and cancel), so the confirmed statement holds for what it says, random ETS+ARIMA models away from the boundary. (2) RN53 ran at commit 7cf64144, before the shortcut of DC6 (b4a10cc6), and always with ets_model=True, so the pure-ARIMA shortcut branch is not covered by it (see my check of DC6). The compiled _eigenCalc in the venv (built 16:49) is newer than the header's last change (16:48), so RN53 and my AC3.RN2 ran the current C++."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C27",
   "statement": "With [[D14:the check of the whole model and its shortcut for pure ARIMA]], the median time of five fits with bounds=\\\"admissible\\\" of two ARIMA and two ETS+ARIMA models was close to that with [[D13:the check of the parts apart]]; the log-likelihood of SARIMA(1,1,1)(1,1,1)[12] on [[D36:AirPassengers]] rose slightly, and that of ETS(A,N,A)+ARIMA(1,0,1) fell, to another local optimum.",
   "about": {
    "subject": "D14",
    "relation": "takes about as long per fit as",
    "object": null,
    "comparator": "D13",
    "conditions": [
     "D36"
    ]
   },
   "type": "descriptive",
   "role": "secondary",
   "novelty": "no_prior_found",
   "planning": "exploratory",
   "support": [
    {
     "kind": "simulation",
     "evidence": "E23",
     "artefacts": [
      "A11"
     ],
     "results": [
      "E23.T1"
     ]
    }
   ],
   "scope": {
    "population": "fits of adam() and ssarima() on AirPassengers and BJsales",
    "conditions": [
     "R 4.3.3, -O2, one x86_64 machine, median of five fits"
    ]
   },
   "limitations": [
    "L9"
   ],
   "assessments": [
    {
     "by": "author",
     "strength": "low",
     "rationale": "Exploratory timings of four fits on one machine; the optimisation paths differ between the checks."
    }
   ],
   "checks": [
    {
     "by": "P4",
     "outcome": "confirmed",
     "extent": "full",
     "notes": "The shortcut is exact. Derivation: a constant or static regressor has F row e_x, g_x = 0, so row x of D is also e_x and expanding det(I - D L) along it gives theta_whole = theta_ARIMA (1 - B) and phi_whole = phi_ARIMA (1 - B) (checked on adam() matrices of plain, constant and static-regressor ARIMA, 295 models in total, max gap 1.4e-14, AC3.RN3, AC3.RN11). With every MA factor invertible theta_ARIMA has no root on or inside the circle, the (1 - B) factors cancel with phi, so theta* has all roots outside; this holds whether or not the AR is stationary. Code: in R (adam_bounds_checker in R/utils-adam.R and ssarima in R/adam-ssarima.R) and Python (cost_functions.py) the whole check is skipped only when no ETS, no adaptive regressors, arima_model true and ma_reflection < 1, otherwise it runs, so an MA root that cancels with a difference is still accepted (reflection >= 1 goes to the whole check). maReflection is the factor-by-factor Schur-Cohn value, below 1 exactly when every factor is invertible. Tests (mine, the author has no recorded run of the shortcut: RN53 only used ets_model=True and predates b4a10cc6; RN55/RN56 are timing): on 238 adam()-built pure ARIMA models (plain 80, constant 80, static regressor 78; AC3.RN11) 136 have all MA roots outside the circle and smooth_eigens rejects 0 of them; the real R adam_bounds_checker() with etsModel FALSE (AC3.RN12) gives a penalty on 0 of the 136 and its decision equals the forced whole-model check on all 102 non-invertible ones (20 of them are accepted, the cancelling roots). RN55 and RN56 give identical log-likelihoods for the SARIMA (-541.382357389734 both) as the author's NT24 says. Minor: in floating point the shortcut is if anything more robust than the whole check (no cancellation tolerance involved); DC6's text 'the whole model is checked only otherwise' is right but reads as if non-invertible models were rejected, which they are not."
    }
   ],
   "verifiability": "open",
   "verifiability_flags": []
  },
  {
   "id": "C28",
   "statement": "For ETS+ARIMA models with a stationary AR polynomial, $\\theta(B)$ and $\\phi(B)$ of the whole model share no factor with a root in $|B| \\le 1$ that is not cyclotomic, so the [[D5:PBH reference]] and the cancelled MA polynomial decide the same admissibility.",
   "type": "methodological",
   "role": "supporting",
   "support": [
    {
     "kind": "assumption"
    }
   ],
   "assumption_category": "theorem_condition",
   "check": "tested",
   "provenance": "author_stated",
   "check_evidence": "E24",
   "verifiability": "not_applicable",
   "verifiability_flags": []
  }
 ],
 "evidence": [
  {
   "id": "E1",
   "profile": "simulation",
   "description": "Planned test of the per-lag check (lab plan PL1, run RN7): confirm.py --test perlag --seed 2026 --n 200 computed, for 3042 ETS(A,N,A) models (m = 4 and 12, alpha and gamma on the grid 0.05, 0.10, ..., 1.95) and 200 GUM models with lags (1, 12) (entries of F normal with mean 0 and standard deviation 0.35, of g with mean 0 and standard deviation 0.175, of w with mean 1 and standard deviation 0.175), the per-lag check's largest eigenvalue modulus and the PBH reference, and counted the models on which the two decisions disagree beyond a band of 1e-8 around 1.",
   "setup": {
    "studied": [
     "D4"
    ],
    "cases": [
     "D17",
     "D18"
    ],
    "procedure": [
     "D26",
     "D5"
    ],
    "lens": [
     "D29"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN7"
   ],
   "results": [
    {
     "id": "R1",
     "variable": "models accepted by the per-lag check that do not forget their initial states",
     "value": 1482.0,
     "conditions": {
      "family": "ETS(A,N,A)",
      "models": 3042
     }
    },
    {
     "id": "R2",
     "variable": "models rejected by the per-lag check that forget their initial states",
     "value": 0.0,
     "conditions": {
      "family": "ETS(A,N,A)",
      "models": 3042
     }
    },
    {
     "id": "R3",
     "variable": "models accepted by the per-lag check",
     "value": 3042.0,
     "conditions": {
      "family": "ETS(A,N,A)",
      "models": 3042
     }
    },
    {
     "id": "R4",
     "variable": "models accepted by the per-lag check that do not forget their initial states",
     "value": 10.0,
     "conditions": {
      "family": "GUM",
      "models": 200
     }
    },
    {
     "id": "R5",
     "variable": "models rejected by the per-lag check that forget their initial states",
     "value": 1.0,
     "conditions": {
      "family": "GUM",
      "models": 200
     }
    },
    {
     "id": "R6",
     "variable": "models accepted by the per-lag check",
     "value": 193.0,
     "conditions": {
      "family": "GUM",
      "models": 200
     }
    }
   ],
   "execution": {
    "code_version": "fe3ecfad42341fb0d2b81d02a7919b43baa5f695",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v139-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A1",
    "A3"
   ],
   "model": "random lagged SSOE models (additive ETS and GUM) generated by confirm.py",
   "parameters": "A3",
   "runs": 1,
   "seeds": [
    2026
   ]
  },
  {
   "id": "E2",
   "profile": "simulation",
   "description": "Planned test of the per-lag check on GUM models (lab plan PL2, run RN8): the same computation and seed as for plan PL1, counting the GUM models with lags (1, 12) that the per-lag check rejects while their PBH reference lies below 1 - 1e-8.",
   "setup": {
    "studied": [
     "D4"
    ],
    "cases": [
     "D18"
    ],
    "procedure": [
     "D26",
     "D5"
    ],
    "lens": [
     "D29"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN8"
   ],
   "results": [
    {
     "id": "R1",
     "variable": "models accepted by the per-lag check that do not forget their initial states",
     "value": 1482.0,
     "conditions": {
      "family": "ETS(A,N,A)",
      "models": 3042
     }
    },
    {
     "id": "R2",
     "variable": "models rejected by the per-lag check that forget their initial states",
     "value": 0.0,
     "conditions": {
      "family": "ETS(A,N,A)",
      "models": 3042
     }
    },
    {
     "id": "R3",
     "variable": "models accepted by the per-lag check",
     "value": 3042.0,
     "conditions": {
      "family": "ETS(A,N,A)",
      "models": 3042
     }
    },
    {
     "id": "R4",
     "variable": "models accepted by the per-lag check that do not forget their initial states",
     "value": 10.0,
     "conditions": {
      "family": "GUM",
      "models": 200
     }
    },
    {
     "id": "R5",
     "variable": "models rejected by the per-lag check that forget their initial states",
     "value": 1.0,
     "conditions": {
      "family": "GUM",
      "models": 200
     }
    },
    {
     "id": "R6",
     "variable": "models accepted by the per-lag check",
     "value": 193.0,
     "conditions": {
      "family": "GUM",
      "models": 200
     }
    }
   ],
   "execution": {
    "code_version": "fe3ecfad42341fb0d2b81d02a7919b43baa5f695",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v139-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A1",
    "A3"
   ],
   "model": "random lagged SSOE models (additive ETS and GUM) generated by confirm.py",
   "parameters": "A3",
   "runs": 1,
   "seeds": [
    2026
   ]
  },
  {
   "id": "E3",
   "profile": "simulation",
   "description": "Planned test of the cyclotomic cancellation (lab plan PL3, run RN9): confirm.py --test cancel --seed 2026 --n 200 generated 200 additive ETS models (level; no, additive or damped trend with phi in (0.8, 0.99); 0 to 2 seasonal lags from {4, 7, 12, 24, 52}; a constant with probability 0.3; beta = 0 with probability 0.1 and each gamma = 0 with probability 0.15; alpha in (0.01, 1.9)), 100 GUM models with F = I, lags from {1, 4, 12}, g uniform on (-0.3, 0.6) and w normal with mean 1 and standard deviation 0.3, and 200 GUM models with lags from {1, 4, 12, 24} and normal F (standard deviation 0.35); for each it compared the largest root modulus of the cancelled MA polynomial with the PBH reference.",
   "setup": {
    "studied": [
     "D10"
    ],
    "cases": [
     "D19"
    ],
    "procedure": [
     "D26",
     "D5"
    ],
    "lens": [
     "D29",
     "D30"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN9"
   ],
   "results": [
    {
     "id": "R1",
     "variable": "admissibility decisions that differ from the PBH reference",
     "value": 0.0,
     "conditions": {}
    },
    {
     "id": "R2",
     "variable": "max abs difference of max |lambda| from the PBH reference, inadmissible models",
     "value": 4.39648317751562e-13,
     "conditions": {
      "inadmissible_models": 172
     }
    },
    {
     "id": "R3",
     "variable": "models within 1e-8 of the unit circle, excluded",
     "value": 0.0,
     "conditions": {}
    },
    {
     "id": "R4",
     "variable": "models compared",
     "value": 500.0,
     "conditions": {}
    }
   ],
   "execution": {
    "code_version": "fe3ecfad42341fb0d2b81d02a7919b43baa5f695",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v139-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A1",
    "A3"
   ],
   "model": "random lagged SSOE models (additive ETS and GUM) generated by confirm.py",
   "parameters": "A3",
   "runs": 1,
   "seeds": [
    2026
   ]
  },
  {
   "id": "E4",
   "profile": "simulation",
   "description": "Planned test of the step-down test (lab plan PL4, run RN10): confirm.py --test stepdown --seed 2026 --n 200 generated the 500 models of plan PL3 afresh plus 50 additive ETS models with seasonal lags from {24, 168, 365} and 25 GUM models with lags (1, 24, 168) and normal F (standard deviation 0.3), and compared the step-down decision on the cancelled MA polynomial with the decision from its roots computed by numpy. The generator allows MA polynomial degrees up to 536 (level, trend, seasonal lags 168 and 365, constant); the realised maximum was not recorded as a result.",
   "setup": {
    "studied": [
     "D7"
    ],
    "cases": [
     "D20"
    ],
    "procedure": [
     "D26",
     "D15"
    ],
    "lens": [
     "D29"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN10"
   ],
   "results": [
    {
     "id": "R1",
     "variable": "step-down decisions that differ from the decision by the roots",
     "value": 0.0,
     "conditions": {}
    },
    {
     "id": "R2",
     "variable": "models within 1e-8 of the unit circle, excluded",
     "value": 0.0,
     "conditions": {}
    },
    {
     "id": "R3",
     "variable": "models compared",
     "value": 575.0,
     "conditions": {}
    }
   ],
   "execution": {
    "code_version": "fe3ecfad42341fb0d2b81d02a7919b43baa5f695",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v139-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A1",
    "A3"
   ],
   "model": "random lagged SSOE models (additive ETS and GUM) generated by confirm.py",
   "parameters": "A3",
   "runs": 1,
   "seeds": [
    2026
   ]
  },
  {
   "id": "E5",
   "profile": "simulation",
   "description": "Planned test of the bisection (lab plan PL5, run RN11): on the 575 models of plan PL4, for each model whose cancelled MA polynomial has a root-based largest mode modulus above 1 + 1e-8, bisection on r to width 1e-10 with the step-down test on theta*(B/r) was compared with the root-based value. The generator allows MA polynomial degrees up to 536 (level, trend, seasonal lags 168 and 365, constant); the realised maximum was not recorded as a result.",
   "setup": {
    "studied": [
     "D11"
    ],
    "cases": [
     "D20"
    ],
    "procedure": [
     "D26",
     "D15"
    ],
    "lens": [
     "D30"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN11"
   ],
   "results": [
    {
     "id": "R1",
     "variable": "max abs difference of max |lambda|, bisection against roots",
     "value": 5.813682868449632e-11,
     "conditions": {
      "inadmissible_models": 198
     }
    },
    {
     "id": "R2",
     "variable": "models within 1e-8 of the unit circle, excluded",
     "value": 0.0,
     "conditions": {}
    },
    {
     "id": "R3",
     "variable": "models compared",
     "value": 575.0,
     "conditions": {}
    }
   ],
   "execution": {
    "code_version": "fe3ecfad42341fb0d2b81d02a7919b43baa5f695",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v139-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A1",
    "A3"
   ],
   "model": "random lagged SSOE models (additive ETS and GUM) generated by confirm.py",
   "parameters": "A3",
   "runs": 1,
   "seeds": [
    2026
   ]
  },
  {
   "id": "E13",
   "profile": "simulation",
   "description": "Planned test of the implementation in smooth (lab plan PL6, run RN43): cpp_check.py --seed 2027 --n 200 generated 200 models in each of four families (additive ETS with 0-2 seasonal lags from {4, 7, 12, 24, 52}; additive ETS with 0-2 seasonal lags from {24, 168, 365}; GUM with F = I and lags from {1, 4, 12}; GUM with normal F, standard deviation 0.35, and lags from {1, 4, 12, 24}), called smoothEigensR() of the repository (through pkgload::load_all) three times on each, and compared its decision and modulus with the numpy prototype (roots of the cancelled MA polynomial).",
   "setup": {
    "studied": [
     "D12"
    ],
    "cases": [
     "D21"
    ],
    "procedure": [
     "D26",
     "D10"
    ],
    "lens": [
     "D29",
     "D30"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN43"
   ],
   "execution": {
    "code_version": "0630dbeab5173c2a72c7828fca3f71573fa1ea85",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v140-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A1",
    "A5",
    "A8"
   ],
   "model": "random lagged SSOE models (additive ETS and GUM) generated by cpp_check.py",
   "parameters": "A5",
   "runs": 1,
   "seeds": [
    2027
   ],
   "tables": [
    {
     "id": "T1",
     "description": "Comparison of the C++ core (smoothEigensR()) with the numpy prototype on 200 models in each of four families: admissibility decisions that differ, largest absolute difference of the root modulus on the models found inadmissible, models whose cancelled polynomials differ in degree, largest absolute difference between three calls on the same model, and the number of models found inadmissible",
     "conditions": {
      "models": 200
     },
     "row_labels": [
      "family"
     ],
     "columns": [
      "admissibility decisions of the C++ core that differ from the prototype",
      "max abs difference of the largest root modulus on inadmissible models, C++ core against prototype",
      "models whose cancelled polynomials differ in degree, C++ core against prototype",
      "max abs difference between three calls of the C++ core on the same model",
      "inadmissible"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS"
       ],
       "values": [
        0,
        9.48848823512094e-07,
        0,
        0.0,
        86
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS high degree"
       ],
       "values": [
        0,
        9.526633371059745e-07,
        0,
        0.0,
        95
       ]
      },
      {
       "id": "r3",
       "label": [
        "GUM identity"
       ],
       "values": [
        0,
        9.405809149320987e-07,
        0,
        0.0,
        84
       ]
      },
      {
       "id": "r4",
       "label": [
        "GUM random"
       ],
       "values": [
        0,
        9.485389538266276e-07,
        0,
        0.0,
        27
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E10",
   "profile": "simulation",
   "description": "Exploratory run RN2 of explore.py --seed 0: the ARIMA-form polynomials, their cyclotomic cancellation and the PBH reference for ETS(A,N,A,A) with seasonal lags 24 and 168 (alpha = 0.3, gamma = (0.1, 0.05)) and for GUM with orders (2, 2), lags (1, 12), F = I, g = 0.1 and w = 1 (the default starting point of gum()); the determinant identity at random complex B on 100 random GUM models; the expanded discount matrix of a block-diagonal D; and mean times over 50 repeats of three computations for a random GUM with lags (1, 24, 168). The result labelled 'block-diagonal D, lags (1,12)' comes from D = [[0.7, 0], [-0.1, 0.3]], which is lower-triangular rather than block-diagonal.",
   "setup": {
    "studied": [
     "D1",
     "D6",
     "D10"
    ],
    "cases": [
     "D24",
     "D25"
    ],
    "procedure": [
     "D26",
     "D5"
    ],
    "lens": [
     "D30"
    ]
   },
   "artefacts": [
    "A1",
    "A2"
   ],
   "model": "fixed and random lagged SSOE models generated by explore.py",
   "parameters": "A2",
   "runs": 1,
   "seeds": [
    0
   ],
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN2"
   ],
   "results": [
    {
     "id": "R11",
     "variable": "max relative error of the determinant identity",
     "value": 9.171563565208779e-15,
     "conditions": {
      "models": 100
     }
    },
    {
     "id": "R12",
     "variable": "max |lambda|, per-lag check",
     "value": 0.7,
     "conditions": {
      "model": "block-diagonal D, lags (1,12)"
     }
    },
    {
     "id": "R13",
     "variable": "max |lambda|, all modes of the expanded discount matrix",
     "value": 0.9045379057839597,
     "conditions": {
      "model": "block-diagonal D, lags (1,12)"
     }
    },
    {
     "id": "R14",
     "variable": "mean time, ms",
     "value": 4.6963541200011605,
     "conditions": {
      "task": "coefficients by DFT",
      "degree": 193
     }
    },
    {
     "id": "R15",
     "variable": "mean time, ms",
     "value": 0.006939219999821944,
     "conditions": {
      "task": "step-down test",
      "degree": 193
     }
    },
    {
     "id": "R16",
     "variable": "mean time, ms",
     "value": 22.225657179999416,
     "conditions": {
      "task": "all roots, numpy companion eigenvalues",
      "degree": 193
     }
    }
   ],
   "execution": {
    "code_version": "4151c76e4125035cf1258be7f32b24ca2408c4a2",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v139-x86_64-with-glibc2.39"
    },
    "hardware": {
     "machine": "x86_64",
     "cpus": 4
    }
   },
   "tables": [
    {
     "id": "T1",
     "description": "Degree of the MA polynomial theta and of its shared cyclotomic factor, and the largest mode modulus from the roots of theta before and after cancellation and from the PBH reference, for ETS(A,N,A,A) with seasonal lags 24 and 168 and for the default starting point of gum() with orders (2, 2) and lags (1, 12)",
     "row_labels": [
      "model"
     ],
     "columns": [
      "degree of theta",
      "degree of the shared cyclotomic factor",
      "max |lambda|, roots of theta before cancellation",
      "max |lambda|, roots of theta after cancellation",
      "max |lambda|, controllable and observable modes (PBH)"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS(A,N,A,A), alpha=0.3, gamma=(0.1,0.05)"
       ],
       "values": [
        193.0,
        25.0,
        1.0000000000000038,
        0.9999965469723225,
        0.9999965469723241
       ]
      },
      {
       "id": "r2",
       "label": [
        "GUM start, orders (2,2), lags (1,12)"
       ],
       "values": [
        26.0,
        14.0,
        1.0000014857614217,
        0.9829371631611427,
        0.9829371631611421
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E6",
   "profile": "formal",
   "foundation": "linear algebra over the field of rational functions in $B$",
   "description": "Derivation of the ARIMA form of a lagged SSOE model by the matrix determinant lemma.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "\\epsilon_t = y_t - w' v_{t-l} \\Rightarrow v_t = D v_{t-l} + g y_t,\\ D = F - g w'",
     "by": [
      "D1"
     ],
     "rule": "substitution"
    },
    {
     "id": "S2",
     "statement": "v_{t-l} = L(B) v_t \\Rightarrow (I - D L(B)) v_t = g y_t",
     "by": [
      "S1",
      "D1"
     ],
     "rule": "definition of $L(B)$"
    },
    {
     "id": "S3",
     "statement": "\\det(I - D L(B))|_{B=0} = 1 \\Rightarrow I - D L(B) \\text{ is invertible over rational functions}",
     "by": [
      "S2"
     ],
     "rule": "evaluation at $B = 0$"
    },
    {
     "id": "S4",
     "statement": "\\epsilon_t = \\left(1 - w' L(B) (I - D L(B))^{-1} g\\right) y_t",
     "by": [
      "S1",
      "S2",
      "S3"
     ],
     "rule": "substitution"
    },
    {
     "id": "S5",
     "statement": "I - D L(B) - g\\, w' L(B) = I - F L(B)",
     "by": [
      "D1"
     ],
     "rule": "definition of $D$"
    },
    {
     "id": "S6",
     "statement": "\\det(I - F L(B)) = \\det(I - D L(B))\\left(1 - w' L(B)(I - D L(B))^{-1} g\\right)",
     "by": [
      "S3",
      "S5"
     ],
     "rule": "matrix determinant lemma $\\det(A - g u') = \\det(A)(1 - u' A^{-1} g)$"
    },
    {
     "id": "S7",
     "statement": "\\det(I - D L(B))\\, \\epsilon_t = \\det(I - F L(B))\\, y_t",
     "by": [
      "S4",
      "S6"
     ],
     "rule": "substitution"
    }
   ]
  },
  {
   "id": "E7",
   "profile": "formal",
   "foundation": "linear algebra over the complex numbers",
   "description": "Characteristic polynomial of the expanded matrix and its factorisation for a block-diagonal discount matrix.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "\\det(\\lambda I - \\tilde M) = \\det(\\Lambda(\\lambda) - M) \\text{ for the lag-1 expansion } \\tilde M \\text{ of } v_t = M v_{t-l}",
     "by": [
      "C15"
     ],
     "rule": "identity of the lag-1 expansion"
    },
    {
     "id": "S2",
     "statement": "D = \\mathrm{blockdiag}(D_{ll}) \\Rightarrow \\det(\\Lambda(\\lambda) - D) = \\prod_l \\det(\\lambda^l I - D_{ll})",
     "by": [
      "S1",
      "D1"
     ],
     "rule": "determinant of a block-diagonal matrix"
    },
    {
     "id": "S3",
     "statement": "\\det(\\lambda^l I - D_{ll}) = 0 \\iff \\lambda^l = \\mu,\\ \\mu \\in \\mathrm{eig}(D_{ll}) \\Rightarrow |\\lambda| = |\\mu|^{1/l}",
     "by": [
      "S2"
     ],
     "rule": "eigenvalue equation"
    },
    {
     "id": "S4",
     "statement": "|\\lambda| < 1 \\iff |\\mu| < 1",
     "by": [
      "S3"
     ],
     "rule": "monotonicity of $x \\mapsto x^{1/l}$ on $[0, \\infty)$"
    }
   ]
  },
  {
   "id": "E8",
   "profile": "formal",
   "foundation": "linear algebra over the complex numbers",
   "description": "Unobservable or unreachable modes of the expanded transition matrix are modes of the expanded discount matrix and give common roots of the two ARIMA-form polynomials.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "\\tilde F u = \\lambda u,\\ \\tilde w' u = 0 \\Rightarrow \\tilde D u = \\tilde F u - \\tilde g (\\tilde w' u) = \\lambda u",
     "by": [
      "D2"
     ],
     "rule": "substitution of $\\tilde D = \\tilde F - \\tilde g \\tilde w'$"
    },
    {
     "id": "S2",
     "statement": "u' \\tilde F = \\lambda u',\\ u' \\tilde g = 0 \\Rightarrow u' \\tilde D = u' \\tilde F - (u' \\tilde g) \\tilde w' = \\lambda u'",
     "by": [
      "D2"
     ],
     "rule": "substitution of $\\tilde D = \\tilde F - \\tilde g \\tilde w'$"
    },
    {
     "id": "S3",
     "statement": "\\det(\\lambda I - \\tilde M) = \\lambda^{\\sum_j l_j} \\det(I - M L(1/\\lambda)),\\ \\lambda \\neq 0",
     "by": [
      "C15"
     ],
     "rule": "identity of the lag-1 expansion"
    },
    {
     "id": "S4",
     "statement": "\\phi(1/\\lambda) = \\det(I - F L(1/\\lambda)) = 0,\\ \\theta(1/\\lambda) = \\det(I - D L(1/\\lambda)) = 0",
     "by": [
      "S1",
      "S2",
      "S3"
     ],
     "rule": "substitution"
    }
   ]
  },
  {
   "id": "E9",
   "profile": "formal",
   "foundation": "algebra of real polynomials",
   "description": "Evaluation of the ARIMA-form polynomials of ETS(A,N,A) at $B = 1$.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "D = \\begin{pmatrix} 1-\\alpha & -\\alpha \\\\ -\\gamma & 1-\\gamma \\end{pmatrix},\\ L(B) = \\mathrm{diag}(B, B^m)",
     "by": [
      "D9",
      "D1"
     ],
     "rule": "definition"
    },
    {
     "id": "S2",
     "statement": "\\theta(B) = \\det(I - D L(B)) = (1 - (1-\\alpha)B)(1 - (1-\\gamma)B^m) - \\alpha\\gamma B^{m+1}",
     "by": [
      "S1"
     ],
     "rule": "determinant of a $2 \\times 2$ matrix"
    },
    {
     "id": "S3",
     "statement": "\\theta(1) = \\alpha\\gamma - \\alpha\\gamma = 0",
     "by": [
      "S2"
     ],
     "rule": "evaluation at $B = 1$"
    },
    {
     "id": "S4",
     "statement": "\\phi(B) = \\det(I - L(B)) = (1 - B)(1 - B^m),\\ \\phi(1) = 0",
     "by": [
      "D9",
      "D1"
     ],
     "rule": "determinant of a diagonal matrix"
    },
    {
     "id": "S5",
     "statement": "\\det(I - \\tilde D) = 1^{m+1} \\theta(1) = 0",
     "by": [
      "S3",
      "C15"
     ],
     "rule": "identity of the lag-1 expansion at $\\lambda = 1$"
    }
   ]
  },
  {
   "id": "E11",
   "profile": "formal",
   "foundation": "linear algebra over the complex numbers",
   "description": "Schur-complement derivation of the characteristic polynomial of the lag-1 expansion.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "\\lambda I - \\tilde M = \\begin{pmatrix} \\lambda I_k - A & -B \\\\ -C & \\lambda I - S \\end{pmatrix}",
     "by": [
      "D2"
     ],
     "rule": "partition of the states into the $k$ current values (heads) and the $\\sum_j (l_j - 1)$ lagged copies (tails); $S$ shifts each tail chain, $C$ feeds each head into its first copy, $A$ and $B$ hold the entries of $M$ that act on heads with lag 1 and on last copies"
    },
    {
     "id": "S2",
     "statement": "\\det(\\lambda I - S) = \\lambda^{\\sum_j (l_j - 1)}",
     "by": [
      "S1"
     ],
     "rule": "determinant of a lower-triangular matrix with diagonal $\\lambda$"
    },
    {
     "id": "S3",
     "statement": "A + B (\\lambda I - S)^{-1} C = M\\, \\mathrm{diag}(\\lambda^{1 - l_1}, \\dots, \\lambda^{1 - l_k}),\\ \\lambda \\neq 0",
     "by": [
      "S1"
     ],
     "rule": "$(\\lambda I - S)^{-1} C$ maps head $j$ to its copies $\\lambda^{-s}$, $s = 1, \\dots, l_j - 1$, and $B$ reads copy $l_i - 1$ of component $i$"
    },
    {
     "id": "S4",
     "statement": "\\det(\\lambda I - \\tilde M) = \\lambda^{\\sum_j (l_j - 1)} \\det(\\lambda I_k - M\\, \\mathrm{diag}(\\lambda^{1 - l_j})) = \\det(\\Lambda(\\lambda) - M),\\ \\lambda \\neq 0",
     "by": [
      "S2",
      "S3"
     ],
     "rule": "Schur complement, then factoring $\\lambda\\, \\Lambda(\\lambda)^{-1}$ out on the right"
    },
    {
     "id": "S5",
     "statement": "\\det(\\lambda I - \\tilde M) = \\det(\\Lambda(\\lambda) - M) \\text{ for all } \\lambda",
     "by": [
      "S4"
     ],
     "rule": "two polynomials equal on $\\lambda \\neq 0$ are equal"
    },
    {
     "id": "S6",
     "statement": "\\det(\\lambda I - \\tilde M) = \\lambda^{\\sum_j l_j} \\det(I - M L(1/\\lambda)),\\ \\lambda \\neq 0",
     "by": [
      "S5",
      "D1"
     ],
     "rule": "factoring $\\Lambda(\\lambda)$ out on the right: $\\Lambda(\\lambda) - M = (I - M \\Lambda(\\lambda)^{-1}) \\Lambda(\\lambda)$"
    }
   ]
  },
  {
   "id": "E12",
   "profile": "simulation",
   "description": "Exploratory run RN13 of timing.py --seed 3 --repeats 50: for the first admissible and the first inadmissible random GUM with lags (1, 24, 168) (normal F with standard deviation 0.3) and for the cancelled MA polynomial of ETS(A,N,A,A) with seasonal lags 24 and 168 (alpha = 0.3, gamma = (0.1, 0.05)), the number of recursion steps of the step-down test and the mean times over 50 repeats of the step-down test, of all roots by numpy's companion-matrix eigenvalues and of the coefficients by inverse discrete Fourier transform.",
   "setup": {
    "studied": [
     "D7",
     "D15"
    ],
    "cases": [
     "D40",
     "D24"
    ],
    "procedure": [
     "D27"
    ],
    "lens": [
     "D31"
    ]
   },
   "artefacts": [
    "A1",
    "A4"
   ],
   "model": "random GUM and a fixed ETS model generated by timing.py",
   "parameters": "A4",
   "runs": 1,
   "seeds": [
    3
   ],
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN13"
   ],
   "execution": {
    "code_version": "de2f5a7b2ffa38e84f9081ed272efc887eb07555",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v139-x86_64-with-glibc2.39"
    },
    "hardware": {
     "machine": "x86_64",
     "cpus": 4
    }
   },
   "tables": [
    {
     "id": "T1",
     "description": "Recursion steps and mean times over 50 repeats of the step-down test, of all roots by numpy's companion-matrix eigenvalues and of the coefficients of theta and phi by inverse DFT, for an admissible and an inadmissible random GUM with lags (1, 24, 168) and for the cancelled MA polynomial of ETS(A,N,A,A) with seasonal lags 24 and 168",
     "conditions": {
      "repeats": 50
     },
     "row_labels": [
      "model",
      "degree"
     ],
     "columns": [
      "mean time of the step-down test, ms",
      "mean time of all roots by numpy companion eigenvalues, ms",
      "recursion steps run by the step-down test",
      "mean time of the coefficients of theta and phi by inverse DFT, ms"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "random GUM, lags (1, 24, 168), admissible",
        193
       ],
       "values": [
        0.7429920399954426,
        23.75985405999927,
        193,
        6.57281667999996
       ]
      },
      {
       "id": "r2",
       "label": [
        "random GUM, lags (1, 24, 168), inadmissible",
        193
       ],
       "values": [
        0.8138564999990194,
        20.8541055600017,
        170,
        null
       ]
      },
      {
       "id": "r3",
       "label": [
        "ETS(A,N,A,A), lags 24 and 168, cancelled theta",
        168
       ],
       "values": [
        0.4172366199964017,
        17.457083500003137,
        null,
        null
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E14",
   "profile": "formal",
   "foundation": "linear systems theory over the complex numbers",
   "description": "The reduced form of the ARIMA polynomials through the Kalman decomposition of the expanded system.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "\\exists T: T^{-1}\\tilde F T \\text{ block-triangular with a reachable and observable block } (F_{co}, g_{co}, w_{co}),\\ \\tilde w'(zI - \\tilde F)^{-1}\\tilde g = w_{co}'(zI - F_{co})^{-1} g_{co}",
     "by": [
      "D2"
     ],
     "rule": "Kalman canonical decomposition"
    },
    {
     "id": "S2",
     "statement": "\\tilde D = \\tilde F - \\tilde g \\tilde w' \\text{ keeps the reachable and the unobservable subspaces, so } D_{co} = F_{co} - g_{co} w_{co}'",
     "by": [
      "S1",
      "D2"
     ],
     "rule": "reachability is invariant under state feedback and observability under output injection"
    },
    {
     "id": "S3",
     "statement": "1 + w_{co}'(zI - F_{co})^{-1} g_{co} = \\frac{\\det(zI - D_{co})}{\\det(zI - F_{co})},\\ \\gcd(\\det(zI - D_{co}), \\det(zI - F_{co})) = 1",
     "by": [
      "S2"
     ],
     "rule": "matrix determinant lemma; a single-input single-output realisation is minimal if and only if the numerator and denominator of its transfer function are coprime"
    },
    {
     "id": "S4",
     "statement": "1 + \\tilde w'(zI - \\tilde F)^{-1}\\tilde g = \\frac{\\det(zI - \\tilde D)}{\\det(zI - \\tilde F)} = \\frac{\\theta(1/z)}{\\phi(1/z)}",
     "by": [
      "C15",
      "D1"
     ],
     "rule": "matrix determinant lemma and the identity of the lag-1 expansion"
    },
    {
     "id": "S5",
     "statement": "\\frac{\\theta(B)}{\\gcd(\\theta, \\phi)}(B) = 0 \\iff B = 1/\\lambda,\\ \\lambda \\in \\mathrm{spec}(D_{co}) \\setminus \\{0\\} \\text{ (with multiplicity)}",
     "by": [
      "S3",
      "S4"
     ],
     "rule": "uniqueness of the reduced fraction, with z = 1/B: the eigenvalues at zero give no root, theta(0) = phi(0) = 1 makes theta / gcd the reduced numerator, and the reversal keeps coprimality away from B = 0"
    }
   ]
  },
  {
   "id": "E15",
   "profile": "formal",
   "foundation": "algebra of complex polynomials",
   "description": "Scaling the argument of a polynomial scales its roots.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "c(B_i) = 0 \\iff c((r B_i) / r) = 0",
     "by": [],
     "rule": "substitution"
    },
    {
     "id": "S2",
     "statement": "|r B_i| > 1\\ \\forall i \\iff 1/|B_i| < r\\ \\forall i",
     "by": [
      "S1"
     ],
     "rule": "r > 0"
    },
    {
     "id": "S3",
     "statement": "c(B/r) / c(0) = 1 + \\sum_i (c_i / c_0)\\, r^{-i} B^i \\text{ has the roots of } c(B/r)",
     "by": [
      "S1"
     ],
     "rule": "c(0) \\neq 0"
    },
    {
     "id": "S4",
     "statement": "\\text{the step-down passes on } c(B/r) \\iff |r B_i| > 1\\ \\forall i",
     "by": [
      "D7",
      "S1",
      "S3"
     ],
     "rule": "the step-down test passes exactly when all roots lie outside the unit circle"
    }
   ]
  },
  {
   "id": "E16",
   "profile": "formal",
   "foundation": "linear algebra over the field of rational functions in $B$",
   "description": "Expansion of det(I - M L(B)) by multilinearity in the columns.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "\\text{column } j \\text{ of } I - M L(B) = e_j - B^{l_j} m_j",
     "by": [
      "D1"
     ],
     "rule": "definition of $L(B)$"
    },
    {
     "id": "S2",
     "statement": "\\det(I - M L(B)) = \\sum_{S} \\det\\left[\\, e_j\\ (j \\notin S),\\ -B^{l_j} m_j\\ (j \\in S) \\right]",
     "by": [
      "S1"
     ],
     "rule": "multilinearity of the determinant in the columns"
    },
    {
     "id": "S3",
     "statement": "\\det\\left[\\, e_j\\ (j \\notin S),\\ -B^{l_j} m_j\\ (j \\in S) \\right] = (-1)^{|S|} B^{\\sum_{j \\in S} l_j} \\det(M_{SS})",
     "by": [
      "S2"
     ],
     "rule": "Laplace expansion along the unit columns, and pulling the scalars out of the other columns"
    }
   ]
  },
  {
   "id": "E17",
   "profile": "formal",
   "foundation": "linear algebra over the complex numbers",
   "description": "The per-lag discount matrices of Section 5.4 of the ADAM monograph against D.",
   "availability": {
    "level": "public"
   },
   "steps": [
    {
     "id": "S1",
     "statement": "F_{m_i} = F_{\\cdot S_i},\\ g_{m_i} = g_{S_i},\\ w_{m_i} = w_{S_i} \\text{ (zero elsewhere), } S_i \\text{ the components of lag } m_i",
     "by": [
      "D1"
     ],
     "rule": "the split of Section 5.2 of the monograph"
    },
    {
     "id": "S2",
     "statement": "D_{m_i} = F_{m_i} - g_{m_i} w_{m_i}' \\text{ has non-zero columns only in } S_i",
     "by": [
      "S1"
     ],
     "rule": "definition"
    },
    {
     "id": "S3",
     "statement": "D_{m_i} \\sim \\begin{pmatrix} D_{S_i S_i} & 0 \\\\ \\ast & 0 \\end{pmatrix} \\Rightarrow \\mathrm{spec}(D_{m_i}) \\setminus \\{0\\} = \\mathrm{spec}(D_{S_i S_i}) \\setminus \\{0\\}",
     "by": [
      "S2"
     ],
     "rule": "a symmetric permutation and the eigenvalues of a block-triangular matrix"
    },
    {
     "id": "S4",
     "statement": "\\sum_i D_{m_i} = F - \\sum_i g_{m_i} w_{m_i}' = D + \\sum_{i \\neq j} g_{m_i} w_{m_j}'",
     "by": [
      "S1"
     ],
     "rule": "g w' = \\sum_i \\sum_j g_{m_i} w_{m_j}'"
    },
    {
     "id": "S5",
     "statement": "(a, b) \\text{ with lags } m_i \\neq m_j: \\left(\\sum_{i \\neq j} g_{m_i} w_{m_j}'\\right)_{ab} = g_a w_b",
     "by": [
      "S4"
     ],
     "rule": "a single term, so the sum differs from D exactly where g w' links components of different lags"
    }
   ]
  },
  {
   "id": "E18",
   "profile": "simulation",
   "lab_runs": [
    "RN44"
   ],
   "artefacts": [
    "A1",
    "A6"
   ],
   "parameters": "A6",
   "model": "ETS(A,N,A) with m = 12",
   "runs": 1,
   "seeds": [],
   "availability": {
    "level": "public"
   },
   "description": "Exploratory run RN44 of book_check.py --periods 2400: for ETS(A,N,A) with m = 12 and (alpha, gamma) = (0.1, 0.1) and (1.2, 0.9), the largest nonzero eigenvalue modulus of the per-lag discount matrices of the monograph, the effect |w' v_{t-l}| of initial states set to one in the full recursion v_t = D v_{t-l} (y = 0) over 2400 periods and its growth per period over the second half, the growth of the weight of an observation (the same recursion from zero states with one unit observation), and the largest root modulus of the cancelled MA polynomial.",
   "setup": {
    "studied": [
     "D16"
    ],
    "cases": [
     "D35"
    ],
    "procedure": [
     "D28"
    ],
    "lens": [
     "D30",
     "D34"
    ]
   },
   "execution": {
    "code_version": "5d5611bcdcce26a3c363352fdd738c14f18c96f4",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v140-x86_64-with-glibc2.39"
    }
   },
   "tables": [
    {
     "id": "T1",
     "description": "For ETS(A,N,A) with m = 12 at two parameter pairs: the largest nonzero eigenvalue modulus of the monograph's per-lag discount matrices, the effect of the initial states on the fitted value at period 2400 and its growth per period over the second half, the growth of the weight of an observation, and the largest root modulus of the cancelled MA polynomial",
     "conditions": {
      "model": "ETS(A,N,A)",
      "m": 12
     },
     "row_labels": [
      "alpha",
      "gamma"
     ],
     "columns": [
      "largest nonzero eigenvalue modulus of the book's per-lag discount matrices",
      {
       "variable": "effect of the initial states on the fitted value at the last period",
       "conditions": {
        "period": 2400
       }
      },
      "growth of the effect of the initial states per period over the second half",
      "growth of the weight of an observation per period over the second half",
      "largest root modulus of the cancelled MA polynomial"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        0.1,
        0.1
       ],
       "values": [
        0.9,
        1.1870393556989711e-11,
        0.9895781239569994,
        0.9909168445987553,
        0.9911267448787717
       ]
      },
      {
       "id": "r2",
       "label": [
        1.2,
        0.9
       ],
       "values": [
        0.19999999999999996,
        5.968778912343606e+16,
        1.0163934504137493,
        1.0163629094999396,
        1.0164568117563233
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E19",
   "profile": "simulation",
   "lab_runs": [
    "RN40"
   ],
   "artefacts": [
    "A7"
   ],
   "parameters": "A7",
   "model": "fits of gum(), adam() and ces() with bounds=\"admissible\"",
   "runs": 1,
   "seeds": [
    41
   ],
   "availability": {
    "level": "public"
   },
   "description": "Exploratory run RN40 of bench_eigens.R: the package installed at -O2 from a worktree at commit b963693 (the polynomial check with the step-down multiplying by 1 / (1 - k^2), the algorithm kept in the final code), each fit run seven times with smoothEigens() switched in the namespace between the per-lag and the polynomial check; the median time of a fit and its calls of smoothEigens(). The optimisation paths differ between the two checks, whose admissible regions differ.",
   "setup": {
    "studied": [
     "D4",
     "D12"
    ],
    "cases": [
     "D36",
     "D38"
    ],
    "procedure": [
     "D27"
    ],
    "lens": [
     "D32"
    ]
   },
   "tables": [
    {
     "id": "T1",
     "description": "Median time of a fit with bounds=\"admissible\" over seven runs and its calls of smoothEigens(), per-lag against polynomial check",
     "conditions": {
      "build": "R 4.3.3, -O2",
      "repeats": 7
     },
     "row_labels": [
      "fit"
     ],
     "columns": [
      "per-lag, seconds",
      "per-lag, calls",
      "polynomial, seconds",
      "polynomial, calls",
      "polynomial, inadmissible calls",
      "ratio of the times, polynomial / per-lag"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "gum(AirPassengers, orders=c(1,1), lags=c(1,12))"
       ],
       "values": [
        0.0969999999999942,
        484,
        0.0799999999999983,
        484,
        40,
        0.8247
       ]
      },
      {
       "id": "r2",
       "label": [
        "gum(AirPassengers, orders=c(2,1), lags=c(1,12))"
       ],
       "values": [
        0.162999999999997,
        964,
        0.194999999999993,
        964,
        43,
        1.1963
       ]
      },
      {
       "id": "r3",
       "label": [
        "adam(AirPassengers, \"AAdA\")"
       ],
       "values": [
        0.0520000000000067,
        162,
        0.0459999999999923,
        162,
        60,
        0.8846
       ]
      },
      {
       "id": "r4",
       "label": [
        "adam(hourly, \"ANA\", lags=c(24,168))"
       ],
       "values": [
        0.143999999999991,
        122,
        0.155999999999992,
        122,
        52,
        1.0833
       ]
      },
      {
       "id": "r5",
       "label": [
        "ces(AirPassengers, \"full\")"
       ],
       "values": [
        0.0599999999999881,
        324,
        0.0559999999999974,
        310,
        68,
        0.9333
       ]
      }
     ]
    }
   ],
   "execution": {
    "code_version": "b963693",
    "notes": "The lab run records the repository's HEAD at the time (5b9f24a); the benchmark ran the worktree at b963693, whose path is the first argument of the command.",
    "hardware": {
     "machine": "x86_64",
     "cpus": 4
    }
   }
  },
  {
   "id": "E20",
   "profile": "simulation",
   "design": "other",
   "description": "Planned tests (lab plans PL7 and PL8, runs RN49 and RN50, the same command): ets_arima.py --seed 2 --n 500 --adam 20 generated 500 ETS+ARIMA and 500 ETS+SARIMA models (seed 2, new against the exploratory runs RN46-RN48, seed 1), built each in ADAM's form, compared the matrices of 20 of them with adam() (0 lags differed, matrices within 4.4e-15), and decided admissibility by the check of the parts apart, the check of the whole model and the PBH reference.",
   "setup": {
    "studied": [
     "D13"
    ],
    "cases": [
     "D22"
    ],
    "procedure": [
     "D26",
     "D5"
    ],
    "lens": [
     "D29"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN49"
   ],
   "results": [
    {
     "id": "R17",
     "variable": "max abs difference between the ARIMA form of the ARIMA part and its ARI and MA polynomials",
     "value": 2.8171909249863347e-15,
     "conditions": {
      "models": 1000
     }
    },
    {
     "id": "R18",
     "variable": "models whose component lags differ from those of adam()",
     "value": 0,
     "conditions": {
      "models": 20
     }
    },
    {
     "id": "R19",
     "variable": "max abs difference between the matrices built here and those of adam()",
     "value": 4.440892098500626e-15,
     "conditions": {
      "models": 20
     }
    }
   ],
   "execution": {
    "code_version": "acb23120590a35c6b8b19290dbf861f830965b81",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v140-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A10",
    "A1"
   ],
   "tables": [
    {
     "id": "T1",
     "description": "Admissibility decisions of the check of the parts apart ('split') and of the check of the whole model ('joint') against the PBH reference on 500 models of each family: models whose decision differs, models accepted by the check and rejected by the reference, and models rejected by the check and accepted by the reference",
     "conditions": {
      "models": 500
     },
     "row_labels": [
      "family",
      "check"
     ],
     "columns": [
      "models whose admissibility decision differs from the PBH reference",
      "models accepted by the check and rejected by the PBH reference",
      "models rejected by the check and accepted by the PBH reference"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS+ARIMA",
        "split"
       ],
       "values": [
        166,
        104,
        62
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS+ARIMA",
        "joint"
       ],
       "values": [
        0,
        0,
        0
       ]
      },
      {
       "id": "r3",
       "label": [
        "ETS+SARIMA",
        "split"
       ],
       "values": [
        159,
        128,
        31
       ]
      },
      {
       "id": "r4",
       "label": [
        "ETS+SARIMA",
        "joint"
       ],
       "values": [
        0,
        0,
        0
       ]
      }
     ]
    },
    {
     "id": "T2",
     "description": "Per family of 500 models: models found admissible by the PBH reference, and the largest absolute difference of the largest modulus between the check of the whole model and the PBH reference on the models both find inadmissible, with their number",
     "row_labels": [
      "family"
     ],
     "columns": [
      "max abs difference of the largest modulus, check of the whole model against the PBH reference, on models both find inadmissible",
      {
       "variable": "models found admissible by the PBH reference",
       "conditions": {
        "models": 500
       }
      },
      "inadmissible"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS+ARIMA"
       ],
       "values": [
        4.3076653355456074e-13,
        159,
        341
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS+SARIMA"
       ],
       "values": [
        1.6268764113647194e-11,
        87,
        413
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E21",
   "profile": "simulation",
   "design": "other",
   "description": "Planned tests (lab plans PL7 and PL8, runs RN49 and RN50, the same command): ets_arima.py --seed 2 --n 500 --adam 20 generated 500 ETS+ARIMA and 500 ETS+SARIMA models (seed 2, new against the exploratory runs RN46-RN48, seed 1), built each in ADAM's form, compared the matrices of 20 of them with adam() (0 lags differed, matrices within 4.4e-15), and decided admissibility by the check of the parts apart, the check of the whole model and the PBH reference.",
   "setup": {
    "studied": [
     "D10"
    ],
    "cases": [
     "D22"
    ],
    "procedure": [
     "D26",
     "D5"
    ],
    "lens": [
     "D29",
     "D30"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN50"
   ],
   "results": [
    {
     "id": "R17",
     "variable": "max abs difference between the ARIMA form of the ARIMA part and its ARI and MA polynomials",
     "value": 2.8171909249863347e-15,
     "conditions": {
      "models": 1000
     }
    },
    {
     "id": "R18",
     "variable": "models whose component lags differ from those of adam()",
     "value": 0,
     "conditions": {
      "models": 20
     }
    },
    {
     "id": "R19",
     "variable": "max abs difference between the matrices built here and those of adam()",
     "value": 4.440892098500626e-15,
     "conditions": {
      "models": 20
     }
    }
   ],
   "execution": {
    "code_version": "acb23120590a35c6b8b19290dbf861f830965b81",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v140-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A10",
    "A1"
   ],
   "tables": [
    {
     "id": "T1",
     "description": "Admissibility decisions of the check of the parts apart ('split') and of the check of the whole model ('joint') against the PBH reference on 500 models of each family: models whose decision differs, models accepted by the check and rejected by the reference, and models rejected by the check and accepted by the reference",
     "conditions": {
      "models": 500
     },
     "row_labels": [
      "family",
      "check"
     ],
     "columns": [
      "models whose admissibility decision differs from the PBH reference",
      "models accepted by the check and rejected by the PBH reference",
      "models rejected by the check and accepted by the PBH reference"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS+ARIMA",
        "split"
       ],
       "values": [
        166,
        104,
        62
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS+ARIMA",
        "joint"
       ],
       "values": [
        0,
        0,
        0
       ]
      },
      {
       "id": "r3",
       "label": [
        "ETS+SARIMA",
        "split"
       ],
       "values": [
        159,
        128,
        31
       ]
      },
      {
       "id": "r4",
       "label": [
        "ETS+SARIMA",
        "joint"
       ],
       "values": [
        0,
        0,
        0
       ]
      }
     ]
    },
    {
     "id": "T2",
     "description": "Per family of 500 models: models found admissible by the PBH reference, and the largest absolute difference of the largest modulus between the check of the whole model and the PBH reference on the models both find inadmissible, with their number",
     "row_labels": [
      "family"
     ],
     "columns": [
      "max abs difference of the largest modulus, check of the whole model against the PBH reference, on models both find inadmissible",
      {
       "variable": "models found admissible by the PBH reference",
       "conditions": {
        "models": 500
       }
      },
      "inadmissible"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS+ARIMA"
       ],
       "values": [
        4.3076653355456074e-13,
        159,
        341
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS+SARIMA"
       ],
       "values": [
        1.6268764113647194e-11,
        87,
        413
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E22",
   "profile": "simulation",
   "design": "other",
   "description": "Planned test (lab plan PL9, run RN53): ets_arima.py --seed 3 --n 500 --impl generated 500 ETS+ARIMA and 500 ETS+SARIMA models (seed 3) and passed the matrices of each to adam_bounds_checker() of R (through pkgload::load_all of the repository) and of Python, with the AR reflection of its factors, comparing the penalty (zero, or 1e100 times the largest root modulus) with the prototype check of the whole model.",
   "setup": {
    "studied": [
     "D14"
    ],
    "cases": [
     "D22"
    ],
    "procedure": [
     "D26",
     "D10"
    ],
    "lens": [
     "D29",
     "D30"
    ]
   },
   "availability": {
    "level": "public"
   },
   "lab_runs": [
    "RN53"
   ],
   "results": [
    {
     "id": "R17",
     "variable": "max abs difference between the ARIMA form of the ARIMA part and its ARI and MA polynomials",
     "value": 2.6922908347160046e-15,
     "conditions": {
      "models": 1000
     }
    }
   ],
   "execution": {
    "code_version": "7cf641447804173fe3c014451e4311970cb65748",
    "software": {
     "python": "3.13.16",
     "platform": "Linux-6.18.44-fc-v140-x86_64-with-glibc2.39"
    }
   },
   "artefacts": [
    "A10",
    "A1"
   ],
   "tables": [
    {
     "id": "T1",
     "description": "Admissibility decisions of the check of the parts apart ('split') and of the check of the whole model ('joint') against the PBH reference on 500 models of each family: models whose decision differs, models accepted by the check and rejected by the reference, and models rejected by the check and accepted by the reference",
     "conditions": {
      "models": 500
     },
     "row_labels": [
      "family",
      "check"
     ],
     "columns": [
      "models whose admissibility decision differs from the PBH reference",
      "models accepted by the check and rejected by the PBH reference",
      "models rejected by the check and accepted by the PBH reference"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS+ARIMA",
        "split"
       ],
       "values": [
        171,
        115,
        56
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS+ARIMA",
        "joint"
       ],
       "values": [
        0,
        0,
        0
       ]
      },
      {
       "id": "r3",
       "label": [
        "ETS+SARIMA",
        "split"
       ],
       "values": [
        150,
        129,
        21
       ]
      },
      {
       "id": "r4",
       "label": [
        "ETS+SARIMA",
        "joint"
       ],
       "values": [
        0,
        0,
        0
       ]
      }
     ]
    },
    {
     "id": "T2",
     "description": "Per family of 500 models: models found admissible by the PBH reference, and the largest absolute difference of the largest modulus between the check of the whole model and the PBH reference on the models both find inadmissible, with their number",
     "row_labels": [
      "family"
     ],
     "columns": [
      "max abs difference of the largest modulus, check of the whole model against the PBH reference, on models both find inadmissible",
      {
       "variable": "models found admissible by the PBH reference",
       "conditions": {
        "models": 500
       }
      },
      "inadmissible"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS+ARIMA"
       ],
       "values": [
        1.3655743202889425e-13,
        159,
        341
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS+SARIMA"
       ],
       "values": [
        6.726019741165601e-11,
        76,
        424
       ]
      }
     ]
    },
    {
     "id": "T3",
     "description": "The bounds checker of adam() in R and of ADAM in Python against the prototype check of the whole model on 500 models of each family: admissibility decisions that differ, and the largest absolute difference of the largest root modulus on the models found inadmissible, with their number",
     "conditions": {
      "models": 500
     },
     "row_labels": [
      "family",
      "language"
     ],
     "columns": [
      "admissibility decisions of the package's bounds checker that differ from the prototype check of the whole model",
      "max abs difference of the largest modulus, package's bounds checker against the prototype, on models both find inadmissible",
      "inadmissible"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ETS+ARIMA",
        "R"
       ],
       "values": [
        0,
        9.53674319736919e-07,
        341
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS+ARIMA",
        "Python"
       ],
       "values": [
        0,
        9.536743161842054e-07,
        341
       ]
      },
      {
       "id": "r3",
       "label": [
        "ETS+SARIMA",
        "R"
       ],
       "values": [
        0,
        9.484902201428724e-07,
        424
       ]
      },
      {
       "id": "r4",
       "label": [
        "ETS+SARIMA",
        "Python"
       ],
       "values": [
        0,
        9.484902243617199e-07,
        424
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E23",
   "profile": "simulation",
   "lab_runs": [
    "RN55",
    "RN56"
   ],
   "artefacts": [
    "A11"
   ],
   "parameters": "A11",
   "model": "fits of adam() and ssarima() with bounds=\"admissible\"",
   "runs": 2,
   "availability": {
    "level": "public"
   },
   "description": "Exploratory runs of timing_ets_arima.R: the package installed at -O2 from two worktrees, the check of the parts apart (commit 397f255f) and of the whole model, each fit run five times. RN55 (commit af998d26) ran the check of the whole model on every call: pure ARIMA fits took 1.5 and 1.8 times as long. RN56 (commit b4a10cc6) adds the shortcut that, without ETS and adaptive regressors, accepts invertible MA factors without the check of the whole model; its times and log-likelihoods are in the table.",
   "setup": {
    "studied": [
     "D13",
     "D14"
    ],
    "cases": [
     "D36",
     "D37"
    ],
    "procedure": [
     "D27"
    ],
    "lens": [
     "D32",
     "D33"
    ]
   },
   "tables": [
    {
     "id": "T1",
     "description": "Median time of a fit over five runs and its log-likelihood, check of the parts apart against the whole model (RN56)",
     "conditions": {
      "build": "R 4.3.3, -O2",
      "repeats": 5
     },
     "row_labels": [
      "fit"
     ],
     "columns": [
      "parts apart, seconds",
      "whole model, seconds",
      "parts apart, log-likelihood",
      "whole model, log-likelihood"
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        "ARIMA(1,1,1)(1,1,1)[12]"
       ],
       "values": [
        0.0700000000000001,
        0.0740000000000001,
        -541.844444789273,
        -541.382357389734
       ]
      },
      {
       "id": "r2",
       "label": [
        "ETS(A,N,A)+ARIMA(1,0,1)"
       ],
       "values": [
        0.0669999999999997,
        0.0640000000000001,
        -569.649169125733,
        -572.214179521351
       ]
      },
      {
       "id": "r3",
       "label": [
        "ETS(A,Ad,N)+ARIMA(0,1,2)"
       ],
       "values": [
        0.0779999999999998,
        0.0780000000000003,
        -255.264423392167,
        -255.264424161103
       ]
      },
      {
       "id": "r4",
       "label": [
        "ssarima (1,1,1)(1,1,1)[12]"
       ],
       "values": [
        0.0799999999999996,
        0.0829999999999997,
        -556.990376211077,
        -556.990376211077
       ]
      }
     ]
    }
   ]
  },
  {
   "id": "E24",
   "profile": "simulation",
   "lab_runs": [
    "AC3.RN4",
    "AC3.RN5",
    "AC3.RN6",
    "AC3.RN7",
    "AC3.RN8",
    "AC3.RN9",
    "AC3.RN10"
   ],
   "artefacts": [
    "A15"
   ],
   "parameters": "A15",
   "model": "random ADAM ETS+ARIMA models of a wider generator",
   "runs": 7,
   "availability": {
    "level": "public"
   },
   "description": "Exploratory runs of the checker P4 (exact_oracle.py, seeds 21-23 and 31-34, 250 models each): admissibility by an exact oracle (rational determinants and the exact greatest common divisor of theta and phi, which cancels any shared factor) against the cancellation of cyclotomic factors ('author'), the PBH reference ('pbh') and the package ('pkg'); the number of models whose decision differs from the oracle.",
   "setup": {
    "studied": [
     "D10",
     "D5",
     "D14"
    ],
    "cases": [
     "D23"
    ],
    "procedure": [
     "D26",
     "D39"
    ],
    "lens": [
     "D29"
    ]
   },
   "tables": [
    {
     "id": "T1",
     "description": "Models, of 250 per seed, whose admissibility decision differs from the exact gcd oracle, for the cancellation of cyclotomic factors ('author'), the PBH reference ('pbh') and the package ('pkg'), seeds 21 to 23 and 31 to 34",
     "conditions": {
      "models": 250
     },
     "row_labels": [
      "seed"
     ],
     "columns": [
      {
       "variable": "models whose admissibility decision differs from the exact gcd oracle",
       "conditions": {
        "check": "author"
       }
      },
      {
       "variable": "models whose admissibility decision differs from the exact gcd oracle",
       "conditions": {
        "check": "pbh"
       }
      },
      {
       "variable": "models whose admissibility decision differs from the exact gcd oracle",
       "conditions": {
        "check": "pkg"
       }
      }
     ],
     "rows": [
      {
       "id": "r1",
       "label": [
        21
       ],
       "values": [
        0.0,
        0.0,
        1.0
       ]
      },
      {
       "id": "r2",
       "label": [
        22
       ],
       "values": [
        0.0,
        0.0,
        0.0
       ]
      },
      {
       "id": "r3",
       "label": [
        23
       ],
       "values": [
        0.0,
        0.0,
        0.0
       ]
      },
      {
       "id": "r4",
       "label": [
        31
       ],
       "values": [
        0.0,
        0.0,
        0.0
       ]
      },
      {
       "id": "r5",
       "label": [
        32
       ],
       "values": [
        0.0,
        0.0,
        0.0
       ]
      },
      {
       "id": "r6",
       "label": [
        33
       ],
       "values": [
        0.0,
        1.0,
        1.0
       ]
      },
      {
       "id": "r7",
       "label": [
        34
       ],
       "values": [
        0.0,
        0.0,
        1.0
       ]
      }
     ]
    }
   ]
  }
 ],
 "warrants": [],
 "limitations": [
  {
   "id": "L1",
   "category": "analytic_flexibility",
   "statement": "The 3042 ETS(A,N,A) models of the planned test of the per-lag check form the same fixed grid as exploratory run RN3, whose result prompted the hypothesis; only the 200 GUM models of that test were new data.",
   "affects": [
    "C1"
   ],
   "impact": "reduces_transferability",
   "mitigation": "partial",
   "mitigation_evidence": "E1"
  },
  {
   "id": "L2",
   "category": "measurement",
   "statement": "The PBH reference and the cyclotomic cancellation were written by the same agent and share the lag-1 expansion code and numpy's LAPACK eigenvalue routines; no independent implementation was compared.",
   "affects": [
    "C1",
    "C2",
    "C3",
    "C10",
    "C11",
    "C16"
   ],
   "impact": "could_reverse",
   "mitigation": "none"
  },
  {
   "id": "L3",
   "category": "sampling",
   "statement": "The random model sets (persistence ranges, the probabilities of zero persistence and of a constant, the standard deviations of the GUM matrices) were chosen by the agent and not drawn from models estimated on data.",
   "affects": [
    "C2",
    "C3",
    "C4",
    "C5",
    "C16"
   ],
   "impact": "reduces_transferability",
   "mitigation": "none"
  },
  {
   "id": "L4",
   "category": "measurement",
   "statement": "The reference decisions use numpy's polynomial roots (companion-matrix eigenvalues) for polynomials of degree up to 535 before cancellation with many roots near the unit circle, whose accuracy there was not checked by a second method.",
   "affects": [
    "C4",
    "C5",
    "C16"
   ],
   "impact": "could_reverse",
   "mitigation": "none"
  },
  {
   "id": "L5",
   "category": "deviation",
   "statement": "The plans of the tests behind the step-down and bisection claims stated MA polynomial degrees up to 366; the generator code named in the plans, run unchanged, produced degrees up to 535 before cancellation.",
   "affects": [
    "C4",
    "C5"
   ],
   "impact": "reduces_transferability",
   "mitigation": "none"
  },
  {
   "id": "L6",
   "category": "other",
   "statement": "The recursion of the counterexample to the monograph's condition was run for one parameter pair, with the initial states set to one and no data.",
   "affects": [
    "C22"
   ],
   "impact": "reduces_transferability",
   "mitigation": "partial",
   "mitigation_evidence": "E1"
  },
  {
   "id": "L7",
   "category": "computational",
   "statement": "The fit timings come from one machine, seven repeats per fit, with a run-to-run variation of about 10% between benchmark runs of the same code.",
   "affects": [
    "C23"
   ],
   "impact": "reduces_precision",
   "mitigation": "none"
  },
  {
   "id": "L8",
   "category": "model_specification",
   "statement": "For GUM models with structured parameters, such as a state with |F_ii| > 1 and zero persistence, theta and phi can share a factor with a root in |B| <= 1 that is not cyclotomic; the check keeps it and rejects the model although its observation weights decay, because the initial state of that mode has a growing effect.",
   "affects": [
    "C4",
    "C16"
   ],
   "impact": "reduces_transferability",
   "mitigation": "none"
  },
  {
   "id": "L9",
   "category": "measurement",
   "statement": "Estimates with bounds=\"admissible\" change for ETS+ARIMA models, whose admissible region changes, and the likelihood of such models can have several local optima: on ETS(A,N,A)+ARIMA(1,0,1) on AirPassengers the fit with the check of the whole model reached a lower log-likelihood than the fit with the check of the parts apart.",
   "affects": [
    "C27"
   ],
   "impact": "reduces_precision",
   "mitigation": "none"
  },
  {
   "id": "L10",
   "category": "computational",
   "statement": "Two defects found while testing were fixed before the planned runs: adam() with provided MA parameters added the MA coefficient of a lag without AR or differences twice to the persistence vector (and reapply() did so with the drawn ones, in R and Python), found by the structure check of the exploratory runs RN46 and RN47; and the Python build of smooth crashed at exit after checking a model whose MA polynomial has degree 16 or more (runs RN51 and RN52), because the caches of the check were freed through numpy after it had shut down. The second affected the implementation tested by C16 in Python, not its results. After the fixes the matrices built by the study matched those of adam() within 4.4e-15 (E21), and the planned run of the checkers (E22) exited normally.",
   "affects": [
    "C16",
    "C26"
   ],
   "impact": "could_bias_magnitude",
   "mitigation": "addressed",
   "mitigation_evidence": "E21"
  },
  {
   "id": "L11",
   "category": "computational",
   "statement": "For an MA root exactly on the unit circle that does not cancel, the decision of the check is set by rounding: the checker P4 found three models of a wider generator, with values of the check between 0.99999999999 and 1, that the package accepted and the prototype rejected. Since this finding the bounds checkers admit a model only when the value is at most 1 - 1e-10 (decision DC8 of the lab record), which rejects these three; the planned tests ran before the margin, and their random models have no such root.",
   "affects": [
    "C16",
    "C26"
   ],
   "impact": "reduces_transferability",
   "mitigation": "addressed",
   "mitigation_evidence": "E24"
  },
  {
   "id": "L12",
   "category": "measurement",
   "statement": "The PBH reference is not exact for a repeated unit root: the checker P4 found a model whose cancelled MA polynomial keeps a double root at -1, which the reference accepted and the cancellation and an exact gcd rejected. The random models of the planned tests have no such root.",
   "affects": [
    "C24",
    "C25"
   ],
   "impact": "reduces_transferability",
   "mitigation": "none"
  }
 ],
 "artefacts": [
  {
   "id": "A1",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/fe3ecfad42341fb0d2b81d02a7919b43baa5f695/.claude/research/eigenChecker/admissibility.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:f966bd9f065ee5453a2f809cb4e0f3aee938068589540b45ddf36eaa225c8b04",
   "licence": "LGPL-2.1-only",
   "description": "numpy prototype of the admissibility check of pure additive lagged SSOE models: lag-1 expansion, the per-lag check of smoothEigens(), the PBH reference, ARIMA-form polynomials by inverse DFT, cyclotomic cancellation, step-down test and bisection; ETS and GUM model builders"
  },
  {
   "id": "A2",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/fe3ecfad42341fb0d2b81d02a7919b43baa5f695/.claude/research/eigenChecker/explore.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:363cd20efd99fe98d1682440e14d160ddfe3095e27eb89e269465011d18a045d",
   "licence": "LGPL-2.1-only",
   "description": "exploratory script: ETS(A,N,A) cases, multiple seasonality and the GUM starting point, determinant identity, step-down and bisection on random GUMs, timings"
  },
  {
   "id": "A3",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/fe3ecfad42341fb0d2b81d02a7919b43baa5f695/.claude/research/eigenChecker/confirm.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:626d350fd940dd6fc4bdc057e350a3bbfcd92f71a51244fda0c31cb7d97e11f6",
   "licence": "LGPL-2.1-only",
   "description": "test script: per-lag check against the PBH reference, cancellation against the PBH reference, step-down decisions and bisection against roots, on seeded random model sets"
  },
  {
   "id": "A4",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/de2f5a7b2ffa38e84f9081ed272efc887eb07555/.claude/research/eigenChecker/timing.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:0b1019becaecb87919356973d575bd470b6cd47cb1352a5e63b3941b657d7e4a",
   "licence": "LGPL-2.1-only",
   "description": "timing script: recursion steps and mean times of the step-down test, of all roots by numpy companion eigenvalues and of the DFT coefficients, for random GUMs with lags (1, 24, 168) and ETS(A,N,A,A) with seasonal lags 24 and 168"
  },
  {
   "id": "A5",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/5d5611bcdcce26a3c363352fdd738c14f18c96f4/.claude/research/eigenChecker/cpp_check.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:da6d52153154136fa679681afd66ede768f211c56ace67ff139fa063e28cac2d",
   "licence": "LGPL-2.1-only",
   "description": "test script of the C++ implementation: smoothEigensR() through pkgload::load_all, called three times per model, against the numpy prototype on seeded random ETS and GUM models"
  },
  {
   "id": "A6",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/5d5611bcdcce26a3c363352fdd738c14f18c96f4/.claude/research/eigenChecker/book_check.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:8dde6775d393bf9616aa00483e2c9fc3bd9f480f52ca10e07dd2c8c22cc75473",
   "licence": "LGPL-2.1-only",
   "description": "check of the per-lag condition of the ADAM monograph (eqs 5.20-5.22) against the full discount recursion of ETS(A,N,A): the effect of the initial states and the weights of the observations"
  },
  {
   "id": "A7",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/5d5611bcdcce26a3c363352fdd738c14f18c96f4/.claude/research/eigenChecker/bench_eigens.R",
   "availability": {
    "level": "public"
   },
   "version": "sha256:6608bf04045ffe66be0966e2ec55cf2d9ba38721fe0995afb85d890290feec57",
   "licence": "LGPL-2.1-only",
   "description": "benchmark of the per-lag check against the polynomial check: time per call on fixed models and per fit with bounds=admissible, with smoothEigens() switched in the namespace"
  },
  {
   "id": "A8",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/5d5611bcdcce26a3c363352fdd738c14f18c96f4/src/headers/eigenCalc.h",
   "availability": {
    "level": "public"
   },
   "version": "sha256:0f5604775db84b6739363561e87a908fb76c683ffcce3e3771a86227ed88f5d4",
   "licence": "LGPL-2.1-only",
   "description": "the C++ implementation in smooth: lagPolynomial(), minorPolynomial(), complexDeterminant(), fftCore(), cyclotomicPolynomial(), polynomialDivide(), cancelUnitRoots(), largestRootModulus() and smoothEigensCpp()"
  },
  {
   "id": "A9",
   "kind": "lab_record",
   "uri": "https://github.com/openforecast-org/smooth/blob/794bc59c171c1a85b7736515d55f9d1afc461300/claimset/adam-admissible-bounds/lab/lab.jsonl",
   "version": "sha256:e16709960cf7a6d1f3e9bb65b4d1e0147d98c412463cc1ae2080bc5edcf1df68",
   "availability": {
    "level": "public"
   },
   "description": "Lab record of the study: questions, hypotheses, plans, runs, results, checks and decisions, as an append-only, hash-chained event log (Claimset lab record specification v0.6), anchored on the git branch claimset-lab-eigenChecker of openforecast-org/smooth; moved from .claude/lab to claimset/adam-admissible-bounds/lab by its relocation event MV1.",
   "licence": "CC-BY-4.0"
  },
  {
   "id": "A10",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/claimset/adam-admissible-bounds/code/ets_arima.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:f3e394d5f6563d9f9218c7519977a0227761bcdbf8428c8decd83811fa80f712",
   "licence": "LGPL-2.1-only",
   "description": "test script of Q2: random ETS+ARIMA models, the check of the parts apart and of the whole model against the PBH reference, the structure against adam(), and the bounds checkers of the package in R and Python against the prototype"
  },
  {
   "id": "A11",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/claimset/adam-admissible-bounds/code/timing_ets_arima.R",
   "availability": {
    "level": "public"
   },
   "version": "sha256:b9795e42432bd4d38996d496542ec72913564744d8b080312a5c2506fea25738",
   "licence": "LGPL-2.1-only",
   "description": "fit times and log-likelihoods of ARIMA and ETS+ARIMA models with bounds=\"admissible\", the package installed from two commits"
  },
  {
   "id": "A12",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/R/utils-adam.R",
   "availability": {
    "level": "public"
   },
   "version": "sha256:ca4bd6b7b946ca1b5445aa1d8603aa21649bf908ad27950e44a9022052a5d9bc",
   "licence": "LGPL-2.1-only",
   "description": "the bounds checker of adam(), om() and omg() in R (adam_bounds_checker())"
  },
  {
   "id": "A13",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/python/src/smooth/adam_general/core/utils/cost_functions.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:5008ff203b1360619fc081fd152a4b586d6218a5ac43d76dbd9089a251103a91",
   "licence": "LGPL-2.1-only",
   "description": "the bounds checker of ADAM, OM and OMG in Python (adam_bounds_checker())"
  },
  {
   "id": "A15",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/claimset/adam-admissible-bounds/code/checker/exact_oracle.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:f07dd7d664eac2995262cbca9170f347dae9ef9c401645ab7a6259fb35730d75",
   "licence": "LGPL-2.1-only",
   "description": "the exact oracle of the checker P4 (with lib.py in the same folder): rational determinants and the exact gcd of theta and phi against the cancellation, the PBH reference and the package"
  },
  {
   "id": "A16",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/claimset/adam-admissible-bounds/code/checker/formal.py",
   "availability": {
    "level": "public"
   },
   "version": "sha256:93d8218db0821a1d1e5efe153ec0b8f3ebbdda5008a8ded86f29f416c15d925c",
   "licence": "LGPL-2.1-only",
   "description": "the checker P4's exact check of the ARIMA form of ADAM's ARIMA part and of the worked example, on matrices of adam()"
  },
  {
   "id": "A17",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/claimset/adam-admissible-bounds/code/checker/r_shortcut.R",
   "availability": {
    "level": "public"
   },
   "version": "sha256:b5c5b7d689547bb97babb12556e44752157278aecdba0640858c3ed152d90d6e",
   "licence": "LGPL-2.1-only",
   "description": "the checker P4's test of the shortcut for pure ARIMA in R's adam_bounds_checker()"
  },
  {
   "id": "A14",
   "kind": "code",
   "uri": "https://github.com/openforecast-org/smooth/blob/604dbcac0e3ca9cb0e8c7c228cb11b1d6161594c/src/headers/eigenCalc.h",
   "availability": {
    "level": "public"
   },
   "version": "sha256:0f5604775db84b6739363561e87a908fb76c683ffcce3e3771a86227ed88f5d4",
   "licence": "LGPL-2.1-only",
   "description": "the C++ check shared by R and Python (smoothEigensCpp()), at the version tested by C26"
  }
 ],
 "references": [
  {
   "id": "B1",
   "target": "10.1007/978-3-540-71918-2",
   "id_type": "doi"
  },
  {
   "id": "B2",
   "target": "10.1016/0047-259X(73)90030-4",
   "id_type": "doi"
  },
  {
   "id": "B3",
   "target": "10.32614/CRAN.package.smooth",
   "id_type": "doi"
  },
  {
   "id": "B4",
   "target": "10.1201/9781003452652",
   "id_type": "doi"
  }
 ]
}
