feat(time_slice): inference callsites read self.convergence

The three Game::*_with_arena callsites in time_slice.rs (in
TimeSlice::iteration's sequential branch, TimeSlice::log_evidence's
run_event closure, and Event::iteration_direct via parameter) now use
the propagated ConvergenceOptions instead of hardcoded ::default().
sweep_color_groups (both rayon and non-rayon paths) forwards
self.convergence into Event::iteration_direct.

Damped EP (alpha < 1.0) and custom max_iter / epsilon set on
HistoryBuilder::convergence(opts) now actually reach the within-game
inference loop. Bit-equal for users on default options.

Removes the temporary #[allow(dead_code)] on TimeSlice::convergence
that was added in the prior commit.
This commit is contained in:
2026-05-08 15:32:25 +02:00
parent 872f91797d
commit 824b7f50b0
+25 -17
View File
@@ -133,25 +133,21 @@ impl Event {
skills: &mut SkillStore,
agents: &CompetitorStore<T, D>,
p_draw: f64,
convergence: crate::ConvergenceOptions,
arena: &mut ScratchArena,
) {
let teams = self.within_priors(false, false, skills, agents);
let result = self.outputs();
let g = match self.kind {
EventKind::Ranked => Game::ranked_with_arena(
teams,
&result,
&self.weights,
p_draw,
crate::ConvergenceOptions::default(),
arena,
),
EventKind::Ranked => {
Game::ranked_with_arena(teams, &result, &self.weights, p_draw, convergence, arena)
}
EventKind::Scored { score_sigma } => Game::scored_with_arena(
teams,
&result,
&self.weights,
score_sigma,
crate::ConvergenceOptions::default(),
convergence,
arena,
),
};
@@ -175,7 +171,6 @@ pub struct TimeSlice<T: Time = i64> {
pub(crate) skills: SkillStore,
pub(crate) time: T,
p_draw: f64,
#[allow(dead_code)]
pub(crate) convergence: crate::ConvergenceOptions,
arena: ScratchArena,
pub(crate) color_groups: ColorGroups,
@@ -335,7 +330,7 @@ impl<T: Time> TimeSlice<T> {
&result,
&event.weights,
self.p_draw,
crate::ConvergenceOptions::default(),
self.convergence,
&mut self.arena,
),
EventKind::Scored { score_sigma } => Game::scored_with_arena(
@@ -343,7 +338,7 @@ impl<T: Time> TimeSlice<T> {
&result,
&event.weights,
score_sigma,
crate::ConvergenceOptions::default(),
self.convergence,
&mut self.arena,
),
};
@@ -397,6 +392,7 @@ impl<T: Time> TimeSlice<T> {
}
let range = self.color_groups.color_range(color_idx);
let p_draw = self.p_draw;
let convergence = self.convergence;
if group_len >= RAYON_THRESHOLD {
// Obtain a raw pointer from the unique `&mut self.skills` reference.
@@ -414,12 +410,18 @@ impl<T: Time> TimeSlice<T> {
ARENA.with(|cell| {
let mut arena = cell.borrow_mut();
arena.reset();
ev.iteration_direct(skills, agents, p_draw, &mut arena);
ev.iteration_direct(skills, agents, p_draw, convergence, &mut arena);
});
});
} else {
for ev in &mut self.events[range] {
ev.iteration_direct(&mut self.skills, agents, p_draw, &mut self.arena);
ev.iteration_direct(
&mut self.skills,
agents,
p_draw,
self.convergence,
&mut self.arena,
);
}
}
}
@@ -441,7 +443,13 @@ impl<T: Time> TimeSlice<T> {
// allowed within a single method body.
let p_draw = self.p_draw;
for ev in &mut self.events[range] {
ev.iteration_direct(&mut self.skills, agents, p_draw, &mut self.arena);
ev.iteration_direct(
&mut self.skills,
agents,
p_draw,
self.convergence,
&mut self.arena,
);
}
}
}
@@ -527,7 +535,7 @@ impl<T: Time> TimeSlice<T> {
&result,
&event.weights,
self.p_draw,
crate::ConvergenceOptions::default(),
self.convergence,
arena,
)
.evidence
@@ -537,7 +545,7 @@ impl<T: Time> TimeSlice<T> {
&result,
&event.weights,
score_sigma,
crate::ConvergenceOptions::default(),
self.convergence,
arena,
)
.evidence