mirror of
https://github.com/logos-blockchain/research.git
synced 2026-08-07 19:53:10 +00:00
40 lines
1.4 KiB
Python
40 lines
1.4 KiB
Python
"""Multi-epoch trajectory driver for a single config."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
import numpy as np
|
|
|
|
from . import tsi
|
|
from .config import SimConfig
|
|
from .epoch import simulate_epoch
|
|
from .metrics import metric_row
|
|
from .rng import seedseq_for
|
|
from .stake import make_stake
|
|
|
|
|
|
def run_trajectory(config: SimConfig) -> list[dict[str, Any]]:
|
|
"""Run ``config.epochs`` epochs of TSI, returning one metric row per epoch.
|
|
|
|
Stake is drawn once (it is fixed; only ``D_est`` evolves). ``D_est`` starts at the
|
|
hardcoded genesis value ``genesis_d_factor * D_true`` and is updated each epoch from
|
|
the measured density. The RNG is a spawn hierarchy off the config's root SeedSequence:
|
|
child 0 draws the stake, child ``e+1`` drives epoch ``e`` — so every draw is a
|
|
deterministic, order-independent function of the config identity.
|
|
"""
|
|
root = seedseq_for(config)
|
|
children = root.spawn(config.epochs + 1)
|
|
stake = make_stake(config, np.random.default_rng(children[0]))
|
|
d_true = float(stake.sum())
|
|
d_est = config.genesis_d_factor * d_true
|
|
T = config.period_T
|
|
|
|
rows: list[dict[str, Any]] = []
|
|
for epoch in range(config.epochs):
|
|
er = simulate_epoch(config, stake, d_est, children[epoch + 1])
|
|
d_next = tsi.update_D(d_est, er.m, T, config.f, config.beta, config.fixed_point)
|
|
rows.append(metric_row(config, epoch, d_est, d_next, d_true, er))
|
|
d_est = d_next
|
|
return rows
|