refactor: one word per concept
Three vocabulary collisions, from #75. **"rating" meant three things**, one the opposite of the exported type. `Rating` is documented as static *configuration* — "this returns what it was told", against every other accessor's "what inference inferred". But `quality`'s parameter was `rating_groups: &[&[Gaussian]]` and its prose said "rating groups" four times, where "rating" means a *posterior* — the one thing `Rating` is documented not to be. Two error messages used it that way too. So a reader who learned `Rating = config` passed `Rating` values to `quality`, which takes `Gaussian`; and one who learned "rating = what comes out" was baffled that `h.rating(&k)` is not their skill. "rating" is now reserved for the type. `quality(teams: &[&[Gaussian]])`, and "every rating is finite" became "every posterior is finite". **"agent" was a private fourth name for a competitor** — ~200 identifiers against 236 uses of "competitor", and it leaked into two `pub` signatures on `TimeSlice`. Now that #73 has made those internal this is a pure rename, so the crate has one word for the entity throughout. **"player" survived in one public signature** — `free_for_all(players:)` plus two doc lines. Renamed, along with three internal closure bindings. Doc examples that use "player" as a *key* are left alone: that is a user's data, not the crate's vocabulary. The panic-message expectations in tests/quality.rs moved with the prose, which is the point of asserting on message text — the tests caught the rename rather than papering over it. Not touched: "performance" (always skill widened by beta), "skill", "member" and "team" are each used for exactly one thing already. Refs #75 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011hcFjNDmHXZF8URGLku5zZ
This commit is contained in:
+16
-14
@@ -284,7 +284,9 @@ impl<'a, T: Time, D: Drift<T>> Game<'a, T, D> {
|
||||
self.teams[t]
|
||||
.iter()
|
||||
.zip(self.weights[t].iter())
|
||||
.fold(N00, |p, (player, &w)| p + (player.performance() * w))
|
||||
.fold(N00, |p, (competitor, &w)| {
|
||||
p + (competitor.performance() * w)
|
||||
})
|
||||
}));
|
||||
|
||||
let n_diffs = n_teams.saturating_sub(1);
|
||||
@@ -361,18 +363,18 @@ impl<'a, T: Time, D: Drift<T>> Game<'a, T, D> {
|
||||
.iter()
|
||||
.zip(self.weights.iter())
|
||||
.enumerate()
|
||||
.map(|(orig_i, (players, weights))| {
|
||||
.map(|(orig_i, (competitors, weights))| {
|
||||
let si = arena.inv_buf[orig_i];
|
||||
let m = arena.lhood_win[si] * arena.lhood_lose[si];
|
||||
// Already folded into `team_prior` at the top of the chain,
|
||||
// indexed by sorted position.
|
||||
let performance = arena.team_prior[si];
|
||||
players
|
||||
competitors
|
||||
.iter()
|
||||
.zip(weights.iter())
|
||||
.map(|(player, &w)| {
|
||||
((m - performance.exclude(player.performance() * w)) * (1.0 / w))
|
||||
.forget(player.beta.powi(2))
|
||||
.map(|(competitor, &w)| {
|
||||
((m - performance.exclude(competitor.performance() * w)) * (1.0 / w))
|
||||
.forget(competitor.beta.powi(2))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
@@ -577,7 +579,7 @@ impl<T: Time, D: Drift<T>> Game<'_, T, D> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Convenience wrapper over [`Game::ranked`] for two single-player teams.
|
||||
/// Convenience wrapper over [`Game::ranked`] for two single-competitor teams.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
@@ -597,14 +599,14 @@ impl<T: Time, D: Drift<T>> Game<'_, T, D> {
|
||||
|
||||
/// # Errors
|
||||
///
|
||||
/// Wraps each player in a one-member team and delegates to
|
||||
/// Wraps each competitor in a one-member team and delegates to
|
||||
/// [`Game::ranked`], so it returns the same errors.
|
||||
pub fn free_for_all(
|
||||
players: &[&Rating<T, D>],
|
||||
competitors: &[&Rating<T, D>],
|
||||
outcome: crate::Outcome,
|
||||
options: &GameOptions,
|
||||
) -> Result<OwnedGame<T, D>, crate::InferenceError> {
|
||||
let teams: Vec<Vec<Rating<T, D>>> = players.iter().map(|p| vec![**p]).collect();
|
||||
let teams: Vec<Vec<Rating<T, D>>> = competitors.iter().map(|p| vec![**p]).collect();
|
||||
let team_refs: Vec<&[Rating<T, D>]> = teams.iter().map(|t| t.as_slice()).collect();
|
||||
Self::ranked(&team_refs, outcome, options)
|
||||
}
|
||||
@@ -1428,8 +1430,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn run_chain_honours_max_iter_in_convergence_options() {
|
||||
let players: Vec<R> = (0..4).map(|_| R::default()).collect();
|
||||
let teams: Vec<Vec<_>> = players.iter().map(|p| vec![*p]).collect();
|
||||
let competitors: Vec<R> = (0..4).map(|_| R::default()).collect();
|
||||
let teams: Vec<Vec<_>> = competitors.iter().map(|p| vec![*p]).collect();
|
||||
let result = vec![3.0, 2.0, 1.0, 0.0];
|
||||
let weights = vec![vec![1.0]; 4];
|
||||
|
||||
@@ -1476,8 +1478,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn run_chain_with_damping_converges_to_same_posterior() {
|
||||
let players: Vec<R> = (0..4).map(|_| R::default()).collect();
|
||||
let teams: Vec<Vec<_>> = players.iter().map(|p| vec![*p]).collect();
|
||||
let competitors: Vec<R> = (0..4).map(|_| R::default()).collect();
|
||||
let teams: Vec<Vec<_>> = competitors.iter().map(|p| vec![*p]).collect();
|
||||
let result = vec![3.0, 2.0, 1.0, 0.0];
|
||||
let weights = vec![vec![1.0]; 4];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user