Concepts¶
EVI and EI workflows¶
The workflows share a default lower bound but use different upper bounds:
b_min = max(5, ceil(n**(1/3)))
b_max_EVI = min(floor(n**(1 - 1/e)), floor(n/17))
b_max_EI = min(floor(sqrt(n)), floor(n/17))
Here e is Euler's number, so the lower exponent is approximately 0.3333 and
the EVI upper exponent 1 - 1/e is approximately 0.6321; EI uses 0.5. Each
workflow uses the length of its own input series. These are tuning defaults,
not an optimality guarantee.
The EVI grid helper's min_disjoint_blocks defaults to 17; an explicit None
omits that cap. This setting only controls the automatic upper bound, so an
explicit max_block_size is honored unchanged. EI uses the same n/17 cap
alongside its square-root bound.
Neither bound is expanded to create more points. The grid is geometrically spaced,
rounded to integers, and deduplicated; callers can supply explicit block sizes.
The selectors search all usable levels in that range, including its endpoints;
there is no additional edge exclusion. The selected fitting window may be a
subset and need not include either endpoint. By default, EVI requires at least
five positive-summary levels and EI at least four finite path levels per window.
Restrict the search through the block-size bounds or an explicit block_sizes
grid.
Explicit bounds must be integer sizes from 2 through N, with the upper bound
strictly greater than the lower bound; conflicting bounds raise ValueError.
Infeasible automatic bounds also raise ValueError. A feasible grid may still
have too few usable levels for an estimator, which raises at window selection.
Use one grid source: generation controls, an explicit block_sizes grid, or a
reused EVI curve. Combining these sources raises ValueError.
EVI workflow¶
The core EVI path is:
- Choose a block extraction scheme and summary target.
- Build a log block-summary curve across a candidate block-size grid.
- Select a plateau window on the log-log scale.
- Fit a regression slope on the selected window to estimate
xi. - Map the fitted scaling law to design-life levels.
flowchart LR
raw["Observed raw series"] --> blocks["Block extraction over candidate block sizes"]
blocks --> summaries["Block-summary curve<br/>Q_tau(M_b), mean(M_b), or mode(M_b)"]
summaries --> plateau["Observed plateau selection<br/>on log(summary) vs log(block size)"]
raw --> bootstrap["Super-block bootstrap draws<br/>from the original series"]
bootstrap --> covariance["Cross-block covariance estimate<br/>for FGLS"]
plateau --> fit["Observed scaling fit<br/>xi = slope on selected plateau"]
covariance --> fit
fit --> design["Design-life mapping<br/>evaluate the same fitted law at larger block sizes"]
In this package, the design-life-level step is not a separate annual-maxima
fit. UniBM reuses the same block-quantile scaling law and simply evaluates it
at larger block sizes that correspond to longer design-life spans. The fitting
view therefore lives on the block size axis, while the planning-horizon
interpretation lives on the design-life years axis through the chosen
observation clock.
The relevant term for the current package output is a design-life level:
a quantile of the maximum over a design-life span, or equivalently a
T-year block-maximum tau-quantile on the chosen observation clock.
The quantile estimator defaults to tau = 0.5, so its curve is best read as a
median design-life level rather than as a classical return-period level.
The package maps one fitted quantile to design-life levels.
estimate_design_life_level cannot change that fit's tau: a different
quantile requires a matching fit. Separately, the repository's application
workflow exports companion levels at tau = 0.90, 0.95, 0.99. That workflow
holds the median fit's plateau and slope fixed and estimates a new intercept
for each quantile. These are shared-xi application views, not additional
fits automatically produced by the public design-life helper.
Main entrypoints:
unibm.evi.generate_block_sizesunibm.evi.blocks.block_summary_curveunibm.evi.estimation.estimate_target_scalingunibm.estimate_evi_quantileunibm.estimate_design_life_level
EI workflow¶
prepare_ei_bundle prepares all four BM paths by default. Supply path_keys
to compute only the required (base_path, sliding) pairs, or path_keys=() for
threshold-only estimation without any BM grid or path computation. An explicit
single block_sizes=[b] fixes native inference at that level and bypasses window
selection; it has stable_window=None and cannot be passed to pooled inference.
- Prepare block-size paths from the raw series.
- Construct native block-maxima EI paths across the candidate block sizes.
- Pool one preferred stable-window estimator, for example the
BB-sliding-FGLSpath. - Compare against reference estimators such as
K-gaps.
flowchart LR
raw["Observed raw series"] --> cdf["Full-sample empirical CDF<br/>Fhat(X_t) over the whole series"]
cdf --> scores["Observed score sequence<br/>Northrop: -log(Fhat)<br/>BB: 1 - Fhat"]
scores --> path["Observed BM path over block sizes<br/>statistics -> theta_b -> z_b"]
path --> stable["Observed stable-window selection"]
stable --> pooled["Observed pooled EI fit<br/>OLS or FGLS on the selected window"]
pooled --> theta["Headline theta estimate"]
raw --> bootraw["Circular raw-series bootstrap draws"]
bootraw --> bootpath["Bootstrap z-path draws<br/>recomputed from each resample"]
bootpath --> bootcov["Stable-window covariance<br/>estimated from bootstrap paths"]
bootcov --> pooled
The important separation is that the observed path and the bootstrap paths play different roles:
- the observed path is what gets pooled and turned into the headline
thetaestimate - the bootstrap paths are not averaged into a replacement path; they are used only to estimate the cross-block covariance for the FGLS weighting step
Main entrypoints:
unibm.ei.preparation.prepare_ei_bundleunibm.ei.bootstrap.bootstrap_bm_ei_pathunibm.ei.selection.select_stable_path_windowunibm.ei.bm.estimate_pooled_bm_eiunibm.ei.threshold.estimate_k_gapsunibm.ei.threshold.estimate_ferro_segers
Interpreting EVI vs EI outputs¶
The EVI plateau and the EI stable window answer different questions and need not coincide.
- The EVI plateau is the block-size region where the log block-summary curve is
sufficiently linear to support a stable
xiestimate. - The EI stable window is the block-size region where the extremal-index path
is sufficiently stable to support a formal
thetaestimate.
Different block-maximum quantiles Q_tau(M_b) are expected to share the same
asymptotic slope xi and to differ mainly in intercept. In the direct
block-maxima framework used here, serial dependence is already internalized in
the fitted block-maximum law, so the design-life-level curve should be read
directly from the dependent-series fit rather than through a second BM-side
theta adjustment. The shared-slope companion curves described above are an
application-level use of this asymptotic relationship, not a guarantee that
different finite-sample quantile fits have identical slopes.
In practice:
- use the EVI/design-life-level outputs for severity on the original physical scale
- use the EI outputs for extremal clustering; under the usual limiting
interpretation,
1 / thetais a mean number of extreme observations per cluster, not elapsed cluster duration or recovery time
Observation clock and annual maxima¶
The public estimators receive values, not timestamps. They cannot infer whether
one step means a calendar day, an observed day, or an active day. The caller
must establish that clock before fitting. EI preparation preserves the input
order and rejects non-finite values. allow_zeros=True preserves observed zeros;
False requires strictly positive input. Neither setting fills missing days.
Dropping a missing day can shorten an inter-exceedance gap, so it is not a
neutral EI preprocessing operation.
observations_per_year converts a design horizon into a block size; it does not
split the fitted series at January 1. The separate application GEV comparator
does form January–December annual maxima, after checking each year's coverage.
This calendar-year comparator is distinct from the many overlapping block sizes
used to estimate xi and theta.
Bootstrap lengths, repetitions, and regularization¶
The EVI super-block bootstrap uses
L = max(2 * B, floor(sqrt(N))), where N is the input series length and B
is the largest block size supplied to the bootstrap. The standard estimator
supplies the full positive-summary candidate grid, including levels outside
the selected fitting window. The same super-block draws are used across levels.
Both sliding and disjoint variants use this length rule without adjustment.
If floor(N / L) < 2, the automatic bootstrap returns no covariance; strict
FGLS raises an error, while AUTO may fall back to OLS. Two or three segments
retain the computed length, but do not guarantee reliable inference.
An explicit super_block_size
must be a non-boolean integer with B < L <= N and at least two complete
segments; it is used unchanged or rejected with ValueError. Fewer than two
usable segments cannot produce covariance. An incomplete final segment is omitted.
The factor two is a computational default, not an optimality or coverage guarantee.
EI uses its separate raw-series circular bootstrap length; this EVI rule does
not change it.
FGLS uses fixed diagonal shrinkage 0.73 for EVI and 0.37 for EI. The shrinkage
step retains marginal variances and multiplies off-diagonal covariances by
0.27 and 0.63, respectively, followed by a small diagonal ridge for numerical
stability. Adaptive repetitions control the
Monte Carlo error in estimating that covariance and the resulting fit; they do
not tune shrinkage, change the selected window, or create more observed data.
The default checkpoints are 128, 256, 512, 768, 1024. A fixed integer is also
supported. See Reading Returned Objects for the
precision targets and the meaning of a fit that reaches the cap. These are
conditional coefficient-covariance intervals, not bootstrap percentile
intervals, and the adaptive check is not a coverage guarantee.