Advanced usage of FletcherPenaltySolver.jl

Contents

The main function exported by this package is the function fps_solve whose basic usage has been illustrated previously. It is also possible to fine-tune the parameters used in the implementation in two different ways.

Examples

FletcherPenaltySolver.jl exports the function fps_solve:

   fps_solve(nlp::AbstractNLPModel, x0::AbstractVector{T} = nlp.meta.x0; verbose::Int = 0, subsolver_verbose::Int = 0, lagrange_bound = 1 / sqrt(eps(T)), kwargs...)
   fps_solve(stp::NLPStopping; verbose::Int = 0, subsolver_verbose::Int = 0, lagrange_bound = 1 / sqrt(eps()), kwargs...)
   fps_solve(stp::NLPStopping, fpssolver::FPSSSolver{T, QDS, US}; verbose::Int = 0, subsolver_verbose::Int = 0, lagrange_bound::T = 1 / sqrt(eps(T)))

It is, therefore, possible to either call fps_solve(nlp, x, kwargs...) and the keywords arguments are passed to both NLPStopping and/or FPSSSolver constructor or build an instance of NLPStopping and/or FPSSSolver directly.

using ADNLPModels, FletcherPenaltySolver

nlp = ADNLPModel(
  x -> 100 * (x[2] - x[1]^2)^2 + (x[1] - 1)^2,
  [-1.2; 1.0],
  x->[x[1] * x[2] - 1],
  [0.0], [0.0],
  name = "Rosenbrock with x₁x₂=1"
)
stats = fps_solve(nlp)
"Execution stats: first-order stationary"

The alternative using NLPStopping, see Stopping.jl, allow to reuse the same memory if one would re-solve a problem of the same dimension

using ADNLPModels, FletcherPenaltySolver, Stopping
stp = NLPStopping(nlp)
stats = fps_solve(stp)
stp.current_state.x .= rand(2)
stats = fps_solve(stp)
"Execution stats: unknown"

The FPSSSolver, see FPSSSolver, contains all the metadata and additional pre-allocated memory used by the algorithm.

using SolverCore
stp = NLPStopping(nlp)
data = FPSSSolver(stp)
stats = GenericExecutionStats(nlp)
stats = SolverCore.solve!(data, stp, stats)
"Execution stats: first-order stationary"

List of possible options

Find below a list of the main options of fps_solve.

Tolerances on the problem

We use Stopping.jl to control the algorithmic flow, we refer to Stopping.jl and https://solverstoppingjulia.github.io for tutorials and documentation. By default, we use the function Fletcher_penalty_optimality_check as optimality check, and the default tol_check is rtol [1 + c(x₀); 1 + ∇f(x₀)] with rtol = 1e-7.

Additional parameters used in stopping the algorithm are defined in the following table.

ParametersTypeDefaultDescription
lagrange_boundReal1 / sqrt(eps(T))bounds on estimated Lagrange multipliers.
subsolver_max_iterReal20000maximum iteration for the subproblem solver.

Algorithmic parameters

The metadata is defined in a AlgoData structure at the initialization of FPSSolver.

ParametersTypeDefaultDescription
σ_0Real1e3Initialize subproblem's parameter σ
σ_maxReal1 / √eps(T)Maximum value for subproblem's parameter σ
σ_updateRealT(2)Update subproblem's parameter σ
ρ_0RealT(2)Initialize subproblem's parameter ρ
ρ_maxReal1 / √eps(T)Maximum value for subproblem's parameter ρ
ρ_updateRealT(2)Update subproblem's parameter ρ
δ_0Real√eps(T)Initialize subproblem's parameter δ
δ_maxReal1 / √eps(T)Maximum value for subproblem's parameter δ
δ_updateRealT(10)Update subproblem's parameter δ
η_1Realzero(T)Initialize subproblem's parameter η
η_updateRealone(T)Update subproblem's parameter η
yMRealtypemax(T)bound on the Lagrange multipliers
ΔRealT(0.95)expected decrease in feasibility between two iterations
subproblem_solverFunctionKNITRO.has_knitro() ? NLPModelsKnitro.knitro : ipoptsolver used for the subproblem, see also JSOSolvers.jl
subpb_unbounded_thresholdReal1 / √eps(T)below the opposite of this value, the subproblem is unbounded
atol_subFunctionatol -> atolabsolute tolerance for the subproblem in function of atol
rtol_subFunctionrtol -> rtolrelative tolerance for the subproblem in function of rtol
hessian_approxeither Val(1) or Val(2)Val(2)it selects the hessian approximation
convex_subproblemBoolfalsetrue if the subproblem is convex. Useful to set the convex option in knitro.
qds_solverSymbol:ldltInitialize the QDSolver to solve quasi-definite systems, either :ldlt or :iterative.

Feasibility step

The metadata for the feasibility procedure is defined in a GNSolver structure at the initialization of FPSSolver.

ParametersTypeDefaultDescription
η₁Real1e-3Feasibility step: decrease the trust-region radius when Ared/Pred < η₁.
η₂Real0.66Feasibility step: increase the trust-region radius when Ared/Pred > η₂.
σ₁Real0.25Feasibility step: decrease coefficient of the trust-region radius.
σ₂Real2.0Feasibility step: increase coefficient of the trust-region radius.
Δ₀Real1.0Feasibility step: initial radius.
feas_expected_decreaseReal0.95Feasibility step: bad steps are when ‖c(z)‖ / ‖c(x)‖ >feasexpecteddecrease.
bad_steps_limInteger3Feasibility step: consecutive bad steps before using a second order step.
TR_compute_stepKrylovSolverLsmrSolverCompute the direction in feasibility step.
aggressive_stepKrylovSolverCgSolverCompute the (aggressive) direction in feasibility step.