peeksafe 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/LICENSE +190 -0
  3. package/NOTICE +78 -0
  4. package/README.md +492 -2
  5. package/RESEARCH-NOTES.md +274 -0
  6. package/dist/baseline.d.ts +45 -0
  7. package/dist/baseline.d.ts.map +1 -0
  8. package/dist/baseline.js +49 -0
  9. package/dist/baseline.js.map +1 -0
  10. package/dist/check.d.ts +64 -0
  11. package/dist/check.d.ts.map +1 -0
  12. package/dist/check.js +172 -0
  13. package/dist/check.js.map +1 -0
  14. package/dist/cluster.d.ts +328 -0
  15. package/dist/cluster.d.ts.map +1 -0
  16. package/dist/cluster.js +598 -0
  17. package/dist/cluster.js.map +1 -0
  18. package/dist/errors.d.ts +87 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +143 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/evidence.d.ts +15 -0
  23. package/dist/evidence.d.ts.map +1 -0
  24. package/dist/evidence.js +30 -0
  25. package/dist/evidence.js.map +1 -0
  26. package/dist/frontier.d.ts +269 -0
  27. package/dist/frontier.d.ts.map +1 -0
  28. package/dist/frontier.js +460 -0
  29. package/dist/frontier.js.map +1 -0
  30. package/dist/gate.d.ts +173 -0
  31. package/dist/gate.d.ts.map +1 -0
  32. package/dist/gate.js +196 -0
  33. package/dist/gate.js.map +1 -0
  34. package/dist/index.d.ts +60 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +79 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/plan.d.ts +248 -0
  39. package/dist/plan.d.ts.map +1 -0
  40. package/dist/plan.js +482 -0
  41. package/dist/plan.js.map +1 -0
  42. package/dist/rand.d.ts +17 -0
  43. package/dist/rand.d.ts.map +1 -0
  44. package/dist/rand.js +92 -0
  45. package/dist/rand.js.map +1 -0
  46. package/dist/stats.d.ts +397 -0
  47. package/dist/stats.d.ts.map +1 -0
  48. package/dist/stats.js +1245 -0
  49. package/dist/stats.js.map +1 -0
  50. package/dist/stop.d.ts +163 -0
  51. package/dist/stop.d.ts.map +1 -0
  52. package/dist/stop.js +262 -0
  53. package/dist/stop.js.map +1 -0
  54. package/package.json +64 -4
  55. package/src/baseline.ts +72 -0
  56. package/src/check.ts +238 -0
  57. package/src/cluster.ts +830 -0
  58. package/src/errors.ts +208 -0
  59. package/src/evidence.ts +62 -0
  60. package/src/frontier.ts +782 -0
  61. package/src/gate.ts +358 -0
  62. package/src/index.ts +206 -0
  63. package/src/plan.ts +778 -0
  64. package/src/rand.ts +121 -0
  65. package/src/stats.ts +1579 -0
  66. package/src/stop.ts +452 -0
