@mindpeeker/negentropy 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.
- package/LICENSE +21 -0
- package/README.md +160 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +11 -0
- package/dist/errors.js.map +1 -0
- package/dist/estimators/entropy.d.ts +22 -0
- package/dist/estimators/entropy.d.ts.map +1 -0
- package/dist/estimators/entropy.js +78 -0
- package/dist/estimators/entropy.js.map +1 -0
- package/dist/estimators/frequency.d.ts +18 -0
- package/dist/estimators/frequency.d.ts.map +1 -0
- package/dist/estimators/frequency.js +57 -0
- package/dist/estimators/frequency.js.map +1 -0
- package/dist/estimators/negentropy.d.ts +62 -0
- package/dist/estimators/negentropy.d.ts.map +1 -0
- package/dist/estimators/negentropy.js +104 -0
- package/dist/estimators/negentropy.js.map +1 -0
- package/dist/estimators/pipeline.d.ts +25 -0
- package/dist/estimators/pipeline.d.ts.map +1 -0
- package/dist/estimators/pipeline.js +30 -0
- package/dist/estimators/pipeline.js.map +1 -0
- package/dist/estimators/vasicek.d.ts +18 -0
- package/dist/estimators/vasicek.d.ts.map +1 -0
- package/dist/estimators/vasicek.js +57 -0
- package/dist/estimators/vasicek.js.map +1 -0
- package/dist/estimators/windowed.d.ts +27 -0
- package/dist/estimators/windowed.d.ts.map +1 -0
- package/dist/estimators/windowed.js +66 -0
- package/dist/estimators/windowed.js.map +1 -0
- package/dist/experiment/batch.d.ts +15 -0
- package/dist/experiment/batch.d.ts.map +1 -0
- package/dist/experiment/batch.js +179 -0
- package/dist/experiment/batch.js.map +1 -0
- package/dist/experiment/composite.d.ts +12 -0
- package/dist/experiment/composite.d.ts.map +1 -0
- package/dist/experiment/composite.js +26 -0
- package/dist/experiment/composite.js.map +1 -0
- package/dist/experiment/registration.d.ts +20 -0
- package/dist/experiment/registration.d.ts.map +1 -0
- package/dist/experiment/registration.js +54 -0
- package/dist/experiment/registration.js.map +1 -0
- package/dist/experiment/session.d.ts +47 -0
- package/dist/experiment/session.d.ts.map +1 -0
- package/dist/experiment/session.js +245 -0
- package/dist/experiment/session.js.map +1 -0
- package/dist/experiment/types.d.ts +68 -0
- package/dist/experiment/types.d.ts.map +1 -0
- package/dist/experiment/types.js +2 -0
- package/dist/experiment/types.js.map +1 -0
- package/dist/extract/accounting.d.ts +52 -0
- package/dist/extract/accounting.d.ts.map +1 -0
- package/dist/extract/accounting.js +130 -0
- package/dist/extract/accounting.js.map +1 -0
- package/dist/extract/condition.d.ts +23 -0
- package/dist/extract/condition.d.ts.map +1 -0
- package/dist/extract/condition.js +50 -0
- package/dist/extract/condition.js.map +1 -0
- package/dist/extract/debias.d.ts +25 -0
- package/dist/extract/debias.d.ts.map +1 -0
- package/dist/extract/debias.js +80 -0
- package/dist/extract/debias.js.map +1 -0
- package/dist/extract/health.d.ts +44 -0
- package/dist/extract/health.d.ts.map +1 -0
- package/dist/extract/health.js +115 -0
- package/dist/extract/health.js.map +1 -0
- package/dist/extract/toeplitz.d.ts +19 -0
- package/dist/extract/toeplitz.d.ts.map +1 -0
- package/dist/extract/toeplitz.js +83 -0
- package/dist/extract/toeplitz.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/bytes.d.ts +6 -0
- package/dist/internal/bytes.d.ts.map +1 -0
- package/dist/internal/bytes.js +36 -0
- package/dist/internal/bytes.js.map +1 -0
- package/dist/internal/kahan.d.ts +7 -0
- package/dist/internal/kahan.d.ts.map +1 -0
- package/dist/internal/kahan.js +15 -0
- package/dist/internal/kahan.js.map +1 -0
- package/dist/internal/prng.d.ts +7 -0
- package/dist/internal/prng.d.ts.map +1 -0
- package/dist/internal/prng.js +16 -0
- package/dist/internal/prng.js.map +1 -0
- package/dist/internal/special.d.ts +36 -0
- package/dist/internal/special.d.ts.map +1 -0
- package/dist/internal/special.js +258 -0
- package/dist/internal/special.js.map +1 -0
- package/dist/internal/welford.d.ts +13 -0
- package/dist/internal/welford.d.ts.map +1 -0
- package/dist/internal/welford.js +30 -0
- package/dist/internal/welford.js.map +1 -0
- package/dist/numerics.d.ts +32 -0
- package/dist/numerics.d.ts.map +1 -0
- package/dist/numerics.js +32 -0
- package/dist/numerics.js.map +1 -0
- package/dist/stats/calibration.d.ts +14 -0
- package/dist/stats/calibration.d.ts.map +1 -0
- package/dist/stats/calibration.js +41 -0
- package/dist/stats/calibration.js.map +1 -0
- package/dist/stats/cumdev.d.ts +15 -0
- package/dist/stats/cumdev.d.ts.map +1 -0
- package/dist/stats/cumdev.js +38 -0
- package/dist/stats/cumdev.js.map +1 -0
- package/dist/stats/network.d.ts +29 -0
- package/dist/stats/network.d.ts.map +1 -0
- package/dist/stats/network.js +119 -0
- package/dist/stats/network.js.map +1 -0
- package/dist/stats/pvalues.d.ts +11 -0
- package/dist/stats/pvalues.d.ts.map +1 -0
- package/dist/stats/pvalues.js +18 -0
- package/dist/stats/pvalues.js.map +1 -0
- package/dist/stats/trials.d.ts +34 -0
- package/dist/stats/trials.d.ts.map +1 -0
- package/dist/stats/trials.js +149 -0
- package/dist/stats/trials.js.map +1 -0
- package/dist/stats/zscores.d.ts +10 -0
- package/dist/stats/zscores.d.ts.map +1 -0
- package/dist/stats/zscores.js +26 -0
- package/dist/stats/zscores.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { NegentropyError } from '../errors.js';
|
|
2
|
+
import { KahanSum } from '../internal/kahan.js';
|
|
3
|
+
import { chiSquareP, normalP } from './pvalues.js';
|
|
4
|
+
import { stoufferZ } from './zscores.js';
|
|
5
|
+
/**
|
|
6
|
+
* All network statistics consume a "z matrix": one Float64Array of z-scores
|
|
7
|
+
* per source, all the same length (steps), step-aligned across sources.
|
|
8
|
+
* Useful identity relating the three: Z_s(t)² = [Σᵢzᵢ² + 2S(t)] / N — netvar
|
|
9
|
+
* is a specific mixture of device variance and covariance.
|
|
10
|
+
*/
|
|
11
|
+
function checkMatrix(zBySource, sources) {
|
|
12
|
+
if (zBySource.length === 0 || zBySource.length !== sources.length) {
|
|
13
|
+
throw new NegentropyError('invalid_config', `need one z array per source: got ${zBySource.length} arrays for ${sources.length} sources`);
|
|
14
|
+
}
|
|
15
|
+
const steps = zBySource[0].length;
|
|
16
|
+
for (let i = 1; i < zBySource.length; i++) {
|
|
17
|
+
if (zBySource[i].length !== steps) {
|
|
18
|
+
throw new NegentropyError('invalid_config', `z arrays must be step-aligned: ${sources[i]} has ${zBySource[i].length} steps, ${sources[0]} has ${steps}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (steps === 0) {
|
|
22
|
+
throw new NegentropyError('insufficient_data', 'network statistics need at least one step');
|
|
23
|
+
}
|
|
24
|
+
return steps;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Network variance — the GCP standard event statistic: Σₜ Z_s(t)² where
|
|
28
|
+
* Z_s(t) is the per-step Stouffer Z across sources; ~ χ²(steps) under H0.
|
|
29
|
+
* Sensitive to a common signal shared across sources and to mean shifts.
|
|
30
|
+
*/
|
|
31
|
+
export function netvar(zBySource, sources) {
|
|
32
|
+
const steps = checkMatrix(zBySource, sources);
|
|
33
|
+
const acc = new KahanSum();
|
|
34
|
+
const zAt = new Float64Array(zBySource.length);
|
|
35
|
+
for (let t = 0; t < steps; t++) {
|
|
36
|
+
for (let i = 0; i < zBySource.length; i++)
|
|
37
|
+
zAt[i] = zBySource[i][t];
|
|
38
|
+
const z = stoufferZ(zAt);
|
|
39
|
+
acc.add(z * z);
|
|
40
|
+
}
|
|
41
|
+
const statistic = acc.value;
|
|
42
|
+
return {
|
|
43
|
+
statistic,
|
|
44
|
+
df: steps,
|
|
45
|
+
pValue: chiSquareP(statistic, steps),
|
|
46
|
+
n: steps,
|
|
47
|
+
sources: [...sources],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Device variance: Σₜ Σᵢ zᵢ(t)² ~ χ²(steps × sources) under H0. Sensitive to
|
|
52
|
+
* individual sources changing variance; blind to cross-source correlation.
|
|
53
|
+
*/
|
|
54
|
+
export function devvar(zBySource, sources) {
|
|
55
|
+
const steps = checkMatrix(zBySource, sources);
|
|
56
|
+
const acc = new KahanSum();
|
|
57
|
+
for (const zs of zBySource) {
|
|
58
|
+
for (let t = 0; t < steps; t++) {
|
|
59
|
+
const z = zs[t];
|
|
60
|
+
acc.add(z * z);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const df = steps * zBySource.length;
|
|
64
|
+
const statistic = acc.value;
|
|
65
|
+
return {
|
|
66
|
+
statistic,
|
|
67
|
+
df,
|
|
68
|
+
pValue: chiSquareP(statistic, df),
|
|
69
|
+
n: steps,
|
|
70
|
+
sources: [...sources],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Inter-source correlation: per step S(t) = Σᵢ<ⱼ zᵢzⱼ = ((Σz)² − Σz²)/2;
|
|
75
|
+
* statistic = ΣₜS(t) / √(steps·N(N−1)/2), treated as N(0,1) by the CLT.
|
|
76
|
+
* Not valid for tiny steps×pairs — expect ≥ ~100 products before trusting
|
|
77
|
+
* the normal approximation. `df` reports that product count for context; the
|
|
78
|
+
* p-value comes from the normal tail (one-sided: excess correlation).
|
|
79
|
+
*/
|
|
80
|
+
export function interSourceCorrelation(zBySource, sources) {
|
|
81
|
+
const steps = checkMatrix(zBySource, sources);
|
|
82
|
+
const n = zBySource.length;
|
|
83
|
+
if (n < 2) {
|
|
84
|
+
throw new NegentropyError('invalid_config', 'interSourceCorrelation needs at least 2 sources');
|
|
85
|
+
}
|
|
86
|
+
const total = new KahanSum();
|
|
87
|
+
for (let t = 0; t < steps; t++) {
|
|
88
|
+
let sum = 0;
|
|
89
|
+
let sumSq = 0;
|
|
90
|
+
for (let i = 0; i < n; i++) {
|
|
91
|
+
const z = zBySource[i][t];
|
|
92
|
+
sum += z;
|
|
93
|
+
sumSq += z * z;
|
|
94
|
+
}
|
|
95
|
+
total.add((sum * sum - sumSq) / 2);
|
|
96
|
+
}
|
|
97
|
+
const pairCount = (n * (n - 1)) / 2;
|
|
98
|
+
const statistic = total.value / Math.sqrt(steps * pairCount);
|
|
99
|
+
const pairs = [];
|
|
100
|
+
for (let i = 0; i < n; i++) {
|
|
101
|
+
for (let j = i + 1; j < n; j++) {
|
|
102
|
+
const za = zBySource[i];
|
|
103
|
+
const zb = zBySource[j];
|
|
104
|
+
const acc = new KahanSum();
|
|
105
|
+
for (let t = 0; t < steps; t++)
|
|
106
|
+
acc.add(za[t] * zb[t]);
|
|
107
|
+
pairs.push({ a: sources[i], b: sources[j], r: acc.value / steps });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
statistic,
|
|
112
|
+
df: steps * pairCount,
|
|
113
|
+
pValue: normalP(statistic, 'upper'),
|
|
114
|
+
n: steps,
|
|
115
|
+
sources: [...sources],
|
|
116
|
+
pairs,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/stats/network.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floor applied to every public p-value so downstream probit conversion
|
|
3
|
+
* (composites) never sees an exact zero.
|
|
4
|
+
*/
|
|
5
|
+
export declare const P_FLOOR = 1e-300;
|
|
6
|
+
export type Tail = 'two' | 'upper' | 'lower';
|
|
7
|
+
/** p-value of a standard-normal statistic. Default two-sided. */
|
|
8
|
+
export declare function normalP(z: number, tail?: Tail): number;
|
|
9
|
+
/** Upper-tail p-value of a chi-square statistic (the GCP convention: variance excess). */
|
|
10
|
+
export declare function chiSquareP(statistic: number, df: number): number;
|
|
11
|
+
//# sourceMappingURL=pvalues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pvalues.d.ts","sourceRoot":"","sources":["../../src/stats/pvalues.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,OAAO,SAAS,CAAA;AAE7B,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,CAAA;AAE5C,iEAAiE;AACjE,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,IAAY,GAAG,MAAM,CAM7D;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEhE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { chi2Sf, normCdf, normSf } from '../internal/special.js';
|
|
2
|
+
/**
|
|
3
|
+
* Floor applied to every public p-value so downstream probit conversion
|
|
4
|
+
* (composites) never sees an exact zero.
|
|
5
|
+
*/
|
|
6
|
+
export const P_FLOOR = 1e-300;
|
|
7
|
+
/** p-value of a standard-normal statistic. Default two-sided. */
|
|
8
|
+
export function normalP(z, tail = 'two') {
|
|
9
|
+
const upper = normSf(z);
|
|
10
|
+
const lower = normCdf(z);
|
|
11
|
+
const p = tail === 'upper' ? upper : tail === 'lower' ? lower : Math.min(1, 2 * Math.min(upper, lower));
|
|
12
|
+
return Math.max(p, P_FLOOR);
|
|
13
|
+
}
|
|
14
|
+
/** Upper-tail p-value of a chi-square statistic (the GCP convention: variance excess). */
|
|
15
|
+
export function chiSquareP(statistic, df) {
|
|
16
|
+
return Math.max(chi2Sf(statistic, df), P_FLOOR);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=pvalues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pvalues.js","sourceRoot":"","sources":["../../src/stats/pvalues.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAEhE;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAA;AAI7B,iEAAiE;AACjE,MAAM,UAAU,OAAO,CAAC,CAAS,EAAE,OAAa,KAAK;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IACvB,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACxB,MAAM,CAAC,GACL,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;IAC/F,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;AAC7B,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,EAAU;IACtD,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAA;AACjD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Trial, TrialConfig, TrialSeries, TrialSource } from '../types.js';
|
|
2
|
+
export declare const DEFAULT_BITS_PER_TRIAL = 200;
|
|
3
|
+
/**
|
|
4
|
+
* Batch trial extraction: slice a recorded byte buffer into trial sums — the
|
|
5
|
+
* number of one-bits among each run of `bitsPerTrial` consecutive bits
|
|
6
|
+
* (MSB-first). Under H0 each sum ~ Binomial(bitsPerTrial, ½). Trailing bits
|
|
7
|
+
* that do not fill a whole trial are dropped and reported via `leftoverBits`,
|
|
8
|
+
* never zero-padded.
|
|
9
|
+
*/
|
|
10
|
+
export declare function trialsFromBytes(bytes: Uint8Array, source: string, config?: TrialConfig): TrialSeries;
|
|
11
|
+
export interface TrialStreamConfig extends TrialConfig {
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
/** Desired chunk size passed through to the source's stream. */
|
|
14
|
+
chunkBytes?: number;
|
|
15
|
+
/** Clock used by interval mode — injectable for deterministic tests. */
|
|
16
|
+
now?: () => number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Live trial extraction from a byte source. Lazy and pull-based: no I/O
|
|
20
|
+
* happens before the first `next()`, and a slow consumer slows the source
|
|
21
|
+
* (the backpressure convention of `@mindpeeker/entropy` streams).
|
|
22
|
+
*
|
|
23
|
+
* Count mode (default) completes a trial every `bitsPerTrial` bits. Interval
|
|
24
|
+
* mode is GCP-style wall-clock bucketing: the first `bitsPerTrial` bits
|
|
25
|
+
* arriving inside each `intervalMs` bucket form that bucket's trial, extra
|
|
26
|
+
* bits in the bucket are discarded, and an underfilled bucket yields no trial
|
|
27
|
+
* — `Trial.index` is bucket-relative there, so missing buckets appear as
|
|
28
|
+
* index gaps.
|
|
29
|
+
*
|
|
30
|
+
* The source ending simply ends this stream; a source error is rethrown as
|
|
31
|
+
* `source_failed` (or `aborted` when the caller's signal fired).
|
|
32
|
+
*/
|
|
33
|
+
export declare function trialStream(source: TrialSource, config?: TrialStreamConfig): AsyncGenerator<Trial>;
|
|
34
|
+
//# sourceMappingURL=trials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trials.d.ts","sourceRoot":"","sources":["../../src/stats/trials.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE/E,eAAO,MAAM,sBAAsB,MAAM,CAAA;AAczC;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,WAAgB,GACvB,WAAW,CAiCb;AAED,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAuB,WAAW,CAChC,MAAM,EAAE,WAAW,EACnB,MAAM,GAAE,iBAAsB,GAC7B,cAAc,CAAC,KAAK,CAAC,CA0EvB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { NegentropyError } from '../errors.js';
|
|
2
|
+
import { POPCOUNT } from '../internal/bytes.js';
|
|
3
|
+
export const DEFAULT_BITS_PER_TRIAL = 200;
|
|
4
|
+
function validateBitsPerTrial(bitsPerTrial, source) {
|
|
5
|
+
const k = bitsPerTrial ?? DEFAULT_BITS_PER_TRIAL;
|
|
6
|
+
if (!Number.isInteger(k) || k < 8) {
|
|
7
|
+
throw new NegentropyError('invalid_config', `bitsPerTrial must be an integer ≥ 8, got ${bitsPerTrial}`, { source });
|
|
8
|
+
}
|
|
9
|
+
return k;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Batch trial extraction: slice a recorded byte buffer into trial sums — the
|
|
13
|
+
* number of one-bits among each run of `bitsPerTrial` consecutive bits
|
|
14
|
+
* (MSB-first). Under H0 each sum ~ Binomial(bitsPerTrial, ½). Trailing bits
|
|
15
|
+
* that do not fill a whole trial are dropped and reported via `leftoverBits`,
|
|
16
|
+
* never zero-padded.
|
|
17
|
+
*/
|
|
18
|
+
export function trialsFromBytes(bytes, source, config = {}) {
|
|
19
|
+
const k = validateBitsPerTrial(config.bitsPerTrial, source);
|
|
20
|
+
const totalBits = bytes.length * 8;
|
|
21
|
+
const count = Math.floor(totalBits / k);
|
|
22
|
+
const sums = new Float64Array(count);
|
|
23
|
+
if (k % 8 === 0) {
|
|
24
|
+
// fast path: trials are byte-aligned — sum popcounts
|
|
25
|
+
const bytesPerTrial = k / 8;
|
|
26
|
+
for (let t = 0; t < count; t++) {
|
|
27
|
+
let sum = 0;
|
|
28
|
+
const base = t * bytesPerTrial;
|
|
29
|
+
for (let i = 0; i < bytesPerTrial; i++)
|
|
30
|
+
sum += POPCOUNT[bytes[base + i] & 0xff];
|
|
31
|
+
sums[t] = sum;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
let sum = 0;
|
|
36
|
+
let bits = 0;
|
|
37
|
+
let t = 0;
|
|
38
|
+
for (let i = 0; i < bytes.length && t < count; i++) {
|
|
39
|
+
const byte = bytes[i];
|
|
40
|
+
for (let b = 7; b >= 0; b--) {
|
|
41
|
+
sum += (byte >> b) & 1;
|
|
42
|
+
if (++bits === k) {
|
|
43
|
+
sums[t++] = sum;
|
|
44
|
+
sum = 0;
|
|
45
|
+
bits = 0;
|
|
46
|
+
if (t === count)
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { source, bitsPerTrial: k, sums, leftoverBits: totalBits - count * k };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Live trial extraction from a byte source. Lazy and pull-based: no I/O
|
|
56
|
+
* happens before the first `next()`, and a slow consumer slows the source
|
|
57
|
+
* (the backpressure convention of `@mindpeeker/entropy` streams).
|
|
58
|
+
*
|
|
59
|
+
* Count mode (default) completes a trial every `bitsPerTrial` bits. Interval
|
|
60
|
+
* mode is GCP-style wall-clock bucketing: the first `bitsPerTrial` bits
|
|
61
|
+
* arriving inside each `intervalMs` bucket form that bucket's trial, extra
|
|
62
|
+
* bits in the bucket are discarded, and an underfilled bucket yields no trial
|
|
63
|
+
* — `Trial.index` is bucket-relative there, so missing buckets appear as
|
|
64
|
+
* index gaps.
|
|
65
|
+
*
|
|
66
|
+
* The source ending simply ends this stream; a source error is rethrown as
|
|
67
|
+
* `source_failed` (or `aborted` when the caller's signal fired).
|
|
68
|
+
*/
|
|
69
|
+
export async function* trialStream(source, config = {}) {
|
|
70
|
+
const k = validateBitsPerTrial(config.bitsPerTrial, source.name);
|
|
71
|
+
const clock = config.clock ?? { mode: 'count' };
|
|
72
|
+
if (clock.mode === 'interval' && (!Number.isFinite(clock.intervalMs) || clock.intervalMs <= 0)) {
|
|
73
|
+
throw new NegentropyError('invalid_config', `intervalMs must be > 0, got ${clock.intervalMs}`, {
|
|
74
|
+
source: source.name,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const now = config.now ?? (() => Date.now());
|
|
78
|
+
const signal = config.signal;
|
|
79
|
+
const abortError = () => new NegentropyError('aborted', 'trial stream aborted', { source: source.name });
|
|
80
|
+
if (signal?.aborted)
|
|
81
|
+
throw abortError();
|
|
82
|
+
let sum = 0;
|
|
83
|
+
let bits = 0;
|
|
84
|
+
let index = 0;
|
|
85
|
+
// interval-mode state
|
|
86
|
+
let activeBucket = Number.NEGATIVE_INFINITY;
|
|
87
|
+
let bucketFilled = false;
|
|
88
|
+
let firstBucket;
|
|
89
|
+
try {
|
|
90
|
+
for await (const chunk of source.stream({ signal, chunkBytes: config.chunkBytes })) {
|
|
91
|
+
if (signal?.aborted)
|
|
92
|
+
throw abortError();
|
|
93
|
+
const at = now();
|
|
94
|
+
if (clock.mode === 'interval') {
|
|
95
|
+
const bucket = Math.floor(at / clock.intervalMs);
|
|
96
|
+
if (bucket !== activeBucket) {
|
|
97
|
+
activeBucket = bucket;
|
|
98
|
+
sum = 0;
|
|
99
|
+
bits = 0;
|
|
100
|
+
bucketFilled = false;
|
|
101
|
+
}
|
|
102
|
+
if (bucketFilled)
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
106
|
+
const byte = chunk[i];
|
|
107
|
+
if (bits + 8 < k) {
|
|
108
|
+
sum += POPCOUNT[byte & 0xff];
|
|
109
|
+
bits += 8;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
for (let b = 7; b >= 0; b--) {
|
|
113
|
+
sum += (byte >> b) & 1;
|
|
114
|
+
if (++bits === k) {
|
|
115
|
+
if (clock.mode === 'interval') {
|
|
116
|
+
firstBucket ??= activeBucket;
|
|
117
|
+
bucketFilled = true;
|
|
118
|
+
yield { sum, index: activeBucket - firstBucket, at };
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
yield { sum, index: index++, at };
|
|
122
|
+
}
|
|
123
|
+
sum = 0;
|
|
124
|
+
bits = 0;
|
|
125
|
+
if (clock.mode === 'interval')
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (clock.mode === 'interval' && bucketFilled)
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
if (error instanceof NegentropyError)
|
|
136
|
+
throw error;
|
|
137
|
+
if (signal?.aborted) {
|
|
138
|
+
throw new NegentropyError('aborted', 'trial stream aborted', {
|
|
139
|
+
source: source.name,
|
|
140
|
+
cause: error,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
throw new NegentropyError('source_failed', `${source.name} stream failed`, {
|
|
144
|
+
source: source.name,
|
|
145
|
+
cause: error,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=trials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trials.js","sourceRoot":"","sources":["../../src/stats/trials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Calibration, TrialSeries } from '../types.js';
|
|
2
|
+
/** z_i = (sum_i − cal.mean) / cal.sd for every trial in the series. */
|
|
3
|
+
export declare function zScores(series: TrialSeries, cal: Calibration): Float64Array;
|
|
4
|
+
/**
|
|
5
|
+
* Stouffer's combined z: Σz / √n. Assumes the inputs are independent —
|
|
6
|
+
* correlated sources inflate its variance, which is exactly what
|
|
7
|
+
* `interSourceCorrelation` measures; do not "fix" it here.
|
|
8
|
+
*/
|
|
9
|
+
export declare function stoufferZ(zs: ArrayLike<number>): number;
|
|
10
|
+
//# sourceMappingURL=zscores.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zscores.d.ts","sourceRoot":"","sources":["../../src/stats/zscores.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE3D,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,GAAG,YAAY,CAW3E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAOvD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { NegentropyError } from '../errors.js';
|
|
2
|
+
/** z_i = (sum_i − cal.mean) / cal.sd for every trial in the series. */
|
|
3
|
+
export function zScores(series, cal) {
|
|
4
|
+
if (cal.source !== series.source || cal.bitsPerTrial !== series.bitsPerTrial) {
|
|
5
|
+
throw new NegentropyError('calibration_required', `calibration is for ${cal.source}@${cal.bitsPerTrial} bits, series is ${series.source}@${series.bitsPerTrial} bits`, { source: series.source });
|
|
6
|
+
}
|
|
7
|
+
const zs = new Float64Array(series.sums.length);
|
|
8
|
+
for (let i = 0; i < zs.length; i++)
|
|
9
|
+
zs[i] = (series.sums[i] - cal.mean) / cal.sd;
|
|
10
|
+
return zs;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Stouffer's combined z: Σz / √n. Assumes the inputs are independent —
|
|
14
|
+
* correlated sources inflate its variance, which is exactly what
|
|
15
|
+
* `interSourceCorrelation` measures; do not "fix" it here.
|
|
16
|
+
*/
|
|
17
|
+
export function stoufferZ(zs) {
|
|
18
|
+
if (zs.length === 0) {
|
|
19
|
+
throw new NegentropyError('insufficient_data', 'stoufferZ needs at least one z-score');
|
|
20
|
+
}
|
|
21
|
+
let sum = 0;
|
|
22
|
+
for (let i = 0; i < zs.length; i++)
|
|
23
|
+
sum += zs[i];
|
|
24
|
+
return sum / Math.sqrt(zs.length);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=zscores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zscores.js","sourceRoot":"","sources":["../../src/stats/zscores.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAG9C,uEAAuE;AACvE,MAAM,UAAU,OAAO,CAAC,MAAmB,EAAE,GAAgB;IAC3D,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,KAAK,MAAM,CAAC,YAAY,EAAE,CAAC;QAC7E,MAAM,IAAI,eAAe,CACvB,sBAAsB,EACtB,sBAAsB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,YAAY,oBAAoB,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,YAAY,OAAO,EACnH,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAC1B,CAAA;IACH,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAY,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAA;IAC5F,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,EAAqB;IAC7C,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,eAAe,CAAC,mBAAmB,EAAE,sCAAsC,CAAC,CAAA;IACxF,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAW,CAAA;IAC1D,OAAO,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;AACnC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal structural view of a live byte source. Any `@mindpeeker/entropy`
|
|
3
|
+
* EntropyProvider satisfies this — no import required.
|
|
4
|
+
*/
|
|
5
|
+
export interface TrialSource {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
stream(opts?: TrialStreamOptions): AsyncIterable<Uint8Array>;
|
|
8
|
+
}
|
|
9
|
+
export interface TrialStreamOptions {
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
/** Desired chunk size in bytes. Passed through to the source. */
|
|
12
|
+
chunkBytes?: number;
|
|
13
|
+
}
|
|
14
|
+
/** How raw bits are grouped into trials. */
|
|
15
|
+
export type TrialClock = {
|
|
16
|
+
mode: 'count';
|
|
17
|
+
} | {
|
|
18
|
+
mode: 'interval';
|
|
19
|
+
intervalMs: number;
|
|
20
|
+
};
|
|
21
|
+
export interface TrialConfig {
|
|
22
|
+
/** Bits summed per trial. Default 200 (GCP convention → Binomial(200, ½)). Minimum 8. */
|
|
23
|
+
bitsPerTrial?: number;
|
|
24
|
+
clock?: TrialClock;
|
|
25
|
+
}
|
|
26
|
+
/** One trial: the number of one-bits among bitsPerTrial raw bits. */
|
|
27
|
+
export interface Trial {
|
|
28
|
+
sum: number;
|
|
29
|
+
index: number;
|
|
30
|
+
/** Epoch ms of trial completion — set in live mode, absent in batch. */
|
|
31
|
+
at?: number;
|
|
32
|
+
}
|
|
33
|
+
/** A source's recorded trial data — the archival unit every analysis consumes. */
|
|
34
|
+
export interface TrialSeries {
|
|
35
|
+
readonly source: string;
|
|
36
|
+
readonly bitsPerTrial: number;
|
|
37
|
+
readonly sums: Float64Array;
|
|
38
|
+
readonly timestamps?: Float64Array;
|
|
39
|
+
/** Trailing bits that did not fill a whole trial (batch extraction only). */
|
|
40
|
+
readonly leftoverBits?: number;
|
|
41
|
+
}
|
|
42
|
+
/** Normalization parameters mapping one source's trial sums to z-scores. */
|
|
43
|
+
export interface Calibration {
|
|
44
|
+
readonly source: string;
|
|
45
|
+
readonly bitsPerTrial: number;
|
|
46
|
+
/** Trials the calibration was fit on (0 for theoretical). */
|
|
47
|
+
readonly trials: number;
|
|
48
|
+
readonly mean: number;
|
|
49
|
+
readonly sd: number;
|
|
50
|
+
readonly basis: 'empirical' | 'theoretical';
|
|
51
|
+
}
|
|
52
|
+
/** A test statistic with honest attribution of what went into it. */
|
|
53
|
+
export interface StatResult {
|
|
54
|
+
statistic: number;
|
|
55
|
+
df: number;
|
|
56
|
+
pValue: number;
|
|
57
|
+
/** Trials (or steps) that entered the statistic. */
|
|
58
|
+
n: number;
|
|
59
|
+
sources: readonly string[];
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,IAAI,CAAC,EAAE,kBAAkB,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;CAC7D;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,4CAA4C;AAC5C,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5C,MAAM,WAAW,WAAW;IAC1B,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB;AAED,qEAAqE;AACrE,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,YAAY,CAAA;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAAA;CAC5C;AAED,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,CAAC,EAAE,MAAM,CAAA;IACT,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mindpeeker/negentropy",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Measure order in noise and manufacture order from noise — GCP-style network statistics, negentropy estimators, and SP 800-90B extraction over any byte stream.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=20.3"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./numerics": {
|
|
20
|
+
"types": "./dist/numerics.d.ts",
|
|
21
|
+
"default": "./dist/numerics.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc -p tsconfig.build.json",
|
|
26
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
27
|
+
"test": "bun test"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"negentropy",
|
|
34
|
+
"entropy",
|
|
35
|
+
"randomness",
|
|
36
|
+
"statistics",
|
|
37
|
+
"gcp",
|
|
38
|
+
"rng",
|
|
39
|
+
"randomness-extractor",
|
|
40
|
+
"toeplitz",
|
|
41
|
+
"min-entropy",
|
|
42
|
+
"sp800-90b",
|
|
43
|
+
"stouffer",
|
|
44
|
+
"anomaly-detection"
|
|
45
|
+
]
|
|
46
|
+
}
|