/ concept-collection / timeseries-compressibility
Sign in
concept-collection / timeseries-compressibility
timeseries-compressibility / src / entropy / index.ts
52 lines · 1.9 KBBlameHistoryRaw
1/**
2 * In-browser unbiased estimation of H(z_{M+1} | z_1..z_M) — the entropy
3 * rate R — for the app's model. Hand-synced TypeScript port of the sibling
4 * timeseries-entropy package (see the headers of estimator.ts / model.ts);
5 * defaults match its CLI so browser runs and `timeseries-entropy` runs
6 * target the same estimand with the same variance behavior.
7 */
8import { unbiasedEntropy } from './estimator'
9import { ConditionalChain } from './model'
10import { Rng } from './rng'
12export { unbiasedEntropy } from './estimator'
13export { ConditionalChain, truncatedStdNormal } from './model'
14export { Rng } from './rng'
15export { ndtr, ndtri, erfc } from './normal'
16export { predictEntropyRate, gaussUniformEntropy, logSpectrumMean } from './theory'
18export const N0 = 128
19export const R_EXPONENT = 1.5
20export const REPS_PER_PAST = 8
21export const THIN = 1
23/** The conditioning window M at a given kernel length, as in the CLI. */
24export function defaultPast(kernelLength: number): number {
25 return Math.max(512, 4 * kernelLength)
28/** The seed for one independent past, derived so past i is reproducible
29 * whether or not the run was stopped and resumed in between. */
30export function pastSeed(baseSeed: number, pastIndex: number): number {
31 return (baseSeed + Math.imul(0x9e3779b9, pastIndex + 1)) >>> 0
34/** One independent past's unbiased estimate: a fresh stationary chain,
35 * averaged over reps randomized-telescoping realizations run back-to-back
36 * on it. Averaging these over pasts estimates H(z_{M+1} | z_1..z_M). */
37export function estimateOnePast(
38 kernel: Float64Array,
39 sigma: number,
40 past: number,
41 seed: number,
42 onRep?: (repsDone: number) => void,
43): number {
44 const rng = new Rng(seed)
45 const chain = new ConditionalChain(kernel, sigma, past, rng, THIN)
46 let sum = 0
47 for (let rep = 0; rep < REPS_PER_PAST; rep++) {
48 sum += unbiasedEntropy(chain.draw, N0, R_EXPONENT, rng)
49 onRep?.(rep + 1)
50 }
51 return sum / REPS_PER_PAST
moveopenescclose