docs: state filtered accessor cost and evidence semantics precisely
filtered_learning_curve's signature mirrors learning_curve, which is cheap per key — so the mirroring trained callers to assume this one is too. It is a full forward pass per call, making the natural loop over competitors O(competitors * events). The doc now says so in complexity terms and points multi-key callers at the plural form. filtered_log_evidence claimed each event is scored "using only what was known before it". That is exact for a slice holding one event, but events sharing a timestamp inform each other through the within-slice sweep, so the honest claim is "before that time". The behaviour is deliberate and matches log_evidence's own convention; only the promise was too strong. This branch exists because a feature's documentation was quietly false. Shipping it with two more overstated doc comments would be a poor joke. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T5SYDExxL4vZgvunrcNSMc
This commit is contained in:
+15
-8
@@ -383,7 +383,9 @@ impl<T: Time, D: Drift<T>, O: Observer<T>, K: Eq + Hash + Clone> History<T, D, O
|
||||
/// time — "what we knew then". Contrast `learning_curves`, whose points
|
||||
/// are smoothed and so incorporate rounds played later.
|
||||
///
|
||||
/// Runs a full forward pass per call and caches nothing.
|
||||
/// Runs a full forward pass per call and caches nothing. This is the
|
||||
/// entry point for multi-key work — see `filtered_learning_curve` for
|
||||
/// why calling that once per key is far more expensive.
|
||||
pub fn filtered_learning_curves(&self) -> HashMap<K, Vec<(T, Gaussian)>> {
|
||||
let mut data: HashMap<K, Vec<(T, Gaussian)>> = HashMap::new();
|
||||
|
||||
@@ -401,9 +403,11 @@ impl<T: Time, D: Drift<T>, O: Observer<T>, K: Eq + Hash + Clone> History<T, D, O
|
||||
/// Filtered learning curve for a single key: (time, posterior) pairs in
|
||||
/// time order.
|
||||
///
|
||||
/// Runs the same full pass as `filtered_learning_curves` and keeps one
|
||||
/// key, so asking for several keys individually costs a pass each — use
|
||||
/// the plural form for that.
|
||||
/// Despite mirroring `learning_curve`'s signature, this is not the cheap
|
||||
/// per-key lookup that method is: it runs a full forward pass, O(events),
|
||||
/// discarding every posterior but the requested key's. N keys fetched
|
||||
/// this way costs O(N * events); use `filtered_learning_curves` for
|
||||
/// multi-key work instead — it computes the same pass once.
|
||||
pub fn filtered_learning_curve<Q>(&self, key: &Q) -> Vec<(T, Gaussian)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
@@ -484,10 +488,13 @@ impl<T: Time, D: Drift<T>, O: Observer<T>, K: Eq + Hash + Clone> History<T, D, O
|
||||
|
||||
/// Total log-evidence under forward-only (filtering) information.
|
||||
///
|
||||
/// Each event is scored using only what was known before it, which is the
|
||||
/// right quantity for prequential scoring and model comparison. Contrast
|
||||
/// `log_evidence`, whose per-event priors carry information from events
|
||||
/// that had not happened yet.
|
||||
/// Each event is scored using only what was known before that *time*,
|
||||
/// which is the right quantity for prequential scoring and model
|
||||
/// comparison. Events sharing a timestamp still inform each other
|
||||
/// through the within-slice sweep, so within one slice this is not a
|
||||
/// guarantee that event A is scored independently of simultaneous event
|
||||
/// B. Contrast `log_evidence`, whose per-event priors carry information
|
||||
/// from events that had not happened yet.
|
||||
///
|
||||
/// Runs a full forward pass per call and caches nothing. The result does
|
||||
/// not depend on whether `converge` has been called.
|
||||
|
||||
Reference in New Issue
Block a user