#[derive(Debug, Clone, Copy)]
pub struct Weights {
pub w_nb: f32,
pub w_mn: f32,
pub w_fp: f32,
}
pub fn weights_at(t: usize, phase_iters: &[usize; 3]) -> Weights {
let p1 = phase_iters[0];
let p2 = phase_iters[1];
if t <= p1 {
let progress = if p1 > 1 { (t - 1) as f32 / (p1 - 1) as f32 } else { 1.0 };
let w_mn = 1000.0 * (1.0 - progress) + 3.0 * progress;
Weights { w_nb: 2.0, w_mn, w_fp: 1.0 }
} else if t <= p1 + p2 {
Weights { w_nb: 3.0, w_mn: 3.0, w_fp: 1.0 }
} else {
Weights { w_nb: 1.0, w_mn: 0.0, w_fp: 1.0 }
}
}
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_abs_diff_eq;
#[test]
fn phase_1_start() {
let w = weights_at(1, &[100, 100, 250]);
assert_abs_diff_eq!(w.w_nb, 2.0);
assert_abs_diff_eq!(w.w_mn, 1000.0, epsilon = 0.01);
assert_abs_diff_eq!(w.w_fp, 1.0);
}
#[test]
fn phase_1_end() {
let w = weights_at(100, &[100, 100, 250]);
assert_abs_diff_eq!(w.w_mn, 3.0, epsilon = 0.01);
}
#[test]
fn phase_2() {
let w = weights_at(150, &[100, 100, 250]);
assert_abs_diff_eq!(w.w_nb, 3.0);
assert_abs_diff_eq!(w.w_mn, 3.0);
}
#[test]
fn phase_3() {
let w = weights_at(300, &[100, 100, 250]);
assert_abs_diff_eq!(w.w_nb, 1.0);
assert_abs_diff_eq!(w.w_mn, 0.0);
assert_abs_diff_eq!(w.w_fp, 1.0);
}
}