Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0e15b92
Add R2N and R2NLS solvers with HSL and QRMumps support
farhadrclass Jan 13, 2026
b36f192
Update src/R2NLS.jl
farhadrclass Jan 29, 2026
da4a54f
Apply suggestion from @dpo
farhadrclass Jan 29, 2026
34b0979
Apply suggestion from @dpo
farhadrclass Jan 29, 2026
884dbb3
Apply suggestions from code review
farhadrclass Jan 29, 2026
fc7337d
first round
farhadrclass Jan 29, 2026
456039e
Update R2NLS.jl
farhadrclass Jan 29, 2026
c66525e
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
24dee02
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
ad5cbb2
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
c9fe60b
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
14d889a
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
e21ff41
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
ce6443c
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
88183c9
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
3068d17
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
e88c379
Update src/R2NLS.jl
farhadrclass Feb 6, 2026
697eff6
Refactor nlp->nls and QRMumps/Krylov fixes
farhadrclass Feb 8, 2026
d20f6cf
Refactor R2N: use LineModel and simplify line search
farhadrclass Feb 8, 2026
da6ded4
Update R2N.jl
farhadrclass Feb 8, 2026
a0b3921
Update src/R2NLS.jl
farhadrclass Feb 10, 2026
043fc15
Introduce abstract subsolver API and refactor R2NLS
farhadrclass Feb 11, 2026
a6e1a37
Refactor subsolver API and QRMumps init
farhadrclass Feb 16, 2026
aad6f08
Refactor subsolver interface and implementations
farhadrclass Feb 16, 2026
693800a
Update R2N.jl
farhadrclass Feb 16, 2026
2711888
Update src/R2NLS.jl
farhadrclass Feb 16, 2026
50c74c3
Update src/R2NLS.jl
farhadrclass Feb 17, 2026
71cfbed
Refactor QRMumpsSubsolver init and return API
farhadrclass Feb 17, 2026
a4354df
Update R2NLS.jl
farhadrclass Feb 17, 2026
5e3a671
Update R2NLS.jl
farhadrclass Feb 17, 2026
7bac142
Update R2NLS.jl
farhadrclass Feb 17, 2026
ef17112
Update R2NLS.jl
farhadrclass Feb 17, 2026
241c929
Add subsolver interface; refactor QRMumps
farhadrclass Feb 18, 2026
66c3c1a
Update R2NLS.jl
farhadrclass Feb 18, 2026
7a4c66f
created small test env
farhadrclass Feb 18, 2026
9a2a3d7
Update R2NLS.jl
farhadrclass Feb 21, 2026
eb61c0d
Update R2N.jl
farhadrclass Feb 24, 2026
fa66f45
Add Arpack/TSVD deps and R2N updates
farhadrclass Feb 24, 2026
4029aeb
Update R2N.jl
farhadrclass Feb 24, 2026
190154d
Update R2N.jl
farhadrclass Feb 24, 2026
c9dbd21
Refactor subsolvers into separate modules
farhadrclass Mar 27, 2026
850194a
Use HSL subsolver direction in NPC step
farhadrclass Mar 27, 2026
b854564
Support Armijo-Goldstein NPC and fast σ update
farhadrclass Mar 27, 2026
cff3465
Update JSOSolvers.jl
farhadrclass Mar 30, 2026
6631c17
Update R2N.jl
farhadrclass Mar 30, 2026
036187d
Update R2N_subsolvers.jl
farhadrclass Mar 30, 2026
318856e
1
farhadrclass Mar 30, 2026
4866e52
Update R2N.jl
farhadrclass Mar 31, 2026
e5cbdba
Rename update! API to update_subsolver!
farhadrclass Mar 31, 2026
e812cd3
Update R2N.jl
farhadrclass Apr 2, 2026
6db8594
Multiple_Arm Bandit
farhadrclass Apr 5, 2026
6ef1e26
Update R2N_MAB.jl
farhadrclass Apr 5, 2026
775e889
Update R2N_MAB.jl
farhadrclass Apr 6, 2026
992d774
remove MAB
farhadrclass Apr 6, 2026
b975ccd
Fix subsolver σ/atol and update subtol bound
farhadrclass Apr 7, 2026
0fc816c
testing R2N
farhadrclass Apr 7, 2026
007bf13
Support Function/Type subsolver and add tests
farhadrclass Apr 8, 2026
6f20361
Update R2N_subsolvers.jl
farhadrclass Apr 16, 2026
76c3e09
fix the Hessian issue
farhadrclass Apr 16, 2026
eed735b
fix the LBFGS
farhadrclass Apr 16, 2026
941631d
Update R2N_op.jl
farhadrclass Apr 16, 2026
25bf5b8
Refactor quasi-Newton updates into callbacks
farhadrclass Apr 17, 2026
1c1ce03
Update JSOSolvers.jl
farhadrclass Apr 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,40 @@ uuid = "10dff2fc-5484-5881-a0e0-c90441020f8a"
version = "0.14.8"

