<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>eproc, branch HEAD</title>
<subtitle>Anytime-valid sequential testing and confidence sequences.
</subtitle>
<entry>
<id>74e20bd89b53c21da1878c4a6bb9ef63c2b59c3e</id>
<published>2026-07-04T18:59:31Z</published>
<updated>2026-07-04T18:59:31Z</updated>
<title type="text">release: v0.4.1</title>
<link rel="alternate" type="text/html" href="commit/74e20bd89b53c21da1878c4a6bb9ef63c2b59c3e.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 74e20bd89b53c21da1878c4a6bb9ef63c2b59c3e
parent 54282d253042a7ec1891ef4fe72496f4908ffa52
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sat,  4 Jul 2026 16:29:31 -0230

release: v0.4.1

</content>
</entry>
<entry>
<id>54282d253042a7ec1891ef4fe72496f4908ffa52</id>
<published>2026-07-04T18:57:06Z</published>
<updated>2026-07-04T18:57:06Z</updated>
<title type="text">fix: uncap the ConfSeq plug-in bet</title>
<link rel="alternate" type="text/html" href="commit/54282d253042a7ec1891ef4fe72496f4908ffa52.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 54282d253042a7ec1891ef4fe72496f4908ffa52
parent 18a95aecce2a74ea6abd7b1a62adf07c927e4a9c
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sat,  4 Jul 2026 16:27:06 -0230

fix: uncap the ConfSeq plug-in bet

Numeric.Eproc.ConfSeq pre-capped the shared predictable plug-in bet
at the truncation level c = 1/2 before applying the candidate-
specific truncations c/m and c/(1 - m). Since both exceed c on the
interior grid, those truncations could never bind: a conservative
deviation from the WSR (2024) eq. (26) bet that Theorem 3 and the
module documentation describe, slowing rejection of extreme
candidates early in the stream.

Drop the pre-cap. The raw eq. (26) bet is now truncated only per-
candidate, restoring the paper&#39;s construction and its early power;
every capital factor retains the 1 - c floor via the truncations
themselves, so coverage is unaffected. The update haddock, which
carried the same pre-cap in its bet formula, and the module-header
example output are corrected to match.

Validated with and without -f+llvm.

</content>
</entry>
<entry>
<id>18a95aecce2a74ea6abd7b1a62adf07c927e4a9c</id>
<published>2026-07-03T17:39:21Z</published>
<updated>2026-07-03T17:39:21Z</updated>
<title type="text">release: v0.4.0</title>
<link rel="alternate" type="text/html" href="commit/18a95aecce2a74ea6abd7b1a62adf07c927e4a9c.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 18a95aecce2a74ea6abd7b1a62adf07c927e4a9c
parent fd9e56f36fadee3edca61961dbb558d8ce52546a
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 15:09:21 -0230

release: v0.4.0

Anytime-valid p-values and e-values on every test module, uniform
convex mixtures of e-processes (Numeric.Eproc.Mixture), and
time-uniform confidence sequences for bounded means
(Numeric.Eproc.ConfSeq). README, CHANGELOG, and cabal description
refreshed to match; the Mixture module example is now
self-contained, with outputs verified against a live GHCi session.

</content>
</entry>
<entry>
<id>fd9e56f36fadee3edca61961dbb558d8ce52546a</id>
<published>2026-07-03T17:09:09Z</published>
<updated>2026-07-03T17:09:09Z</updated>
<title type="text">Merge branch &#39;impl/confseq&#39;</title>
<link rel="alternate" type="text/html" href="commit/fd9e56f36fadee3edca61961dbb558d8ce52546a.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit fd9e56f36fadee3edca61961dbb558d8ce52546a
parent e5232a884dd0c98ed00f8bd6611d353d24b614d4
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:39:09 -0230

Merge branch &#39;impl/confseq&#39;

Numeric.Eproc.ConfSeq: anytime-valid confidence sequences for
bounded means, via the hedged-capital construction of Waudby-Smith
&amp; Ramdas (2024), Theorem 3, over a finite grid of candidate means.

The betting scheme is pinned by the theorem rather than reusing the
library&#39;s Bettor strategies: a single m-free predictable plug-in
bet (their eq. (26)) is computed once per update from running
regularized statistics and shared across all candidates, with only
the c/m and c/(1-m) truncations (c = 1/2) candidate-specific, and
rejection decided by the max-hedge at theta = 1/2. This m-freeness
is what makes the survivor set provably an interval (m-dependent
bets like aGRAPA/ONS can produce non-interval survivor sets, their
Section E.4), which in turn makes the sentinel-widened grid
interval a sound superset of the continuum confidence sequence:
whenever &#39;interval&#39; reports Just, it covers the true mean uniformly
over time with probability at least 1 - alpha. Nothing signals
resolution below the grid; rerun with a larger grid.

Rejected candidates are dropped permanently, so intervals are
nested and per-update cost is O(live candidates): ~2.1 us per
observation at g = 200, shrinking as evidence accumulates. Coverage
verified by simulation at an off-grid truth, checked after every
observation. Adds InvalidGridSize to ConfigError and the WSR paper
under etc/. Validated with and without -f+llvm.

Merge resolutions: union of the mixture- and confseq-side additions
to ConfigError, exposed-modules, the test main list, and the bench
suites.

</content>
</entry>
<entry>
<id>b0fe75351d6a55ecbd90e4f95b7af53ebd58c5ef</id>
<published>2026-07-03T17:00:42Z</published>
<updated>2026-07-03T17:00:42Z</updated>
<title type="text">bench: ConfSeq update and fold benchmarks</title>
<link rel="alternate" type="text/html" href="commit/b0fe75351d6a55ecbd90e4f95b7af53ebd58c5ef.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit b0fe75351d6a55ecbd90e4f95b7af53ebd58c5ef
parent 5c12e9d87bdd71a96170381c6fceaefb371ce395
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:30:42 -0230

bench: ConfSeq update and fold benchmarks

One-step update and 1000-sample fold at g = 200, in both the
criterion and weigh suites. The NFData orphan for ConfSeq.State
relies on the module&#39;s invariant that the live-candidate list is
fully forced on construction, so WHNF == NF.

</content>
</entry>
<entry>
<id>5c12e9d87bdd71a96170381c6fceaefb371ce395</id>
<published>2026-07-03T17:00:42Z</published>
<updated>2026-07-03T17:00:42Z</updated>
<title type="text">test: confidence-sequence coverage, nesting, and safety tests</title>
<link rel="alternate" type="text/html" href="commit/5c12e9d87bdd71a96170381c6fceaefb371ce395.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 5c12e9d87bdd71a96170381c6fceaefb371ce395
parent 15f814b89fc95af7646eabf8330f3e611c1454c9
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:30:42 -0230

test: confidence-sequence coverage, nesting, and safety tests

Covers the initial full-range interval, interval nesting (unit and
property forms), simulated time-uniform coverage at an off-grid
Bernoulli mean, consistency/shrinkage onto the true mean, affine
correctness on a shifted range, config validation, and endpoint
well-formedness on arbitrary admissible streams.

</content>
</entry>
<entry>
<id>e5232a884dd0c98ed00f8bd6611d353d24b614d4</id>
<published>2026-07-03T16:58:21Z</published>
<updated>2026-07-03T16:58:21Z</updated>
<title type="text">Merge branch &#39;impl/mixture&#39;</title>
<link rel="alternate" type="text/html" href="commit/e5232a884dd0c98ed00f8bd6611d353d24b614d4.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit e5232a884dd0c98ed00f8bd6611d353d24b614d4
parent 768d004f1949a588f2a8293e2c6ff42be15e7daf
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:28:21 -0230

