@timmeck/brain-core 2.5.0 → 2.6.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/dist/index.d.ts +18 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/research/adaptive-strategy.d.ts +56 -0
- package/dist/research/adaptive-strategy.js +236 -0
- package/dist/research/adaptive-strategy.js.map +1 -0
- package/dist/research/agenda-engine.d.ts +46 -0
- package/dist/research/agenda-engine.js +264 -0
- package/dist/research/agenda-engine.js.map +1 -0
- package/dist/research/anomaly-detective.d.ts +62 -0
- package/dist/research/anomaly-detective.js +318 -0
- package/dist/research/anomaly-detective.js.map +1 -0
- package/dist/research/counterfactual-engine.d.ts +63 -0
- package/dist/research/counterfactual-engine.js +263 -0
- package/dist/research/counterfactual-engine.js.map +1 -0
- package/dist/research/cross-domain-engine.d.ts +52 -0
- package/dist/research/cross-domain-engine.js +283 -0
- package/dist/research/cross-domain-engine.js.map +1 -0
- package/dist/research/experiment-engine.d.ts +77 -0
- package/dist/research/experiment-engine.js +328 -0
- package/dist/research/experiment-engine.js.map +1 -0
- package/dist/research/journal.d.ts +62 -0
- package/dist/research/journal.js +262 -0
- package/dist/research/journal.js.map +1 -0
- package/dist/research/knowledge-distiller.d.ts +95 -0
- package/dist/research/knowledge-distiller.js +426 -0
- package/dist/research/knowledge-distiller.js.map +1 -0
- package/dist/research/self-observer.d.ts +55 -0
- package/dist/research/self-observer.js +268 -0
- package/dist/research/self-observer.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { getLogger } from '../utils/logger.js';
|
|
2
|
+
// ── Migration ───────────────────────────────────────────
|
|
3
|
+
export function runCrossDomainMigration(db) {
|
|
4
|
+
db.exec(`
|
|
5
|
+
CREATE TABLE IF NOT EXISTS cross_domain_events (
|
|
6
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
7
|
+
brain TEXT NOT NULL,
|
|
8
|
+
event_type TEXT NOT NULL,
|
|
9
|
+
timestamp INTEGER NOT NULL,
|
|
10
|
+
data TEXT,
|
|
11
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
12
|
+
);
|
|
13
|
+
CREATE INDEX IF NOT EXISTS idx_xd_events_brain ON cross_domain_events(brain);
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_xd_events_ts ON cross_domain_events(timestamp);
|
|
15
|
+
|
|
16
|
+
CREATE TABLE IF NOT EXISTS cross_domain_correlations (
|
|
17
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
+
timestamp INTEGER NOT NULL,
|
|
19
|
+
source_brain TEXT NOT NULL,
|
|
20
|
+
source_event TEXT NOT NULL,
|
|
21
|
+
target_brain TEXT NOT NULL,
|
|
22
|
+
target_event TEXT NOT NULL,
|
|
23
|
+
correlation REAL NOT NULL,
|
|
24
|
+
lag_seconds INTEGER NOT NULL,
|
|
25
|
+
p_value REAL NOT NULL,
|
|
26
|
+
effect_size REAL NOT NULL,
|
|
27
|
+
direction TEXT NOT NULL,
|
|
28
|
+
narrative TEXT NOT NULL,
|
|
29
|
+
sample_size INTEGER NOT NULL,
|
|
30
|
+
confirmed INTEGER DEFAULT 0,
|
|
31
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
32
|
+
);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_xd_corr_brains ON cross_domain_correlations(source_brain, target_brain);
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
// ── Engine ──────────────────────────────────────────────
|
|
37
|
+
export class CrossDomainEngine {
|
|
38
|
+
db;
|
|
39
|
+
config;
|
|
40
|
+
log = getLogger();
|
|
41
|
+
constructor(db, config) {
|
|
42
|
+
this.db = db;
|
|
43
|
+
this.config = {
|
|
44
|
+
windowMs: config?.windowMs ?? 7_200_000,
|
|
45
|
+
minCorrelation: config?.minCorrelation ?? 0.3,
|
|
46
|
+
alpha: config?.alpha ?? 0.05,
|
|
47
|
+
maxEvents: config?.maxEvents ?? 10_000,
|
|
48
|
+
};
|
|
49
|
+
runCrossDomainMigration(db);
|
|
50
|
+
}
|
|
51
|
+
/** Record an event from a brain. */
|
|
52
|
+
recordEvent(brain, eventType, data) {
|
|
53
|
+
this.db.prepare(`
|
|
54
|
+
INSERT INTO cross_domain_events (brain, event_type, timestamp, data)
|
|
55
|
+
VALUES (?, ?, ?, ?)
|
|
56
|
+
`).run(brain, eventType, Date.now(), data ? JSON.stringify(data) : null);
|
|
57
|
+
// Cleanup old events
|
|
58
|
+
const count = this.db.prepare(`SELECT COUNT(*) as c FROM cross_domain_events`).get().c;
|
|
59
|
+
if (count > this.config.maxEvents) {
|
|
60
|
+
this.db.prepare(`
|
|
61
|
+
DELETE FROM cross_domain_events WHERE id IN (
|
|
62
|
+
SELECT id FROM cross_domain_events ORDER BY timestamp ASC LIMIT ?
|
|
63
|
+
)
|
|
64
|
+
`).run(count - this.config.maxEvents);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Run cross-domain correlation analysis. */
|
|
68
|
+
analyze() {
|
|
69
|
+
const brains = this.db.prepare(`
|
|
70
|
+
SELECT DISTINCT brain FROM cross_domain_events
|
|
71
|
+
`).all();
|
|
72
|
+
if (brains.length < 2)
|
|
73
|
+
return [];
|
|
74
|
+
const cutoff = Date.now() - this.config.windowMs * 10; // Analyze 10 windows of data
|
|
75
|
+
const discoveries = [];
|
|
76
|
+
// Get all event types per brain
|
|
77
|
+
const brainEvents = new Map();
|
|
78
|
+
for (const { brain } of brains) {
|
|
79
|
+
const types = this.db.prepare(`
|
|
80
|
+
SELECT DISTINCT event_type FROM cross_domain_events
|
|
81
|
+
WHERE brain = ? AND timestamp > ?
|
|
82
|
+
`).all(brain, cutoff);
|
|
83
|
+
brainEvents.set(brain, types.map(t => t.event_type));
|
|
84
|
+
}
|
|
85
|
+
// Cross-correlate every pair from different brains
|
|
86
|
+
const brainList = [...brainEvents.keys()];
|
|
87
|
+
for (let i = 0; i < brainList.length; i++) {
|
|
88
|
+
for (let j = i + 1; j < brainList.length; j++) {
|
|
89
|
+
const brainA = brainList[i];
|
|
90
|
+
const brainB = brainList[j];
|
|
91
|
+
const typesA = brainEvents.get(brainA) ?? [];
|
|
92
|
+
const typesB = brainEvents.get(brainB) ?? [];
|
|
93
|
+
for (const typeA of typesA) {
|
|
94
|
+
for (const typeB of typesB) {
|
|
95
|
+
const corr = this.computeCorrelation(brainA, typeA, brainB, typeB, cutoff);
|
|
96
|
+
if (corr && Math.abs(corr.correlation) >= this.config.minCorrelation && corr.p_value < this.config.alpha) {
|
|
97
|
+
discoveries.push(corr);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Persist new discoveries
|
|
104
|
+
for (const d of discoveries) {
|
|
105
|
+
this.persistCorrelation(d);
|
|
106
|
+
}
|
|
107
|
+
return discoveries;
|
|
108
|
+
}
|
|
109
|
+
/** Get all found correlations. */
|
|
110
|
+
getCorrelations(limit = 20) {
|
|
111
|
+
return this.db.prepare(`
|
|
112
|
+
SELECT * FROM cross_domain_correlations
|
|
113
|
+
ORDER BY ABS(correlation) DESC LIMIT ?
|
|
114
|
+
`).all(limit).map(r => this.rowToCorrelation(r));
|
|
115
|
+
}
|
|
116
|
+
/** Generate a narrative summary of the most important cross-domain findings. */
|
|
117
|
+
getNarrative() {
|
|
118
|
+
const correlations = this.getCorrelations(10);
|
|
119
|
+
if (correlations.length === 0)
|
|
120
|
+
return 'No cross-domain correlations discovered yet.';
|
|
121
|
+
const lines = ['Cross-Domain Research Narrative:\n'];
|
|
122
|
+
for (const c of correlations) {
|
|
123
|
+
lines.push(`- ${c.narrative}`);
|
|
124
|
+
lines.push(` (r=${c.correlation.toFixed(2)}, p=${c.p_value.toFixed(3)}, d=${c.effect_size.toFixed(2)}, lag=${c.lag_seconds}s, n=${c.sample_size})`);
|
|
125
|
+
lines.push('');
|
|
126
|
+
}
|
|
127
|
+
return lines.join('\n');
|
|
128
|
+
}
|
|
129
|
+
computeCorrelation(brainA, typeA, brainB, typeB, since) {
|
|
130
|
+
// Get event timestamps for both
|
|
131
|
+
const eventsA = this.db.prepare(`
|
|
132
|
+
SELECT timestamp FROM cross_domain_events
|
|
133
|
+
WHERE brain = ? AND event_type = ? AND timestamp > ?
|
|
134
|
+
ORDER BY timestamp
|
|
135
|
+
`).all(brainA, typeA, since);
|
|
136
|
+
const eventsB = this.db.prepare(`
|
|
137
|
+
SELECT timestamp FROM cross_domain_events
|
|
138
|
+
WHERE brain = ? AND event_type = ? AND timestamp > ?
|
|
139
|
+
ORDER BY timestamp
|
|
140
|
+
`).all(brainB, typeB, since);
|
|
141
|
+
if (eventsA.length < 3 || eventsB.length < 3)
|
|
142
|
+
return null;
|
|
143
|
+
// Compute temporal cross-correlation with varying lag
|
|
144
|
+
// Bin events into time windows
|
|
145
|
+
const binSize = this.config.windowMs;
|
|
146
|
+
const minTs = Math.min(eventsA[0].timestamp, eventsB[0].timestamp);
|
|
147
|
+
const maxTs = Math.max(eventsA[eventsA.length - 1].timestamp, eventsB[eventsB.length - 1].timestamp);
|
|
148
|
+
const numBins = Math.ceil((maxTs - minTs) / binSize);
|
|
149
|
+
if (numBins < 3)
|
|
150
|
+
return null;
|
|
151
|
+
const binsA = new Array(numBins).fill(0);
|
|
152
|
+
const binsB = new Array(numBins).fill(0);
|
|
153
|
+
for (const e of eventsA) {
|
|
154
|
+
const bin = Math.min(numBins - 1, Math.floor((e.timestamp - minTs) / binSize));
|
|
155
|
+
binsA[bin]++;
|
|
156
|
+
}
|
|
157
|
+
for (const e of eventsB) {
|
|
158
|
+
const bin = Math.min(numBins - 1, Math.floor((e.timestamp - minTs) / binSize));
|
|
159
|
+
binsB[bin]++;
|
|
160
|
+
}
|
|
161
|
+
// Pearson correlation at different lags (-2 to +2 bins)
|
|
162
|
+
let bestCorr = 0;
|
|
163
|
+
let bestLag = 0;
|
|
164
|
+
for (let lag = -2; lag <= 2; lag++) {
|
|
165
|
+
const r = pearsonCorrelation(binsA, binsB, lag);
|
|
166
|
+
if (Math.abs(r) > Math.abs(bestCorr)) {
|
|
167
|
+
bestCorr = r;
|
|
168
|
+
bestLag = lag;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (Math.abs(bestCorr) < this.config.minCorrelation)
|
|
172
|
+
return null;
|
|
173
|
+
// Approximate p-value for Pearson correlation
|
|
174
|
+
const n = Math.min(binsA.length, binsB.length) - Math.abs(bestLag);
|
|
175
|
+
const t = bestCorr * Math.sqrt((n - 2) / (1 - bestCorr * bestCorr));
|
|
176
|
+
const pValue = n > 2 ? approxPValue(Math.abs(t), n - 2) : 1;
|
|
177
|
+
const narrative = this.generateNarrative(brainA, typeA, brainB, typeB, bestCorr, bestLag * binSize / 1000);
|
|
178
|
+
return {
|
|
179
|
+
timestamp: Date.now(),
|
|
180
|
+
source_brain: brainA,
|
|
181
|
+
source_event: typeA,
|
|
182
|
+
target_brain: brainB,
|
|
183
|
+
target_event: typeB,
|
|
184
|
+
correlation: bestCorr,
|
|
185
|
+
lag_seconds: Math.round(bestLag * binSize / 1000),
|
|
186
|
+
p_value: pValue,
|
|
187
|
+
effect_size: Math.abs(bestCorr), // r as effect size
|
|
188
|
+
direction: bestCorr > 0 ? 'positive' : 'negative',
|
|
189
|
+
narrative,
|
|
190
|
+
sample_size: eventsA.length + eventsB.length,
|
|
191
|
+
confirmed: false,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
generateNarrative(brainA, typeA, brainB, typeB, correlation, lagSeconds) {
|
|
195
|
+
const direction = correlation > 0 ? 'increases' : 'decreases';
|
|
196
|
+
const strength = Math.abs(correlation) > 0.7 ? 'strongly' : Math.abs(correlation) > 0.5 ? 'moderately' : 'weakly';
|
|
197
|
+
const lagStr = lagSeconds === 0 ? 'simultaneously' :
|
|
198
|
+
lagSeconds > 0 ? `${lagSeconds}s later` : `${Math.abs(lagSeconds)}s before`;
|
|
199
|
+
return `When ${brainA} reports "${typeA}", ${brainB}'s "${typeB}" ${strength} ${direction} (${lagStr}).`;
|
|
200
|
+
}
|
|
201
|
+
persistCorrelation(corr) {
|
|
202
|
+
// Upsert: update if same pair exists
|
|
203
|
+
const existing = this.db.prepare(`
|
|
204
|
+
SELECT id FROM cross_domain_correlations
|
|
205
|
+
WHERE source_brain = ? AND source_event = ? AND target_brain = ? AND target_event = ?
|
|
206
|
+
`).get(corr.source_brain, corr.source_event, corr.target_brain, corr.target_event);
|
|
207
|
+
if (existing) {
|
|
208
|
+
this.db.prepare(`
|
|
209
|
+
UPDATE cross_domain_correlations
|
|
210
|
+
SET correlation = ?, lag_seconds = ?, p_value = ?, effect_size = ?,
|
|
211
|
+
direction = ?, narrative = ?, sample_size = ?, timestamp = ?
|
|
212
|
+
WHERE source_brain = ? AND source_event = ? AND target_brain = ? AND target_event = ?
|
|
213
|
+
`).run(corr.correlation, corr.lag_seconds, corr.p_value, corr.effect_size, corr.direction, corr.narrative, corr.sample_size, corr.timestamp, corr.source_brain, corr.source_event, corr.target_brain, corr.target_event);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
this.db.prepare(`
|
|
217
|
+
INSERT INTO cross_domain_correlations
|
|
218
|
+
(timestamp, source_brain, source_event, target_brain, target_event,
|
|
219
|
+
correlation, lag_seconds, p_value, effect_size, direction, narrative, sample_size)
|
|
220
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
221
|
+
`).run(corr.timestamp, corr.source_brain, corr.source_event, corr.target_brain, corr.target_event, corr.correlation, corr.lag_seconds, corr.p_value, corr.effect_size, corr.direction, corr.narrative, corr.sample_size);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
rowToCorrelation(row) {
|
|
225
|
+
return {
|
|
226
|
+
id: row.id,
|
|
227
|
+
timestamp: row.timestamp,
|
|
228
|
+
source_brain: row.source_brain,
|
|
229
|
+
source_event: row.source_event,
|
|
230
|
+
target_brain: row.target_brain,
|
|
231
|
+
target_event: row.target_event,
|
|
232
|
+
correlation: row.correlation,
|
|
233
|
+
lag_seconds: row.lag_seconds,
|
|
234
|
+
p_value: row.p_value,
|
|
235
|
+
effect_size: row.effect_size,
|
|
236
|
+
direction: row.direction,
|
|
237
|
+
narrative: row.narrative,
|
|
238
|
+
sample_size: row.sample_size,
|
|
239
|
+
confirmed: row.confirmed === 1,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// ── Helper Functions ────────────────────────────────────
|
|
244
|
+
function pearsonCorrelation(a, b, lag = 0) {
|
|
245
|
+
const n = Math.min(a.length, b.length) - Math.abs(lag);
|
|
246
|
+
if (n < 3)
|
|
247
|
+
return 0;
|
|
248
|
+
let sumA = 0, sumB = 0;
|
|
249
|
+
const offsetA = lag > 0 ? lag : 0;
|
|
250
|
+
const offsetB = lag < 0 ? -lag : 0;
|
|
251
|
+
for (let i = 0; i < n; i++) {
|
|
252
|
+
sumA += a[i + offsetA];
|
|
253
|
+
sumB += b[i + offsetB];
|
|
254
|
+
}
|
|
255
|
+
const meanA = sumA / n;
|
|
256
|
+
const meanB = sumB / n;
|
|
257
|
+
let cov = 0, varA = 0, varB = 0;
|
|
258
|
+
for (let i = 0; i < n; i++) {
|
|
259
|
+
const dA = a[i + offsetA] - meanA;
|
|
260
|
+
const dB = b[i + offsetB] - meanB;
|
|
261
|
+
cov += dA * dB;
|
|
262
|
+
varA += dA * dA;
|
|
263
|
+
varB += dB * dB;
|
|
264
|
+
}
|
|
265
|
+
const denom = Math.sqrt(varA * varB);
|
|
266
|
+
return denom === 0 ? 0 : cov / denom;
|
|
267
|
+
}
|
|
268
|
+
function approxPValue(t, df) {
|
|
269
|
+
if (df <= 0)
|
|
270
|
+
return 1;
|
|
271
|
+
// Normal approximation for large df
|
|
272
|
+
const z = t * (1 - 1 / (4 * df)) / Math.sqrt(1 + t * t / (2 * df));
|
|
273
|
+
return 2 * (1 - normalCDF(z));
|
|
274
|
+
}
|
|
275
|
+
function normalCDF(x) {
|
|
276
|
+
const a1 = 0.254829592, a2 = -0.284496736, a3 = 1.421413741, a4 = -1.453152027, a5 = 1.061405429;
|
|
277
|
+
const p = 0.3275911;
|
|
278
|
+
const sign = x < 0 ? -1 : 1;
|
|
279
|
+
const t = 1.0 / (1.0 + p * Math.abs(x));
|
|
280
|
+
const y = 1.0 - ((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * Math.exp(-x * x / 2);
|
|
281
|
+
return 0.5 * (1.0 + sign * y);
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=cross-domain-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-domain-engine.js","sourceRoot":"","sources":["../../src/research/cross-domain-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
export type ExperimentStatus = 'planned' | 'running_control' | 'running_treatment' | 'analyzing' | 'complete' | 'aborted';
|
|
3
|
+
export interface Experiment {
|
|
4
|
+
id?: number;
|
|
5
|
+
name: string;
|
|
6
|
+
hypothesis: string;
|
|
7
|
+
independent_variable: string;
|
|
8
|
+
dependent_variable: string;
|
|
9
|
+
control_value: number;
|
|
10
|
+
treatment_value: number;
|
|
11
|
+
duration_cycles: number;
|
|
12
|
+
status: ExperimentStatus;
|
|
13
|
+
control_results: number[];
|
|
14
|
+
treatment_results: number[];
|
|
15
|
+
current_cycle: number;
|
|
16
|
+
conclusion: ExperimentConclusion | null;
|
|
17
|
+
created_at?: string;
|
|
18
|
+
completed_at?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ExperimentConclusion {
|
|
21
|
+
significant: boolean;
|
|
22
|
+
p_value: number;
|
|
23
|
+
effect_size: number;
|
|
24
|
+
direction: 'positive' | 'negative' | 'neutral';
|
|
25
|
+
recommendation: 'adopt_treatment' | 'keep_control' | 'inconclusive_extend';
|
|
26
|
+
control_mean: number;
|
|
27
|
+
treatment_mean: number;
|
|
28
|
+
control_std: number;
|
|
29
|
+
treatment_std: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ExperimentProposal {
|
|
32
|
+
name: string;
|
|
33
|
+
hypothesis: string;
|
|
34
|
+
independent_variable: string;
|
|
35
|
+
dependent_variable: string;
|
|
36
|
+
control_value: number;
|
|
37
|
+
treatment_value: number;
|
|
38
|
+
duration_cycles?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface ExperimentEngineConfig {
|
|
41
|
+
brainName: string;
|
|
42
|
+
/** Default experiment duration in cycles. Default: 10 */
|
|
43
|
+
defaultDuration?: number;
|
|
44
|
+
/** Significance level for hypothesis testing. Default: 0.05 */
|
|
45
|
+
alpha?: number;
|
|
46
|
+
/** Maximum concurrent experiments. Default: 3 */
|
|
47
|
+
maxConcurrent?: number;
|
|
48
|
+
}
|
|
49
|
+
export declare function runExperimentMigration(db: Database.Database): void;
|
|
50
|
+
export declare class ExperimentEngine {
|
|
51
|
+
private db;
|
|
52
|
+
private config;
|
|
53
|
+
private log;
|
|
54
|
+
constructor(db: Database.Database, config: ExperimentEngineConfig);
|
|
55
|
+
/** Propose a new experiment. */
|
|
56
|
+
propose(proposal: ExperimentProposal): Experiment;
|
|
57
|
+
/** Start an experiment (transitions from planned to running_control). */
|
|
58
|
+
start(experimentId: number): Experiment | null;
|
|
59
|
+
/** Record a measurement for the current phase of an experiment. */
|
|
60
|
+
recordMeasurement(experimentId: number, value: number): Experiment | null;
|
|
61
|
+
/** Analyze a completed experiment. */
|
|
62
|
+
analyze(experimentId: number): Experiment | null;
|
|
63
|
+
/** Abort a running experiment. */
|
|
64
|
+
abort(experimentId: number): boolean;
|
|
65
|
+
/** Get a single experiment by ID. */
|
|
66
|
+
get(id: number): Experiment | null;
|
|
67
|
+
/** List experiments by status. */
|
|
68
|
+
list(status?: ExperimentStatus, limit?: number): Experiment[];
|
|
69
|
+
/** Get currently running experiments. */
|
|
70
|
+
getRunning(): Experiment[];
|
|
71
|
+
/** Get results of completed experiments. */
|
|
72
|
+
getResults(limit?: number): Experiment[];
|
|
73
|
+
/** Calculate minimum required sample size for a desired effect size. */
|
|
74
|
+
getMinimumSampleSize(expectedEffectSize: number): number;
|
|
75
|
+
private completeExperiment;
|
|
76
|
+
private rowToExperiment;
|
|
77
|
+
}
|