pub trait UpdateRule {
type Params: Clone;
type Step;
const LANES: usize;
fn step(params: &Self::Params, t: usize) -> Self::Step;
fn strategy_from_lanes(
params: &Self::Params,
regret: &[f32],
last_inst: &[f32],
regret_discount: f32,
out: &mut [f32],
);
fn pre_discount(step: &Self::Step) -> f32;
fn post_discount(step: &Self::Step) -> f32;
fn accumulate_regret(step: &Self::Step, old_regret: f32, reward: f32, expected: f32) -> f32;
fn strategy_accumulation(step: &Self::Step) -> (f32, f32);
fn regret_weight_step(step: &Self::Step, old_w: f32) -> f32;
fn regret_weight_total(params: &Self::Params, t: usize, accum_w: f32) -> f32;
}
#[cfg(test)]
mod tests {
use super::*;
struct MockRule;
impl UpdateRule for MockRule {
type Params = ();
type Step = ();
const LANES: usize = 2;
fn step(_: &Self::Params, _t: usize) -> Self::Step {}
fn strategy_from_lanes(
_: &Self::Params,
regret: &[f32],
_last_inst: &[f32],
_regret_discount: f32,
out: &mut [f32],
) {
crate::regret_minimizer::regret_match(regret, out);
}
fn pre_discount(_: &Self::Step) -> f32 {
0.0
}
fn post_discount(_: &Self::Step) -> f32 {
0.0
}
fn accumulate_regret(_: &Self::Step, old_r: f32, reward: f32, expected: f32) -> f32 {
old_r + (reward - expected)
}
fn strategy_accumulation(_: &Self::Step) -> (f32, f32) {
(1.0, 1.0)
}
fn regret_weight_step(_: &Self::Step, old_w: f32) -> f32 {
old_w + 1.0
}
fn regret_weight_total(_: &Self::Params, _t: usize, accum_w: f32) -> f32 {
accum_w
}
}
#[test]
fn strategy_from_zero_regret_is_uniform() {
let mut out = [0.0f32; 3];
MockRule::strategy_from_lanes(&(), &[0.0, 0.0, 0.0], &[0.0, 0.0, 0.0], 0.0, &mut out);
assert!(out.iter().all(|&v| (v - 1.0 / 3.0).abs() < 1e-6));
}
#[test]
fn non_predictive_is_two_lane() {
assert_eq!(MockRule::LANES, 2);
}
}