feat(convergence): add ConvergenceOptions::alpha damping field

Adds an EP damping coefficient defaulting to 1.0 (undamped). Will be
read by run_chain in a follow-up commit. By itself this commit changes
no behavior — existing constructors using ..Default::default() pick up
the new field automatically.
This commit is contained in:
2026-05-08 15:00:34 +02:00
parent 0dd7dab266
commit 0fa4e7d277
2 changed files with 19 additions and 0 deletions
+17
View File
@@ -8,6 +8,11 @@ use smallvec::SmallVec;
pub struct ConvergenceOptions {
pub max_iter: usize,
pub epsilon: f64,
/// EP damping factor in natural-parameter space: each per-factor
/// update writes `α·new + (1−α)·old`. `1.0` is undamped (default);
/// `< 1.0` stabilises oscillating fixed-point loops at the cost of
/// more iterations. Must be in `(0.0, 1.0]`.
pub alpha: f64,
}
impl Default for ConvergenceOptions {
@@ -15,6 +20,7 @@ impl Default for ConvergenceOptions {
Self {
max_iter: crate::ITERATIONS,
epsilon: crate::EPSILON,
alpha: 1.0,
}
}
}
@@ -29,3 +35,14 @@ pub struct ConvergenceReport {
pub per_iteration_time: SmallVec<[Duration; 32]>,
pub slices_skipped: usize,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_alpha_is_one_for_undamped_behavior() {
let opts = ConvergenceOptions::default();
assert_eq!(opts.alpha, 1.0);
}
}
+2
View File
@@ -1368,6 +1368,7 @@ mod tests {
h.convergence = ConvergenceOptions {
max_iter: 11,
epsilon: EPSILON,
alpha: 1.0,
};
h.converge().unwrap();
@@ -1685,6 +1686,7 @@ mod tests {
.convergence(ConvergenceOptions {
max_iter: 30,
epsilon: 1e-6,
alpha: 1.0,
})
.build();