Merge branch &#39;impl/mixture&#39;

Numeric.Eproc.Mixture: uniform K-way convex mixtures of e-processes.

The arithmetic mean of K component e-processes adapted to a common
filtration is itself an e-process, so a single Ville threshold
log(K/alpha) tests the combined null with power against a union of
qualitatively different alternatives, strictly dominating a
Bonferroni union. Components stay caller-owned (they are typically
heterogeneous); update consumes the per-step vector of component
log e-values as exposed by the new log_evalue accessors. The
rejection latch lives on the supremum of the mixture&#39;s own
log-wealth -- latching per-component suprema combines peaks from
different times and silently inflates alpha, the pitfall downstream
consumers previously had to avoid by hand.

Adds InvalidComponentCount to ConfigError. K=4 update measures
~31 ns and 32 bytes allocated per step. Validated with and without
-f+llvm.

</content>
</entry>
<entry>
<id>662222b16d770527e35280b188fb92ca0b14bc14</id>
<published>2026-07-03T16:58:21Z</published>
<updated>2026-07-03T16:58:21Z</updated>
<title type="text">test,bench: Mixture coverage and measurement</title>
<link rel="alternate" type="text/html" href="commit/662222b16d770527e35280b188fb92ca0b14bc14.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 662222b16d770527e35280b188fb92ca0b14bc14
parent ff6be8e3b2692d735be121efdf1486b2310852e0
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:28:21 -0230

test,bench: Mixture coverage and measurement

Tests pin the identity between a K-fold mixture of identical
components and the component itself (shifted by log K), the
mixture-sup latch against the per-component-sup alpha-inflation
pitfall, decide/p_value agreement, monotonicity/latching, config
validation, and simulated type-I error and power for a censor-style
sign + magnitude hedge. Criterion and weigh entries measure the
K=4 update: ~31 ns and 32 bytes per step.

</content>
</entry>
<entry>
<id>15f814b89fc95af7646eabf8330f3e611c1454c9</id>
<published>2026-07-03T16:55:17Z</published>
<updated>2026-07-03T16:55:17Z</updated>
<title type="text">api: anytime-valid confidence sequences via WSR Theorem 3</title>
<link rel="alternate" type="text/html" href="commit/15f814b89fc95af7646eabf8330f3e611c1454c9.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 15f814b89fc95af7646eabf8330f3e611c1454c9
parent addadd93c816781d8f2ad32ca905efaa44d96198
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:25:17 -0230

api: anytime-valid confidence sequences via WSR Theorem 3

Numeric.Eproc.ConfSeq estimates the conditional mean of bounded
observations with a time-uniform confidence interval, running a
grid of hedged-capital e-processes (Waudby-Smith &amp; Ramdas (2024),
Theorem 3) with the predictable plug-in bet of their eq. (26),
max-hedge theta = 1/2, truncation c = 1/2.

The bet is deliberately m-free (only the truncation depends on the
candidate mean), which is what makes the survivor set provably an
interval; the module therefore does not use the library&#39;s Bettor
strategies. Rejected grid candidates are dropped permanently, so
per-update cost shrinks as evidence accumulates and reported
intervals are nested.

Adds the InvalidGridSize constructor to ConfigError in Common.

</content>
</entry>
<entry>
<id>ff6be8e3b2692d735be121efdf1486b2310852e0</id>
<published>2026-07-03T16:54:28Z</published>
<updated>2026-07-03T16:54:28Z</updated>
<title type="text">api: Numeric.Eproc.Mixture, uniform convex mixtures of e-processes</title>
<link rel="alternate" type="text/html" href="commit/ff6be8e3b2692d735be121efdf1486b2310852e0.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit ff6be8e3b2692d735be121efdf1486b2310852e0
parent 768d004f1949a588f2a8293e2c6ff42be15e7daf
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:24:28 -0230

api: Numeric.Eproc.Mixture, uniform convex mixtures of e-processes

A K-way arithmetic mean of component e-processes is itself an
e-process, so a single Ville threshold log(K/alpha) tests the
combined null with power against a union of alternatives, strictly
dominating Bonferroni. The module consumes per-step vectors of
component log e-values (the components stay caller-owned, since
they are typically heterogeneous) and keeps the rejection latch on
the supremum of the mixture&#39;s own log-wealth; latching per-component
suprema would combine peaks from different times and silently
inflate alpha, which is precisely the pitfall this module exists to
absorb. Adds the InvalidComponentCount configuration error.

</content>
</entry>
<entry>
<id>768d004f1949a588f2a8293e2c6ff42be15e7daf</id>
<published>2026-07-03T16:50:04Z</published>
<updated>2026-07-03T16:50:04Z</updated>
<title type="text">Merge branch &#39;impl/evalue-accessors&#39;</title>
<link rel="alternate" type="text/html" href="commit/768d004f1949a588f2a8293e2c6ff42be15e7daf.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 768d004f1949a588f2a8293e2c6ff42be15e7daf
parent 3b66da8d75aef92493c251a3b2e8039c86ad91fb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:20:04 -0230

Merge branch &#39;impl/evalue-accessors&#39;

Calibrated evidence accessors across all four test modules:

  * log_evalue: current log e-value, normalized so a fresh state
    sits at zero (log_wealth less log 2 for the hedged modules,
    log_wealth itself for the one-sided Bernoulli test). Uniform
    across modules, and the natural input for convex combinations
    of e-processes.
  * log_evalue_sup: the running supremum of the above.
  * p_value: the anytime-valid p-value min 1 (exp (negate
    log_evalue_sup)); decide remains equivalent to comparing it
    against the configured alpha.

Property tests pin the decide/p_value equivalence, monotonicity,
normalization at fresh states, and the relation to log_wealth.
Validated with and without -f+llvm.

</content>
</entry>
<entry>
<id>8b371fff9c9653db5ac26a595d5dad8ca25888c5</id>
<published>2026-07-03T16:50:04Z</published>
<updated>2026-07-03T16:50:04Z</updated>
<title type="text">test: coverage for the e-value accessors</title>
<link rel="alternate" type="text/html" href="commit/8b371fff9c9653db5ac26a595d5dad8ca25888c5.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 8b371fff9c9653db5ac26a595d5dad8ca25888c5
parent e93692ea1a08ac732c15618f7c5e8fa9383478ef
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:20:04 -0230

test: coverage for the e-value accessors

</content>
</entry>
<entry>
<id>e93692ea1a08ac732c15618f7c5e8fa9383478ef</id>
<published>2026-07-03T16:48:28Z</published>
<updated>2026-07-03T16:48:28Z</updated>
<title type="text">api: log_evalue, log_evalue_sup, and p_value accessors</title>
<link rel="alternate" type="text/html" href="commit/e93692ea1a08ac732c15618f7c5e8fa9383478ef.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit e93692ea1a08ac732c15618f7c5e8fa9383478ef
parent 3b66da8d75aef92493c251a3b2e8039c86ad91fb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:18:28 -0230

api: log_evalue, log_evalue_sup, and p_value accessors

Every test module now exposes its evidence in calibrated form: the
log e-value (log-wealth normalized so a fresh state sits at zero,
uniform across one-sided and hedged modules), its running supremum,
and the anytime-valid p-value derived from that supremum. decide
remains equivalent to comparing p_value against alpha.

