hawkes-engine 0.2.0
Released 2026-10-24. Pre-alpha research release.
0.1.0 measured its own weakness and stopped there. It shipped a map that says, for
a given regime, how much the reported standard error understates the sampling
spread – and left the user to read the map and decide what to do. 0.2.0 answers
that in code: fit(..., se_method="auto") consults the map, and where the map
measured a shortfall it reports a different interval rather than the one it knows
to be too narrow. This release also turns the paper into a submission.
The API may change between 0.x minor versions, and this one adds an argument and three result fields. See ADR-009.
What changed in behaviour
This is the part to read before upgrading.
se_method="auto"is new; the default is unchanged."hessian"is still the default and still behaves exactly as in 0.1.0."auto"is opt-in, and it may choose the bootstrap, which costs time.A fit with
se_method="auto"can take minutes. The bootstrap refits the model 200 times. Before it runs, the projected cost is compared withauto_max_seconds(default 120). The projection is a power law fitted to the four measured serial configurations of the capability table, times the measured efficiency of the process pool; it reproduces every measured row to within three percent. Above the limit,autokeeps the Hessian interval, says inse_notewhat was indicated and what it would have cost, and emits aRuntimeWarning. It does not silently spend the time.FitResultgainsse_source,se_noteandauto.se_sourceis"hessian","bootstrap"or"none", and it is the field to read before readingse: a result can carryse is Nonewithse_source == "none", which is a statement, not a failure. The serialisation schema is 2; schema-1 documents still load, withse_sourcereading as"hessian"and no record, because a 0.1.0 document cannot know what it did not record.n_bootstrapbelow 10 is refused for"bootstrap"and"auto". The bootstrap never reports an interval below ten usable replications; failing at the call is clearer than a fit that runs and returns nothing.fitacceptsbootstrap_workers. A study that parallelises over fits should set it to 1; leaving it atNonestarts one pool per fit.
What auto does when it does not know
The policy is written down in
docs/se_policy.md
before the feature, and the four cases are:
The map says |
|
|
|---|---|---|
a block’s 2-SE interval around the measured |
bootstrap, if the projection fits in |
|
the regime is outside the measured box |
Hessian, labelled uncalibrated |
|
the estimator is undefined in this regime |
no interval at all |
|
|
Hessian |
|
The threshold is twice the Monte Carlo standard error of the measured q itself,
which is the precision the study’s 2000 replications support. A consequence worth
stating: at that threshold every cell in the shipped map fires, so auto
chooses the bootstrap wherever the map has measured, and the Hessian only where the
map is silent or the projection exceeds the limit. That is a measured property of
the estimator, not an artefact of the rule, and the Limits
page
says so.
The interval study
The switch is tested, not asserted. A second pre-registration was frozen before its harness existed – a fresh document rather than an amendment to H6, because H6 measured no alternative interval and the hypothesis this study tests is not in that document. Three cells at 2000 events, 2000 replications each, both arms fitted to the same simulated event stream so the comparison is paired.
The result, whatever it is, is in studies/results/auto/analysis/report.txt in the
repository, with the hypotheses labelled there. A null result is reported as a null
result.
The result: the switch works, and it does not overshoot. All three pre-registered hypotheses were confirmed.
|
coverage, Hessian |
coverage, |
difference from nominal |
|---|---|---|---|
0.3028 |
0.9207 +/- 0.0030 |
0.9609 +/- 0.0017 |
-0.0229 +/- 0.0023 |
0.85 |
0.9378 +/- 0.0020 |
0.9627 +/- 0.0015 |
-0.0124 +/- 0.0010 |
0.95 |
0.8937 +/- 0.0037 |
0.9488 +/- 0.0025 |
-0.0326 +/- 0.0025 |
H-A1 (the switch lands closer to nominal) is confirmed at all three cells, on the
decay block and on the pooled block. H-A2 (it never exceeds 1.05 of nominal) is
confirmed: the highest coverage anywhere is 0.9762 on the decay block at
rho = 0.95, against a ceiling of 0.9975. H-A3 (the gain is larger at high
branching ratio) is confirmed and exploratory, because the map’s own pattern
suggested the direction.
Two things the release reports rather than rounds off. The worst Hessian cell is
the baseline block at rho = 0.95, at 0.7817, which is the failure the map
predicted there. And at that cell 274 of 2000 replications had a fitted branching
ratio above 0.95, so auto recorded them as outside the map and kept the Hessian
interval; the 0.9488 above is measured over all 2000, so those replications pull
it down rather than being excluded.
A third detail, from the same run: in 15 of the 2000 replications at
rho = 0.3028 the nearest measured cell was in a different branching-ratio
column, because the fitted parameters had drifted; the median distance to the
nearest cell was 0.206 grid steps and the largest 1.316. In one of those a fit with
a fitted rho near 0.45 landed nearest a shallow-decay cell the map marks
undefined, and auto returned no interval. That is the lookup doing what
trust.md
says it does — it answers from the nearest cell however far that cell is — and it is
a limitation of a nearest-neighbour map rather than a fault in the switch.
The paper
paper/main.tex builds to a PDF from one command, and every number and every table
in it is emitted by studies/make_paper_tex.py from a committed output; nothing is
typed by hand. All seven entries in paper/refs.bib have been checked against the
publisher record or the arXiv listing. paper/SUBMISSION.md is the arXiv checklist.
Nothing has been submitted to arXiv.
The paper is deposited on HAL, and the deposit is in moderation: HAL assigns a
hal- identifier at deposit but does not serve the record publicly until a
moderator accepts it. The reserved identifier is hal-05838093, and the record
becomes readable at https://hal.science/hal-05838093 when moderation clears.
Until then no public HAL link exists, and this paragraph should not name one. HAL
is CNRS-run and needs no endorsement, unlike a first arXiv submission; that is why
it was chosen as the route that does not depend on a stranger. The arXiv listing is
still pending an endorsement for stat.ME; when either becomes public, this
paragraph will say so.
Before 0.2.0 the paper had never been typeset: no session that prepared it had a
TeX installation, and the structure checks cannot see a failing compile. The first
real one failed, on twenty macros whose names contained digits. A Paper workflow
now typesets it on every change and uploads the PDF, and the release notes say so
because “builds to a PDF from one command” was, until then, a claim nobody had run.
What this release does not fix
Stated as plainly as 0.1.0 stated its limits.
autodoes not fix bias. The point estimate is unchanged. Only the width of an interval it reports can change, and only where the map measured a reason to change it.autodoes not make the undefined region estimable. Where the window holds too few decay times for the decay to be identified,autorefuses to report an interval. It does not find one.autodoes not covershared_decay=True, which is a different model withMdecay rates and is outside the measured map. It says so and uses the Hessian.autodoes not extrapolate. Outside the measured box it uses the Hessian and labels the interval uncalibrated.If the bootstrap fails to produce a usable refit often enough, the result is
se_source="none"with a note, not a wider interval.Large
Mat smallNremains slow and unreliable, and the calibration map still covers two types and one decay form.
Install
python -m pip install hawkes-engine==0.2.0
Supported platforms and Python versions are unchanged from 0.1.0.
The DOI
This release is archived at DOI
10.5281/zenodo.23620653.
Note that this begins a second Zenodo record. 0.1.0 was deposited by hand as
10.5281/zenodo.23613789, with concept DOI 10.5281/zenodo.23613788; 0.2.0 was
deposited by the GitHub integration as 10.5281/zenodo.23620653, with concept DOI
10.5281/zenodo.23620652. The two are separate series, so neither concept DOI
resolves to the other’s versions. Cite the version DOI above for this release, and
the record’s own concept DOI if you need “all versions of 0.2.0”.
That split is a defect in how the archive is published rather than a choice, and
later releases should be deposited into the 23620652 series so that one concept DOI
covers everything from 0.2.0 onward. See docs/RELEASING.md.