Welcome to TRLib’s documentation!¶
TRLib is a library that provides various methods related to the trust region subproblem and in particular implements the Generalized Lanczos Method [Gould1999] for iterative solution of the trust region subproblem:
A detailed description of the problem and the method as well as the implementation can be found in [Lenders2016].
Contents:¶
Installation¶
Dependencies¶
You have to make sure that the following requirements are provided:
- BLAS
- LAPACK
- CMake
The following dependencies are optional:
- for the unittests:
- Check
- for the documentation:
- sphinx with read the docs theme
- numpydoc
- for the python interface:
- Python Header, TRLIB works with Python 2 and 3 and compiles for the versions it finds
- Cython
- NumPy
- SciPy
- for the matlab interface:
- MATLAB with mex compiler and header files
Ubuntu/Debian Packages¶
To install all dependencies in a Ubuntu/Debian environment:
If you want to use Python 3:
sudo apt-get install cmake check build-essential python3-dev python3-numpy python3-scipy cython3 liblapack-dev libblas-dev python3-sphinx python3-sphinx-rtd-theme
If you want to use Python 2:
sudo apt-get install cmake check cython build-essential python-dev python-numpy python-scipy cython liblapack-dev libblas-dev python-sphinx python-sphinx-rtd-theme
Compilation¶
TRLIB is set up to create out of source builds using CMake. First create a build directory and change to that:
mkdir build cd build
Set up CMake in this directory:
cmake -DCMAKE_BUILD_TYPE=Release ..
Instead of Release
you may also choose Debug
which disables compiler optimization and enables debugging.
You may want change settings as described below in CMake, especially you have to turn on compilation of the python/matlab interface if you wish. After that execute:
ccmake .
Press c
to reconfigure with changes and q
to exit.
You can now compile TRLIB, generate the documentation and run the tests by executing:
make
make test
make doc
make install
Depending on the installation location, you might have to execute make install
as super user:
sudo make install
CMake Options¶
Option | default | Description |
---|---|---|
TRLIB_MEASURE_TIME |
OFF |
measure time for trlib function calls |
TRLIB_MEASURE_SUBTIME |
OFF |
measure time for blas and lapack function calls |
TRLIB_BUILD_MEX |
OFF |
build matlab interface |
TRLIB_BUILD_PYTHON2 |
OFF |
build python 2 interface |
TRLIB_BUILD_PYTHON3 |
OFF |
build python 3 interface |
Matlab Interface¶
Installation¶
Build trlib as declared in installation with CMake flag TRLIB_BUILD_MEX
set to ON
.
At the moment, there is nothing in CMake to install the interface.
You have to ensure that $TRLIB_BUILD_DIR/bindings/matlab
is found by your Matlab Installation.
Usage¶
From Matlab you can access trlib via the functions trlib
, trlib_options
, trlib_problem
, trlib_set_hotstart
and trlib_solve
.
trlib
is a convenience function above the others that does everything in one step:
>> Hess = diag(sparse(linspace(-1, 100, 10000)));
>> grad = ones(10000, 1);
>> [x, flag] = trlib(Hess, grad, 0.1);
>> norm(x)
In this example we solve the indefinite problem
Hotstart¶
It is possible to hotstart the solution in the case that only the radius in the norm constraint changes. This is typically the case in applications in nonlinear programming after a rejected step. To employ hotstart after solution, you have to store the TR cell structure that contains data of the previous solution process and call trlib_set_hotstart before the next solution:
>> Hess = diag(sparse(linspace(-1, 100, 10000)));
>> grad = ones(10000, 1);
>> [x, flag, prob, TR] = trlib(Hess, grad, 0.1);
>> norm(x)
>> trlib_set_hotstart(TR);
>> [x, flag, prob, TR] = trlib_solve(prob, 0.05, TR);
>> norm(x)
Matlab API Documentation¶
For a documentation of the matlab API use the help
command in matlab on the functions trlib
, trlib_options
, trlib_problem
, trlib_set_hotstart
and trlib_solve
.
Python Interface¶
Installation¶
We don’t have a setup.py
yet but use CMake to build the interface.
Ensure that either TRLIB_BUILD_PYTHON2` or ``TRLIB_BUILD_PYTHON3
is set to ON
before compilation, depending on the python version you like to use.
At the moment you have to ensure that $TRLIB_DIR/build
is contained in your $PYTHON_PATH
.
Usage¶
Use the function trlib_solve()
to solve a trust region subproblem und umin()
to solve an unconstrained nonlinear optimization problem with a standard trust-region algorithm.
Functions¶
-
trlib_solve
(hess, grad, radius, invM = lambda x: x, TR=None, reentry=False, verbose=0, ctl_invariant=0, convexify=1, earlyterm=1)¶ Solves trust-region subproblem
\(\min_{x \in \mathbb R^n} \tfrac 12 x^T H x + g^T x \quad \text{s.t.} \, \Vert x \Vert_M \le r\)
with a projected CG/Lanczos method.
Parameters: - hess ({sparse matrix, dense matrix, LinearOperator}) – hessian matrix/operator H with shape (n,n)
- grad (array) – gradient g with shape (n,1)
- radius (float) – trust-region radius r
- invM ({sparse matrix, dense matrix, LinearOperator}, optional) – inverse of matrix/operator defining trust-region constraint norm, default: identity, acts as preconditioner in CG/Lanczos
- TR (dict, optional) – TR output of previous call for hotstarting
- reentry (boolean, optional) – set this to True, if you want to resolve with all data fixed but changed trust-region radius, provide TR of previous call
- verbose (int, optional) – verbosity level
- ctl_invariant (int, optional) – flag that determines how to treat hard-case, see C API of
trlib_krylov_min()
- convexify (int, optional) – flag that determines if resolving with convexified should be tried if solution seems unrealistic
- earlyterm (int, optional) – flag that determines if solver should terminate early prior to convergence if it seems unlikely that progress will be made soon
Returns: (sol, TR): solution vector and trust-region instance data, needed for warmstart
- TR[‘ret’] gives return code of
trlib_krylov_min()
, - TR[‘obj’] gives objective funtion value,
- TR[‘lam’] lagrange multiplier
Return type: (array, dict)
Example: Solve a sample large-scale problem with indefinite diagonal hessian matrix:
>>> import scipy.sparse >>> import numpy as np >>> H = scipy.sparse.diags(np.linspace(-1.0, 100.0, 1000),0) >>> g = np.ones(1000) >>> x, TR = trlib.trlib_solve(H, g, 1.0) >>> np.linalg.norm(x) 1.0000000000000002 >>> x, TR = trlib.trlib_solve(H, g, .5, reentry=True, TR=TR) 0.50000000000000011
-
umin
(obj, grad, hessvec, x, tol=1e-5, eta1=1e-2, eta2=.95, gamma1=.5, gamma2=2., itmax=-1, verbose=1)¶ Standard Trust Region Algorithm for Unconstrained Optimization Problem:
\(\min_{x \in \mathbb R^n} f(x)\)This implements Algorithm 6.1 of [Gould1999] with slight modifications:
- check for descent
- aggresive trust region reduction upon failed step if next iteration will have the same subproblem solution
Parameters: - obj (function) – callback that computes \(x \mapsto f(x)\)
- grad (function) – callback that computes \(x \mapsto \nabla f(x)\)
- hessvec (function) – callback that computes \((x, d) \mapsto \nabla^2 f(x) \cdot d\)
- x (array) – starting point
- tol (float, optional) – convergence tolerance, convergence achieved if \(\Vert \nabla f(x) \Vert_2 \le \texttt{tol}\)
- eta1 (float, optional) – tolerance to discard step: \(\rho = \frac{\text{actual reducion}}{\text{predicted reduction}} \le \eta_1\)
- eta2 (float, optional) – tolerance to enlarge trust region: \(\rho = \frac{\text{actual reducion}}{\text{predicted reduction}} \ge \eta_2\)
- gamma1 (float, optional) – reduction factor for trust region radius upon failed step
- gamma2 (float, optional) – blow-up factor for trust region radius upon succesfully accepted step
- itmax (int, optional) – maximum number of iterations
- verbose (int, optional) – verbosity level
Returns: last point, solution in case of convergence
Return type: array
Example: Compute the minimizer of the extended Rosenbrock function in R^10:
>>> import trlib >>> import numpy as np >>> import scipy.optimize >>> trlib.umin(scipy.optimize.rosen, scipy.optimize.rosen_der, scipy.optimize.rosen_hess_prod, np.zeros(5)) it obj ‖g‖ radius step rho ? nhv 0 +4.0000e+00 4.0000e+00 4.4721e-01 4.4721e-01 -3.9705e+00 - 2 1 +4.0000e+00 4.0000e+00 2.2361e-01 2.2361e-01 +6.4377e-01 + 0 2 +3.7258e+00 1.0252e+01 2.2361e-01 4.5106e-02 +1.0011e+00 + 1 3 +3.4943e+00 2.3702e+00 4.4721e-01 4.4721e-01 -1.6635e+00 - 3 4 +3.4943e+00 2.3702e+00 2.2361e-01 2.2361e-01 +6.3041e-01 + 0 5 +3.1553e+00 1.0513e+01 2.2361e-01 3.2255e-02 +1.0081e+00 + 1 6 +2.9844e+00 3.0912e+00 4.4721e-01 4.4721e-01 -8.6302e-01 - 3 7 +2.9844e+00 3.0912e+00 2.2361e-01 2.2361e-01 +8.2990e-01 + 0 8 +2.5633e+00 8.4640e+00 2.2361e-01 4.1432e-02 +1.0074e+00 + 2 9 +2.4141e+00 3.2440e+00 4.4721e-01 4.4721e-01 -3.3029e-01 - 4 10 +2.4141e+00 3.2440e+00 2.2361e-01 2.2361e-01 +7.7786e-01 + 0 11 +1.9648e+00 6.5362e+00 2.2361e-01 2.2361e-01 +1.1319e+00 + 4 12 +1.4470e+00 5.1921e+00 4.4721e-01 4.0882e-01 +1.7910e-01 + 5 13 +1.3564e+00 1.6576e+01 4.4721e-01 7.9850e-02 +1.0404e+00 + 2 14 +6.8302e-01 3.7423e+00 8.9443e-01 4.0298e-01 -4.9142e-01 - 5 15 +6.8302e-01 3.7423e+00 3.6268e-01 3.6268e-01 +8.1866e-02 + 0 16 +6.5818e-01 1.3817e+01 3.6268e-01 4.8671e-02 +1.0172e+00 + 1 17 +3.1614e-01 5.9764e+00 7.2536e-01 1.3202e-02 +1.0081e+00 + 2 18 +2.8033e-01 1.4543e+00 1.4507e+00 3.5557e-01 -8.6703e-02 - 5 19 +2.8033e-01 1.4543e+00 3.2001e-01 3.2001e-01 +3.4072e-01 + 0 it obj ‖g‖ radius step rho ? nhv 20 +2.3220e-01 1.0752e+01 3.2001e-01 2.0244e-02 +1.0101e+00 + 1 21 +1.2227e-01 5.0526e+00 6.4002e-01 1.1646e-02 +1.0073e+00 + 2 22 +9.6271e-02 1.6755e+00 1.2800e+00 1.4701e-03 +9.9992e-01 + 1 23 +9.5040e-02 6.1617e-01 2.5601e+00 3.3982e-01 -3.6365e-01 - 5 24 +9.5040e-02 6.1617e-01 3.0584e-01 3.0584e-01 +1.3003e-01 + 0 25 +8.6495e-02 9.2953e+00 3.0584e-01 1.1913e-02 +1.0071e+00 + 1 26 +3.0734e-02 4.0422e+00 6.1167e-01 7.7340e-03 +1.0056e+00 + 2 27 +1.7104e-02 1.1570e+00 1.2233e+00 9.7535e-04 +1.0004e+00 + 1 28 +1.6540e-02 3.6078e-01 2.4467e+00 2.0035e-01 +5.5171e-01 + 5 29 +8.6950e-03 3.5281e+00 2.4467e+00 3.7360e-03 +1.0023e+00 + 1 30 +2.0894e-03 1.4262e+00 4.8934e+00 2.4287e-03 +1.0018e+00 + 2 31 +5.8038e-04 3.5326e-01 9.7868e+00 4.3248e-04 +1.0004e+00 + 2 32 +5.1051e-04 7.3221e-02 1.9574e+01 4.3231e-02 +9.9862e-01 + 5 33 +1.4135e-05 1.4757e-01 3.9147e+01 2.0304e-04 +1.0001e+00 + 3 34 +7.1804e-07 1.3804e-02 7.8294e+01 1.5512e-03 +1.0008e+00 + 5 35 +2.2268e-11 1.8517e-04 1.5659e+02 2.0956e-06 +1.0000e+00 + 5 36 +3.7550e-21 1.2923e-10
Julia Interface¶
Installation¶
Ensure that TRLIB_INSTALL_DIR/lib
is part of your LD_LIBRARY_PATH
environment variable.
You include the Julia interface by adding:
include("TRLIB_DIR/bindings/julia/trlib.jl")
using trlib
to your Julia code.
Usage¶
The interface allows to solve the trust region problem
\(\min_{x \in \mathbb R^n} \tfrac 12 x^T H x + x^T g \quad \text{s.t.} \, \Vert x \Vert \le \text{radius}\)
respective
\(\min_{x \in \mathbb R^n} \tfrac 12 x^T H x + x^T g \quad \text{s.t.} \, \Vert x \Vert_M \le \text{radius}\)
with \(\Vert x \Vert_M = \sqrt{ x^T M x }\).
The module provides a type trlib_data
to hold the necessary data of a trust region problem and a function trlib_solve
to solve the trust region problem.
To instaniate the data holding a trust region problem instance, execute:
TR = trlib.trlib_data(H, g)
respective:
TR = trlib.trlib_data(H, g, invM)
where H is such data the action H * p is defined, yielding \(Hp\) and invM such that invM * p is defined yielding \(M^{-1} p\).
You can then solve the problem with:
trlib.trlib_solve(TR, radius)
and get the solution as TR.sol, the lagrange multiplier as TR.lam and the objective value as TR.obj.
To hotstart the solution process with changed radius, just execute trlib_solve again.
Example: | Solve a sample large-scale problem with indefinite diagonal hessian matrix: julia> include("TRLIB_DIR/bindings/julia/trlib.jl");
julia> using trlib;
julia> H = spdiagm(linspace(-1.0, 100.0, n));
julia> g = ones(1000);
julia> TR = trlib.trlib_data(H, g);
julia> trlib.trlib_solve(TR, 1.0);
julia> norm(TR.sol)
(1.0000000000000002,2.9355512148709044,-15.283315647553387)
julia> trlib.trlib_solve(TR, 0.5);
julia> norm(TR.sol), TR.lam, TR.obj
(0.5000000000000001,28.860019828697034,-11.01602177675002)
|
---|
C Example¶
Using the C interface to solve a trust region subproblem is done by repeated calls to trlib_krylov_min()
, using a reverse communication pattern.
This is explained in detail in the API doc of trlib_krylov_min()
, here we show an example how to solve a trust region subproblem and resolve it with a different radius:
First we include the necessary headers and provide declarations for the linear algebra routines provided by BLAS and LAPACK:
#include <stdlib.h>
#include "math.h"
#include "string.h"
#include "trlib.h"
// blas
void daxpy_(trlib_int_t *n, trlib_flt_t *alpha, trlib_flt_t *x, trlib_int_t *incx, trlib_flt_t *y, trlib_int_t *incy);
void dscal_(trlib_int_t *n, trlib_flt_t *alpha, trlib_flt_t *x, trlib_int_t *incx);
void dcopy_(trlib_int_t *n, trlib_flt_t *x, trlib_int_t *incx, trlib_flt_t *y, trlib_int_t *incy);
trlib_flt_t dnrm2_(trlib_int_t *n, trlib_flt_t *x, trlib_int_t *incx);
trlib_flt_t ddot_(trlib_int_t *n, trlib_flt_t *x, trlib_int_t *incx, trlib_flt_t *y, trlib_int_t *incy);
// lapack
void dgemv_(char *trans, trlib_int_t *m, trlib_int_t *n, trlib_flt_t *alpha, trlib_flt_t *a, trlib_int_t *lda, trlib_flt_t *x, trlib_int_t *incx, trlib_flt_t *beta, trlib_flt_t *y, trlib_int_t *incy);
Then we define a data structure to be used in the reverse communication with trlib_krylov_min()
:
struct trlib_qpdata {
trlib_int_t n; ///< dimension of problem
trlib_int_t maxiter; ///< maximum number of Krylov subspace iterations
trlib_int_t *iwork; ///< integer work space
trlib_flt_t *fwork; ///< floating point workspace
trlib_flt_t *gradient; ///< gradient of QP
trlib_int_t hotstart; ///< flag that determines if hotstarted or not
void (*hv_cb)(const int n, const double *, double *);
///< callback to compute hessian vector product
trlib_int_t iter; ///< iteration counter
trlib_flt_t *g; ///< gradient of Krylov iteration
trlib_flt_t *gm; ///< previous gradient of Krylov iteration
trlib_flt_t *p; ///< direction
trlib_flt_t *Hp; ///< hessian product
trlib_flt_t *Q; ///< matrix with Lanczos directions
};
The following function fills useful defaults in such a data structure once the problem data are known:
int prepare_qp(trlib_int_t n, trlib_int_t maxiter,
const double *gradient,
void (*hv_cb)(const int n, const double *, double *),
struct trlib_qpdata *data) {
data->n = n;
data->maxiter = maxiter;
data->gradient = (double *)gradient;
data->hv_cb = hv_cb;
data->hotstart = 0;
trlib_int_t iwork_size, fwork_size, h_pointer;
trlib_krylov_memory_size(maxiter, &iwork_size, &fwork_size, &h_pointer);
data->iwork = malloc(iwork_size*sizeof(trlib_int_t));
data->fwork = malloc(fwork_size*sizeof(trlib_flt_t));
data->g = malloc(n*sizeof(double));
data->gm = malloc(n*sizeof(double));
data->p = malloc(n*sizeof(double));
data->Hp = malloc(n*sizeof(double));
data->Q = malloc((maxiter+1)*n*sizeof(double));
data->iter = 0;
return 0;
}
This function cleans up the data after the solution process has been finished:
int destroy_qp(struct trlib_qpdata *data) {
free(data->iwork);
free(data->fwork);
free(data->g);
free(data->gm);
free(data->p);
free(data->Hp);
free(data->Q);
return 0;
}
This function does the actual solution process by answering the reverse communication requests:
int solve_qp(struct trlib_qpdata *data, trlib_flt_t radius, double *sol, double *lam) {
// some default settings
trlib_int_t equality = 0;
trlib_int_t maxlanczos = 100;
trlib_int_t ctl_invariant = 0;
trlib_int_t refine = 1;
trlib_int_t verbose = 1;
trlib_int_t unicode = 0;
trlib_flt_t tol_rel_i = -2.0;
trlib_flt_t tol_abs_i = 0.0;
trlib_flt_t tol_rel_b = -3.0;
trlib_flt_t tol_abs_b = 0.0;
trlib_flt_t obj_lo = -1e20;
trlib_int_t convexify = 1;
trlib_int_t earlyterm = 1;
trlib_int_t ret = 0;
trlib_int_t n = data->n;
trlib_int_t init = 0, inc = 1, itp1 = 0;
trlib_flt_t minus = -1.0, one = 1.0, z = 0.0, half = .5;
if(!data->hotstart) {
init = TRLIB_CLS_INIT;
trlib_krylov_prepare_memory(data->maxiter, data->fwork);
}
else { init = TRLIB_CLS_HOTSTART; }
trlib_flt_t v_dot_g = 0.0, p_dot_Hp = 0.0, flt1, flt2, flt3;
trlib_int_t action, ityp;
trlib_int_t iwork_size, fwork_size, h_pointer;
trlib_krylov_memory_size(data->maxiter, &iwork_size, &fwork_size, &h_pointer);
while(1) {
ret = trlib_krylov_min(init, radius, equality, data->maxiter, maxlanczos,
tol_rel_i, tol_abs_i, tol_rel_b, tol_abs_b,
TRLIB_EPS*TRLIB_EPS, obj_lo, ctl_invariant, convexify, earlyterm,
v_dot_g, v_dot_g, p_dot_Hp, data->iwork, data->fwork,
refine, verbose, unicode, "", stdout, NULL,
&action, &(data->iter), &ityp, &flt1, &flt2, &flt3);
init = 0;
switch(action) {
case TRLIB_CLA_INIT:
memset(sol, 0, n*sizeof(trlib_flt_t)); memset(data->gm, 0, n*sizeof(trlib_flt_t));
dcopy_(&n, data->gradient, &inc, data->g, &inc);
v_dot_g = ddot_(&n, data->g, &inc, data->g, &inc);
// p = -g
dcopy_(&n, data->g, &inc, data->p, &inc); dscal_(&n, &minus, data->p, &inc);
// Hp = H*p
data->hv_cb(n, data->p, data->Hp);
p_dot_Hp = ddot_(&n, data->p, &inc, data->Hp, &inc);
// Q(0:n) = g
dcopy_(&n, data->g, &inc, data->Q, &inc);
// Q(0:n) = g/sqrt(<g,g>)
flt1 = 1.0/sqrt(v_dot_g); dscal_(&n, &flt1, data->Q, &inc);
break;
case TRLIB_CLA_RETRANSF:
itp1 = data->iter+1;
// s = Q_i * h_i
dgemv_("N", &n, &itp1, &one, data->Q, &n, data->fwork+h_pointer, &inc, &z, sol, &inc);
break;
case TRLIB_CLA_UPDATE_STATIO:
// s += flt1*p
if (ityp == TRLIB_CLT_CG) { daxpy_(&n, &flt1, data->p, &inc, sol, &inc); };
break;
case TRLIB_CLA_UPDATE_GRAD:
if (ityp == TRLIB_CLT_CG) {
// Q(iter*n:(iter+1)*n) = flt2*g
dcopy_(&n, data->g, &inc, data->Q+(data->iter)*n, &inc);
dscal_(&n, &flt2, data->Q+(data->iter)*n, &inc);
// gm = g; g += flt1*Hp
dcopy_(&n, data->g, &inc, data->gm, &inc);
daxpy_(&n, &flt1, data->Hp, &inc, data->g, &inc);
}
if (ityp == TRLIB_CLT_L) {
// s = Hp + flt1*g + flt2*gm
dcopy_(&n, data->Hp, &inc, sol, &inc);
daxpy_(&n, &flt1, data->g, &inc, sol, &inc);
daxpy_(&n, &flt2, data->gm, &inc, sol, &inc);
// gm = flt3*g
dcopy_(&n, data->g, &inc, data->gm, &inc); dscal_(&n, &flt3, data->gm, &inc);
// g = s
dcopy_(&n, sol, &inc, data->g, &inc);
}
v_dot_g = ddot_(&n, data->g, &inc, data->g, &inc);
break;
case TRLIB_CLA_UPDATE_DIR:
if (ityp == TRLIB_CLT_CG) {
// p = -g + flt2 * p
dscal_(&n, &flt2, data->p, &inc);
daxpy_(&n, &minus, data->g, &inc, data->p, &inc);
}
if (ityp == TRLIB_CLT_L) {
// p = flt1*g
dcopy_(&n, data->g, &inc, data->p, &inc);
dscal_(&n, &flt1, data->p, &inc);
}
// Hp = H*p
data->hv_cb(n, data->p, data->Hp);
p_dot_Hp = ddot_(&n, data->p, &inc, data->Hp, &inc);
if ( ityp == TRLIB_CLT_L) {
// Q(iter*n:(iter+1)*n) = p
dcopy_(&n, data->p, &inc, data->Q+(data->iter)*n, &inc);
}
break;
case TRLIB_CLA_CONV_HARD:
itp1 = data->iter+1;
trlib_flt_t *temp = malloc(n*sizeof(trlib_flt_t));
// temp = H*s
data->hv_cb(n, sol, temp);
// temp = H*s + g
daxpy_(&n, &one, data->gradient, &inc, temp, &inc);
// temp = H*s + g + flt1*s
daxpy_(&n, &flt1, sol, &inc, temp, &inc);
v_dot_g = ddot_(&n, temp, &inc, temp, &inc);
free(temp);
break;
case TRLIB_CLA_NEW_KRYLOV:
printf("Hit invariant Krylov subspace. Please implement proper reorthogonalization!");
break;
case TRLIB_CLA_OBJVAL:
trlib_flt_t *temp = malloc(n*sizeof(trlib_flt_t));
// temp = H*s
data->hv_cb(n, sol, temp);
// temp = .5*H*s + g
daxpy_(&n, &half, data->gradient, &inc, temp, &inc);
// g_dot_g = .5 s^T H*s + g^T s
g_dot_g = ddot_(&n, temp, &inc, sol, &inc);
free(temp);
}
if( ret < 10 ) { break; }
}
*lam = data->fwork[7];
if(!data->hotstart) { data->hotstart = 1; }
return ret;
}
This function defines for a test example the function that computes hessian vector products:
/* Test the driver program to solve a 3D problem with two different radii
*/
void hessvec(const int n, const double *d, double *Hd) {
Hd[0] = d[0] + 4.0*d[2];
Hd[1] = 2.0*d[1];
Hd[2] = 4.0*d[0] + 3.0*d[2];
}
This main routine initializes data to solve a trust region subproblem with radius 2.0 and hotstart it afterwards to resolve with radius 1.0 from the previous solution:
int main () {
trlib_int_t n = 3; // number of variables
trlib_int_t maxiter = 10*n; // maximum number of CG iterations
// gradient of QP
double *g = malloc(n*sizeof(double));
g[0] = 5.0; g[1] = 0.0; g[2] = 4.0;
// get datastructure for QP solution and prepare it
struct trlib_qpdata data;
prepare_qp(n, maxiter, g, &hessvec, &data);
// allocate memory for solution
double *sol = malloc(n*sizeof(double));
double lam = 0.0;
// solve QP with trust region radius 2.0
double radius = 2.0;
printf("Attempting to solve trust region problem with radius %f\n", radius);
solve_qp(&data, radius, sol, &lam);
printf("Got lagrange multiplier %f and solution vector [%f %f %f]\n\n", lam, sol[0], sol[1], sol[2]);
// resolve QP with trust region radius 1.0
radius = 1.0;
printf("Attempting to solve trust region problem with radius %f\n", radius);
solve_qp(&data, radius, sol, &lam);
printf("Got lagrange multiplier %f and solution vector [%f %f %f]\n\n", lam, sol[0], sol[1], sol[2]);
// clean up
destroy_qp(&data);
free(g); free(sol);
return 0;
}
CAPI trlib_krylov¶
Functions¶
-
trlib_int_t
trlib_krylov_min
(trlib_int_t init, trlib_flt_t radius, trlib_int_t equality, trlib_int_t itmax, trlib_int_t itmax_lanczos, trlib_flt_t tol_rel_i, trlib_flt_t tol_abs_i, trlib_flt_t tol_rel_b, trlib_flt_t tol_abs_b, trlib_flt_t zero, trlib_flt_t obj_lo, trlib_int_t ctl_invariant, trlib_int_t convexify, trlib_int_t earlyterm, trlib_flt_t g_dot_g, trlib_flt_t v_dot_g, trlib_flt_t p_dot_Hp, trlib_int_t *iwork, trlib_flt_t *fwork, trlib_int_t refine, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_int_t *timing, trlib_int_t *action, trlib_int_t *iter, trlib_int_t *ityp, trlib_flt_t *flt1, trlib_flt_t *flt2, trlib_flt_t *flt3)¶ Solves trust region subproblem: Computes minimizer to
\(\min \frac 12 \langle s, H s \rangle + \langle g_0, s \rangle\) subject to the trust region constraint \(\Vert s \Vert_M \le r\), where
- \(H\) is available via matrix-vector products \(v \mapsto Hv\),
- \(\Vert s \Vert_M = \sqrt{\langle s, Ms \rangle}\) with \(M\) positive definite,
- \(M\) is available via matrix-vector products of its inverse, \(v \mapsto M^{-1}v\).
The minimizer is a global minimizer (modulo floating point), as long as the hard case does not occur. The hard case is characterized by the fact that the eigenspace corresponding to the smallest eigenvalue is degenerate.
In that case a global minimizer in the Krylov subspaces sampled so far is returned, sampling the complete search space can be forced by setting
ctl_invariant
toTRLIB_CLC_EXP_INV_GLO
, but if this is desired factorization based method will most likely be much more efficient.A preconditioned Conjugate Gradient / Lanczos method is used, that possibly employs a reduction to a tridiagnoal subproblem that is solved using Moré-Sorensens method by explicitly factorizing the tridiagonal matrix, calling
trlib_tri_factor_min()
.The method builds upon algorithm 5.1 in [Gould1999], details of the implementation can be found [Lenders2016]:
Convergence
The stopping criterion is based on the gradient of the Lagrangian. Convergence in iteration \(i\) is reported as soon as
- interior case: \(\Vert g_{i+1} \Vert_{M^{-1}} \le \max\{ \texttt{tol}\_\texttt{abs}\_\texttt{i}, \eta_i \, \Vert g_0 \Vert_{M^{-1}} \}\).
- boundary case: \(\Vert g_{i+1} \Vert_{M^{-1}} \le \max\{ \texttt{tol}\_\texttt{abs}\_\texttt{b}, \eta_b \, \Vert g_0 \Vert_{M^{-1}} \}\).
- hard case:
ctl_invariant
determines if this is the sole stopping criterion or if further invariant subspaces are going to be explored. See the documentation of this option.
Here \(\eta_i = \begin{cases} \texttt{tol}\_\texttt{rel}\_\texttt{i} & \texttt{tol}\_\texttt{rel}\_\texttt{i} > 0 \\ \min\{ 0.5, \sqrt{\Vert g_{i+1} \Vert_{M^{-1}}} \} & \texttt{tol}\_\texttt{rel}\_\texttt{i} = -1 \\ \min\{ 0.5, \Vert g_{i+1} \Vert_{M^{-1}} \} & \texttt{tol}\_\texttt{rel}\_\texttt{i} = -2 \end{cases},\) \(\eta_b = \begin{cases} \texttt{tol}\_\texttt{rel}\_\texttt{b} & \texttt{tol}\_\texttt{rel}\_\texttt{b} > 0 \\ \min\{ 0.5, \sqrt{\Vert g_{i+1} \Vert_{M^{-1}}} \} & \texttt{tol}\_\texttt{rel}\_\texttt{b} = -1 \\ \min\{ 0.5, \Vert g_{i+1} \Vert_{M^{-1}} \} & \texttt{tol}\_\texttt{rel}\_\texttt{b} = -2, \\ \max\{10^{-6}, \min\{ 0.5, \sqrt{\Vert g_{i+1} \Vert_{M^{-1}}} \}\} & \texttt{tol}\_\texttt{rel}\_\texttt{b} = -3 \\ \max\{10^{-6}, \min\{ 0.5, \Vert g_{i+1} \Vert_{M^{-1}}\} \} & \texttt{tol}\_\texttt{rel}\_\texttt{b} = -4 \end{cases}.\)
Choice of \(\eta_i\) and \(\eta_b\) depend on the application, the author has good overall experience in unconstrained optimization with \(\texttt{tol}\_\texttt{rel}\_\texttt{i} = -2\) and \(\texttt{tol}\_\texttt{rel}\_\texttt{b} = -3\). Some remarks to keep in mind when choosing the tolerances:
- Choosing fixed small values for \(\eta_i\) and \(\eta_b\), for example \(\texttt{tol}\_\texttt{rel}\_\texttt{i} = 10^{-8}\) and \(\texttt{tol}\_\texttt{rel}\_\texttt{b} = 10^{-6}\) lead to quick convergence in a NLP algorithm with lowest number of function evaluations but at a possible excessive amount of matrix-vector products as this also solves problems accurately far away from the solution.
- Choosing \(\eta \sim O(\sqrt{\Vert g \Vert_{M^{-1}}})\) leads to superlinear convergence in a nonlinear programming algorithm.
- Choosing \(\eta \sim O(\Vert g \Vert_{M^{-1}})\) leads to quadratic convergence in a nonlinear programming algorithm.
- It is questionable whether it makes sense to solve the boundary with very high accuracy, as the final solution of a nonlinear program should be interior.
Calling Scheme
This function employs a reverse communication paradigm. The functions exits whenever there is an action to be performed by the user as indicated by the
action
. The user should perform this action and continue with the other values unchanged as long as the return value is positive.User provided storage
The user has to manage 5/6 vectors refered by the names \(g\), \(g_-\), \(v\), \(s\), \(p\), \(\textit{Hp}\) and a matrix \(Q\) with
itmax
columns to store the Lanczos directions \(p_i\). The user must perform the actions on those as indicated by the return value.In the case of trivial preconditioner, \(M = I\), it always holds \(v = g\) and the vector \(v\) is not necessary.
\(s\) holds the solution candidate.
Note that the action \(s \leftarrow Q h\) will only sometimes be requested in the very final iteration before convergence. If memory and not computational load is an issue, you may very well save
iter
,ityp
,flt1
,flt2
flt2
instead of \(q_j\) and when \(s \leftarrow Q s\) is requested simultaniously recompute the directions \(q_j\) and update the direction \(s\) once \(q_j\) has been computed as \(s \leftarrow h_j q_j\) with initialization \(s \leftarrow 0\).Furthermore the user has to provide a integer and floating point workspace, details are described in
iwork
andfwork
.Resolves
Reentry with new radius
You can efficiently hotstart from old results if you have a new problem with decreased trust region radius. Just set status to
TRLIB_CLS_HOTSTART
. Furthermore hotstarting with increased trust region radius should be trivial as you should be able to just increase the radius and take off the computation from the previous stage. However as this is an untypical scenario, it has not been tested at all.Reentry to get minimizer of regularized problem
You can reenter to compute the solution of a convexified trust region problem. You may be interested to this once you see the effect of bad conditioning or also as a cheap retry in a trust region algorithm before continuing to the next point after a discarded step.
In this case, call the function with status set to
TRLIB_CLS_HOTSTART_P
.Reentry to get unconstrained minimizer of constant regularized problem
After a successful solve you can compute the norm of the unconstrained minimizer to the problem with regularized hessian \(H + \beta M\) (\(\beta\) large enough such that \(H + \beta M\) is positive definite) in the previously expanded Krylov subspace. You will certainly be interested in this if you want to implement the TRACE algorithm described in [Curtis2016].
In this case, call the function with status set to
TRLIB_CLS_HOTSTART_R
andradius
set to \(\beta\).On exit, the
obj
field offwork
yields the norm of the solution vector.If you not only want the norm but also the unconstrained minimizer, you can get it by one step of
TRLIB_CLA_RETRANSF()
. However since this is usually not the case, you are not asked to do this in the reverse communication scheme.Reentry to find suitable TRACE regularization parameter
For the aforementioned TRACE algorithm, there is also the need to compute \(\beta\) such that \(\sigma_{\text l} \le \frac{\beta}{\Vert s(\beta) \Vert} \le \sigma_{\text u}\), where \(\Vert s(\beta) \Vert\) denotes the norm of the regularized unconstrained minimizer.
To get this, set
status
toTRLIB_CLS_HOTSTART_T
andradius
to an initial guess for \(\beta\),tol_rel_i
to \(\sigma_{\text l}\) andtol_rel_b
to \(\sigma_{\text u}\). The fieldobj
offwork
contains the desired solution norm on exit andflt1
is the desired regularization parameter \(\beta\).If you not only want the norm but also the unconstrained minimizer, you can get it by one step of
TRLIB_CLA_RETRANSF
. However since this is usually not the case, you are not asked to do this in the reverse communication scheme.Reentry with new gradient
You can efficiently hotstart from old results if you have a new problem with changed \(g_0\) where the previous sampled Krylov subspace is large enough to contain the solution to the new problem, convergence will not be checked:
- get pointer
gt
to negative gradient of tridiagonal problem in fwork withtrlib_krylov_gt()
- store
gt[0]
and overwrite \(\texttt{gt} \leftarrow - Q_i^T \texttt{grad}\) - set
status
toTRLIB_CLS_HOTSTART_G
and start reverse communication process - to reset data for new problem make sure that you restore
gt[0]
and setgt[1:] = 0
for those elements previously overwritten
Hard case
If you want to investigate the problem also if the hard case, you can either sample through the invariant subspaces (
ctl_invariant
set toTRLIB_CLC_EXP_INV_GLO
) or solve the problem with a gradient for which the hard does not occur and then hotstart with the actual gradient.Parameters: - init (
trlib_int_t
, input) – set toTRLIB_CLS_INIT
on first call, toTRLIB_CLS_HOTSTART
on hotstart with smaller radius and otherwise to0
. - radius (
trlib_flt_t
, input) – trust region radius - equality (
trlib_int_t
, input) – set to1
if trust region constraint should be enforced as equality - itmax (
trlib_int_t
, input) – maximum number of iterations - itmax_lanczos (
trlib_int_t
, input) – maximum number of Lanczos type iterations. You are strongly advised to set this to a small number (say 25) unless you know better. Keep in mind that Lanczos type iteration are only performed when curvature information is flat and Lanczos may amplify rounding errors without reorthogonalization. If you allow a lot of Lanczos type iterations consider reorthogonalizing the new direction against the vector storage. - tol_rel_i (
trlib_flt_t
, input) – relative stopping tolerance for interior solution - tol_abs_i (
trlib_flt_t
, input) – absolute stopping tolerance for interior solution - tol_rel_b (
trlib_flt_t
, input) – relative stopping tolerance for boundary solution - tol_abs_b (
trlib_flt_t
, input) – absolute stopping tolerance for boundary solution - zero (
trlib_flt_t
, input) – threshold that determines when \(\langle p, Hp \rangle\) is considered to be zero and thus control eventual Lanczos switch - obj_lo (
trlib_flt_t
, input) – lower bound on objective, returns if a point is found with function value \(\le \texttt{obj}\_\texttt{lo}\). Set to a positive value to ignore this bound. - ctl_invariant (
trlib_int_t
, input) –- set to
TRLIB_CLC_NO_EXP_INV
if you want to search only in the first invariant Krylov subspace - set to
TRLIB_CLC_EXP_INV_LOC
if you want to continue to expand the Krylov subspaces but terminate if there is convergence indication in the subspaces sampled so far. - set to
TRLIB_CLC_EXP_INV_GLO
if you want to continue to expand the Krylov subspaces even in the case of convergence to a local minimizer within in the subspaces sampled so far. Reverse communication continues as long as ctl_invariant is set toTRLIB_CLC_EXP_INV_GLO
, so you should resetctl_invariant
to eitherTRLIB_CLC_EXP_INV_LOC
orTRLIB_CLC_EXP_INV_LOC
if there is no reason to continue, for example because you cannot find a new nonzero random vector orthogonal to the sampled directions ifaction
isTRLIB_CLA_NEW_KRYLOV
.
- set to
- convexify (
trlib_int_t
, input) – set to 1 if you like to monitor if the tridiagonal solution and the backtransformed solution match and if not resolve with a convexified problem, else set to 0 - earlyterm (
trlib_int_t
, input) – set to 1 if you like to terminate in the boundary case if it unlikely that much progress will be made fast but no convergence is reached, else set to 0 - g_dot_g (
trlib_flt_t
, input) – dot product \(\langle g, g \rangle\) - v_dot_g (
trlib_flt_t
, input) – dot product \(\langle v, g \rangle\) - p_dot_Hp (
trlib_flt_t
, input) – dot product \(\langle p, Hp \rangle\) - iwork (
trlib_int_t
, input/output) –integer workspace for problem, internal memory layout described in table below
- on first call, provide allocated memory for
iwork_size
entries provided bytrlib_krylov_memory_size()
- leave untouched between iterations
start end(exclusive) description 0 1 internal status flag 1 2 iteration counter 2 3 flag that indicates if \(H\) is positive definite in sampled Krylov subspace 3 4 flag that indicates if interior solution is expected 4 5 flag that indicates if warmstart information to leftmost
is available5 6 index to block with smallest leftmost 6 7 flag that indicates if warmstart information to \(\lambda_0\) is available 7 8 flag that indicates if warmstart information to \(\lambda\) is available 8 9 iteration in which switched to Lanczos iteration, -1
: no switch occured9 10 return code from trlib_tri_factor_min()
10 11 sub_fail
exit code from subrotines called intrlib_tri_factor_min()
11 12 number of newton iterations needed in trlib_tri_factor_min()
12 13 last iteration in which a headline has been printed 13 14 kind of iteration headline that has been printed last 14 15 status variable if convexified version is going to be resolved 15 16 number of irreducible blocks 16 17 + itmax
decomposition into irredecubile block, irblk
fortrlib_tri_factor_min()
- on first call, provide allocated memory for
- fwork (
trlib_flt_t
, input/output) –floating point workspace for problem, internal memory layout described in table below
- on very first call, provide allocated memory for at least
fwork_size
entries that has been initialized usingtrlib_prepare_memory()
,fwork_size
can be obtained by callingtrlib_krylov_memory_size()
- can be used for different problem instances with matching dimensions and itmax without reinitialization
- leave untouched between iterations
start end (exclusive) description 0 1 stopping tolerance in case of interior solution 1 2 stopping tolerance in case of boundary solution 2 3 dot product \(\langle v, g \rangle\) in current iteration 3 4 dot product \(\langle p, Hp \rangle\) in current iteration 4 5 ratio between projected CG gradient and Lanczos direction in current iteration 5 6 ratio between projected CG gradient and Lanczos direction in previous iteration 6 7 Lagrange multiplier \(\lambda_0\) for trust region constraint 7 8 Lagrange multiplier \(\lambda\) for trust region constraint 8 9 objective function value in current iterate 9 10 \(\langle s_i, Mp_i \rangle\) 10 11 \(\langle p_i, Mp_i \rangle\) 11 12 \(\langle s_i, Ms_i \rangle\) 12 13 \(\sigma_i\) 13 14 max Rayleigh quotient, \(\max_i \frac{\langle p, Hp \rangle}{\langle p, M p \rangle}\) 14 15 min Rayleigh quotient, \(\min_i \frac{\langle p, Hp \rangle}{\langle p, M p \rangle}\) 15 16 + itmax
\(\alpha_i, i \ge 0\), step length CG 16 + itmax
17 + 2 itmax
\(\beta_i, i \ge 0\), step update factor CG 17 + 2 itmax
18 + 3 itmax
neglin
fortrlib_tri_factor_min()
, just given by \(- \gamma_0 e_1\)18 + 3 itmax
19 + 4 itmax
solution \(h_0\) of tridiagonal subproblem provided as sol
bytrlib_tri_factor_min()
19 + 4 itmax
20 + 5 itmax
solution \(h\) of tridiagonal subproblem provided as sol
bytrlib_tri_factor_min()
20 + 5 itmax
21 + 6 itmax
\(\delta_i, i \ge 0\), curvature in Lanczos, diagonal of \(T\) in Lanczos tridiagonalization process 21 + 6 itmax
22 + 7 itmax
diagonal of Cholesky of \(T_0 + \lambda_0 I\) 22 + 7 itmax
23 + 8 itmax
diagonal of Cholesky of \(T + \lambda I\) 23 + 8 itmax
23 + 9 itmax
\(\gamma_i, i \ge 1\), norm of gradients in Lanczos; provides offdiagonal of \(T\) in Lanczos tridiagonalization process 23 + 9 itmax
23 + 10 itmax
offdiagonal of Cholesky factorization of \(T_0 + \lambda_0 I\) 23 + 10 itmax
23 + 11 itmax
offdiagonal of Cholesky factorization of \(T + \lambda I\) 23 + 11 itmax
24 + 12 itmax
ones
fortrlib_tri_factor_min()
andtrlib_eigen_inverse()
24 + 12 itmax
25 + 13 itmax
leftmost
fortrlib_tri_factor_min()
25 + 13 itmax
26 + 14 itmax
regdiag
fortrlib_tri_factor_regularize_posdef()
26 + 14 itmax
27 + 15 itmax
history of convergence criteria values 27 + 15 itmax
27 + 15 itmax
+fmz
fwork
fortrlib_tri_factor_min()
,fmz
is given bytrlib_tri_factor_memory_size()
with argumentitmax+1
- on very first call, provide allocated memory for at least
- refine (
trlib_int_t
, input) – set to1
if iterative refinement should be used on solving linear systems, otherwise to0
- verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (char, input) – string that is printed before iteration output
- fout (FILE, input) – output stream
- timing (
trlib_int_t
, input/output) –gives timing details, all values are multiples of nanoseconds, provide zero allocated memory of length
trlib_krylov_timing_size()
block description 0 total duration 1 timing
oftrlib_tri_factor_min()
- action (
trlib_int_t
, output) –The user should perform the following action depending on
action
andityp
on the vectors he manages, see the table below. The table makes use of the notation explained in the User provided storage above and the following:- \(i\):
iter
- \(q_j\): \(j\)-th column of \(Q\)
- \(Q_i\): matrix consisting of the first \(i+1\) columns of \(Q\), \(Q_i = (q_0, \ldots, q_i)\)
- \(h_i\): vector of length \(i+1\) stored in
fwork
at start positionh_pointer
provided bytrlib_krylov_memory_size()
- \(p \leftarrow \perp_M Q_j\): optionally \(M\)-reorthonormalize \(p\) against \(Q_j\)
- \(g \leftarrow \texttt{rand}\perp Q_j\) find nonzero random vector that is orthogonal to \(Q_j\)
- Note that
TRLIB_CLA_NEW_KRYLOV
is unlikely and only occurs on problems that employ the hard case and only ifctl_invariant
\(\neq\)TRLIB_CLC_NO_EXP_INV
. If you want to safe yourself from the trouble implementing this and are confident that you don’t need to expand several invariant Krylov subspaces, just ensure thatctl_invariant
is set toTRLIB_CLC_NO_EXP_INV
.
action ityp command TRLIB_CLA_TRIVIAL
TRLIB_CLT_CG
,TRLIB_CLT_L
do nothing TRLIB_CLA_RETRANSF
TRLIB_CLT_CG
,TRLIB_CLT_L
\(s \leftarrow Q_i h_i\) TRLIB_CLA_INIT
TRLIB_CLT_CG
,TRLIB_CLT_L
\(s \leftarrow 0\), \(g \leftarrow g_0\), \(g_- \leftarrow 0\), \(v \leftarrow M^{-1} g\), \(p \leftarrow -v\), \(\textit{Hp} \leftarrow Hp\), \(\texttt{g}\_\texttt{dot}\_\texttt{g} \leftarrow \langle g, g \rangle\), \(\texttt{v}\_\texttt{dot}\_\texttt{g} \leftarrow \langle v, g \rangle\), \(\texttt{p}\_\texttt{dot}\_\texttt{Hp} \leftarrow \langle p, \textit{Hp} \rangle\), \(q_0 \leftarrow \frac{1}{\sqrt{\texttt{v}\_\texttt{dot}\_\texttt{g}}} v\) TRLIB_CLA_UPDATE_STATIO
TRLIB_CLT_CG
\(s \leftarrow s + \texttt{flt1} \, p\) TRLIB_CLA_UPDATE_STATIO
TRLIB_CLT_L
do nothing TRLIB_CLA_UPDATE_GRAD
TRLIB_CLT_CG
\(q_i \leftarrow \texttt{flt2} \, v\), \(g_- \leftarrow g\), \(g \leftarrow g + \texttt{flt1} \, \textit{Hp}\), \(v \leftarrow M^{-1} g\), \(\texttt{g}\_\texttt{dot}\_\texttt{g} \leftarrow \langle g, g \rangle\), \(\texttt{v}\_\texttt{dot}\_\texttt{g} \leftarrow \langle v, g \rangle\) TRLIB_CLA_UPDATE_GRAD
TRLIB_CLT_L
\(s \leftarrow \textit{Hp} + \texttt{flt1}\, g + \texttt{flt2}\, g_-\), \(g_- \leftarrow \texttt{flt3}\, g\), \(g \leftarrow s\), \(v \leftarrow M^{-1} g\), \(\texttt{v}\_\texttt{dot}\_\texttt{g} \leftarrow \langle v, g \rangle\) TRLIB_CLA_UPDATE_DIR
TRLIB_CLT_CG
\(p \leftarrow \texttt{flt1} \, v + \texttt{flt2} \, p\) with \(\texttt{flt1} = -1\), \(\textit{Hp} \leftarrow Hp\), \(\texttt{p}\_\texttt{dot}\_\texttt{Hp} \leftarrow \langle p, \textit{Hp} \rangle\) TRLIB_CLA_UPDATE_DIR
TRLIB_CLT_L
\(p \leftarrow \texttt{flt1} \, v + \texttt{flt2} \, p\) with \(\texttt{flt2} = 0\), \(p \leftarrow \perp_M Q_{i-1}\), \(\textit{Hp} \leftarrow Hp\), \(\texttt{p}\_\texttt{dot}\_\texttt{Hp} \leftarrow \langle p, \textit{Hp} \rangle\), \(q_i \leftarrow p\) TRLIB_CLA_NEW_KRYLOV
TRLIB_CLT_CG
,TRLIB_CLT_L
\(g \leftarrow \texttt{rand}\perp Q_{i-1}\), \(g_- \leftarrow 0\), \(v \leftarrow M^{-1} g\), \(\texttt{v}\_\texttt{dot}\_\texttt{g} \leftarrow \langle v, g \rangle\), \(p \leftarrow \frac{1}{\sqrt{\texttt{v}\_\texttt{dot}\_\texttt{g}}} v\), \(\texttt{p}\_\texttt{dot}\_\texttt{Hp} \leftarrow \langle p, \textit{Hp} \rangle\), \(q_{i+1} \leftarrow p\) TRLIB_CLA_CONV_HARD
TRLIB_CLT_CG
,TRLIB_CLT_L
\(\texttt{v}\_\texttt{dot}\_\texttt{g} \leftarrow \langle Hs+g_0+\texttt{flt1}\, Ms, M^{-1}(Hs+g_0) + \texttt{flt1} s \rangle\) TRLIB_CLA_OBJVAL
TRLIB_CLT_CG
,TRLIB_CLT_L
\(\texttt{g}\_\texttt{dot}\_\texttt{g} \leftarrow \tfrac 12 \langle s, Hs \rangle + \langle g, s \rangle\) - \(i\):
- iter (
trlib_int_t
, output) – iteration counter to tell user position in vector storage - ityp (
trlib_int_t
, output) – iteration type, seeaction
- flt1 (
trlib_flt_t
, output) – floating point value that user needs for actions - flt2 (
trlib_flt_t
, output) – floating point value that user needs for actions - flt3 (
trlib_flt_t
, output) – floating point value that user needs for actions
Returns: status flag with following meaning:
TRLIB_CLR_CONTINUE
no convergence yet, continue in reverse communicationTRLIB_CLR_CONV_BOUND
successful exit with converged solution on boundary, end reverse communication processTRLIB_CLR_CONV_INTERIOR
successful exit with converged interior solution, end reverse communication processTRLIB_CLR_APPROX_HARD
succesful exit with approximate solution, hard case occured, end reverse communication processTRLIB_CLR_NEWTON_BREAK
exit with breakdown in Newton iteration intrlib_tri_factor_min()
, most likely converged to boundary solutionTRLIB_TTR_HARD_INIT_LAM
hard case encountered without being able to find suitable initial \(\lambda\) for Newton iteration, returned approximate stationary point that maybe suboptimalTRLIB_CLR_ITMAX
iteration limit exceeded, end reverse communication processTRLIB_CLR_UNBDBEL
problem seems to be unbounded from below, end reverse communication processTRLIB_CLR_FAIL_FACTOR
failure on factorization, end reverse communication processTRLIB_CLR_FAIL_LINSOLVE
failure on backsolve, end reverse communication processTRLIB_CLR_FAIL_NUMERIC
failure as one of the valuesv_dot_g
orp_dot_Hp
are not a floating point numberTRLIB_CLR_UNLIKE_CONV
exit early as convergence seems to be unlikelyTRLIB_CLR_PCINDEF
preconditioner apperas to be indefinite, end reverse communication processTRLIB_CLR_UNEXPECT_INT
unexpected interior solution found, expected boundary solution, end reverse communication processTRLIB_CLR_FAIL_TTR
failure occured intrlib_tri_factor_min()
, checkiwork[7]
andiwork[8]
for detailsTRLIB_CLR_FAIL_HARD
failure due to occurence of hard case: invariant subspace encountered without local convergence and request for early termination without exploring further invariant subspaces
Return type: trlib_int_t
-
trlib_int_t
trlib_krylov_prepare_memory
(trlib_int_t itmax, trlib_flt_t *fwork)¶ Prepares floating point workspace for :c:func::trlib_krylov_min
Initializes floating point workspace
fwork
fortrlib_krylov_min()
Parameters: - itmax (
trlib_int_t
, input) – maximum number of iterations - fwork (
trlib_flt_t
, input/output) – floating point workspace to be used bytrlib_krylov_min()
Returns: 0
Return type: trlib_int_t
- itmax (
-
trlib_int_t
trlib_krylov_memory_size
(trlib_int_t itmax, trlib_int_t *iwork_size, trlib_int_t *fwork_size, trlib_int_t *h_pointer)¶ Gives information on memory that has to be allocated for :c:func::trlib_krylov_min
Parameters: - itmax (
trlib_int_t
, input) – maximum number of iterations - iwork_size (
trlib_int_t
, output) – size of integer workspace iwork that has to be allocated fortrlib_krylov_min()
- fwork_size (
trlib_int_t
, output) – size of floating point workspace fwork that has to be allocated fortrlib_krylov_min()
- h_pointer (
trlib_int_t
, output) – start index of vector \(h\) that has to be used in reverse communication in actionTRLIB_CLA_RETRANSF
Returns: 0
Return type: trlib_int_t
- itmax (
-
trlib_int_t
trlib_krylov_timing_size
(void)¶ size that has to be allocated for
timing
intrlib_krylov_min()
Returns: 0
Return type: trlib_int_t
-
trlib_int_t
trlib_krylov_gt
(trlib_int_t itmax, trlib_int_t *gt_pointer)¶ Gives pointer to negative gradient of tridiagonal problem
Parameters: - itmax (
trlib_int_t
, input) – itmax maximum number of iterations - gt_pointer (
trlib_int_t
, output) – pointer to negative gradient of tridiagonal subproblem
Returns: 0
Return type: trlib_int_t
- itmax (
Definitions¶
-
TRLIB_CLR_CONV_BOUND
¶ 0
-
TRLIB_CLR_CONV_INTERIOR
¶ 1
-
TRLIB_CLR_APPROX_HARD
¶ 2
-
TRLIB_CLR_NEWTON_BREAK
¶ 3
-
TRLIB_CLR_HARD_INIT_LAM
¶ 4
-
TRLIB_CLR_FAIL_HARD
¶ 5
-
TRLIB_CLR_UNBDBEL
¶ 6
-
TRLIB_CLR_UNLIKE_CONV
¶ 7
-
TRLIB_CLR_CONTINUE
¶ 10
-
TRLIB_CLR_ITMAX
¶ -1
-
TRLIB_CLR_FAIL_FACTOR
¶ -3
-
TRLIB_CLR_FAIL_LINSOLVE
¶ -4
-
TRLIB_CLR_FAIL_NUMERIC
¶ -5
-
TRLIB_CLR_FAIL_TTR
¶ -7
-
TRLIB_CLR_PCINDEF
¶ -8
-
TRLIB_CLR_UNEXPECT_INT
¶ -9
-
TRLIB_CLT_CG
¶ 1
-
TRLIB_CLT_L
¶ 2
-
TRLIB_CLA_TRIVIAL
¶ 0
-
TRLIB_CLA_INIT
¶ 1
-
TRLIB_CLA_RETRANSF
¶ 2
-
TRLIB_CLA_UPDATE_STATIO
¶ 3
-
TRLIB_CLA_UPDATE_GRAD
¶ 4
-
TRLIB_CLA_UPDATE_DIR
¶ 5
-
TRLIB_CLA_NEW_KRYLOV
¶ 6
-
TRLIB_CLA_CONV_HARD
¶ 7
-
TRLIB_CLA_OBJVAL
¶ 8
-
TRLIB_CLS_INIT
¶ 1
-
TRLIB_CLS_HOTSTART
¶ 2
-
TRLIB_CLS_HOTSTART_G
¶ 3
-
TRLIB_CLS_HOTSTART_P
¶ 4
-
TRLIB_CLS_HOTSTART_R
¶ 5
-
TRLIB_CLS_HOTSTART_T
¶ 6
-
TRLIB_CLS_VEC_INIT
¶ 7
-
TRLIB_CLS_CG_NEW_ITER
¶ 8
-
TRLIB_CLS_CG_UPDATE_S
¶ 9
-
TRLIB_CLS_CG_UPDATE_GV
¶ 10
-
TRLIB_CLS_CG_UPDATE_P
¶ 11
-
TRLIB_CLS_LANCZOS_SWT
¶ 12
-
TRLIB_CLS_L_UPDATE_P
¶ 13
-
TRLIB_CLS_L_CMP_CONV
¶ 14
-
TRLIB_CLS_L_CMP_CONV_RT
¶ 15
-
TRLIB_CLS_L_CHK_CONV
¶ 16
-
TRLIB_CLS_L_NEW_ITER
¶ 17
-
TRLIB_CLS_CG_IF_IRBLK_P
¶ 18
-
TRLIB_CLS_CG_IF_IRBLK_C
¶ 19
-
TRLIB_CLS_CG_IF_IRBLK_N
¶ 20
-
TRLIB_CLC_NO_EXP_INV
¶ 0
-
TRLIB_CLC_EXP_INV_LOC
¶ 1
-
TRLIB_CLC_EXP_INV_GLO
¶ 2
-
TRLIB_CLT_CG_INT
¶ 0
-
TRLIB_CLT_CG_BOUND
¶ 1
-
TRLIB_CLT_LANCZOS
¶ 2
-
TRLIB_CLT_HOTSTART
¶ 3
CAPI trlib_tri_factor¶
Functions¶
-
trlib_int_t
trlib_tri_factor_min
(trlib_int_t nirblk, trlib_int_t *irblk, trlib_flt_t *diag, trlib_flt_t *offdiag, trlib_flt_t *neglin, trlib_flt_t radius, trlib_int_t itmax, trlib_flt_t tol_rel, trlib_flt_t tol_newton_tiny, trlib_int_t pos_def, trlib_int_t equality, trlib_int_t *warm0, trlib_flt_t *lam0, trlib_int_t *warm, trlib_flt_t *lam, trlib_int_t *warm_leftmost, trlib_int_t *ileftmost, trlib_flt_t *leftmost, trlib_int_t *warm_fac0, trlib_flt_t *diag_fac0, trlib_flt_t *offdiag_fac0, trlib_int_t *warm_fac, trlib_flt_t *diag_fac, trlib_flt_t *offdiag_fac, trlib_flt_t *sol0, trlib_flt_t *sol, trlib_flt_t *ones, trlib_flt_t *fwork, trlib_int_t refine, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_int_t *timing, trlib_flt_t *obj, trlib_int_t *iter_newton, trlib_int_t *sub_fail)¶ Solves tridiagonal trust region subproblem
Computes minimizer to
\(\min \frac 12 \langle h, T h \rangle + \langle g, h \rangle\) subject to the trust region constraint \(\Vert h \Vert \le r\), where \(T \in \mathbb R^{n \times n}\) is symmetric tridiagonal.
Let \(T = \begin{pmatrix} T_1 & & \\ & \ddots & \\ & & T_\ell \end{pmatrix}\) be composed into irreducible blocks \(T_i\).
The minimizer is a global minimizer (modulo floating point).
The algorithm is the Moré-Sorensen-Method as decribed as Algorithm 5.2 in [Gould1999].
Convergence
Exit with success is reported in several cases:
- interior solution: the stationary point \(T h = - g\) is suitable, iterative refinement is used in the solution of this system.
- hard case: the smallest eigenvalue \(-\theta\) was found to be degenerate and \(h = v + \alpha w\) is returned with \(v\) solution of \((T + \theta I) v = -g\), \(w\) eigenvector corresponding to \(- \theta\) and \(\alpha\) chosen to satisfy the trust region constraint and being a minimizer.
- boundary and hard case: convergence in Newton iteration is reported if \(\Vert h(\lambda) \Vert - r \le \texttt{tol}\_\texttt{rel} \, r\) with \((T+\lambda I) h(\lambda) = -g\), Newton breakdown reported if \(\vert d\lambda \vert \le \texttt{macheps} \vert \lambda \vert\).
Parameters: - nirblk (
trlib_int_t
, input) – number of irreducible blocks \(\ell\), ensure \(\ell > 0\) - irblk (
trlib_int_t
, input) –pointer to indices of irreducible blocks, length
nirblk+1
:irblk[i]
is the start index of block \(i\) indiag
andoffdiag
irblk[i+1] - 1
is the stop index of block \(i\)irblk[i+1] - irred[i]
the dimension \(n_\ell\) of block \(i\)irblk[nirred]
the dimension of \(T\)
- diag (
trlib_flt_t
, input) – pointer to array holding diagonal of \(T\), lengthirblk[nirblk]
- offdiag (
trlib_flt_t
, input) – pointer to array holding offdiagonal of \(T\), lengthirblk[nirblk]
- neglin (
trlib_flt_t
, input) – pointer to array holding \(-g\), lengthn
- radius (
trlib_flt_t
, input) – trust region constraint radius \(r\) - itmax (
trlib_int_t
, input) – maximum number of Newton iterations - tol_rel (
trlib_flt_t
, input) – relative stopping tolerance for residual in Newton iteration forlam
, good default may be \(\texttt{macheps}\) (TRLIB_EPS
) - tol_newton_tiny (
trlib_flt_t
, input) – stopping tolerance for step in Newton iteration forlam
, good default may be \(10 \texttt{macheps}^{.75}\) - pos_def (
trlib_int_t
, input) – set1
if you know \(T\) to be positive definite, otherwise0
- equality (
trlib_int_t
, input) – set1
if you want to enfore trust region constraint as equality, otherwise0
- warm0 (
trlib_int_t
, input/output) – set1
if you provide a valid value inlam0
, otherwise0
- lam0 (
trlib_flt_t
, input/output) – Lagrange multiplier such that \(T_0+ \mathtt{lam0} I\) positive definite and \((T_0+ \mathtt{lam0} I) \mathtt{sol0} = \mathtt{neglin}\) - on entry: estimate suitable for warmstart - on exit: computed multiplier - warm (
trlib_int_t
, input/output) – set1
if you provide a valid value inlam
, otherwise0
- lam (
trlib_flt_t
, input/output) – Lagrange multiplier such that \(T+ \mathtt{lam} I\) positive definite and \((T+ \mathtt{lam} I) \mathtt{sol} = \mathtt{neglin}\) - on entry: estimate suitable for warmstart - on exit: computed multiplier - warm_leftmost (
trlib_int_t
, input/output) –- on entry: set
1
if you provide a valid value in leftmost section infwork
- on exit:
1
if leftmost section infwork
holds valid exit value, otherwise0
- on entry: set
- ileftmost (
trlib_int_t
, input/output) – index to block with smallest leftmost eigenvalue - leftmost (
trlib_flt_t
, input/output) – array holding leftmost eigenvalues of blocks - warm_fac0 (
trlib_int_t
, input/output) – set1
if you provide a valid factoricization indiag_fac0
,offdiag_fac0
- diag_fac0 (
trlib_flt_t
, input/output) – pointer to array holding diagonal of Cholesky factorization of \(T_0 + \texttt{lam0} I\), lengthirblk[1]
- on entry: factorization corresponding to provided estimationlam0
on entry - on exit: factorization corresponding to computed multiplierlam0
- offdiag_fac0 (
trlib_flt_t
, input/output) – pointer to array holding offdiagonal of Cholesky factorization of \(T_0 + \texttt{lam0} I\), lengthirblk[1]-1
- on entry: factorization corresponding to provided estimationlam0
on entry - on exit: factorization corresponding to computed multiplierlam0
- warm_fac (
trlib_int_t
, input/output) – set1
if you provide a valid factoricization indiag_fac
,offdiag_fac
- diag_fac (
trlib_flt_t
, input/output) – pointer to array of lengthn
that holds the following: - let \(j = \texttt{ileftmost}\) and \(\theta = - \texttt{leftmost[ileftmost]}\) - on position \(0, \ldots, \texttt{irblk[1]}\): diagonal of factorization of \(T_0 + \theta I\) - other positions have to be allocated - offdiag_fac (
trlib_flt_t
, input/output) – pointer to array of lengthn-1
that holds the following: - let \(j = \texttt{ileftmost}\) and \(\theta = - \texttt{leftmost[ileftmost]}\) - on position \(0, \ldots, \texttt{irblk[1]}-1\): offdiagonal of factorization of \(T_0 + \theta I\) - other positions have to be allocated - sol0 (
trlib_flt_t
, input/output) – pointer to array holding solution, lengthirblk[1]
- sol (
trlib_flt_t
, input/output) – pointer to array holding solution, lengthn
- ones (
trlib_flt_t
, input) – array with every value1.0
, lengthn
- fwork (
trlib_flt_t
, input/output) –floating point workspace, must be allocated memory on input of size
trlib_tri_factor_memory_size()
(call with argumentn
) and can be discarded on output, memory layout:start end (excl) description 0 n
auxiliary vector n
2 n
holds diagonal of \(T + \lambda I\) 2 n
4 n
workspace for iterative refinement - refine (
trlib_int_t
, input) – set to1
if iterative refinement should be used on solving linear systems, otherwise to0
- verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (char, input) – string that is printed before iteration output
- fout (FILE, input) – output stream
- timing (
trlib_int_t
, input/output) –gives timing details, provide allocated zero initialized memory of length
trlib_tri_timing_size()
block description 0 total duration 1 timing of linear algebra calls 2 timing
fromtrlib_leftmost_irreducible()
3 timing
fromtrlib_eigen_inverse()
- obj (
trlib_flt_t
, output) – objective function value at solution point - iter_newton (
trlib_int_t
, output) – number of Newton iterations - sub_fail (
trlib_int_t
, output) – status code of subroutine if failure occured in subroutines called
Returns: status
TRLIB_TTR_CONV_BOUND
success with solution on boundaryTRLIB_TTR_CONV_INTERIOR
success with interior solutionTRLIB_TTR_HARD
success, but hard case encountered and solution may be approximateTRLIB_TTR_NEWTON_BREAK
most likely success with accurate result; premature end of Newton iteration due to tiny stepTRLIB_TTR_HARD_INIT_LAM
hard case encountered without being able to find suitable initial \(\lambda\) for Newton iteration, returned approximate stationary point that maybe suboptimalTRLIB_TTR_ITMAX
iteration limit exceededTRLIB_TTR_FAIL_FACTOR
failure on matrix factorizationTRLIB_TTR_FAIL_LINSOLVE
failure on backsolveTRLIB_TTR_FAIL_EIG
failure on eigenvalue computation. status code oftrlib_eigen_inverse()
insub_fail
TRLIB_TTR_FAIL_LM
failure on leftmost eigenvalue computation. status code oftrlib_leftmost_irreducible()
insub_fail
Return type: trlib_int_t
-
trlib_int_t
trlib_tri_factor_regularized_umin
(trlib_int_t n, trlib_flt_t *diag, trlib_flt_t *offdiag, trlib_flt_t *neglin, trlib_flt_t lam, trlib_flt_t *sol, trlib_flt_t *ones, trlib_flt_t *fwork, trlib_int_t refine, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_int_t *timing, trlib_flt_t *norm_sol, trlib_int_t *sub_fail)¶ Computes minimizer of regularized unconstrained problem
Computes minimizer of
\(\min \frac 12 \langle h, (T + \lambda I) h \rangle + \langle g, h \rangle\), where \(T \in \mathbb R^{n \times n}\) is symmetric tridiagonal and \(\lambda\) such that \(T + \lambda I\) is spd.
Parameters: - n (
trlib_int_t
, input) – dimension, ensure \(n > 0\) - diag (
trlib_flt_t
, input) – pointer to array holding diagonal of \(T\), lengthn
- offdiag (
trlib_flt_t
, input) – pointer to array holding offdiagonal of \(T\), lengthn-1
- neglin (
trlib_flt_t
, input) – pointer to array holding \(-g\), lengthn
- lam (
trlib_flt_t
, input) – regularization parameter \(\lambda\) - sol (
trlib_flt_t
, input/output) – pointer to array holding solution, lengthn
- ones (
trlib_flt_t
, input) – array with every value1.0
, lengthn
- fwork (
trlib_flt_t
, input/output) –floating point workspace, must be allocated memory on input of size
trlib_tri_factor_memory_size()
(call with argumentn
) and can be discarded on output, memory layout:start end (excl) description 0 n
holds diagonal of \(T + \lambda I\) n
2 n
holds diagonal of factorization \(T + \lambda I\) 2 n
3 n
holds offdiagonal of factorization \(T + \lambda I\) 3 n
5 n
workspace for iterative refinement - refine (
trlib_int_t
, input) – set to1
if iterative refinement should be used on solving linear systems, otherwise to0
- verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (char, input) – string that is printed before iteration output
- fout (FILE, input) – output stream
- timing (
trlib_int_t
, input/output) –gives timing details, provide allocated zero initialized memory of length
trlib_tri_timing_size()
block description 0 total duration 1 timing of linear algebra calls - norm_sol (
trlib_flt_t
, output) – norm of solution fector - sub_fail (
trlib_int_t
, output) – status code of subroutine if failure occured in subroutines called
Returns: status
TRLIB_TTR_CONV_INTERIOR
success with interior solutionTRLIB_TTR_FAIL_FACTOR
failure on matrix factorizationTRLIB_TTR_FAIL_LINSOLVE
failure on backsolve
Return type: trlib_int_t
- n (
-
trlib_int_t
trlib_tri_factor_get_regularization
(trlib_int_t n, trlib_flt_t *diag, trlib_flt_t *offdiag, trlib_flt_t *neglin, trlib_flt_t *lam, trlib_flt_t sigma, trlib_flt_t sigma_l, trlib_flt_t sigma_u, trlib_flt_t *sol, trlib_flt_t *ones, trlib_flt_t *fwork, trlib_int_t refine, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_int_t *timing, trlib_flt_t *norm_sol, trlib_int_t *sub_fail)¶ Computes regularization parameter needed in trace
Let \(s(\lambda)\) be solution of \((T + \lambda I) s(\lambda) + g = 0\), where \(T \in \mathbb R^{n \times n}\) is symmetric tridiagonal and \(\lambda\) such that \(T + \lambda I\) is spd.
Then find \(\lambda\) with \(\sigma_{\text l} \le \frac{\lambda}{s(\lambda)} \le \sigma_{\text u}\).
Parameters: - n (
trlib_int_t
, input) – dimension, ensure \(n > 0\) - diag (
trlib_flt_t
, input) – pointer to array holding diagonal of \(T\), lengthn
- offdiag (
trlib_flt_t
, input) – pointer to array holding offdiagonal of \(T\), lengthn-1
- neglin (
trlib_flt_t
, input) – pointer to array holding \(-g\), lengthn
- lam (
trlib_flt_t
, input/output) – regularization parameter \(\lambda\), on input initial guess, on exit desired parameter - sigma (
trlib_flt_t
, input) – value that is used in root finding, e.g. \(\frac 12 (\sigma_{\text l} + \sigma_{\text u})\) - sigma_l (
trlib_flt_t
, input) – lower bound - sigma_u (
trlib_flt_t
, input) – upper bound - sol (
trlib_flt_t
, input/output) – pointer to array holding solution, lengthn
- ones (
trlib_flt_t
, input) – array with every value1.0
, lengthn
- fwork (
trlib_flt_t
, input/output) –floating point workspace, must be allocated memory on input of size
trlib_tri_factor_memory_size()
(call with argumentn
) and can be discarded on output, memory layout:start end (excl) description 0 n
holds diagonal of \(T + \lambda I\) n
2 n
holds diagonal of factorization \(T + \lambda I\) 2 n
3 n
holds offdiagonal of factorization \(T + \lambda I\) 3 n
5 n
workspace for iterative refinement 5 n
6 n
auxiliary vector - refine (
trlib_int_t
, input) – set to1
if iterative refinement should be used on solving linear systems, otherwise to0
- verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (char, input) – string that is printed before iteration output
- fout (FILE, input) – output stream
- timing (
trlib_int_t
, input/output) –gives timing details, provide allocated zero initialized memory of length
trlib_tri_timing_size()
block description 0 total duration 1 timing of linear algebra calls - norm_sol (
trlib_flt_t
, output) – norm of solution fector - sub_fail (
trlib_int_t
, output) – status code of subroutine if failure occured in subroutines called
Returns: status
TRLIB_TTR_CONV_INTERIOR
success with interior solutionTRLIB_TTR_FAIL_FACTOR
failure on matrix factorizationTRLIB_TTR_FAIL_LINSOLVE
failure on backsolve
Return type: trlib_int_t
- n (
-
trlib_int_t
trlib_tri_factor_regularize_posdef
(trlib_int_t n, trlib_flt_t *diag, trlib_flt_t *offdiag, trlib_flt_t tol_away, trlib_flt_t security_step, trlib_flt_t *regdiag)¶ Compute diagonal regularization to make tridiagonal matrix positive definite
Parameters: - n (
trlib_int_t
, input) – dimension, ensure \(n > 0\) - diag (
trlib_flt_t
, input) – pointer to array holding diagonal of \(T\), lengthn
- offdiag (
trlib_flt_t
, input) – pointer to array holding offdiagonal of \(T\), lengthn-1
- tol_away (
trlib_flt_t
, input) – tolerance that diagonal entries in factorization should be away from zero, relative to previous entry. Good default \(10^{-12}\). - security_step (
trlib_flt_t
, input) – factor greater1.0
that defines a margin to get away from zero in the step taken. Good default2.0
. - regdiag (
trlib_flt_t
, input/output) – pointer to array holding regularization term, lengthn
Returns: 0
Return type: trlib_int_t
- n (
-
trlib_int_t
trlib_tri_factor_memory_size
(trlib_int_t n)¶ Gives information on memory that has to be allocated for
trlib_tri_factor_min()
Parameters: - n (
trlib_int_t
, input) – dimension, ensure \(n > 0\) - fwork_size (
trlib_flt_t
, output) – size of floating point workspace fwork that has to be allocated fortrlib_tri_factor_min()
Returns: 0
Return type: trlib_int_t
- n (
-
trlib_int_t
trlib_tri_timing_size
(void)¶ size that has to be allocated for
timing
intrlib_tri_factor_min()
CAPI trlib_leftmost¶
Functions¶
-
trlib_int_t
trlib_leftmost
(trlib_int_t nirblk, trlib_int_t *irblk, trlib_flt_t *diag, trlib_flt_t *offdiag, trlib_int_t warm, trlib_flt_t leftmost_minor, trlib_int_t itmax, trlib_flt_t tol_abs, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_int_t *timing, trlib_int_t *ileftmost, trlib_flt_t *leftmost)¶ Computes smallest eigenvalue of symmetric tridiagonal matrix \(T \in \mathbb R^{n\times n}\), using a iteration based on last-pivot function of Parlett and Reid.
Let \(T = \begin{pmatrix} T_1 & & \\ & \ddots & \\ & & T_\ell \end{pmatrix}\) be composed into irreducible blocks \(T_i\).
Calls
trlib_leftmost_irreducible()
on every irreducible block in case of coldstart, in case of warmstart just updates information on \(T_\ell\).Parameters: - nirblk (
trlib_int_t
, input) – number of irreducible blocks \(\ell\), ensure \(\ell > 0\) - irblk (
trlib_int_t
, input) –pointer to indices of irreducible blocks, length
nirblk+1
:irblk[i]
is the start index of block \(i\) indiag
andoffdiag
irblk[i+1] - 1
is the stop index of block \(i\)irblk[i+1] - irred[i]
the dimension \(n_\ell\) of block \(i\)irblk[nirred]
the dimension of \(T\)
- diag (
trlib_flt_t
, input) – pointer to array holding diagonal of \(T\), lengthirblk[nirblk]
- offdiag (
trlib_flt_t
, input) – pointer to array holding offdiagonal of \(T\), lengthirblk[nirblk]
- warm (
trlib_int_t
, input) – set \(\ge 1\) if you want to update information about block \(\ell\), provide values inleftmost_minor
,ileftmost
,leftmost
; else0
- leftmost_minor (
trlib_flt_t
, input) – smallest eigenvalue of principal \((n_\ell-1)\times (n_\ell-1)\) submatrix of \(T_\ell\) - itmax (
trlib_int_t
, input) – maximum number of iterations - tol_abs (
trlib_flt_t
, input) – absolute stopping tolerance in Reid-Parlett zero finding, good default may be \(\sqrt{\texttt{macheps}}^{3/4}\) (TRLIB_EPS_POW_75
) - verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (char, input) – string that is printed before iteration output
- fout (FILE, input) – output stream
- timing (
trlib_int_t
, input/output) –gives timing details, provide allocated zero initialized memory of length
trlib_leftmost_timing_size()
block description 0 total duration - ileftmost (
trlib_int_t
, input/output) – index of block that corresponds to absolute smallest eigenvalue - leftmost (
trlib_flt_t
, input/output) –smallest eigenvalue of \(T\), length \(\ell\)
- on entry: allocated memory
- on exit:
leftmost[i]
smallest eigenvalue of \(T_i\)
Returns: status
TRLIB_LMR_CONV
successTRLIB_LMR_ITMAX
iteration limit exceeded
Return type: trlib_int_t
- nirblk (
-
trlib_int_t
trlib_leftmost_irreducible
(trlib_int_t n, trlib_flt_t *diag, trlib_flt_t *offdiag, trlib_int_t warm, trlib_flt_t leftmost_minor, trlib_int_t itmax, trlib_flt_t tol_abs, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_int_t *timing, trlib_flt_t *leftmost, trlib_int_t *iter_pr)¶ Computes smallest eigenvalue of irreducible symmetric tridiagonal matrix \(T \in \mathbb R^{n\times n}\), using a iteration based on last-pivot function of Parlett and Reid.
Method is sketched on p. 516 in [Gould1999].
Note that this function most likely will fail in the case of a reducible matrix (
offdiag
contains 0).Convergence
Convergence is reported if \(\texttt{up}-\texttt{low} \le \texttt{tol}\_\texttt{abs} * \max\{1, \vert \texttt{low} \vert, \vert \texttt{up} \vert \}\) or \(\texttt{prlp} \le \texttt{tol}\_\texttt{abs}\), \(\texttt{low}\) and \(\texttt{up}\) denote bracket values enclosing the leftmost eigenvalue and \(\texttt{prlp}\) denotes the last-pivot function value used in root finding.
Parameters: - n (
trlib_int_t
, input) – dimension, ensure \(n > 0\) - diag (
trlib_flt_t
, input) – pointer to array holding diagonal of \(T\), lengthn
- offdiag (
trlib_flt_t
, input) – pointer to array holding offdiagonal of \(T\), lengthn-1
- warm (
trlib_int_t
, input) –set \(\ge 1\) if you provide a valid value in
leftmost_minor
, else0
. Exact value determines which model will be used for zero-findingwarm model 0 linear model for rational function 1 sensible heuristic model choice for lifted rational function 2 asymptotic quadratic model \(\theta^2 + b \theta + c\) for lifted rational function 3 taylor quadratic model \(a \theta^2 + b \theta + c\) for lifted rational function 4 linear model \(b \theta + c\) for lifted rational function - leftmost_minor (
trlib_flt_t
, input) – smallest eigenvalue of principal \((n-1)\times (n-1)\) submatrix of \(T\) - itmax (
trlib_int_t
, input) – maximum number of iterations - tol_abs (
trlib_flt_t
, input) – absolute stopping tolerance in Reid-Parlett zero finding, good default may be \(\sqrt{\texttt{macheps}}^{3/4}\) (TRLIB_EPS_POW_75
) - verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (char, input) – string that is printed before iteration output
- fout (FILE, input) – output stream
- timing (
trlib_int_t
, input/output) –gives timing details, provide allocated zero initialized memory of length
trlib_leftmost_timing_size()
block description 0 total duration - leftmost (
trlib_flt_t
, output) – smallest eigenvalue of \(T\) - iter_pr (
trlib_int_t
, output) – number of Parlett-Reid iterations
Returns: status
TRLIB_LMR_CONV
successTRLIB_LMR_ITMAX
iteration limit exceeded
Return type: trlib_int_t
- n (
-
trlib_int_t
trlib_leftmost_timing_size
(void)¶ size that has to be allocated for
timing
intrlib_leftmost_irreducible()
andtrlib_leftmost()
CAPI trlib_eigen_inverse¶
Functions¶
-
trlib_int_t
trlib_eigen_inverse
(trlib_int_t n, trlib_flt_t *diag, trlib_flt_t *offdiag, trlib_flt_t lam_init, trlib_int_t itmax, trlib_flt_t tol_abs, trlib_flt_t *ones, trlib_flt_t *diag_fac, trlib_flt_t *offdiag_fac, trlib_flt_t *eig, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_int_t *timing, trlib_flt_t *lam_pert, trlib_flt_t *pert, trlib_int_t *iter_inv)¶ Computes eigenvector to provided eigenvalue of symmetric tridiagonal matrix \(T \in \mathbb R^{n\times n}\), using inverse iteration.
For a description of the method see https://en.wikipedia.org/wiki/Inverse_iteration.
Convergence
Convergence is reported if \(\vert \frac{1}{\Vert w_{i+1} \Vert} - \texttt{pert} \vert \le \texttt{tol}\_\texttt{abs}\), where \((T-\lambda I) w_{i+1} = v_i\), \(v_i\) the current normalized iterate and \(\texttt{pert}\) is the perturbation applied to the provided eigenvalue.
Parameters: - n (
trlib_int_t
, input) – dimension, ensure \(n > 0\) - diag (
trlib_flt_t
, input) – pointer to array holding diagonal of \(T\), lengthn
- offdiag (
trlib_flt_t
, input) – pointer to array holding offdiagonal of \(T\), lengthn-1
- lam_init (
trlib_flt_t
, input) – estimation of eigenvalue corresponding to eigenvector to compute - itmax (
trlib_int_t
, input) – maximum number of iterations - tol_abs (
trlib_flt_t
, input) – absolute stopping tolerance in inverse iteration, good default may be \(\sqrt{\texttt{macheps}}\) (TRLIB_EPS_POW_5
) - ones (
trlib_flt_t
, input) – array with every value1.0
, lengthn
- diag_fac (
trlib_flt_t
, input/output) –pointer to array holding diagonal of Cholesky factorization of \(T - \lambda I\), length
n
- on entry: allocated memory
- on exit: factorization corresponding to computed eigenvalue @p lam
- offdiag_fac –
pointer to array holding offdiagonal of Cholesky factorization of \(T - \lambda I\), length
n-1
- on entry: allocated memory
- on exit: factorization corresponding to computed eigenvalue @p lam
- eig (
trlib_flt_t
, input/output) – pointer to array holding eigenvector, lengthn
- verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (char, input) – string that is printed before iteration output
- fout (FILE, input) – output stream
- timing (
trlib_int_t
, input/output) –gives timing details, provide allocated zero initialized memory of length
trlib_eigen_timing_size()
block description 0 total duration 1 timing of linear algebra calls - lam_pert (
trlib_flt_t
, output) – eigenvalue corresponding to eigenvector - pert (
trlib_flt_t
, output) – perturbation applied to provided eigenvalue - iter_inv (
trlib_int_t
, output) – number of inverse iterations
Returns: status
TRLIB_EIR_CONV
successTRLIB_EIR_ITMAX
iteration limit exceededTRLIB_EIR_FAIL_FACTOR
failure on matrix factorizationTRLIB_EIR_FAIL_LINSOLVE
failure on backsolve
Return type: trlib_int_t
- n (
-
trlib_int_t
trlib_eigen_timing_size
(void)¶ size that has to be allocated for
timing
intrlib_eigen_inverse()
CAPI trlib_quadratic_zero¶
Functions¶
-
trlib_int_t
trlib_quadratic_zero
(trlib_flt_t c_abs, trlib_flt_t c_lin, trlib_flt_t tol, trlib_int_t verbose, trlib_int_t unicode, char *prefix, FILE *fout, trlib_flt_t *t1, trlib_flt_t *t2)¶ Computes real zeros of normalized quadratic polynomial.
Parameters: - c_abs (
trlib_flt_t
, input) – absolute coefficient - c_lin (
trlib_flt_t
, input) – coefficinet of linear term - tol (
trlib_flt_t
, input) – tolerance that indicates if ill-conditioning present, good default may be \(\texttt{macheps}^{3/4}\) (TRLIB_EPS_POW_75
) - verbose (
trlib_int_t
, input) – determines the verbosity level of output that is written tofout
- unicode (
trlib_int_t
, input) – set to1
iffout
can handle unicode, otherwise to0
- prefix (
trlib_int_t
, input) – string that is printed before iteration output - fout (FILE, input) – output stream
- t1 – first zero, \(\texttt{t1} \le \texttt{t2}\)
- t2 (
trlib_flt_t
, output) – second zero, \(\texttt{t1} \le \texttt{t2}\)
Returns: number of zeros
Return type: trlib_int_t
- c_abs (
Definitions¶
References¶
[Gould1999] | N. Gould, S. Lucidi, M. Roma, P. Toint: Solving the Trust-Region Subproblem using the Lanczos Method, SIAM J. Optim., 9(2), 504–525, (1999). http://epubs.siam.org/doi/abs/10.1137/S1052623497322735 |
[Lenders2016] | F. Lenders, C. Kirches, A. Potschka: trlib: A vector-free implementation of the GLTR method for iterative solution of the trust region problem, submitted to Optimization, Methods and Software. http://www.optimization-online.org/DB_HTML/2016/11/5724.html https://arxiv.org/abs/1611.04718 |
[Curtis2016] | F. Curtis, D. Robinson, M. Samadi: A trust region algorithm with a worst-case iteration complexity of :math:`mathcal O(epsilon^{-3/2})` for nonconvex optimization, Mathematical Programming A, 2016, pp. 1-32. http://dx.doi.org/10.1007/s10107-016-1026-2 |