[deps]
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
GenericLinearAlgebra = "14197337-ba66-59df-a3e3-ca00e7dcff7a"
HSL = "34c5aeac-e683-54a6-a0e9-6e0fdc586c50"
HSL_jll = "017b0a0e-03f4-516a-9b91-836bbd1904dd"
Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
LinearOperators = "5c8ed15e-5a4c-59e4-a42b-c7e8811fb125"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
NLPModels = "a4795742-8479-5a88-8948-cc11e1c8c1a6"
NLPModelsModifiers = "e01155f1-5c6f-4375-a9d8-616dd036575f"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
QRMumps = "422b30a1-cc69-4d85-abe7-cc07b540c444"
SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843"
SolverParameters = "d076d87d-d1f9-4ea3-a44b-64b4cdd1e470"
SolverTools = "b5612192-2639-5dc1-abfe-fbedd65fab29"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
SparseMatricesCOO = "fa32481b-f100-4b48-8dc8-c62f61b13870"
TSVD = "9449cd9e-2762-5aa3-a617-5413e99d722e"

[compat]
Krylov = "0.10.0"
LinearOperators = "2.0"
Arpack = "0.5.4"
GenericLinearAlgebra = "0.3.19"
HSL = "0.5.2"
Krylov = "0.10.1"
LinearOperators = "2.12.0"
NLPModels = "0.21"
NLPModelsModifiers = "0.7, 0.8"
QRMumps = "0.3.2"
SolverCore = "0.3"
SolverParameters = "0.1"
SolverTools = "0.10"
SparseArrays = "1.11.0"
SparseMatricesCOO = "0.2.6"
TSVD = "0.4.4"
julia = "1.10"