</content>
</entry>
<entry>
<id>addadd93c816781d8f2ad32ca905efaa44d96198</id>
<published>2026-07-03T16:47:58Z</published>
<updated>2026-07-03T16:47:58Z</updated>
<title type="text">etc: add WSR (2024) reference paper</title>
<link rel="alternate" type="text/html" href="commit/addadd93c816781d8f2ad32ca905efaa44d96198.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit addadd93c816781d8f2ad32ca905efaa44d96198
parent 3b66da8d75aef92493c251a3b2e8039c86ad91fb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:17:58 -0230

etc: add WSR (2024) reference paper

</content>
</entry>
<entry>
<id>3b66da8d75aef92493c251a3b2e8039c86ad91fb</id>
<published>2026-07-03T16:43:05Z</published>
<updated>2026-07-03T16:43:05Z</updated>
<title type="text">docs: rationale for the Newton accumulator-seed deviation from WSR</title>
<link rel="alternate" type="text/html" href="commit/3b66da8d75aef92493c251a3b2e8039c86ad91fb.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 3b66da8d75aef92493c251a3b2e8039c86ad91fb
parent 93246df3eb4bd63c4e970fe43fdfe1b0b439d2fd
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Fri,  3 Jul 2026 14:13:05 -0230

docs: rationale for the Newton accumulator-seed deviation from WSR

</content>
</entry>
<entry>
<id>93246df3eb4bd63c4e970fe43fdfe1b0b439d2fd</id>
<published>2026-07-02T21:55:01Z</published>
<updated>2026-07-02T21:55:01Z</updated>
<title type="text">release: v0.3.0</title>
<link rel="alternate" type="text/html" href="commit/93246df3eb4bd63c4e970fe43fdfe1b0b439d2fd.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 93246df3eb4bd63c4e970fe43fdfe1b0b439d2fd
parent 709017518315c6d80df87492e7300e86abdb7a5e
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 19:25:01 -0230

release: v0.3.0

</content>
</entry>
<entry>
<id>709017518315c6d80df87492e7300e86abdb7a5e</id>
<published>2026-07-02T19:53:55Z</published>
<updated>2026-07-02T19:53:55Z</updated>
<title type="text">Merge branch &#39;impl/log-wealth-sup&#39;</title>
<link rel="alternate" type="text/html" href="commit/709017518315c6d80df87492e7300e86abdb7a5e.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 709017518315c6d80df87492e7300e86abdb7a5e
parent 05542c668916429b9dd6b0ddafe42c88da145ffb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 17:23:55 -0230

Merge branch &#39;impl/log-wealth-sup&#39;

Splits the log-wealth accessor, uniformly across Bounded, Paired,
Bernoulli, and Bernoulli.TwoSided: log_wealth now returns the
current log-wealth, and the latched supremum-so-far statistic
that &#39;decide&#39; monitors is exposed separately as log_wealth_sup.

Internal state fields are renamed to match (st_sup_log_sum,
st_sup_log_w); the stale Paired &#39;log_wealth s0&#39; Haddock example
(0.0 -&gt; log 2) is fixed; property tests now target log_wealth_sup
for monotonicity, cover both accessors for finiteness, and check
that log_wealth is bounded above by log_wealth_sup pointwise;
README and CHANGELOG updated.

Breaking: callers that relied on log_wealth returning the
supremum should switch to log_wealth_sup.

</content>
</entry>
<entry>
<id>280df8abb83452f56f340e5b10e358210dfe2904</id>
<published>2026-07-02T19:53:08Z</published>
<updated>2026-07-02T19:53:08Z</updated>
<title type="text">docs: README example and CHANGELOG for the log-wealth split</title>
<link rel="alternate" type="text/html" href="commit/280df8abb83452f56f340e5b10e358210dfe2904.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 280df8abb83452f56f340e5b10e358210dfe2904
parent e13bae8f4a7ef5c918f1a38071281b1653a736ff
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 17:23:08 -0230

docs: README example and CHANGELOG for the log-wealth split

The README GHCi session now shows both accessors at s10 (current
0.6187772969384595 vs supremum 0.916290731874155) and uses
log_wealth_sup for the rejection at s300. CHANGELOG gains an
unreleased entry noting the breaking rename.

</content>
</entry>
<entry>
<id>e13bae8f4a7ef5c918f1a38071281b1653a736ff</id>
<published>2026-07-02T19:52:58Z</published>
<updated>2026-07-02T19:52:58Z</updated>
<title type="text">api: log_wealth is now the current value; add log_wealth_sup</title>
<link rel="alternate" type="text/html" href="commit/e13bae8f4a7ef5c918f1a38071281b1653a736ff.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit e13bae8f4a7ef5c918f1a38071281b1653a736ff
parent 05542c668916429b9dd6b0ddafe42c88da145ffb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 17:22:58 -0230

api: log_wealth is now the current value; add log_wealth_sup

Downstream wants to observe the running log-wealth, not just the
latched supremum. Split the accessor, uniformly across Bounded,
Paired, Bernoulli, and Bernoulli.TwoSided:

- log_wealth now returns the current log-wealth: for the
  two-sided modules, log(K^+ + K^-) recomputed on demand via
  log_sum_exp; for the one-sided Bernoulli, the running field.

- log_wealth_sup returns the supremum-so-far statistic that
  &#39;decide&#39; monitors, i.e. what log_wealth returned previously.

Internal fields renamed to match (st_max_log_sum -&gt;
st_sup_log_sum, st_max_log_w -&gt; st_sup_log_w).

Also fixes the stale Paired &#39;log_wealth s0&#39; Haddock example,
which claimed 0.0 but has started at log 2 since the switch to
the convex-hedge combination.

Property tests updated: monotonicity now targets log_wealth_sup,
finiteness covers both accessors, and a new property checks that
log_wealth is bounded above by log_wealth_sup along the whole
stream (exact, since both derive from the same log_sum_exp
values).

</content>
</entry>
<entry>
<id>05542c668916429b9dd6b0ddafe42c88da145ffb</id>
<published>2026-07-02T19:20:35Z</published>
<updated>2026-07-02T19:20:35Z</updated>
<title type="text">release: v0.2.2</title>
<link rel="alternate" type="text/html" href="commit/05542c668916429b9dd6b0ddafe42c88da145ffb.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 05542c668916429b9dd6b0ddafe42c88da145ffb
parent d9ce56dd4e90a053e8c8e67b1fa96d272ab42724
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 16:50:35 -0230

release: v0.2.2

</content>
</entry>
<entry>
<id>d9ce56dd4e90a053e8c8e67b1fa96d272ab42724</id>
<published>2026-07-02T19:16:15Z</published>
<updated>2026-07-02T19:16:15Z</updated>
<title type="text">docs: refresh CHANGELOG and README for the unreleased work</title>
<link rel="alternate" type="text/html" href="commit/d9ce56dd4e90a053e8c8e67b1fa96d272ab42724.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit d9ce56dd4e90a053e8c8e67b1fa96d272ab42724
parent 1998344fea37369058a401bec35870a1347043de
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 16:46:15 -0230

docs: refresh CHANGELOG and README for the unreleased work

- CHANGELOG unreleased entry now mentions the perf work
  (log1p + log_sum_exp fast-path) alongside the new
  Bernoulli.TwoSided module, and notes that TwoSided is a
  newtype wrapper over Bounded.

