feat(outcome): per-event score_sigma override on Outcome::Scored
Outcome::Scored shape changes from tuple to struct:
{ scores, sigma: Option<f64> }. New constructor scores_with_sigma
sets sigma=Some(s) and debug-asserts s > 0.0; existing scores(I)
constructor keeps its signature and builds with sigma=None internally.
team_count, as_scores, as_ranks accessor pattern matches updated.
History::add_events resolves sigma.unwrap_or(self.score_sigma) at the
ingest arm, so downstream EventKind::Scored stays a plain f64 and
TimeSlice / run_chain need zero changes.
Breaking change to the public Outcome::Scored variant shape
(acceptable in 0.1.x). Bit-equal for callers using the no-override
path because the resolution falls through to self.score_sigma exactly
as before.
This commit is contained in:
+7
-2
@@ -732,9 +732,14 @@ impl<T: Time, D: Drift<T>, O: Observer<T>, K: Eq + Hash + Clone> History<T, D, O
|
||||
kinds.push(EventKind::Ranked);
|
||||
ranks.iter().map(|&r| max_rank - r as f64).collect()
|
||||
}
|
||||
crate::Outcome::Scored(scores) => {
|
||||
crate::Outcome::Scored { scores, sigma } => {
|
||||
let resolved = sigma.unwrap_or(self.score_sigma);
|
||||
debug_assert!(
|
||||
resolved > 0.0,
|
||||
"resolved score_sigma must be > 0.0 (got {resolved})"
|
||||
);
|
||||
kinds.push(EventKind::Scored {
|
||||
score_sigma: self.score_sigma,
|
||||
score_sigma: resolved,
|
||||
});
|
||||
scores.to_vec()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user