decent_bench.metrics.utils#
- decent_bench.metrics.utils.x_mean(agents: tuple[AgentMetricsView, ...], iteration: int = -1) Array[source]#
Calculate the mean x at iteration (or using the agents’ final x if iteration is -1).
Agents that did not reach iteration are disregarded.
- Raises:
ValueError – if no agent reached iteration
- decent_bench.metrics.utils.all_sorted_iterations(agents: Sequence[AgentMetricsView]) list[int][source]#
Get a sorted list of all iterations reached by any agent in agents.
- Parameters:
agents – sequence of agents to get the iterations from
- Returns:
sorted list of iterations reached by any agent
- decent_bench.metrics.utils.linear_convergence_rate(y: Sequence[float]) float[source]#
Compute the linear (a.k.a. exponential or geometric) convergence rate from a given trajectory.
Fits a piecewise linear model to the log10-scaled trajectory to identify the transitory phase and extract its slope. The convergence rate is then computed as \(10^{\text{slope}}\), giving the multiplicative factor by which the error decreases per iteration during the transitory phase. A convergence rate below \(1\) indicates convergence, while above \(1\) indicates divergence. The smaller the convergence rate, the faster the convergence.
- Parameters:
y – sequence of error values from optimization trajectory (assumed to be positive)
- Returns:
the convergence rate (multiplicative factor per iteration)
Example
>>> print("Convergence rate of:") >>> for alg, results in metric_results.plot_results.items(): >>> for metric, stat_results in results.items(): >>> if type(metric) == metric_library.GradientNorm: >>> print(f"\t- {alg.name}: {utils.linear_convergence_rate(stat_results[1])}")
- decent_bench.metrics.utils.fit_elbow_curve(y: ndarray[tuple[Any, ...], dtype[float64]], max_trials: int = 10, tol: float = 1e-5, num_grid_points: int = 10) tuple[float, float, int][source]#
Fit a piecewise linear “elbow curve” to data.
Fits two connected line segments to the input data: one with a slope for the transitory phase and one horizontal for the steady-state phase. Formally, the elbow curve is defined as
\[\begin{split}f(x) = \begin{cases} s x + y_0 & \text{if } x \leq b \\ s b + y_0 & \text{if } x > b \end{cases}\end{split}\]where \(s\) is the slope, \(y_0\) is the intercept, \(b\) the breakpoint. The parameters \(s\), \(y_0\), and \(b\) are fitted to the input data using linear regression with an analytical solution (for efficiency), and grid search to find the optimal breakpoint.
- Parameters:
y – 1D array of data points to fit
max_trials – maximum number of refinement iterations for grid search
tol – grid search stops when fit of residual is less than this value
num_grid_points – number of candidate breakpoints to evaluate in each grid search iteration
- Returns:
the intercept, slope, and breakpoint fitted to the data
Note
A large value of max_trials, a small value of tol, a large value of num_grid_points will increase the accuracy of the fit, but will require longer computational time.
Note
numpy.nan, numpy.inf or -numpy.inf values in y are disregarded during the fit. These values might occur in case of divergence (there is only a transient phase, with positive slope), and discarding them allows to still fit the slope.
- Raises:
ValueError – if the input arguments are invalid