Repository navigation
Guides Lineage and Variants
The names
fit_lsi,fit_eac,LSIFilterandEACFilterbelow are the pre-image API. Today they arefit(basis="legendre"),fit(basis="block")andImageFilter(basis=...); the historical forms themselves live in thedtfit-legacypackage.
This page is the single map of everything dtfit contains: where each method
came from, how it was improved (its versions), every variant and tuning
approach, and every adaptation -- promoted or still experimental. If
methods-explained.md tells you how each method works,
this page tells you how they all relate and how they evolved.
It is written to be read top-to-bottom, but you can also use it as a reference:
- 1. The family tree -- symbolic originals -> numeric successors -> streaming
- 2. Why the methods were rewritten -- the one hard design rule
- 3. The version history of each method -- original vs. current
- 4. The variant catalog -- every approach and knob, in one table
- 5. The adaptations -- #1-#6 and the rest, promoted and experimental
- 6. The whole library at a glance
Everything descends from one principle (see the guide): a function is identified by its differential spectrum (its integral "fingerprint"), so you recover parameters by matching the model's fingerprint to the data's. That principle was first realized as a set of symbolic methods, which were then rewritten as numeric methods for production, and finally extended to a streaming tier.
Differential-transformation principle
"match the fingerprint to recover parameters"
|
+-----------------------------+------------------------------+
| |
SYMBOLIC ERA (analytical, exact, fragile) (kept only as reference)
| |
+----+-----+---------------+ |
DSB DSBI DSBE <--- the three original |
(balance) (integral) (equal areas) "differential spectra |
| | | balance" formulations |
| | | |
| rewritten rewritten |
| numerically numerically DSB
v v v (the only symbolic
(reference) LSI EAC method still shipped,
| | as a derivation tool)
| |
NUMERIC ERA (production: noise-tolerant, bounded latency)
| |
+-------+-------+
| run recursively, one sample at a time
v
STREAMING TIER (online, real-time, drift-aware)
+----+----+
LSIFilter EACFilter
- DSB / DSBI / DSBE are the original symbolic methods (the "differential spectra balance" family): DSB balances spectra and solves exactly, DSBI is the integral-least-squares variant, DSBE the equal-areas variant.
- LSI is the numeric successor of DSBI; EAC is the numeric successor of DSBE. These are what you use in production.
- DSB survives as the lone symbolic method, kept as the analytical reference the numeric methods are checked against (not for fitting noisy data).
- LSIFilter / EACFilter are the streaming twins of LSI / EAC -- the same matching run recursively per sample.
-
Stochastic (
fit_stochastic,StochasticModel,StochasticFilter) is a layer built on top of LSI/EAC, not a new matcher. A random series has no deterministicf, but its functionals (autocorrelation, spectrum, aggregated variance, trend+cycle) do -- and they have the exp/power-law/cosine shapes the numeric methods fit. So the stochastic tier fits those functionals with the same LSI/EAC machinery and reads the process parameters out. See methods-explained.md#stochastic.
The dissertation imposes a single hard requirement on anything that runs at
deploy time: no unbounded symbolic solve on the runtime path. A symbolic
solver (sympy.nonlinsolve) has input-dependent, unbounded latency -- fine for an
offline derivation, unacceptable in a control loop or a streaming pipeline.
That rule is the reason the whole numeric era exists. SymPy is allowed exactly once, offline, at derivation/initialization time (to differentiate the model and compile a fast callable); after that, every fit is pure NumPy/SciPy with bounded cost. So:
- the symbolic DSB stays a reference/derivation tool;
- the numeric LSI / EAC do the actual batch fitting;
- the filters do the real-time work, compiling once in
__init__and then running fixed-cost updates.
A second motivation was noise. The exact symbolic balance matches the
high-order coefficients of a polynomial pre-fit -- exactly the coefficients noise
corrupts most. Relaxing "exact match" to "best least-squares match," and working
directly on the raw (x, y), is what made the numeric methods noise-tolerant.
Each numeric method went through real revisions. Knowing the old version explains why the current defaults are what they are.
| original DSB | current DSB | |
|---|---|---|
| Model spectrum | a hand-written table of closed-form "discretes" for exp, sin, cos, monomials -- plus a symbolic "reflection" pass |
generic SymPy differentiation: the Maclaurin coefficients of any differentiable expression |
| Models supported | only the handful with table entries | anything SymPy can differentiate (rational, log, mixed) |
The H^k factor |
tracked explicitly | shown to cancel on both sides of the balance, so it's dropped -- the balance is just matching plain polynomial coefficients |
The key realization -- that the scale factor cancels in a balance -- is what let DSB drop its per-function table and become general. Details: ../methods/dsb.md.
| original LSI (~= DSBI) | current LSI | |
|---|---|---|
| Basis | plain monomials |
Legendre polynomials, evaluated once into the data's own image |
| The match matrix | a (weighted) Hilbert matrix -- condition number explodes (~$10^7$ by order 5) | the image's own Gram matrix |
| Empirical spectrum | raw numpy.polyfit (ill-conditioned Vandermonde) |
the data's image: weighted projections |
| Model spectrum | Taylor-truncated | the model's own projection |
| High-order control | a hand-tuned exponential weight |
Gram-whitened projected least squares; no exponential weight needed |
In short, the original LSI spent effort fighting a bad basis; the current LSI changes the basis so the problem is well-posed to begin with, and reads the whole match off one fixed-size image. Details: ../methods/lsi.md.
| original EAC (~= DSBE) | current EAC | |
|---|---|---|
| Windows | exactly |
|
| Noise | no redundancy -> throws away the averaging that integration buys | extra equations average out per-window noise |
| Uncertainty | none (square system) | a covariance from the leftover residuals |
| Statistic | -- | the block image: window sums |
| Best for | -- | transients, saturating shapes, few params |
Details: ../methods/eac.md.
A "variant" here means a distinct approach you can call or switch on. This is the complete list across the stable API.
| approach | call / switch | what it is |
|---|---|---|
| LSI (default) | fit(..., basis="legendre") |
accurate batch fit on the Legendre image; k_star=None/"auto" (an omitted order) takes order_for's default |
| LSI, global search | fit(..., bounds=..., basis="legendre") |
trust-region local solve, with a differential-evolution stage when it's poor -- escapes bad local minima |
| LSI oscillatory recipe |
fit(..., freq_param="w", basis="legendre") or oscillatory=True
|
order raised to resolve a cycle, frequency seeded from the FFT -- recovers sinusoids to <1% |
| EAC (default) | fit(..., basis="block") |
overdetermined block image: local windows, a diagonal Gram that stays well conditioned on any grid |
| Robust image |
robust=True on fit, fit(basis="legendre"), fit(basis="block")
|
Huber-reweights the image before any model is fit -- self-scaling, no scale to tune |
| EAC, bounded | fit(..., bounds=..., basis="block") |
constrained trust-region fit |
| Missing data | Original(x, y, nan_policy="omit") |
drop NaNs instead of raising |
| DSB |
fit_dsb(...) (in dtfit_legacy.dsb) |
symbolic exact balance (reference only) |
| EACFilter | ImageFilter(..., basis="block") |
streaming EAC (area measurement) |
| LSIFilter | ImageFilter(..., basis="legendre") |
streaming LSI (spectrum measurement) -- for oscillatory plants |
| Gap coasting |
filter.coast(...), coast_cov(...)
|
dead-reckon a streaming fit through measurement dropouts (uncertainty grows with the gap) |
| Fused detection | sum(f.nis_ for f in filters) |
several filters' nis_ sum to a chi-square with the summed degrees of freedom, pooling their innovations into a shared-fault test |
| Stochastic fit |
fit_stochastic(...) -> StochasticModel
|
detect the regime of a random series (long-memory / mean-reversion / GARCH / cycle), forecast it, and .simulate it -- by fitting its functionals |
| Stochastic streaming | StochasticFilter(...) |
per-sample regime tracking + change detection |
| Stochastic estimators |
hurst_aggvar, hurst_spectral, ar1_reversion, garch_persistence, cycle_period, ar_order, fit_ar, fractional_difference
|
read one process parameter from a functional (all in dtfit.stochastic) |
| Model wrapper | Stochastic().fit(series) |
the catalog .fit() convention over fit_stochastic
|
| sklearn estimator |
NonlineRegressor(..., basis=, order=) (in dtfit.sklearn) |
fit behind fit/predict/score, with the basis and the order tunable |
| Auto basis | fit(..., basis="auto") |
fits the candidate bases and keeps the lowest-residual one |
| Auto-forecast | auto_forecast(...) |
structured fit-then-extrapolate, with guards |
| Model catalog | models.<family>() |
self-seeding named families; + to compose |
| Model inference | suggest_models(x, y) |
fit a shortlist, rank by AIC |
Every entry is documented with full signatures under ../api/.
Beyond the core methods, the research program produced a numbered series of
structural adaptations -- new ways to compose the fingerprint machinery.
Each was prototyped in dtfit-experimental, validated across the experiment
suite, and either promoted into stable dtfit (physically moved there) or
kept experimental until it proves itself. Here is the complete list with status.
| # | adaptation | in dtfit as |
what it is & how it works |
|---|---|---|---|
| #1 | one-pass / distributed map-reduce |
ImageStream accumulator |
the image is additive over the domain (a sum of per-chunk projections), so a dataset too big for memory is reduced chunk-by-chunk in one pass, and distributed workers' partial images merge() exactly on contiguous chunks of a uniform grid (or grid="explicit" for other sample sets); the estimators of the original study live in dtfit_legacy.scale. -> ../api/scaling.md
|
| -- | GEMM-batched projection | ImageStream(channels=B) |
the image is linear across channels, so B channels' projections are one matrix multiply over one shared Gram, on CPU/GPU by swapping only the backend; the estimators of the original study live in dtfit_legacy.scale. -> ../api/scaling.md
|
| -- | LSI oscillatory recipe |
fit(oscillatory=..., freq_param=..., basis="legendre"), fft_frequency_seed
|
high order + FFT-seeded frequency, so a cycle isn't erased. -> ../api/fitting.md#fit_lsi |
| adaptation | names | what it is & how it works |
|---|---|---|
| image bases |
FourierBasis, ChebyshevBasis, LaguerreBasis
|
keep the image criterion but choose the basis, passed as fit(..., basis=FourierBasis(K)) -- Fourier for periodic signals (a cycle is a few harmonics, not many polynomial orders), Laguerre for decays, Chebyshev for the Legendre span with a better-conditioned Gram |
| windows with explicit edges |
EdgeBlockBasis, SegmentBasis
|
the block basis with the equal-window constraint dropped: a window edge placed on a known jump epoch, windows left out, or a Legendre polynomial per segment |
| data known as window totals |
aggregated_image, fit_aggregated
|
per-window totals and counts are the block image, so the model's window sums are fitted to them directly -- the equal-areas criterion on aggregated data |
| window alignment |
fit_aligned, detect_jumps
|
find level jumps at unknown epochs from a fine block image, leave the windows that hold them out, refit with one shift per epoch |
| weak-form rate laws |
weak_operators, fit_logistic, fit_michaelis_menten, fit_damped_oscillator, fit_lotka_volterra_prey, seed_nlls
|
identify an ODE's constants from projections against test functions that vanish at the record's ends: no ODE solve, no starting guess; the estimate seeds the solved fit |
| a tracker in local time |
LocalTimeFilter, shift_matrix
|
ImageFilter on a polynomial whose origin moves onto every new sample, exact under the coefficient shift map, so the clock's zero does not condition the window |
| information-form fusion | InformationFilter |
inverse-covariance recursive linear estimator: additive updates, associative fuse() for sensor fusion and streaming map-reduce. Shares no code with ImageFilter, which runs the covariance form |
| several streams |
FilterBank, FusedChiSquareDetector (in dtfit_experimental.streaming) |
run many ImageFilter instances in lockstep and pool their per-stream innovations into one chi-square statistic; the stable equivalent is summing several ImageFilter.nis_ values directly. -> Methods-Filter-Bank
|
Full signatures and usage: ../experimental/adaptations-api.md. The conceptual write-up, the math each rests on and what its experiment reads: ../experimental/README.md.
An adaptation graduates only after the experiment notebooks show it helps
across a range of applications, not one cherry-picked case. On promotion it is
moved into dtfit and imported from there (no re-export shim -- the dependency
points one way only). The validation methodology and the baselines each
adaptation is measured against are in
../experimental/baselines.md.
dtfit (stable, public)
+-- batch fitting fit (basis="legendre" | "block" | "auto", robust=, freq_param=)
| support Original . Image . order_for . image.fft_frequency_seed
+-- result type FittingResult
+-- sklearn estimator sklearn.NonlineRegressor
+-- one-call entry points auto_forecast
+-- model framework models.<family> . models.Model . suggest_models
+-- streaming / online ImageFilter (basis="legendre" | "block")
| (coast/coast_cov dead-reckon through gaps; inflate/rearm hooks)
+-- stochastic (random) fit_stochastic . StochasticModel . StochasticFilter . models.Stochastic
| estimators: hurst_aggvar/spectral . ar1_reversion . garch_persistence
| cycle_period . decompose_trend_cycle . ar_order . fit_ar . fractional_difference
+-- scaling backends fit_many . ImageStream
| (accumulator . block streams . channels; merge/checkpoint/resume)
+-- diagnostics fit_report . residual_diagnostics . residual_stats . FitDisplay . ResidualsDisplay
dtfit-experimental (separate; promotes into dtfit when validated)
+-- image bases FourierBasis . ChebyshevBasis . LaguerreBasis
+-- explicit windows EdgeBlockBasis . SegmentBasis . aggregated_image . fit_aggregated
| fit_aligned . detect_jumps
+-- weak-form rate laws weak_operators . fit_logistic . fit_michaelis_menten
| fit_damped_oscillator . fit_lotka_volterra_prey . seed_nlls
+-- streaming LocalTimeFilter . InformationFilter
| streaming.FilterBank . streaming.FusedChiSquareDetector
+-- backend helpers available_backends . resolve_backend . Backend
+-- study tier study.families . study.baselines . study.montecarlo . ...
+-- experiments/ method/ . technology/ . realdata/ (the notebooks)
dtfit-legacy (separate; the historical stages, for the evolution matrix)
+-- source forms dsb.fit_dsb . dsb.find_degree . integral.fit_lsi . integral.fit_eac
+-- recursive filters streaming.EACFilter . streaming.LSIFilter
+-- map-reduce scale.PartitionedLSI . scale.PartitionedEAC . scale.PartitionedBatchLSI
| scale.fit_lsi_batched . scale.project_spectra
Where to go next:
- What each one does, plainly -> methods-explained.md
- Which to pick -> choosing-a-method.md
- Exact signatures -> ../api/ (stable) and ../experimental/adaptations-api.md (experimental)
- The proofs -> ../methods/
- How it was validated -> ../experimental/
Published automatically from the repo's wiki/ directory by the wiki workflow. All pages are maintained directly in wiki/.
Start here
Guides
Examples
- Overview
- 01 Quickstart
- 02 Fitting methods
- 03 Models & auto
- 04 sklearn estimator
- 05 Streaming
- 06 Scaling
- 07 Diagnostics
- 08 Stochastic
API reference
Methods (math)
Experimental
Validation