- README performance section refreshed with current
  LLVM-enabled numbers, including a nod to the new Bernoulli
  and Bernoulli.TwoSided bench groups.

- README GHCi example refreshed: &#39;log_wealth s10&#39; had drifted
  because the two-sided combination switched from Bonferroni
  max to convex hedge and &#39;log_wealth&#39; now reports
  sup log(K^+ + K^-), starting at log 2.

</content>
</entry>
<entry>
<id>1998344fea37369058a401bec35870a1347043de</id>
<published>2026-07-02T19:11:25Z</published>
<updated>2026-07-02T19:11:25Z</updated>
<title type="text">Bernoulli.TwoSided: newtype-wrap Bounded</title>
<link rel="alternate" type="text/html" href="commit/1998344fea37369058a401bec35870a1347043de.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 1998344fea37369058a401bec35870a1347043de
parent c35e2ca28eb847b2b556c5bc017723d88dc426bc
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 16:41:25 -0230

Bernoulli.TwoSided: newtype-wrap Bounded

The two-sided Bernoulli rate test at p_0 is exactly the
two-sided bounded-mean test on [0, 1] with m = p_0: same
safe-bet ceilings (0.5/p_0 and 0.5/(1-p_0)), same convex-hedge
construction, same log(2/alpha) threshold, same latched-max
statistic. The prior implementation had all this machinery
duplicated verbatim from Bounded, including the log_sum_exp
fast-path skip that would otherwise need to be maintained in
lockstep across two modules.

Refactor along the same lines as Numeric.Eproc.Paired: newtype
Config = Config Bounded.Config, newtype State = State
Bounded.State, and each operation delegates. update maps the
Bool observation to its numeric encoding and forwards. &#39;config&#39;
still emits InvalidBaselineRate for p_0 out of (0, 1) — that&#39;s
the meaningful error for a Bernoulli-facing caller, not the
Bounded-flavoured InvalidNullMean.

122 lines deleted, 31 added. INLINE pragmas make the wrapping
transparent; the criterion fold numbers are unchanged or
marginally better (14.84 us vs 15.65 us for the newton case).
All 59 tests still pass.

</content>
</entry>
<entry>
<id>c35e2ca28eb847b2b556c5bc017723d88dc426bc</id>
<published>2026-07-02T19:05:05Z</published>
<updated>2026-07-02T19:05:05Z</updated>
<title type="text">perf: log1p for the per-step wealth factor, fast-path log_sum_exp</title>
<link rel="alternate" type="text/html" href="commit/c35e2ca28eb847b2b556c5bc017723d88dc426bc.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit c35e2ca28eb847b2b556c5bc017723d88dc426bc
parent 4eddb4d8cf371b4fb2196183b3fca241021544bd
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 16:35:05 -0230

perf: log1p for the per-step wealth factor, fast-path log_sum_exp

Two small changes to the per-observation work in the update
functions:

1. Replace &#39;log (1 + lambda * z)&#39; with &#39;log1p (lambda * z)&#39; in
   all four update paths. Improves accuracy for small &#39;lambda *
   z&#39; (the standard log1p rationale) and avoids the &#39;1 + ...&#39;
   add.

2. In the two-sided combinations (Bounded, BernTS), skip the
   &#39;log_sum_exp&#39; call when the cheap upper bound
   &#39;max(logw_p, logw_n) + log 2&#39; is already at or below the
   running max-log-sum. Under H_0 the wealth process is a
   supermartingale that stays near its early peak, so this
   fast-path fires on the vast majority of steps once the peak
   is set.

Impact from criterion on a 1000-sample cycle at p = p_0:

  * Bernoulli.TwoSided fold newton: 25.62 us -&gt; 15.65 us (-39%)
  * Bernoulli.TwoSided fold fixed:  16.21 us -&gt;  8.27 us (-49%)
  * Bounded fold adaptive:          14.09 us -&gt; 12.88 us  (-9%)
  * Bounded fold newton:            14.83 us -&gt; 14.57 us  (-2%)

