diff --git a/app-proto/src/diagnostics.rs b/app-proto/src/diagnostics.rs index 47a9086..a2f090a 100644 --- a/app-proto/src/diagnostics.rs +++ b/app-proto/src/diagnostics.rs @@ -119,11 +119,10 @@ fn SpectrumHistory() -> View { on_mount(move || { create_effect(move || { // get the spectrum of the Hessian at each step, split into its - // positive and negative parts. exact zero eigenvalues will be - // filtered out by `into_log10_time_point` later + // positive, negative, and strictly-zero parts let ( - hess_eigvals_pos, - hess_eigvals_neg + hess_eigvals_zero, + hess_eigvals_nonzero ): (Vec<_>, Vec<_>) = state.assembly.descent_history.with( |history| history.hess_eigvals .iter() @@ -134,8 +133,20 @@ fn SpectrumHistory() -> View { ) ) .flatten() - .partition(|&(_, val)| val > 0.0) + .partition(|&(_, val)| val == 0.0) ); + let zero_level = hess_eigvals_nonzero + .iter() + .map(|(_, val)| val.abs()) + .reduce(f64::min) + .map(|val| 0.1 * val) + .unwrap_or(1.0); + let ( + hess_eigvals_pos, + hess_eigvals_neg + ): (Vec<_>, Vec<_>) = hess_eigvals_nonzero + .into_iter() + .partition(|&(_, val)| val > 0.0); // initialize the chart axes let step_axis = Axis::new() @@ -172,6 +183,20 @@ fn SpectrumHistory() -> View { vec![vec![Some(0.0), None::]] } ); + let eigval_series_zero = Scatter::new() + .symbol(Symbol::Triangle) + .symbol_size(5.0) + .data( + if hess_eigvals_zero.len() > 0 { + hess_eigvals_zero + .into_iter() + .map(|(step, _)| (step, zero_level)) + .map(into_log10_time_point) + .collect() + } else { + vec![vec![Some(0.0), None::]] + } + ); let chart = Chart::new() .animation(false) .data_zoom(DataZoom::new().y_axis_index(0).right(40)) @@ -179,7 +204,8 @@ fn SpectrumHistory() -> View { .y_axis(eigval_axis) .grid(Grid::new().top(20).right(80).bottom(30).left(60)) .series(eigval_series_pos) - .series(eigval_series_neg); + .series(eigval_series_neg) + .series(eigval_series_zero); renderer.render(CONTAINER_ID, &chart).unwrap(); }); });