[extras]
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ This package provides an implementation of four classic algorithms for unconstra
> DOI: [10.1007/BF01589116](https://doi.org/10.1007/BF01589116)


- `R2N`: An inexact second-order quadratic regularization method for unconstrained optimization (with shifted L-BFGS or shifted Hessian operator);

- `R2`: a first-order quadratic regularization method for unconstrained optimization;

> E. G. Birgin, J. L. Gardenghi, J. M. Martínez, S. A. Santos, Ph. L. Toint. (2017).
> Worst-case evaluation complexity for unconstrained nonlinear optimization using
> high-order regularized models. *Mathematical Programming*, 163(1), 359-368.
> DOI: [10.1007/s10107-016-1065-8](https://doi.org/10.1007/s10107-016-1065-8)

- `R2NLS`: an inexact second-order quadratic regularization method for nonlinear least-squares problems;

- `fomo`: a first-order method with momentum for unconstrained optimization;

- `tron`: a pure Julia implementation of TRON, a trust-region solver for bound-constrained optimization described in
Expand Down Expand Up @@ -68,7 +72,7 @@ using JSOSolvers, ADNLPModels

# Rosenbrock
nlp = ADNLPModel(x -> 100 * (x[2] - x[1]^2)^2 + (x[1] - 1)^2, [-1.2; 1.0])
stats = lbfgs(nlp) # or trunk, tron, R2
stats = lbfgs(nlp) # or trunk, tron, R2, R2N
```

## Documentation
Expand Down
8 changes: 6 additions & 2 deletions docs/src/solvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
- [`trunk`](@ref)
- [`R2`](@ref)
- [`fomo`](@ref)
- [`R2N`](@ref)
- [`R2NLS`](@ref)

| Problem type | Solvers |
| --------------------- | -------- |
| Unconstrained Nonlinear Optimization Problem | [`lbfgs`](@ref), [`tron`](@ref), [`trunk`](@ref), [`R2`](@ref), [`fomo`](@ref)|
| Unconstrained Nonlinear Least Squares | [`trunk`](@ref), [`tron`](@ref) |
| Unconstrained Nonlinear Optimization Problem | [`lbfgs`](@ref), [`tron`](@ref), [`trunk`](@ref), [`R2`](@ref), [`fomo`](@ref), ['R2N'](@ref)|
| Unconstrained Nonlinear Least Squares | [`trunk`](@ref), [`tron`](@ref), ['R2NLS'](@ref)|
| Bound-constrained Nonlinear Optimization Problem | [`tron`](@ref) |
| Bound-constrained Nonlinear Least Squares | [`tron`](@ref) |

Expand All @@ -23,4 +25,6 @@ tron
trunk
R2
fomo
R2N
R2NLS
```
20 changes: 20 additions & 0 deletions my_R2N_tester/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[deps]
ADNLPModels = "54578032-b7ea-4c30-94aa-7cbd1cce6c9a"
Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
CUTEst = "1b53aba6-35b6-5f92-a507-53c67d53f819"
GenericLinearAlgebra = "14197337-ba66-59df-a3e3-ca00e7dcff7a"
HSL = "34c5aeac-e683-54a6-a0e9-6e0fdc586c50"
HSL_jll = "017b0a0e-03f4-516a-9b91-836bbd1904dd"
JSOSolvers = "10dff2fc-5484-5881-a0e0-c90441020f8a"
Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
LinearOperators = "5c8ed15e-5a4c-59e4-a42b-c7e8811fb125"
NLPModels = "a4795742-8479-5a88-8948-cc11e1c8c1a6"
NLPModelsModifiers = "e01155f1-5c6f-4375-a9d8-616dd036575f"
OptimizationProblems = "5049e819-d29b-5fba-b941-0eee7e64c1c6"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
QRMumps = "422b30a1-cc69-4d85-abe7-cc07b540c444"
Quadmath = "be4d8f0f-7fa4-5f49-b795-2f01399ab2dd"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
TSVD = "9449cd9e-2762-5aa3-a617-5413e99d722e"
77 changes: 77 additions & 0 deletions my_R2N_tester/R2N_op.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Revise
using JSOSolvers
using HSL
using Arpack, TSVD, GenericLinearAlgebra
using SparseArrays, LinearAlgebra
using ADNLPModels, Krylov, LinearOperators, NLPModels, NLPModelsModifiers, SolverCore
using Printf
using CUTEst

using OptimizationProblems, OptimizationProblems.ADNLPProblems
nlp = chainwoo(n=100)

solvers_to_test = [
("GS (Goldstein)--minres", MinresR2NSubsolver, :ag, 0.0),
# ("GS (Goldstein)--cr", CRR2NSubsolver, :ag, 0.0),
# ("Sigma Increase", MinresR2NSubsolver, :sigma, 0.0),
# ("Previous Step", MinresR2NSubsolver, :prev, 0.0),
# ("Cauchy Point", MinresR2NSubsolver, :cp, 0.0),
]


# 3. Run R2N Variants
results = []

for (name, sub_type, handler, sigma_min) in solvers_to_test
println("\nRunning $name...")
stats = R2N(
nlp;
verbose = 1,
max_iter = 700,
subsolver = sub_type,
npc_handler = handler,
σmin = sigma_min,
always_accept_npc_ag = true,
)
push!(results, (name, stats))
print("stats: ")
print(stats)
end

# 4. Run Benchmark Solver (Trunk from JSOSolvers)
println("\nRunning Trunk (JSOSolvers)...")
stats_trunk = trunk(nlp; verbose = 1, max_iter = 700)
push!(results, ("Trunk", stats_trunk))


#####
# LBFGS
# 1. Wrap the model so R2N knows it's a Quasi-Newton problem
qn_nlp = LBFGSModel(nlp)

R2N(
qn_nlp;
subsolver = MinresR2NSubsolver, # Just pass the type, R2N will construct it with qn_nlp
npc_handler = :ag,
max_iter = 750,
η1 = 1.0e-6,
verbose = 10,
fast_local_convergence = false
)



qn_nlp = LBFGSModel(nlp)

R2N(
qn_nlp;
subsolver = ShiftedLBFGSSolver, # Just pass the type, R2N will construct it with qn_nlp
npc_handler = :ag,
max_iter = 750,
η1 = 1.0e-6,
verbose = 10,
fast_local_convergence = false
)



105 changes: 105 additions & 0 deletions my_R2N_tester/R2N_subsolver_test.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
println("==============================================================")
println(" Exhaustive Testing R2N Combinations ")
println("==============================================================")

# 1. Define the Problem
n = 30
nlp = ADNLPModel(
x -> sum(100 * (x[i + 1] - x[i]^2)^2 + (x[i] - 1)^2 for i = 1:(n - 1)),
collect(1:n) ./ (n + 1),
name = "Extended Rosenbrock"
)

# 2. Define Parameter Grids for Combinations
subsolvers = [CGR2NSubsolver, CRR2NSubsolver, MinresR2NSubsolver, MinresQlpR2NSubsolver]

# Automatically append HSL solvers if available
if LIBHSL_isfunctional()
push!(subsolvers, MA97R2NSubsolver, MA57R2NSubsolver)
end

npc_handlers = [:ag, :sigma, :prev, :cp]
scp_flags = [true, false]
always_accept_npc_ags = [true, false]
fast_local_convergences = [true, false]

# 3. Storage for Results
passed_runs = []
failed_runs = []

# Calculate total combinations
total_combinations = length(subsolvers) * length(npc_handlers) * length(scp_flags) * length(always_accept_npc_ags) * length(fast_local_convergences)
println("Testing $total_combinations combinations...\n")

# 4. Execution Loop
current_run = 1
for params in Iterators.product(subsolvers, npc_handlers, scp_flags, always_accept_npc_ags, fast_local_convergences)
sub_type, handler, scp, accept_ag, fast_conv = params

# Create a string identifying this exact setup
config_name = "Sub: $(string(sub_type)) | NPC: $(handler) | scp: $(scp) | accept_ag: $(accept_ag) | fast_conv: $(fast_conv)"

print("\rProgress: $current_run / $total_combinations combinations tested...")

try
# Run silently with a smaller max_iter so the mass-test finishes quickly
stats = R2N(
nlp;
verbose = 0,
max_iter = 100,
subsolver = sub_type,
npc_handler = handler,
scp_flag = scp,
always_accept_npc_ag = accept_ag,
fast_local_convergence = fast_conv
)
push!(passed_runs, (config_name, stats.status, stats.iter, stats.objective))
catch e
# If it crashes, catch the error and the backtrace so we can inspect it later
bt = catch_backtrace()
err_msg = sprint(showerror, e, bt)
push!(failed_runs, (config_name, err_msg))
end

current_run += 1
end

println("\n\n==============================================================")
println(" Testing Summary ")
println("==============================================================")
println("Total Tested: $total_combinations")
println("Passed: $(length(passed_runs))")
println("Failed: $(length(failed_runs))")
println("==============================================================\n")

# 5. Print Error Report
if !isempty(failed_runs)
println("### 🚨 ERROR REPORT 🚨 ###\n")
for (config, err) in failed_runs
println("❌ CONFIGURATION:")
println(" ", config)
println("\n ERROR DETAILS:")

# Print just the first few lines of the stacktrace to avoid terminal flooding
err_lines = split(err, '\n')
for line in err_lines[1:min(12, length(err_lines))]
println(" ", line)
end
println("-" ^ 80)
end
else
println("🎉 All configurations ran without throwing exceptions!")
end

# Optional: Print a small sample of passed runs to verify it's working
if !isempty(passed_runs)
println("\nSample of Passed Runs:")
@printf("%-100s %-15s %-5s\n", "Configuration", "Status", "Iter")
println("-" ^ 125)
for (cfg, st, it, obj) in passed_runs[1:min(5, length(passed_runs))]
@printf("%-100s %-15s %-5d\n", cfg, st, it)
end
end

# Clean up CUTEst model memory
finalize(nlp)
Loading
Loading