--- a/src/types.rs Tue Aug 01 10:32:12 2023 +0300 +++ b/src/types.rs Thu Aug 29 00:00:00 2024 -0500 @@ -27,7 +27,7 @@ pub struct IterInfo<F : Float, const N : usize> { /// Function value pub value : F, - /// Number of speaks + /// Number of spikes pub n_spikes : usize, /// Number of iterations this statistic covers pub this_iters : usize, @@ -37,6 +37,10 @@ pub pruned : usize, /// Number of inner iterations since last IterInfo statistic pub inner_iters : usize, + /// Tuple of (transported mass, source mass) + pub untransported_fraction : Option<(F, F)>, + /// Tuple of (|destination mass - untransported_mass|, transported mass) + pub transport_error : Option<(F, F)>, /// Current tolerance pub ε : F, /// Solve fin.dim problem for this measure to get the optimal `value`. @@ -55,19 +59,38 @@ inner_iters : 0, ε : F::NAN, postprocessing : None, + untransported_fraction : None, + transport_error : None, } } } +#[replace_float_literals(F::cast_from(literal))] impl<F, const N : usize> LogRepr for IterInfo<F, N> where F : LogRepr + Float { fn logrepr(&self) -> ColoredString { - format!("{}\t| N = {}, ε = {:.8}, inner_iters_mean = {}, merged+pruned_mean = {}+{}", + format!("{}\t| N = {}, ε = {:.8}, inner_iters_mean = {}, merged+pruned_mean = {}+{}{}{}", self.value.logrepr(), self.n_spikes, self.ε, self.inner_iters as float / self.this_iters as float, self.merged as float / self.this_iters as float, self.pruned as float / self.this_iters as float, + match self.untransported_fraction { + None => format!(""), + Some((a, b)) => if b > 0.0 { + format!(", untransported {:.2}%", 100.0*a/b) + } else { + format!("") + } + }, + match self.transport_error { + None => format!(""), + Some((a, b)) => if b > 0.0 { + format!(", transport error {:.2}%", 100.0*a/b) + } else { + format!("") + } + } ).as_str().into() } }