jaxfit.trf module
Trust Region Reflective algorithm for least-squares optimization. The algorithm is based on ideas from paper [STIR]. The main idea is to account for the presence of the bounds by appropriate scaling of the variables (or, equivalently, changing a trust-region shape). Let’s introduce a vector v:
| ub[i] - x[i], if g[i] < 0 and ub[i] < np.inf
v[i] = | x[i] - lb[i], if g[i] > 0 and lb[i] > -np.inf
| 1, otherwise
where g is the gradient of a cost function and lb, ub are the bounds. Its components are distances to the bounds at which the anti-gradient points (if this distance is finite). Define a scaling matrix D = diag(v**0.5). First-order optimality conditions can be stated as:
D^2 g(x) = 0.
Meaning that components of the gradient should be zero for strictly interior variables, and components must point inside the feasible region for variables on the bound. Now consider this system of equations as a new optimization problem. If the point x is strictly interior (not on the bound), then the left-hand side is differentiable and the Newton step for it satisfies:
(D^2 H + diag(g) Jv) p = -D^2 g
where H is the Hessian matrix (or its J^T J approximation in least squares), Jv is the Jacobian matrix of v with components -1, 1 or 0, such that all elements of matrix C = diag(g) Jv are non-negative. Introduce the change of the variables x = D x_h (_h would be “hat” in LaTeX). In the new variables, we have a Newton step satisfying:
B_h p_h = -g_h,
where B_h = D H D + C, g_h = D g. In least squares B_h = J_h^T J_h, where J_h = J D. Note that J_h and g_h are proper Jacobian and gradient with respect to “hat” variables. To guarantee global convergence we formulate a trust-region problem based on the Newton step in the new variables:
0.5 * p_h^T B_h p + g_h^T p_h -> min, ||p_h|| <= Delta
In the original space B = H + D^{-1} C D^{-1}, and the equivalent trust-region problem is:
0.5 * p^T B p + g^T p -> min, ||D^{-1} p|| <= Delta
Here, the meaning of the matrix D becomes more clear: it alters the shape
of a trust-region, such that large steps towards the bounds are not allowed.
In the implementation, the trust-region problem is solved in “hat” space,
but handling of the bounds is done in the original space (see below and read
the code).
The introduction of the matrix D doesn’t allow to ignore bounds, the algorithm
must keep iterates strictly feasible (to satisfy aforementioned
differentiability), the parameter theta controls step back from the boundary
(see the code for details).
The algorithm does another important trick. If the trust-region solution
doesn’t fit into the bounds, then a reflected (from a firstly encountered
bound) search direction is considered. For motivation and analysis refer to
[STIR] paper (and other papers of the authors). In practice, it doesn’t need
a lot of justifications, the algorithm simply chooses the best step among
three: a constrained trust-region step, a reflected step and a constrained
Cauchy step (a minimizer along -g_h in “hat” space, or -D^2 g in the original
space).
Another feature is that a trust-region radius control strategy is modified to
account for appearance of the diagonal C matrix (called diag_h in the code).
Note that all described peculiarities are completely gone as we consider
problems without bounds (the algorithm becomes a standard trust-region type
algorithm very similar to ones implemented in MINPACK).
The implementation supports two methods of solving the trust-region problem.
The first, called ‘exact’, applies SVD on Jacobian and then solves the problem
very accurately using the algorithm described in [JJMore]. It is not
applicable to large problem. The second, called ‘lsmr’, uses the 2-D subspace
approach (sometimes called “indefinite dogleg”), where the problem is solved
in a subspace spanned by the gradient and the approximate Gauss-Newton step
found by scipy.sparse.linalg.lsmr. A 2-D trust-region problem is
reformulated as a 4th order algebraic equation and solved very accurately by
numpy.roots. The subspace approach allows to solve very large problems
(up to couple of millions of residuals on a regular PC), provided the Jacobian
matrix is sufficiently sparse.
.. rubric:: References
Branch, M.A., T.F. Coleman, and Y. Li, “A Subspace, Interior, and Conjugate Gradient Method for Large-Scale Bound-Constrained Minimization Problems,” SIAM Journal on Scientific Computing, Vol. 21, Number 1, pp 1-23, 1999.
More, J. J., “The Levenberg-Marquardt Algorithm: Implementation and Theory,” Numerical Analysis, ed. G. A. Watson, Lecture
- class jaxfit.trf.TrustRegionJITFunctions[source]
Bases:
objectJIT functions for trust region algorithm.
- create_check_isfinite()[source]
Create the function to check if the evaluated residuals are finite.
- create_default_loss_func()[source]
Create the default loss function which is simply the sum of the squares of the residuals.
- create_grad_func()[source]
Create the function to compute the gradient of the loss function which is simply the function evaluation dotted with the Jacobian.
- class jaxfit.trf.TrustRegionReflective[source]
Bases:
TrustRegionJITFunctions- select_step(x, J_h, diag_h, g_h, p, p_h, d, Delta, lb, ub, theta)[source]
Select the best step according to Trust Region Reflective algorithm.
- Parameters:
x (np.ndarray) – Current set parameter vector.
J_h (jnp.ndarray) – Jacobian matrix in the scaled ‘hat’ space.
diag_h (jnp.ndarray) – Diagonal of the scaled matrix C = diag(g * scale) Jv?
g_h (jnp.ndarray) – Gradient vector in the scaled ‘hat’ space.
p (np.ndarray) – Trust-region step in the original space.
p_h (np.ndarray) – Trust-region step in the scaled ‘hat’ space.
d (np.ndarray) – Scaling vector.
Delta (float) – Trust-region radius.
lb (np.ndarray) – Lower bounds on variables.
ub (np.ndarray) – Upper bounds on variables.
theta (float) – Controls step back step ratio from the bounds.
- Returns:
step (np.ndarray) – Step in the original space.
step_h (np.ndarray) – Step in the scaled ‘hat’ space.
predicted_reduction (float) – Predicted reduction in the cost function.
- trf(fun, xdata, ydata, jac, data_mask, transform, x0, f0, J0, lb, ub, ftol, xtol, gtol, max_nfev, f_scale, x_scale, loss_function, tr_options, verbose, timeit=False)[source]
Minimize a scalar function of one or more variables using the trust-region reflective algorithm. Although I think this is not good coding style, I maintained the original code format from SciPy such that the code is easier to compare with the original. See the note from the algorithms original author below.
For efficiency, it makes sense to run the simplified version of the algorithm when no bounds are imposed. We decided to write the two separate functions. It violates the DRY principle, but the individual functions are kept the most readable.
- Parameters:
fun (callable) – The residual function
xdata (array_like or tuple of array_like) – The independent variable where the data is measured. If xdata is a tuple, then the input arguments to fun are assumed to be
(xdata[0], xdata[1], ...).ydata (jnp.ndarray) – The dependent data
jac (callable) – The Jacobian of fun.
data_mask (jnp.ndarray) – The mask for the data.
transform (jnp.ndarray) – The uncertainty transform for the data.
x0 (jnp.ndarray) – Initial guess. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
f0 (jnp.ndarray) – Initial residuals. Array of real elements of size (m,), where ‘m’ is the number of data points.
J0 (jnp.ndarray) – Initial Jacobian. Array of real elements of size (m, n), where ‘m’ is the number of data points and ‘n’ is the number of independent variables.
lb (jnp.ndarray) – Lower bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ub (jnp.ndarray) – Upper bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ftol (float) – Tolerance for termination by the change of the cost function.
xtol (float) – Tolerance for termination by the change of the independent variables.
gtol (float) – Tolerance for termination by the norm of the gradient.
max_nfev (int) – Maximum number of function evaluations.
f_scale (float) – Cost function scalar
x_scale (jnp.ndarray) – Scaling factors for independent variables.
loss_function (callable, optional) – Loss function. If None, the standard least-squares problem is solved.
tr_options (dict) – Options for the trust-region algorithm.
verbose (int) –
Level of algorithm’s verbosity:
0 (default) : work silently.
1 : display a termination report.
timeit (bool, optional) – If True, the time for each step is measured if the unbounded version is being ran. Default is False.
- Return type:
Dict
- trf_bounds(fun, xdata, ydata, jac, data_mask, transform, x0, f, J, lb, ub, ftol, xtol, gtol, max_nfev, f_scale, x_scale, loss_function, tr_options, verbose)[source]
Bounded version of the trust-region reflective algorithm.
- Parameters:
fun (callable) – The residual function
xdata (array_like or tuple of array_like) – The independent variable where the data is measured. If xdata is a tuple, then the input arguments to fun are assumed to be
(xdata[0], xdata[1], ...).ydata (jnp.ndarray) – The dependent data
jac (callable) – The Jacobian of fun.
data_mask (jnp.ndarray) – The mask for the data.
transform (jnp.ndarray) – The uncertainty transform for the data.
x0 (jnp.ndarray) – Initial guess. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
f0 (jnp.ndarray) – Initial residuals. Array of real elements of size (m,), where ‘m’ is the number of data points.
J0 (jnp.ndarray) – Initial Jacobian. Array of real elements of size (m, n), where ‘m’ is the number of data points and ‘n’ is the number of independent variables.
lb (jnp.ndarray) – Lower bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ub (jnp.ndarray) – Upper bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ftol (float) – Tolerance for termination by the change of the cost function.
xtol (float) – Tolerance for termination by the change of the independent variables.
gtol (float) – Tolerance for termination by the norm of the gradient.
max_nfev (int) – Maximum number of function evaluations.
f_scale (float) – Cost function scalar
x_scale (jnp.ndarray) – Scaling factors for independent variables.
loss_function (callable, optional) – Loss function. If None, the standard least-squares problem is solved.
tr_options (dict) – Options for the trust-region algorithm.
verbose (int) –
Level of algorithm’s verbosity:
0 (default) : work silently.
1 : display a termination report.
f (Array) –
J (Array) –
- Returns:
result – The optimization result represented as a
OptimizeResultobject. Important attributes are:xthe solution array,successa Boolean flag indicating if the optimizer exited successfully andmessagewhich describes the cause of the termination. See OptimizeResult for a description of other attributes.- Return type:
Notes
The algorithm is described in [13].
References
- trf_no_bounds(fun, xdata, ydata, jac, data_mask, transform, x0, f, J, lb, ub, ftol, xtol, gtol, max_nfev, f_scale, x_scale, loss_function, tr_options, verbose)[source]
Unbounded version of the trust-region reflective algorithm.
- Parameters:
fun (callable) – The residual function
xdata (array_like or tuple of array_like) – The independent variable where the data is measured. If xdata is a tuple, then the input arguments to fun are assumed to be
(xdata[0], xdata[1], ...).ydata (jnp.ndarray) – The dependent data
jac (callable) – The Jacobian of fun.
data_mask (jnp.ndarray) – The mask for the data.
transform (jnp.ndarray) – The uncertainty transform for the data.
x0 (jnp.ndarray) – Initial guess. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
f0 (jnp.ndarray) – Initial residuals. Array of real elements of size (m,), where ‘m’ is the number of data points.
J0 (jnp.ndarray) – Initial Jacobian. Array of real elements of size (m, n), where ‘m’ is the number of data points and ‘n’ is the number of independent variables.
lb (jnp.ndarray) – Lower bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ub (jnp.ndarray) – Upper bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ftol (float) – Tolerance for termination by the change of the cost function.
xtol (float) – Tolerance for termination by the change of the independent variables.
gtol (float) – Tolerance for termination by the norm of the gradient.
max_nfev (int) – Maximum number of function evaluations.
f_scale (float) – Cost function scalar
x_scale (jnp.ndarray) – Scaling factors for independent variables.
loss_function (callable, optional) – Loss function. If None, the standard least-squares problem is solved.
tr_options (dict) – Options for the trust-region algorithm.
verbose (int) –
Level of algorithm’s verbosity:
0 (default) : work silently.
1 : display a termination report.
f (Array) –
J (Array) –
- Returns:
result – The optimization result represented as a
OptimizeResultobject. Important attributes are:xthe solution array,successa Boolean flag indicating if the optimizer exited successfully andmessagewhich describes the cause of the termination. See OptimizeResult for a description of other attributes.- Return type:
Notes
The algorithm is described in [13].
- trf_no_bounds_timed(fun, xdata, ydata, jac, data_mask, transform, x0, f, J, lb, ub, ftol, xtol, gtol, max_nfev, f_scale, x_scale, loss_function, tr_options, verbose)[source]
Trust Region Reflective algorithm with no bounds and all the operations performed on JAX and the GPU are timed. We need a separate function for this because to time each operation we need a block_until_ready() function which makes the main Python thread wait until the GPU has finished the operation. However, for the main algorithm we don’t want to wait for the GPU to finish each operation because it would slow down the algorithm. Thus, this is just used for analysis of the algorithm.
- Parameters:
fun (callable) – The residual function
xdata (array_like or tuple of array_like) – The independent variable where the data is measured. If xdata is a tuple, then the input arguments to fun are assumed to be
(xdata[0], xdata[1], ...).ydata (jnp.ndarray) – The dependent data
jac (callable) – The Jacobian of fun.
data_mask (jnp.ndarray) – The mask for the data.
transform (jnp.ndarray) – The uncertainty transform for the data.
x0 (jnp.ndarray) – Initial guess. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
f0 (jnp.ndarray) – Initial residuals. Array of real elements of size (m,), where ‘m’ is the number of data points.
J0 (jnp.ndarray) – Initial Jacobian. Array of real elements of size (m, n), where ‘m’ is the number of data points and ‘n’ is the number of independent variables.
lb (jnp.ndarray) – Lower bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ub (jnp.ndarray) – Upper bounds on independent variables. Array of real elements of size (n,), where ‘n’ is the number of independent variables.
ftol (float) – Tolerance for termination by the change of the cost function.
xtol (float) – Tolerance for termination by the change of the independent variables.
gtol (float) – Tolerance for termination by the norm of the gradient.
max_nfev (int) – Maximum number of function evaluations.
f_scale (float) – Cost function scalar
x_scale (jnp.ndarray) – Scaling factors for independent variables.
loss_function (callable, optional) – Loss function. If None, the standard least-squares problem is solved.
tr_options (dict) – Options for the trust-region algorithm.
verbose (int) –
Level of algorithm’s verbosity:
0 (default) : work silently.
1 : display a termination report.
f (Array) –
J (Array) –
- Returns:
result – The optimization result represented as a
OptimizeResultobject. Important attributes are:xthe solution array,successa Boolean flag indicating if the optimizer exited successfully andmessagewhich describes the cause of the termination. See OptimizeResult for a description of other attributes.- Return type:
Notes
The algorithm is described in [13].