@@ -0,0 +1,397 @@
1
+ /** Lanczos approximation to log Γ(x), x > 0. ~15 significant digits. */
2
+ export declare function logGamma(x: number): number;
3
+ export declare const logBeta: (a: number, b: number) => number;
4
+ /** Regularized lower incomplete gamma P(a,x), accurate to ~1e-15. */
5
+ export declare function gammaP(a: number, x: number): number;
6
+ /**
7
+ * erf(x) = sign(x)·P(½, x²).
8
+ * Built on the incomplete gamma rather than a rational fit: the usual 7-digit
9
+ * approximation is visible in a p-value and we compare p-values to thresholds.
10
+ */
11
+ export declare function erf(x: number): number;
12
+ /** Φ(x): standard normal CDF. */
13
+ export declare const normalCdf: (x: number) => number;
14
+ /** Φ⁻¹(p): Acklam's inverse normal CDF, refined by one Halley step. */
15
+ export declare function normalQuantile(p: number): number;
16
+ /** Regularized incomplete beta Iₓ(a,b) = P(Beta(a,b) ≤ x). */
17
+ export declare function ibeta(a: number, b: number, x: number): number;
18
+ export interface Interval {
19
+ low: number;
20
+ high: number;
21
+ point: number;
22
+ /**
23
+ * How many observations the interval rests on, when the producer knows.
24
+ * `0` means the interval is vacuous and `point` is a placeholder, not an
25
+ * estimate, check it before printing the point as a number.
26
+ */
27
+ observations?: number;
28
+ }
29
+ /**
30
+ * Wilson score interval for a binomial proportion.
31
+ * Correct at the boundaries (0/n and n/n) where Wald is degenerate, which is
32
+ * exactly where eval cases live.
33
+ */
34
+ export declare function wilsonInterval(successes: number, n: number, z?: number): Interval;
35
+ export interface BetaPosterior {
36
+ alpha: number;
37
+ beta: number;
38
+ mean: number;
39
+ mode: number;
40
+ variance: number;
41
+ sd: number;
42
+ n: number;
43
+ successes: number;
44
+ }
45
+ /** Conjugate Beta posterior for a per-case latent success probability. */
46
+ export declare function betaPosterior(successes: number, failures: number, prior?: {
47
+ alpha: number;
48
+ beta: number;
49
+ }): BetaPosterior;
50
+ /** Inverse of the Beta CDF by bisection on ibeta (monotone, so this is exact to 1e-10). */
51
+ export declare function betaQuantile(alpha: number, beta: number, q: number): number;
52
+ /**
53
+ * Student-t quantile, from the Beta inverse CDF.
54
+ *
55
+ * Needed because the cluster-robust suite interval has a *small* number of
56
+ * degrees of freedom, one per case family, not one per case, and at 39 df the
57
+ * difference between t and z is already 3.2% of the half-width. Using z there
58
+ * would reintroduce, in miniature, exactly the too-narrow-interval bug that
59
+ * clustering exists to fix.
60
+ *
61
+ * The identity is the standard one: for T ~ t_ν and t > 0,
62
+ * P(|T| > t) = I_x(ν/2, ½) with x = ν/(ν + t²)
63
+ * so inverting `ibeta` in x inverts the t CDF. Exact to the ~1e-10 of
64
+ * `betaQuantile`, and it degenerates to `normalQuantile` as ν → ∞.
65
+ */
66
+ export declare function tQuantile(p: number, df: number): number;
67
+ /** Equal-tailed credible interval of a Beta posterior. */
68
+ export declare function betaCredibleInterval(post: BetaPosterior, level?: number): Interval;
69
+ /** P(a < θ < b) under a Beta posterior. */
70
+ export declare function betaMassBetween(post: BetaPosterior, a: number, b: number): number;
71
+ /**
72
+ * Newcombe's hybrid-score interval for a difference of proportions (p₂ − p₁).
73
+ * Built from the two Wilson intervals, so it stays inside [-1,1] and behaves at
74
+ * the boundaries. This is the "effect size with a CI" that replaces "-4.5%".
75
+ */
76
+ export declare function diffInterval(s1: number, n1: number, s2: number, n2: number, z?: number): Interval;
77
+ /** Cohen's h, the scale-free effect size for proportions (arcsine transform). */
78
+ export declare function cohensH(p1: number, p2: number): number;
79
+ export interface TestResult {
80
+ statistic: number;
81
+ p: number;
82
+ }
83
+ /** Pooled two-proportion z-test, two-sided. */
84
+ export declare function twoProportionZTest(s1: number, n1: number, s2: number, n2: number): TestResult;
85
+ /**
86
+ * Fisher's exact test on a 2×2 table [[a,b],[c,d]], two-sided by the
87
+ * sum-of-small-probabilities convention. Exact, which matters because eval
88
+ * cases are run 8 to 30 times, not 8000.
89
+ */
90
+ export declare function fisherExact2x2(a: number, b: number, cc: number, d: number): TestResult;
91
+ export type SprtDecision = "ACCEPT_H0" | "ACCEPT_H1" | "CONTINUE";
92
+ export interface SprtResult {
93
+ decision: SprtDecision;
94
+ logLR: number;
95
+ upper: number;
96
+ lower: number;
97
+ /** How far through the [lower, upper] corridor we are: -1 = H0 wall, +1 = H1 wall. */
98
+ progress: number;
99
+ }
100
+ export interface SprtOpts {
101
+ successes: number;
102
+ trials: number;
103
+ /** null hypothesis success probability (e.g. the baseline rate) */
104
+ p0: number;
105
+ /** alternative worth detecting (e.g. baseline − minimum detectable regression) */
106
+ p1: number;
107
+ alpha?: number;
108
+ beta?: number;
109
+ }
110
+ /**
111
+ * Wald's Sequential Probability Ratio Test for a Bernoulli stream.
112
+ *
113
+ * logLR = s·log(p₁/p₀) + (n−s)·log((1−p₁)/(1−p₀))
114
+ * accept H₁ when logLR ≥ log((1−β)/α); accept H₀ when logLR ≤ log(β/(1−α)).
115
+ *
116
+ * The whole point: it is evaluated after *every* batch, so a case that is
117
+ * obviously fine (or obviously broken) stops consuming samples immediately.
118
+ */
119
+ export declare function sprtDecision(opts: SprtOpts): SprtResult;
120
+ /**
121
+ * Expected sample number for Wald's SPRT under a true rate p (Wald's
122
+ * approximation).
123
+ *
124
+ * `(L₁·log A + (1−L₁)·log B) / E_p[log λ]`, where `L₁` is the probability of
125
+ * finishing at the H₁ wall. Exactness here is about `L₁` and not about the
126
+ * result: the formula treats the test as stopping exactly on a wall, where a
127
+ * real one overshoots it, so the answer under-states the true expected sample
128
+ * number. `L₁` is Wald's operating characteristic in exact form,
129
+ * `(1 − B^h) / (A^h − B^h)` at the tilt `h` above, rather than the
130
+ * textbook three-point interpolation: both the numerator and the drift have to
131
+ * change sign at the same rate, and an interpolation that misses that rate by
132
+ * even a little returns a *negative* number of runs. The version this replaces
133
+ * interpolated `L₁` as `(p − p1)/(p0 − p1)`, which rises from 0 at `p1` to 1 at
134
+ * `p0` where the OC falls from `1 − β` to `α`, so it matched neither hypothesis
135
+ * and came out negative over most of the corridor. Every caller here tests the
136
+ * result for `> 0` and falls back to `maxTrials`, so a case landing in the
137
+ * corridor was priced at the per-case cap: a 9/30 baseline, whose posterior
138
+ * median sits above its own rate, costs 32 runs and was quoted at 96.
139
+ * `test/exports.test.ts` pins both the positivity and that case.
140
+ */
141
+ export declare function sprtExpectedN(p: number, p0: number, p1: number, alpha?: number, beta?: number): number;
142
+ export interface BhResult {
143
+ /** rejected[i] === true ⇒ case i is a discovery at FDR ≤ q */
144
+ rejected: boolean[];
145
+ /** BH-adjusted p-values (monotone step-up), aligned with the input order */
146
+ adjusted: number[];
147
+ /** the largest raw p-value that was rejected, or 0 if none */
148
+ cutoff: number;
149
+ discoveries: number;
150
+ }
151
+ /**
152
+ * Benjamini-Hochberg FDR control.
153
+ * With 200 cases at α=0.05 you expect ~10 false alarms per clean run; BH is why
154
+ * a green suite stays green.
155
+ */
156
+ export declare function bhCorrect(pvalues: number[], q?: number): BhResult;
157
+ /**
158
+ * Log marginal likelihood of s successes in n Bernoulli trials when the rate
159
+ * carries a Beta(a,b) prior, the beta-binomial, minus the C(n,s) term (which
160
+ * cancels in every ratio we take).
161
+ */
162
+ export declare function logMarginalBetaBinomial(s: number, n: number, a: number, b: number): number;
163
+ /**
164
+ * A **two-sample e-value** for "the candidate is worse than the baseline".
165
+ *
166
+ * The one-sample alternative, test the candidate against the baseline's point
167
+ * estimate, quietly assumes the baseline rate is known. It is not: it came
168
+ * from 24 noisy runs, and a baseline that got lucky manufactures regressions
169
+ * that were never there.
170
+ *
171
+ * So the null keeps the baseline's uncertainty: p ~ Beta(1+s_b, 1+f_b), and the
172
+ * alternative is the same amount of information centred `mde` lower. The ratio
173
+ * of the two marginal likelihoods is a Bayes factor, and a Bayes factor between
174
+ * two joint distributions of the same sequence is a non-negative martingale
175
+ * with mean 1 under the null's own marginal, here the shared rate drawn from
176
+ * the uniform prior. At a fixed rate the mean can exceed 1, so the frequentist
177
+ * type I error is checked exactly in `test/error-control.test.ts` instead.
178
+ */
179
+ export declare function twoSampleLogE(candidateSuccesses: number, candidateTrials: number, baselineSuccesses: number, baselineTrials: number, mde: number,
180
+ /**
181
+ * Concentration of the alternative prior. Low values spread the alternative
182
+ * over "anything materially worse", which is what actually happens when a
183
+ * change breaks a case, it rarely lands exactly `mde` below.
184
+ */
185
+ altConcentration?: number): number;
186
+ /**
187
+ * e-BH, Benjamini-Hochberg for **e-values** (Wang & Ramdas).
188
+ *
189
+ * Why this exists: a p-value computed after optional stopping is not a
190
+ * p-value. The likelihood ratio a sequential test accumulates *is* a valid
191
+ * e-value under H₀ (it is a non-negative martingale, so Ville's inequality
192
+ * gives P(sup LR ≥ 1/α) ≤ α), and it stays valid if you keep sampling, which
193
+ * is exactly what peeksafe does to confirm a flagged case.
194
+ *
195
+ * Reject the k largest e-values where k* = max{ k : e₍ₖ₎ ≥ m / (q·k) }.
196
+ * Controls FDR at q under *arbitrary* dependence between cases.
197
+ */
198
+ export interface EbhResult {
199
+ rejected: boolean[];
200
+ discoveries: number;
201
+ /** the e-value a case had to beat, given how many discoveries were made */
202
+ threshold: number;
203
+ }
204
+ export declare function ebhCorrect(evalues: number[], q?: number): EbhResult;
205
+ /** The e-value a case must reach to be certain of rejection whatever the others do. */
206
+ export declare const ebhSoloThreshold: (m: number, q?: number) => number;
207
+ /**
208
+ * Fixed-N sample size per arm for detecting a `delta` drop from `p0` at the
209
+ * given error rates. This is the "naive approach" peeksafe is measured against.
210
+ *
211
+ * Returns **Infinity** when the effect is one the case cannot suffer, a case
212
+ * whose baseline rate is 10% cannot lose 15 points, and no number of samples
213
+ * will find a drop that is arithmetically impossible. The old version clamped
214
+ * `p1` to 1e-6 and answered "44 runs", which is a plausible-looking lie
215
+ * and exactly the sort of thing a budget planner must not do.
216
+ */
217
+ export declare function sampleSizeTwoProportion(p0: number, delta: number, alpha?: number, beta?: number): number;
218
+ /** Shannon entropy in bits of a Bernoulli(p), used as a raw instability signal. */
219
+ export declare function bernoulliEntropy(p: number): number;
220
+ /** log of the Beta(a,b) density at p. */
221
+ export declare function logBetaPdf(p: number, a: number, b: number): number;
222
+ /** The two prior shapes `twoSampleLogE` compares. Exposed so the planner can
223
+ * reason about the *limit* of the evidence, not just its value at some n. */
224
+ export declare function twoSamplePriors(baselineSuccesses: number, baselineTrials: number, mde: number, altConcentration?: number): {
225
+ nullPrior: {
226
+ a: number;
227
+ b: number;
228
+ };
229
+ altPrior: {
230
+ a: number;
231
+ b: number;
232
+ };
233
+ };
234
+ /**
235
+ * The **evidence ceiling** of the unpaired two-sample e-value.
236
+ *
237
+ * This is the single most useful number the planner has, and it is not
238
+ * obvious: the two-sample Bayes factor does *not* grow without bound in the
239
+ * number of candidate runs. Both marginals are the same binomial likelihood
240
+ * under different priors, so by Laplace approximation
241
+ *
242
+ * log m_a(s, n) = n·h(p̂) + log f_a(p̂) + ½log(2π p̂(1−p̂)/n) + O(1/n)
243
+ *
244
+ * and every term except `log f(p̂)` is common to numerator and denominator.
245
+ * The ratio therefore converges to the **prior density ratio at the observed
246
+ * rate**:
247
+ *
248
+ * lim_{n→∞} log E = log f_alt(p) − log f_null(p)
249
+ *
250
+ * Consequences `gate` and `makePlan` report directly:
251
+ * - a case whose ceiling sits below the e-BH bar `m/(q·k)` is **undetectable
252
+ * at any budget**: buying more candidate runs cannot certify it;
253
+ * - the remedy is more *baseline* runs, which sharpen f_null and raise the
254
+ * ceiling, that is the amortised baseline, quantified;
255
+ * - the paired design (`pairedLogE`) has no such ceiling, because its null is
256
+ * an exact point mass at ½ rather than an estimated prior.
257
+ */
258
+ export declare function evidenceCeilingLogE(pTrue: number, baselineSuccesses: number, baselineTrials: number, mde: number, altConcentration?: number): number;
259
+ /**
260
+ * The **rate** at which the evidence ceiling grows in baseline runs: the
261
+ * Kullback-Leibler divergence `KL(p_b ‖ p)` in nats, with the *baseline* rate
262
+ * as the first argument.
263
+ *
264
+ * This is not the obvious direction, and getting it the wrong way round gives a
265
+ * materially different number (at 85% losing 15 points: 0.0611 the right way,
266
+ * 0.0720 the wrong way). It falls out of the Laplace expansion of the null
267
+ * prior's own density, see `evidenceCeilingAsymptotic`.
268
+ */
269
+ export declare function evidenceCeilingSlope(pBaseline: number, pCandidate: number): number;
270
+ /**
271
+ * The evidence ceiling in closed form, to O(1/n_b).
272
+ *
273
+ * `evidenceCeilingLogE` evaluates the exact prior density ratio. This says what
274
+ * that ratio *is*, as a function of the baseline size, and it is the useful
275
+ * form because it inverts:
276
+ *
277
+ * ceiling(n_b) ≈ n_b · KL(p̄_b ‖ p) + log f_alt(p) + ½·log(2π p̄_b(1−p̄_b)/n_b)
278
+ *
279
+ * The leading term comes from Stirling on the null prior's normaliser:
280
+ * `f_null` is a Beta posterior, its log density at `p` is
281
+ * `−n_b·KL(p̄_b ‖ p) − ½log(2π p̄_b(1−p̄_b)/n_b) + O(1/n_b)`, and the alternative
282
+ * prior does not move with `n_b` at all.
283
+ *
284
+ * Two consequences that are the practical point of the whole ceiling result:
285
+ *
286
+ * - **the ceiling grows linearly in baseline runs**, at a rate that is a
287
+ * property of the case's pass rate and the MDE and of nothing else;
288
+ * - so the baseline size a case needs to be detectable at all is roughly
289
+ * `log(m/q) / KL(p̄_b ‖ p̄_b − δ)`, an O(1) formula where `plan.ts` searches.
290
+ * It is a *lower* bound: the two lower-order terms are negative at realistic
291
+ * `n_b`, so the honest quote is that rule of thumb plus about 20%, and
292
+ * `makePlan` keeps reporting the exact search.
293
+ *
294
+ * Matches `evidenceCeilingLogE` to better than 0.1% for `n_b ≥ 240`; checked in
295
+ * `test/paper.test.ts`.
296
+ */
297
+ export declare function evidenceCeilingAsymptotic(baselineSuccesses: number, baselineTrials: number, pTrue: number, mde: number, altConcentration?: number): number;
298
+ /**
299
+ * The two-sample log e-value along the **mean trajectory**: the value it takes
300
+ * when the candidate scores exactly its expected `pTrue·n` successes in `n`
301
+ * runs. Fractional successes are legal, the beta-binomial marginal is a ratio
302
+ * of Beta functions, which is defined on the reals.
303
+ *
304
+ * This is a plug-in for E[log E], not E[log E] itself. `expectedLogEExact`
305
+ * computes the true expectation by summing over the binomial.
306
+ */
307
+ export declare function expectedLogE(pTrue: number, n: number, baselineSuccesses: number, baselineTrials: number, mde: number, altConcentration?: number): number;
308
+ /** E[log E] computed exactly, by summing over every binomial outcome. O(n). */
309
+ export declare function expectedLogEExact(pTrue: number, n: number, baselineSuccesses: number, baselineTrials: number, mde: number, altConcentration?: number): number;
310
+ /**
311
+ * Smallest number of candidate runs whose mean-trajectory log e-value clears
312
+ * `logThreshold`. Returns **Infinity** when the ceiling is below the threshold
313
+ *, the honest answer to "how many runs would it take", when the answer is
314
+ * that no number of runs will do.
315
+ */
316
+ export declare function samplesForEvidence(pTrue: number, baselineSuccesses: number, baselineTrials: number, mde: number, logThreshold: number, maxN?: number, altConcentration?: number): number;
317
+ /**
318
+ * The two-sample e-value for "the candidate is worse than the baseline", valid
319
+ * at every pair of rates and at any stopping time. Same arguments as
320
+ * `twoSampleLogE`, which it never exceeds.
321
+ */
322
+ export declare function universalTwoSampleLogE(candidateSuccesses: number, candidateTrials: number, baselineSuccesses: number, baselineTrials: number, mde: number, altConcentration?: number): number;
323
+ /**
324
+ * An upper bound on `universalTwoSampleLogE` over every future candidate run
325
+ * count, for a candidate observed at rate `pTrue`. It plays the part
326
+ * `evidenceCeilingLogE` plays for the default statistic.
327
+ *
328
+ * The alternative's marginal is at most the candidate's maximum likelihood, and
329
+ * the pooled likelihood ratio is at most `n_b · KL(p̂_b ‖ pTrue)`, so the bound
330
+ * is the baseline's mixture over its maximum likelihood plus that term.
331
+ */
332
+ export declare function universalCeilingLogE(pTrue: number, baselineSuccesses: number, baselineTrials: number): number;
333
+ export interface PairedCounts {
334
+ /** both arms passed */
335
+ bothPass: number;
336
+ /** baseline passed, candidate failed, the direction that indicates a regression */
337
+ worse: number;
338
+ /** candidate passed, baseline failed */
339
+ better: number;
340
+ /** both arms failed */
341
+ bothFail: number;
342
+ }
343
+ export declare const discordant: (p: PairedCounts) => number;
344
+ /**
345
+ * Phi coefficient of the 2×2 pair table, how well the pairing actually
346
+ * coupled the two arms. 0 means the seeds bought nothing (the arms are
347
+ * independent and you may as well not have paired); 1 means perfect coupling.
348
+ * This is the number the variance-reduction claim has to be measured against,
349
+ * not assumed.
350
+ */
351
+ export declare function pairPhi(p: PairedCounts): number;
352
+ /**
353
+ * A **paired e-value** for "the candidate is worse".
354
+ *
355
+ * Null: each discordant pair points the wrong way with probability at most ½.
356
+ * Alternative: it points the wrong way with probability θ ~ Beta centred on
357
+ * `thetaAlt`, truncated to θ > ½. Every θ in that support gives a likelihood
358
+ * ratio against ½ that is a supermartingale whenever the true probability is
359
+ * ½ or less, so the mixture is an e-value valid under optional stopping for a
360
+ * candidate that is unchanged or better, not only for one that is unchanged.
361
+ */
362
+ export declare function pairedLogE(worse: number, discordantPairs: number, thetaAlt?: number, concentration?: number): number;
363
+ /**
364
+ * The discordance model a paired plan runs on.
365
+ *
366
+ * With probability `rho` the two arms see the same random draw and a
367
+ * discordance can only occur inside the (p_c, p_b) gap, always in the "worse"
368
+ * direction. With probability 1−rho they are independent and discordances go
369
+ * both ways. `rho` is *measured* from a pilot (see `pairPhi`), not assumed.
370
+ */
371
+ export declare function pairedDiscordance(pBaseline: number, mde: number, rho: number): {
372
+ rate: number;
373
+ theta: number;
374
+ };
375
+ /**
376
+ * Expected number of **pairs** for the paired e-value to clear `logThreshold`.
377
+ * One pair costs one candidate run plus one baseline run, so the caller must
378
+ * double it before comparing with `samplesForEvidence`. Even so it usually
379
+ * wins, and unlike the unpaired design it never returns Infinity for a real
380
+ * effect.
381
+ */
382
+ export declare function mcnemarSamplesForEvidence(pBaseline: number, mde: number, rho: number, logThreshold: number, maxPairs?: number, concentration?: number): number;
383
+ /**
384
+ * P(p_candidate ≤ p_baseline − mde) under independent Beta posteriors, the
385
+ * posterior probability that a case *moved*, given whatever handful of runs it
386
+ * has so far.
387
+ *
388
+ * This is the screening score: cheap (one quadrature over `ibeta`), needs only
389
+ * 3 to 4 candidate runs to be informative, and orders cases by where the
390
+ * expensive sequential test can actually pay. It is deliberately **not** a
391
+ * decision, screening decides where to spend, the e-value decides what is
392
+ * true, and the FDR guarantee is unaffected by which cases you chose to look
393
+ * at (e-BH is valid under arbitrary dependence, including a data-dependent
394
+ * choice of which cases to sample further).
395
+ */
396
+ export declare function probabilityMoved(baselineSuccesses: number, baselineTrials: number, candidateSuccesses: number, candidateTrials: number, mde: number, nodes?: number): number;
397
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"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"}