The BernTS gap closes because its H_0 workload triggers the
fast-path aggressively. Bounded is more modest because the
input stream (&#39;cycle [0.3, 0.7]&#39;) keeps both directional
wealths active at similar magnitudes, so the log_sum_exp fires
more often.

Also moves &#39;log 2&#39; to a shared &#39;log2_dbl&#39; constant in Common
(used both as the initial two-sided max-log-sum and as the
fast-path slack).

I checked GHC Core for the Newton fold specialisation
question: the current bench&#39;s shared &#39;run_b&#39; helper causes GHC
to emit one worker taking &#39;Bettor&#39; as an argument, with a
per-iteration case dispatch. Rewriting the bench to inline the
fold at each arm produces the specialised code, but the
measurable difference is in the noise (&lt;1 us on a 15 us
fold). Left the library shape alone.

All 59 tests still pass.

</content>
</entry>
<entry>
<id>4eddb4d8cf371b4fb2196183b3fca241021544bd</id>
<published>2026-07-02T18:53:35Z</published>
<updated>2026-07-02T18:53:35Z</updated>
<title type="text">bench: add TwoSided groups</title>
<link rel="alternate" type="text/html" href="commit/4eddb4d8cf371b4fb2196183b3fca241021544bd.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 4eddb4d8cf371b4fb2196183b3fca241021544bd
parent 0db7982a791fbcb5d61bb0d8f208a575c2780871
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 16:23:35 -0230

bench: add TwoSided groups

Adds &#39;Bernoulli.TwoSided.update (one step)&#39; and
&#39;Bernoulli.TwoSided.update (1000-sample fold)&#39; to both the
criterion and weigh benchmark suites (fixed / adaptive / newton
each), plus the NFData orphan for &#39;BernTS.State&#39;. Cost is
roughly 2x the one-sided variant, matching the shape of the
work (two per-direction bettors + log-sum-exp).

</content>
</entry>
<entry>
<id>0db7982a791fbcb5d61bb0d8f208a575c2780871</id>
<published>2026-07-02T18:51:03Z</published>
<updated>2026-07-02T18:51:03Z</updated>
<title type="text">test: bring TwoSided coverage up to parity</title>
<link rel="alternate" type="text/html" href="commit/0db7982a791fbcb5d61bb0d8f208a575c2780871.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 0db7982a791fbcb5d61bb0d8f208a575c2780871
parent 3d8e7f8c1a33691e3d9b46e483a280f496a96817
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 16:21:03 -0230

test: bring TwoSided coverage up to parity

Adds the four QuickCheck safety properties the other test
modules already have (log_wealth finiteness, monotonicity,
Fixed-bettor safety under arbitrary lambdas, latched-rejection
invariant) for &#39;Numeric.Eproc.Bernoulli.TwoSided&#39;, plus an
Adaptive detection HUnit case so both non-baseline bettors are
exercised on the new module. 54 -&gt; 59.

</content>
</entry>
<entry>
<id>3d8e7f8c1a33691e3d9b46e483a280f496a96817</id>
<published>2026-07-02T18:48:01Z</published>
<updated>2026-07-02T18:48:01Z</updated>
<title type="text">Bernoulli: add two-sided variant via convex hedge</title>
<link rel="alternate" type="text/html" href="commit/3d8e7f8c1a33691e3d9b46e483a280f496a96817.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 3d8e7f8c1a33691e3d9b46e483a280f496a96817
parent ffcd36e3be7a982e7e551e1173a2a69530280292
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 16:18:01 -0230

Bernoulli: add two-sided variant via convex hedge

Adds &#39;Numeric.Eproc.Bernoulli.TwoSided&#39;, a sibling module to
&#39;Numeric.Eproc.Bernoulli&#39; testing H_0: p = p_0 against p != p_0.
The primary use case is the sign test at p_0 = 1/2, and more
generally any comparison of Bernoulli rates where the shift
direction isn&#39;t known in advance (which the existing one-sided
variant can&#39;t handle).

Construction is the convex hedge of Waudby-Smith &amp; Ramdas
(2024) §4, mirroring what &#39;Bounded&#39; does: two per-direction
Bernoulli capital processes K^+ (betting against p &gt; p_0) and
K^- (betting against p &lt; p_0) are combined into the hedged
e-process (K^+ + K^-) / 2 with E[K_0] = 1, and the test rejects
when the supremum of log(K^+ + K^-) has ever crossed
log(2/alpha). State carries per-direction log-wealths plus a
single max-log-sum field, updated each step via log-sum-exp
(moved from &#39;Bounded&#39; into &#39;Common&#39; so both consumers can use
it). Rejection is latched.

The sibling module keeps the same &#39;config&#39; / &#39;initial&#39; /
&#39;update&#39; / &#39;decide&#39; / &#39;log_wealth&#39; / &#39;samples&#39; shape as the
one-sided version, so downstream code just qualifies both and
picks:

  import qualified Numeric.Eproc.Bernoulli as Bern
  import qualified Numeric.Eproc.Bernoulli.TwoSided as BernTS

Seven new test cases cover upward/downward shift detection,
null calibration, latched rejection, and config validation.

</content>
</entry>
<entry>
<id>ffcd36e3be7a982e7e551e1173a2a69530280292</id>
<published>2026-07-02T17:03:50Z</published>
<updated>2026-07-02T17:03:50Z</updated>
<title type="text">release: v0.2.1</title>
<link rel="alternate" type="text/html" href="commit/ffcd36e3be7a982e7e551e1173a2a69530280292.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit ffcd36e3be7a982e7e551e1173a2a69530280292
parent d2a8f8c31f770670a0c63ed51cc17e6fdd434b75
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  2 Jul 2026 14:33:50 -0230

release: v0.2.1

</content>
</entry>
<entry>
<id>d2a8f8c31f770670a0c63ed51cc17e6fdd434b75</id>
<published>2026-06-29T23:29:53Z</published>
<updated>2026-06-29T23:29:53Z</updated>
<title type="text">Bounded: switch two-sided combination to convex hedge</title>
<link rel="alternate" type="text/html" href="commit/d2a8f8c31f770670a0c63ed51cc17e6fdd434b75.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit d2a8f8c31f770670a0c63ed51cc17e6fdd434b75
parent 0356542ed038b607762dd9cfb414e3d96851eb65
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Mon, 29 Jun 2026 20:59:53 -0230

Bounded: switch two-sided combination to convex hedge

Replace the Bonferroni union over the two one-sided e-processes
(reject when max(K^+, K^-) &gt;= 2/alpha) with the convex-hedge
construction from Waudby-Smith &amp; Ramdas (2024) §4 (reject when
K^+ + K^- &gt;= 2/alpha, monitored via the running supremum of the
log-sum).

Both are valid two-sided combinations under H_0, but the convex-
hedge rejection region strictly contains Bonferroni&#39;s: where
Bonferroni rejects (max &gt;= 2/alpha), so does the hedge (since
K^+ + K^- &gt;= max(K^+, K^-) &gt;= 2/alpha). Where one side is moderately
large and the other contributes meaningfully, only the hedge fires.
Same alpha guarantee via Ville on the averaged e-process
K = (K^+ + K^-)/2 which has E[K_0] = 1.

For one-sided alternatives — the common case in practice — the gap
is small (the losing-direction bettor&#39;s wealth stays near 1). For
genuinely two-sided alternatives it can be substantial.

State is simplified: dropped the per-direction max fields, added a
single max-log-sum field tracked via log-sum-exp. The decide
threshold is unchanged at log(2/alpha). log_wealth now reports the
max-log-sum directly (starts at log 2 rather than 0 since
K^+_0 + K^-_0 = 2); documented in the haddock.

Behaviour change is monotone: any stream that rejected under the
old code also rejects under the new code, possibly with fewer
samples. Bernoulli (one-sided) is unaffected. Paired wraps Bounded
so inherits automatically.

</content>
</entry>
<entry>
<id>0356542ed038b607762dd9cfb414e3d96851eb65</id>
<published>2026-06-29T00:01:18Z</published>
<updated>2026-06-29T00:01:18Z</updated>
<title type="text">release: v0.2.0</title>
<link rel="alternate" type="text/html" href="commit/0356542ed038b607762dd9cfb414e3d96851eb65.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 0356542ed038b607762dd9cfb414e3d96851eb65
parent 67999374211a038876017be1b90c74742ebc555e
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 28 Jun 2026 21:31:18 -0230

release: v0.2.0

</content>
</entry>
<entry>
<id>67999374211a038876017be1b90c74742ebc555e</id>
<published>2026-06-28T23:47:23Z</published>
<updated>2026-06-28T23:47:23Z</updated>
<title type="text">reject non-finite parameters in config constructors</title>
<link rel="alternate" type="text/html" href="commit/67999374211a038876017be1b90c74742ebc555e.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 67999374211a038876017be1b90c74742ebc555e
parent b0a7a7cf7abdbae101d2efb87bcaf13a132b7501
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 28 Jun 2026 21:17:23 -0230

reject non-finite parameters in config constructors

NaN and +/-Infinity were slipping past the existing range checks
(NaN comparisons are False, and -Inf &lt; +Inf passes &#39;lo &lt; hi&#39;),
leaving the door open to e.g. infinite bounds that silently
zeroed the safe-bet ceilings. Tighten each smart constructor to
require finite m/lo/hi/alpha (Bounded), lo/hi/alpha (Paired),
and p0/alpha (Bernoulli) via a shared &#39;finite&#39; helper in Common.

</content>
</entry>
<entry>
<id>b0a7a7cf7abdbae101d2efb87bcaf13a132b7501</id>
<published>2026-06-28T23:27:37Z</published>
<updated>2026-06-28T23:44:17Z</updated>
<title type="text">tighten correctness and validation across the API</title>
<link rel="alternate" type="text/html" href="commit/b0a7a7cf7abdbae101d2efb87bcaf13a132b7501.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit b0a7a7cf7abdbae101d2efb87bcaf13a132b7501
parent 8c7d3c072dba28c933e84c15ddff14a8ded14509
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 28 Jun 2026 20:57:37 -0230

tighten correctness and validation across the API

Acts on a code review of v0.1.0. The headline change is that
&#39;decide&#39; now reflects &quot;ever crossed the threshold,&quot; not &quot;currently
above the threshold&quot; -- this is the supremum-style event Ville&#39;s
inequality actually bounds. State carries a running max log-wealth
per direction (Bounded) or globally (Bernoulli), and &#39;log_wealth&#39;
returns the supremum so far.

Other correctness fixes:

  * &#39;Fixed&#39; bettor is now clipped to &#39;[0, lambda_max]&#39; like the
    other bettors. The Bounded module no longer needs the &#39;tiny&#39;
    wealth-factor floor; that was hiding a violation rather than
    fixing one.

  * The Newton bettor uses the WSR (2024) Algorithm 2 learning
    rate &#39;2 / (2 - log 3)&#39;, matching the paper.

API hardening:

  * Config constructors return &#39;Either ConfigError Config&#39; and
    reject invalid statistical parameters (alpha out of (0,1),
    lo &gt;= hi, m outside (lo,hi), p0 outside (0,1)).

  * &#39;Numeric.Eproc.Bernoulli.config&#39; argument order changed from
    (alpha, p0, bettor) to (p0, alpha, bettor) so alpha is
    second-to-last across all three test modules.

Internal cleanup:

  * Bettor logic (BetState, init_bet, bet_lambda, step_bet) lives
    in &#39;Numeric.Eproc.Common&#39;; Bounded and Bernoulli are thin
    consumers. Bench numbers unchanged.

Docs:

  * Module headers reframe H_0 in conditional-expectation form,
    which is what anytime validity actually requires.

  * &#39;update&#39; docstrings state the support precondition explicitly.

Tests: 16 -&gt; 41. Added latched-rejection cases, config-validation
group, and QuickCheck properties for log-wealth finiteness,
monotonicity, Fixed-bettor safety under arbitrary lambdas, and
the latched-rejection invariant. Tightened null-FPR slack
0.10 -&gt; 0.08. Added a Bernoulli Fixed-bettor smoke test.

Benches: added Bernoulli update/fold groups.

</content>
</entry>
<entry>
<id>8c7d3c072dba28c933e84c15ddff14a8ded14509</id>
<published>2026-06-04T21:06:33Z</published>
<updated>2026-06-04T21:06:33Z</updated>
<title type="text">release: v0.1.0</title>
<link rel="alternate" type="text/html" href="commit/8c7d3c072dba28c933e84c15ddff14a8ded14509.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 8c7d3c072dba28c933e84c15ddff14a8ded14509
parent 2a3196374cc7b58d3cd7ad1fd774a5cd914469aa
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 18:36:33 -0230

release: v0.1.0

</content>
</entry>
<entry>
<id>2a3196374cc7b58d3cd7ad1fd774a5cd914469aa</id>
<published>2026-06-04T19:31:51Z</published>
<updated>2026-06-04T19:31:51Z</updated>
<title type="text">extract Bettor and Verdict into Numeric.Eproc.Common</title>
<link rel="alternate" type="text/html" href="commit/2a3196374cc7b58d3cd7ad1fd774a5cd914469aa.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 2a3196374cc7b58d3cd7ad1fd774a5cd914469aa
parent dea08bd4741aa02cc1c0039090dca018c5aeedbd
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 17:01:51 -0230

extract Bettor and Verdict into Numeric.Eproc.Common

Both types are now defined once in Numeric.Eproc.Common and
re-exported from each test module (Bounded, Paired, Bernoulli).
Single source of truth for the shared vocabulary; callers can
still import any test module and get the full surface without a
second import.

</content>
</entry>
<entry>
<id>dea08bd4741aa02cc1c0039090dca018c5aeedbd</id>
<published>2026-06-04T19:29:58Z</published>
<updated>2026-06-04T19:29:58Z</updated>
<title type="text">add Numeric.Eproc.Bernoulli; fix per-trial test seeding</title>
<link rel="alternate" type="text/html" href="commit/dea08bd4741aa02cc1c0039090dca018c5aeedbd.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit dea08bd4741aa02cc1c0039090dca018c5aeedbd
parent 0a4b12ab29ad1259b97f3db16f47539af56449eb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 16:59:58 -0230

add Numeric.Eproc.Bernoulli; fix per-trial test seeding

Numeric.Eproc.Bernoulli is a one-sided Bernoulli rate test
(H_0: E[x] &lt;= p_0 vs H_1: E[x] &gt; p_0). Single wealth process, so
no Bonferroni adjustment; threshold is log(1 / alpha). Useful for
fingerprint-style divergence detection where the per-observation
quantity is a Bool, not a real.

Bettors mirror Bounded: Fixed, Adaptive (aGRAPA), Newton (ONS).

While adding tests for the new module, found that the existing
gen_seq harness produced trial seeds one PRNG step apart, so
consecutive trials shared all but one observation. Fine under a
symmetric H_0 (rare streaks cancel) but catastrophic under a
skewed one (rare streaks dominate every overlapping trial,
producing FPR ~ 0.5). Replaced with independent seeds via a
splitmix-style finalizer.

</content>
</entry>
<entry>
<id>0a4b12ab29ad1259b97f3db16f47539af56449eb</id>
<published>2026-06-04T18:32:36Z</published>
<updated>2026-06-04T18:32:36Z</updated>
<title type="text">flake: add clang</title>
<link rel="alternate" type="text/html" href="commit/0a4b12ab29ad1259b97f3db16f47539af56449eb.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 0a4b12ab29ad1259b97f3db16f47539af56449eb
parent 18bc2ced8ae223a05147151379439ce6818bf625
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 16:02:36 -0230

flake: add clang

</content>
</entry>
<entry>
<id>18bc2ced8ae223a05147151379439ce6818bf625</id>
<published>2026-06-04T17:54:49Z</published>
<updated>2026-06-04T17:54:49Z</updated>
<title type="text">meta: description tweaks</title>
<link rel="alternate" type="text/html" href="commit/18bc2ced8ae223a05147151379439ce6818bf625.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 18bc2ced8ae223a05147151379439ce6818bf625
parent e3b0b0b1a9e3c7f62bfbec57f24a603275cfcaa7
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 15:24:49 -0230

meta: description tweaks

</content>
</entry>
<entry>
<id>e3b0b0b1a9e3c7f62bfbec57f24a603275cfcaa7</id>
<published>2026-06-04T17:52:29Z</published>
<updated>2026-06-04T17:52:29Z</updated>
<title type="text">add module-level examples to Bounded and Paired</title>
<link rel="alternate" type="text/html" href="commit/e3b0b0b1a9e3c7f62bfbec57f24a603275cfcaa7.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit e3b0b0b1a9e3c7f62bfbec57f24a603275cfcaa7
parent 01225b5275cdae0215412fc0704c88bfc2128dd6
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 15:22:29 -0230

add module-level examples to Bounded and Paired

</content>
</entry>
<entry>
<id>01225b5275cdae0215412fc0704c88bfc2128dd6</id>
<published>2026-06-04T17:26:18Z</published>
<updated>2026-06-04T17:26:18Z</updated>
<title type="text">rename Agrapa to Adaptive, Ons to Newton</title>
<link rel="alternate" type="text/html" href="commit/01225b5275cdae0215412fc0704c88bfc2128dd6.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 01225b5275cdae0215412fc0704c88bfc2128dd6
parent 55bab648d1e9a7b46ef8d51ff2b506dbb08dcc0c
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 14:56:18 -0230

rename Agrapa to Adaptive, Ons to Newton

retains the aGRAPA acronym expansion in the Adaptive haddock.

</content>
</entry>
<entry>
<id>55bab648d1e9a7b46ef8d51ff2b506dbb08dcc0c</id>
<published>2026-06-04T16:53:57Z</published>
<updated>2026-06-04T16:53:57Z</updated>
<title type="text">lib: line lengths</title>
<link rel="alternate" type="text/html" href="commit/55bab648d1e9a7b46ef8d51ff2b506dbb08dcc0c.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 55bab648d1e9a7b46ef8d51ff2b506dbb08dcc0c
parent 6c09da6ddd72d3d29f7045d040dfb8ce15b6a075
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Thu,  4 Jun 2026 14:23:57 -0230

lib: line lengths

</content>
</entry>
<entry>
<id>6c09da6ddd72d3d29f7045d040dfb8ce15b6a075</id>
<published>2026-06-03T18:15:13Z</published>
<updated>2026-06-03T18:15:13Z</updated>
<title type="text">meta: refine text</title>
<link rel="alternate" type="text/html" href="commit/6c09da6ddd72d3d29f7045d040dfb8ce15b6a075.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 6c09da6ddd72d3d29f7045d040dfb8ce15b6a075
parent 347be5310855537b93d034bbd5338ce6b5afeca9
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Wed,  3 Jun 2026 15:45:13 -0230

meta: refine text

</content>
</entry>
<entry>
<id>347be5310855537b93d034bbd5338ce6b5afeca9</id>
<published>2026-06-03T14:10:29Z</published>
<updated>2026-06-03T14:10:29Z</updated>
<title type="text">fold Bettor into Bounded; drop Numeric.Eproc.Bettor</title>
<link rel="alternate" type="text/html" href="commit/347be5310855537b93d034bbd5338ce6b5afeca9.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 347be5310855537b93d034bbd5338ce6b5afeca9
parent dcd9754da35f9ded3faeef878fbf234497ed11c2
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Wed,  3 Jun 2026 11:40:29 -0230

fold Bettor into Bounded; drop Numeric.Eproc.Bettor

The Bettor module was thin -- just a three-constructor enum and its
documentation -- and the only module that actually case-analyzes on
Bettor is Bounded (Paired delegates to Bounded internally). Moving
the type to where it is used eliminates the thin module without
duplicating across the two test families.

  * &#39;data Bettor&#39; now lives in Numeric.Eproc.Bounded and is exported
    alongside Config / State / Verdict.
  * Numeric.Eproc.Paired re-exports Bettor(..) the same way it
    re-exports Verdict(..); no API change at the Paired call site.
  * Numeric.Eproc.Bettor deleted; removed from cabal exposed-modules.
  * Tests, benches, and the README drop the &#39;B&#39; import; bettor
    constructors are referenced as Bounded.Ons / Bounded.Agrapa /
    Bounded.Fixed throughout (and as the bare constructors inside the
    library&#39;s own haddock examples).

Tests pass.

</content>
</entry>
<entry>
<id>dcd9754da35f9ded3faeef878fbf234497ed11c2</id>
<published>2026-06-03T13:58:29Z</published>
<updated>2026-06-03T13:58:29Z</updated>
<title type="text">rename Mean to Bounded</title>
<link rel="alternate" type="text/html" href="commit/dcd9754da35f9ded3faeef878fbf234497ed11c2.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit dcd9754da35f9ded3faeef878fbf234497ed11c2
parent 8b73a8dc0a86c40d9e7845ce275580f9e87d083a
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Wed,  3 Jun 2026 11:28:29 -0230

rename Mean to Bounded

Module Numeric.Eproc.Mean -- which provides the two-sided bounded-mean
test, not just mean calculation -- becomes Numeric.Eproc.Bounded.
&#39;Bounded&#39; parallels &#39;Paired&#39; as a noun describing the test family.

Import alias changes from &#39;M&#39; to the spelled-out &#39;Bounded&#39; (the
natural single-letter &#39;B&#39; is already in use by Bettor); call sites in
Paired, tests, bench, and the README updated.

Internal helpers and labels updated to match: local test helper
&#39;run_mean_bernoulli&#39; -&gt; &#39;run_bounded_bernoulli&#39;; benchmark bgroup
labels &#39;Mean.update ...&#39; / &#39;Mean.decide&#39; -&gt; &#39;Bounded.update ...&#39; /
&#39;Bounded.decide&#39;; README&#39;s captured benchmark output relabeled.

No semantic / API changes; tests pass.

</content>
</entry>
<entry>
<id>8b73a8dc0a86c40d9e7845ce275580f9e87d083a</id>
<published>2026-06-03T12:59:16Z</published>
<updated>2026-06-03T12:59:16Z</updated>
<title type="text">rename Test to Paired</title>
<link rel="alternate" type="text/html" href="commit/8b73a8dc0a86c40d9e7845ce275580f9e87d083a.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 8b73a8dc0a86c40d9e7845ce275580f9e87d083a
parent c8c70f93df09bbe173951220453ef661036d33e3
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Wed,  3 Jun 2026 10:29:16 -0230

rename Test to Paired

&#39;Test&#39; was overly generic given that Mean is itself a test (the
two-sided bounded-mean test). &#39;Paired&#39; more precisely names what the
module provides: the paired two-sample mean-equality test.

Module Numeric.Eproc.Test becomes Numeric.Eproc.Paired; import alias
&#39;T&#39; becomes &#39;P&#39;; benchmark bgroup labels (&#39;Test.update ...&#39;) updated
to &#39;Paired.update ...&#39;.

No semantic / API changes; tests pass.

</content>
</entry>
<entry>
<id>c8c70f93df09bbe173951220453ef661036d33e3</id>
<published>2026-06-03T12:52:57Z</published>
<updated>2026-06-03T12:52:57Z</updated>
<title type="text">rename TwoSample to Test</title>
<link rel="alternate" type="text/html" href="commit/c8c70f93df09bbe173951220453ef661036d33e3.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit c8c70f93df09bbe173951220453ef661036d33e3
parent f84c84ac03843da025ad73533629af10e6867691
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Wed,  3 Jun 2026 10:22:57 -0230

rename TwoSample to Test

Module Numeric.Eproc.TwoSample becomes Numeric.Eproc.Test. The &#39;TS&#39;
import alias becomes &#39;T&#39; to match the single-letter M / B convention.
Local test helpers (&#39;run_ts_paired&#39;, &#39;ts_avg_rate&#39;) renamed to
&#39;run_paired&#39; and &#39;paired_avg_rate&#39; for the same reason. Benchmark
bgroup labels (&#39;TwoSample.update ...&#39;) updated to &#39;Test.update ...&#39;.

No semantic / API changes; tests pass.

</content>
</entry>
<entry>
<id>f84c84ac03843da025ad73533629af10e6867691</id>
<published>2026-06-03T12:50:37Z</published>
<updated>2026-06-03T12:50:37Z</updated>
<title type="text">rename Statistics.EProcess.* to Numeric.Eproc.*</title>
<link rel="alternate" type="text/html" href="commit/f84c84ac03843da025ad73533629af10e6867691.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit f84c84ac03843da025ad73533629af10e6867691
parent e168b262bac7bd5ae011314dab46c37ffee12055
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Wed,  3 Jun 2026 10:20:37 -0230

rename Statistics.EProcess.* to Numeric.Eproc.*

Module path rename only. Each library module moves to its new path
(git tracks the renames), module declarations and internal cross-refs
updated, Haddock cross-links (&#39;Statistics.EProcess.Mean.config&#39; etc.)
follow. ppad-eproc.cabal exposed-modules, test/Main.hs imports,
bench/Main.hs and bench/Weight.hs imports, and the README&#39;s GHCi
example all updated in lockstep.

No semantic / API changes; all 11 tests still pass.

</content>
</entry>
<entry>
<id>e168b262bac7bd5ae011314dab46c37ffee12055</id>
<published>2026-06-03T00:33:57Z</published>
<updated>2026-06-03T00:33:57Z</updated>
<title type="text">docs: enrich haddocks with e-process framework context</title>
<link rel="alternate" type="text/html" href="commit/e168b262bac7bd5ae011314dab46c37ffee12055.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit e168b262bac7bd5ae011314dab46c37ffee12055
parent f60ba344661745c8829cf46c4539694086c473c2
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Tue,  2 Jun 2026 22:03:57 -0230

docs: enrich haddocks with e-process framework context

Expand the module-, type-, and function-level haddocks to give
readers enough domain context to make sense of the API without
needing the WSR paper in hand.

  * Bettor: module header now describes the wealth-process
    construction and Ville&#39;s-inequality justification; per-constructor
    docs explain the strategy (Fixed = baseline, Agrapa = Kelly
    plug-in with mu/sigma^2, Ons = online Newton on per-step
    log-wealth loss) and the role of lambda_max.

  * Mean: module header explains the two-direction (positive /
    negative) Bonferroni decomposition; Config and State get per-field
    haddocks (cfg_lam_max_pos / cfg_lam_max_neg / st_log_w_pos / ...
    so the reader knows what each field is for); &#39;config&#39; derives the
    safe-bet ceilings from sample bounds explicitly; &#39;update&#39;
    documents the wealth-update equation; &#39;decide&#39; explains the
    anytime-valid stopping guarantee; &#39;log_wealth&#39; framed as the
    test statistic.

  * TwoSample: module header explains the reduction (paired diffs
    feed the bounded-mean test); per-function docs refer back to the
    underlying mean test.

No code or API changes; tests pass, haddock builds 14/14 in each
module.

</content>
</entry>
<entry>
<id>f60ba344661745c8829cf46c4539694086c473c2</id>
<published>2026-06-03T00:09:33Z</published>
<updated>2026-06-03T00:09:33Z</updated>
<title type="text">style: align library with ppad conventions</title>
<link rel="alternate" type="text/html" href="commit/f60ba344661745c8829cf46c4539694086c473c2.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit f60ba344661745c8829cf46c4539694086c473c2
parent a230e6558be4050da6ecb1a799d9993a9c957152
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Tue,  2 Jun 2026 21:39:33 -0230

style: align library with ppad conventions

Restyle the library to match the patterns used by ppad-fixed,
ppad-script, ppad-bip32, etc.

  * snake_case for top-level functions (&#39;log_wealth&#39;) and record fields
    (&#39;cfg_bettor&#39;, &#39;st_n&#39;, &#39;cfg_lam_max_pos&#39;, &#39;st_log_w_pos&#39;, ...).
  * Aligned record-field syntax matching bip32&#39;s HDKey.
  * Section dividers (&#39;-- types --------&#39;, &#39;-- streaming --------&#39;, ...)
    organising each module.
  * &#39;&gt;&gt;&gt;&#39; Haddock examples on every public binding; expanded haddocks
    on the Bettor constructors describing each strategy and where
    lambda_max comes from.

Also drop the Statistics.EProcess umbrella module: its renamed
camelCase exports (&#39;meanConfig&#39;, &#39;updateMean&#39;, ...) existed only to
disambiguate overlapping names from Mean/TwoSample/Bettor and fought
the snake_case convention. Users now import the sub-modules directly,
mirroring ppad-fixed&#39;s layout:

  import qualified Statistics.EProcess.Bettor as B
  import qualified Statistics.EProcess.Mean as M

Tests and benches updated to the new imports and snake_case
conventions; README&#39;s GHCi example rewritten accordingly.

All 11 tests still pass; bench allocation and timing unchanged.

</content>
</entry>
<entry>
<id>a230e6558be4050da6ecb1a799d9993a9c957152</id>
<published>2026-06-02T23:35:41Z</published>
<updated>2026-06-02T23:35:41Z</updated>
<title type="text">perf: close Bettor sum, fix per-step Rational conversion</title>
<link rel="alternate" type="text/html" href="commit/a230e6558be4050da6ecb1a799d9993a9c957152.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit a230e6558be4050da6ecb1a799d9993a9c957152
parent f1318f8b4511eae8fe5cbe9af2ab6b988c091dd2
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Tue,  2 Jun 2026 21:05:41 -0230

perf: close Bettor sum, fix per-step Rational conversion

Refactor Bettor from a record of strategy functions (init/step/bet)
parameterised over an opaque state type to a closed sum type with
three constructors (Fixed Double, Agrapa, Ons). Mean.update now
case-dispatches on the bettor; with INLINE, GHC fully specialises
each strategy at the call site. Per-direction bettor state lives in a
separate closed BetState sum carried by Mean.State.

Mean.Config and Mean.State lose their phantom &#39;s&#39; parameter; the
re-exports in Statistics.EProcess drop AGRAPA/ONS/fixed/agrapa/ons in
favour of Bettor(..). Breaking change to the (brand-new) public API.

While here: replace &#39;tiny = 1.0e-300 :: Double&#39; with the MagicHash
form &#39;D# 1.0e-300##&#39;. The fractional literal compiles as
&#39;fromRational (1.0e-300 :: Rational)&#39; and GHC was not folding the
conversion, leaving a $wrationalToDouble call in every update step.
This was the dominant cost once the closed-sum refactor unlocked
inlining.

Combined effect (LLVM, 1000-sample fold):

  Mean fold/fixed  : 128.9 us -&gt;  4.84 us  (27x)
  Mean fold/agrapa : 142.4 us -&gt; 15.67 us  ( 9x)
  Mean fold/ons    : 133.2 us -&gt; 14.43 us  ( 9x)
  TS fold/fixed    : 129.2 us -&gt;  5.33 us  (24x)
  TS fold/agrapa   : 155.7 us -&gt;  9.92 us  (16x)
  TS fold/ons      : 136.9 us -&gt; 16.31 us  ( 8x)

Allocation per 1000-step fold drops from ~850 KB to &lt;33 KB; the
fixed-bettor inner loop is fully fused (48 B total).

All 11 tests pass.

</content>
</entry>
<entry>
<id>f1318f8b4511eae8fe5cbe9af2ab6b988c091dd2</id>
<published>2026-06-02T23:17:24Z</published>
<updated>2026-06-02T23:17:24Z</updated>
<title type="text">bench: add suite</title>
<link rel="alternate" type="text/html" href="commit/f1318f8b4511eae8fe5cbe9af2ab6b988c091dd2.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit f1318f8b4511eae8fe5cbe9af2ab6b988c091dd2
parent f47c6310e1bc44f8a0213beeac799ec75cc4d2b6
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Tue,  2 Jun 2026 20:47:24 -0230

bench: add suite

</content>
</entry>
<entry>
<id>f47c6310e1bc44f8a0213beeac799ec75cc4d2b6</id>
<published>2026-05-31T23:45:11Z</published>
<updated>2026-05-31T23:45:11Z</updated>
<title type="text">Initial release.</title>
<link rel="alternate" type="text/html" href="commit/f47c6310e1bc44f8a0213beeac799ec75cc4d2b6.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit f47c6310e1bc44f8a0213beeac799ec75cc4d2b6
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 31 May 2026 21:15:11 -0230

Initial release.

Anytime-valid sequential testing via e-processes: bounded-mean and
paired two-sample tests built on the WSR betting framework, with
fixed-lambda, aGRAPA, and ONS bettor strategies.

</content>
</entry>
</feed>
