State models are attractive because they turn a noisy sequence into an interpretable evolving belief. They are dangerous for exactly the same reason: a smooth line or decisive regime label can look like fact even when it is only the output of a fragile configuration. This tutorial shows how to propagate sigma points through nonlinear functions and compare that approximation with local linearization while keeping the information boundary and uncertainty visible.
The deliverable is practical. You will calculate one update, implement the recursion in Python and TypeScript, inspect eight model-specific scenarios, and use a guided lab to see why the state changes. The result is an educational filter, not an investment recommendation or a claim of predictive power.
The question this model answers
Unscented Kalman Filter answers a conditional question: given the selected model, its fixed configuration, and observations available through the current timestamp, what state summary should be carried forward?
That wording matters. It does not ask what the state “really was” after seeing the future. It does not estimate parameters. It does not decide whether a trading action is profitable. It provides a transparent alternative when derivatives are awkward or curvature makes a single tangent an unstable teaching approximation.
Intuition before notation
Instead of differentiating one tangent, the UKF moves a small deterministic cloud through the curve and measures how the cloud changes. Every update therefore needs a ledger. The learner should be able to point to the prior, the prediction, the new evidence, and the posterior. If one of those pieces is hidden, the final curve becomes an assertion rather than an explanation.
The state update visual is canonical: its labels correspond directly to the trace produced by both implementations.
The frozen definition
This article uses a scaled scalar sigma-point filter. Scalar scaled UKF with alpha=1, beta=2, kappa=0 and the same nonlinear f and h used in the EKF topic.
The core recursion is:
χ={m,m±√P}; transform each point through f and h, then reconstruct weighted means, variances, and cross-covariance.
The package excludes square-root ukf, augmented noise states, higher-dimensional matrix factorization, smoothing, and parameter fitting. Those are legitimate extensions, but adding them silently would make the arithmetic and information set ambiguous.
The package convention that changes the answer
The package freezes alpha=1, beta=2, and kappa=0; other valid scaled-UKF parameterizations can produce different weights and results.
That sentence belongs beside the formula because two implementations can both be called Unscented Kalman Filter and still disagree when they initialize, index, or parameterize the recursion differently.
When this model is the right abstraction
Use the UKF when deterministic moment propagation is preferable to local derivatives. It still assumes that a Gaussian mean and covariance adequately summarize the posterior.
Derivative-free does not mean model-free, exact, robust to outliers, or immune to poor sigma-point scaling. The practical selection test is not which curve looks smoothest. It is which latent representation, observation model, and information clock match the decision you must audit.
Filtering is not smoothing
A filtered state at t conditions on observations through t. A smoothed state at t can use later observations. Current statsmodels state-space documentation makes the same distinction between filtered and smoothed output (statsmodels 0.14.6 state-space guide).
For an online dashboard, alert, or causal backtest, silently substituting smoothed probabilities is a future-information leak. A retrospective research chart may use smoothing, but it must say so.
Inputs and clocks
The fixture uses 160 daily UTC observations per scenario. They are deterministic and synthetic. The timestamps are observation and availability times together; no exchange calendar, revision process, or vendor feed is implied.
The latent truth or true regime appears only for evaluation. The filter receives the observation values and fixed configuration. This separation lets us ask whether the recursion detects the generator without giving it the answer.
The configuration is part of the claim
{
"a": 0.9,
"b": 0.22,
"c": 0.04,
"q": 0.06,
"r": 0.49,
"alpha": 1.0,
"beta": 2.0,
"kappa": 0.0,
"initial_mean": 0.0,
"initial_variance": 1.5
}
These values are implementation choices, not fitted estimates. A production claim would need a pre-declared fitting sample, likelihood or loss, optimizer, parameter constraints, model-selection process, and out-of-sample evaluation.
One update by hand
The first canonical observation is 0.17405645. Applying the published recursion gives sigma left = -1.22474, sigma center = 0.00000, sigma right = 1.22474, predicted measurement = 0.07096, filtered mean = 0.08042.
The calculation retains full precision and rounds only for display. The validator repeats this first update independently rather than asking the Python implementation to grade itself.
What the state ledger reveals
For this topic, the most useful fields are sigma left, sigma center, sigma right, predicted measurement, filtered mean. Read them together. A posterior without its predicted state hides persistence; a posterior without its innovation or likelihood hides the observation's contribution.
Eight scenarios that target this algorithm
The scenarios are not a generic family checklist. Each one changes a specific assumption that matters to Unscented Kalman Filter:
- Mild curvature: Matched nonlinear functions provide a sigma-point control. The lab asks: How does the three-point cloud reconstruct the next moments?
- Strong curvature: Truth bends more strongly than the frozen measurement model. The lab asks: Which error remains even when no Jacobian is used?
- Broad uncertainty: Truth begins far from the prior and makes sigma spread consequential. The lab asks: What does the deterministic cloud see that a single tangent would miss?
- Abrupt nonlinear shift: A persistent jump moves the cloud into a new curvature region. The lab asks: How rapidly do transformed sigma points relocate?
- High measurement noise: Observation uncertainty dominates the nonlinear signal. The lab asks: Does the gain fall when measurement variance rises?
- Single outlier: One extreme observation tests a Gaussian moment approximation. The lab asks: Why is sigma-point propagation not an outlier-robust likelihood?
- Fast nonlinear dynamics: Truth evolves faster and with stronger sine feedback. The lab asks: Does moment propagation prevent lag under transition mismatch?
- Persistent sensor bias: A measurement offset begins after row 70. The lab asks: Will an unmodeled bias be absorbed into the state estimate?
This is the difference between a demo and a learning reference: the reader can name the stressed assumption before looking at the output.
The algorithm
- Validate observations and the fixed configuration.
- Initialize the declared prior.
- Predict before reading the current observation.
- score the observation under the predicted state or hypotheses.
- update and normalize.
- record diagnostics and carry the filtered state forward.
This order is causal. Reordering it can leak the observation into the prior or apply the transition twice.
A diagnostic that can disagree with the picture
Audit the sigma-point weights and spread, follow each point through the nonlinear maps, and compare the reconstructed moments with tracking diagnostics.
The fixture-backed diagnostic is sigma spread, curvature, and moment error. Prefix tracking scores are interpreted together with sigma spread and innovation consistency so a visually smooth moment approximation is not mistaken for exact nonlinear inference.
For the canonical full path, the published values include filtered state mae 0.1647, filtered state rmse 0.1996, raw observation rmse 0.3855, rmse improvement vs raw 0.1860, mean normalized innovation squared 0.3588, synthetic 95 interval hit rate 1.0000. They are author-derived from known synthetic truth after the causal trace is complete. They are not an empirical result and do not establish usefulness on market data.
The interactive version recalculates the same quantities only over rows revealed through the current step. That makes the score informative without letting future truth influence an earlier filter state.
Python and TypeScript parity
Both implementations accept the same observation list and configuration object. Both return one trace row per observation. The shared JSON fixture compares every primary state field at a tolerance of 1e-9.
Readable reference arithmetic is intentional. Optimization comes after the contract is proved. In production, use stable matrix decompositions, monitored conditioning, and explicit schema/version controls appropriate to the chosen extension.
The model-specific audit discipline
Continuous-state filters must keep covariance nonnegative. Discrete-state filters must keep probabilities normalized. The UKF must publish its sigma-point weights. BOCPD must define whether a change occurs before or after the current observation. MSAR must define transition direction and which regime owns each AR coefficient.
These are not cosmetic implementation details. They determine the answer.
For this topic, the decisive audit is: Audit the sigma-point weights and spread, follow each point through the nonlinear maps, and compare the reconstructed moments with tracking diagnostics.
The outlier trap
A single extreme observation can produce a large innovation, strong emission ratio, or elevated change probability. That evidence is not the same as a persistent break. Compare the next several observations before attaching a narrative.
The failure map is a decision aid: check model assumptions, sensitivity, and subsequent evidence before treating a filtered state as operational truth.
Weak separation is an honest result
When regimes have similar emissions or observation noise dominates state movement, posterior probabilities should remain mixed. Forcing a hard label throws away the most important output: the model is uncertain.
The same principle applies to continuous filters. A narrow covariance is only meaningful if process and measurement variances are credible.
Historical evidence decision
The historical-example decision is not useful. A named market episode would add narrative appeal but would not validate a frozen latent-state model. The package therefore uses deterministic synthetic data so the hidden truth, observation clock, and state transition are auditable. A historical case would require licensed point-in-time observations, a parameter-estimation cutoff, revision policy, benchmark, and redistribution permission.
This avoids an especially common error: showing one named episode, fitting or tuning with knowledge of the whole episode, and then presenting a hindsight state chart as causal detection evidence.
Explore the guided lab
The self-contained playground implements choose → step → observe → explain → compare. Change the scenario and one meaningful parameter, then watch the trace, chart, guidance, and audit table recompute together.
Reset restores the canonical first row. Step and Play share one transition. In reduced-motion mode, Play advances exactly one observation and never starts a timer.
How to validate a production extension
- Freeze the information clock and revision policy.
- Separate fitting, filtering, forecasting, smoothing, and decision evaluation.
- Use time-ordered holdouts or rolling origins.
- Benchmark against a simpler state or regime rule.
- Test parameter sensitivity and transition/emission misspecification.
- Monitor numerical conditioning and probability normalization.
- Keep uncertainty visible in the user interface.
- Never convert a latent-state estimate directly into a performance claim.
Family map
The next tutorial is Hidden Markov Model. The representation changes, but the audit question stays constant: exactly what did the model know when it produced this state?
Summary
You can now implement and audit Unscented Kalman Filter under a precise selected contract. The essential skill is not drawing a smooth state line. It is preserving the prior, prediction, evidence, posterior, and information boundary so another analyst can reproduce the result and challenge the assumptions.
Primary methodological records: Unscented Filtering and Nonlinear Estimation, Bayesian Filtering and Smoothing, A New Approach to Linear Filtering and Prediction Problems, Time Series Analysis by State Space Methods. The complete source-role and limitation ledger is in the canonical package.
Rendered from the canonical Mermaid sources linked by this article.
Unscented Kalman Filter Causal Update Flow
This diagram shows the information order that every implementation and visual preserves.
Takeaway: the observation enters after prediction, and no row after t can affect the filtered state at t.
ReferencesPrimary sources and evidence notesExpand the source trail, evidence role, and limitations behind the engineering choices.
Expand the source trail, evidence role, and limitations behind the engineering choices.
The canonical package distinguishes sourced definitions from implementation choices and synthetic inputs.
JULIER2004 — Unscented Filtering and Nonlinear Estimation
- Organization or authors: Simon J. Julier and Jeffrey K. Uhlmann
- Source type: Peer-reviewed survey paper
- Publication or effective date: 2004-03
- Version: Proceedings of the IEEE 92(3)
- URL or DOI: https://doi.org/10.1109/JPROC.2003.823141
- Accessed: 2026-07-27
- Jurisdiction: Methodological; not jurisdiction-specific
- Supports: Unscented transformation, sigma points, and nonlinear filtering motivation.
- Limitations: Many valid sigma-point parameterizations exist; this package freezes one.
- Evidence role: Public authoritative definition or maintained implementation context
- Publication boundary: No source dataset or copyrighted figure is redistributed
SARKKA2023 — Bayesian Filtering and Smoothing
- Organization or authors: Simo Särkkä and Lennart Svensson
- Source type: Authoritative graduate textbook
- Publication or effective date: 2023-05-31
- Version: Second edition, Cambridge University Press
- URL or DOI: https://doi.org/10.1017/9781108917407
- Accessed: 2026-07-27
- Jurisdiction: Methodological; not jurisdiction-specific
- Supports: Unified Bayesian filtering terminology and modern treatment of linear, extended, and sigma-point filters.
- Limitations: The scalar functions and parameter values in this package remain local teaching choices.
- Evidence role: Public authoritative definition or maintained implementation context
- Publication boundary: No source dataset or copyrighted figure is redistributed
KALMAN1960 — A New Approach to Linear Filtering and Prediction Problems
- Organization or authors: R. E. Kalman
- Source type: Original peer-reviewed paper
- Publication or effective date: 1960-03-01
- Version: Journal of Basic Engineering 82(1), 35–45
- URL or DOI: https://doi.org/10.1115/1.3662552
- Accessed: 2026-07-27
- Jurisdiction: Methodological; not jurisdiction-specific
- Supports: Recursive linear state estimation and covariance propagation.
- Limitations: Original notation differs from this scalar teaching contract.
- Evidence role: Public authoritative definition or maintained implementation context
- Publication boundary: No source dataset or copyrighted figure is redistributed
STATSMODELS_STATE — Time Series Analysis by State Space Methods
- Organization or authors: statsmodels developers
- Source type: Maintained official documentation
- Publication or effective date: 2025-12-05
- Version: statsmodels 0.14.6
- URL or DOI: https://www.statsmodels.org/stable/statespace.html
- Accessed: 2026-07-27
- Jurisdiction: Methodological; not jurisdiction-specific
- Supports: Current state-space terminology and the distinction between filtering and smoothing.
- Limitations: Library capabilities and defaults are not universal mathematical definitions.
- Evidence role: Public authoritative definition or maintained implementation context
- Publication boundary: No source dataset or copyrighted figure is redistributed
Full dependency-light reference implementations in both supported languages.
export function runFilter(observations, config) {
if (!Array.isArray(observations) || !observations.length || observations.some(v => !Number.isFinite(v))) throw new Error("observations must be finite and non-empty");
const c=config,n=1,lambda=c.alpha**2*(n+c.kappa)-n,scale=n+lambda;
if(c.q<0||c.r<=0||c.initial_variance<0||c.alpha<=0||scale<=0)throw new Error("invalid UKF configuration");
const wm=[lambda/scale,1/(2*scale),1/(2*scale)],wc=[wm[0]+1-c.alpha**2+c.beta,wm[1],wm[2]];
const f=x=>c.a*x+c.b*Math.sin(x),h=x=>x+c.c*x*x;
let mean=c.initial_mean,variance=c.initial_variance;const trace=[];
observations.forEach((observation,index)=>{
const spread=Math.sqrt(Math.max(scale*variance,0)),sigma=[mean,mean-spread,mean+spread],propagated=sigma.map(f);
const predicted_mean=wm.reduce((s,w,i)=>s+w*propagated[i],0);
const predicted_variance=c.q+wc.reduce((s,w,i)=>s+w*(propagated[i]-predicted_mean)**2,0);
const updateSpread=Math.sqrt(Math.max(scale*predicted_variance,0)),stateSigma=[predicted_mean,predicted_mean-updateSpread,predicted_mean+updateSpread],measurementSigma=stateSigma.map(h);
const predicted_measurement=wm.reduce((s,w,i)=>s+w*measurementSigma[i],0);
const innovation_variance=c.r+wc.reduce((s,w,i)=>s+w*(measurementSigma[i]-predicted_measurement)**2,0);
const cross=wc.reduce((s,w,i)=>s+w*(stateSigma[i]-predicted_mean)*(measurementSigma[i]-predicted_measurement),0);
const kalman_gain=cross/innovation_variance,innovation=observation-predicted_measurement;
mean=predicted_mean+kalman_gain*innovation;variance=Math.max(predicted_variance-kalman_gain**2*innovation_variance,0);
trace.push({index,sigma_left:sigma[1],sigma_center:sigma[0],sigma_right:sigma[2],predicted_mean,predicted_variance,predicted_measurement,innovation,innovation_variance,kalman_gain,filtered_mean:mean,filtered_variance:variance});
});return trace;
}
The embedded lab now expands to its full document height, keeping the article as the only scroll surface.