From 6ae6e2e519c4849cd500cd37985a99d3fdea3b33 Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Fri, 13 Feb 2026 13:34:20 -0500 Subject: [PATCH 1/5] add _reset_power_norm function --- src/R2N.jl | 1 + src/TR_alg.jl | 1 + src/utils.jl | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/src/R2N.jl b/src/R2N.jl index 74c96f7b..76c5503a 100644 --- a/src/R2N.jl +++ b/src/R2N.jl @@ -225,6 +225,7 @@ function SolverCore.solve!( sub_kwargs::NamedTuple = NamedTuple(), ) where {T, V, G} reset!(stats) + _reset_power_method!(solver.v0) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/TR_alg.jl b/src/TR_alg.jl index dbab9163..3d6b38d8 100644 --- a/src/TR_alg.jl +++ b/src/TR_alg.jl @@ -219,6 +219,7 @@ function SolverCore.solve!( compute_grad::Bool = true, ) where {T, G, V} reset!(stats) + _reset_power_method!(solver.v0) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/utils.jl b/src/utils.jl index ee257198..7f607fc3 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -2,6 +2,11 @@ export RegularizedExecutionStats import SolverCore.GenericExecutionStats +# Reset the initial vector for the power method to [-1/sqrt(n), 1/sqrt(n), -1/sqrt(n), ...]. +function _reset_power_method!(v0::AbstractVector) + v0 .= (isodd.(eachindex(v0)) .* -2 .+ 1) ./ sqrt(length(v0)) +end + function power_method!(B::M, v₀::S, v₁::S, max_iter::Int = 1) where {M, S} @assert max_iter >= 1 "max_iter must be at least 1." mul!(v₁, B, v₀) From c194e13240bf4313c9c8c6860526af5fd76a2758 Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Fri, 13 Feb 2026 13:50:51 -0500 Subject: [PATCH 2/5] add LinearOperators.reset! to reset! quasi-Newton approximations --- src/R2DH.jl | 1 + src/R2N.jl | 1 + src/TRDH_alg.jl | 1 + src/TR_alg.jl | 1 + 4 files changed, 4 insertions(+) diff --git a/src/R2DH.jl b/src/R2DH.jl index d3b7aaf4..2a1abd63 100644 --- a/src/R2DH.jl +++ b/src/R2DH.jl @@ -234,6 +234,7 @@ function SolverCore.solve!( compute_grad::Bool = true, ) where {T, V} reset!(stats) + LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/R2N.jl b/src/R2N.jl index 76c5503a..c4492d42 100644 --- a/src/R2N.jl +++ b/src/R2N.jl @@ -226,6 +226,7 @@ function SolverCore.solve!( ) where {T, V, G} reset!(stats) _reset_power_method!(solver.v0) + LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/TRDH_alg.jl b/src/TRDH_alg.jl index 032e72fc..d593f9cf 100644 --- a/src/TRDH_alg.jl +++ b/src/TRDH_alg.jl @@ -247,6 +247,7 @@ function SolverCore.solve!( compute_grad::Bool = true, ) where {T, G, V} reset!(stats) + LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/TR_alg.jl b/src/TR_alg.jl index 3d6b38d8..12a0d2e4 100644 --- a/src/TR_alg.jl +++ b/src/TR_alg.jl @@ -220,6 +220,7 @@ function SolverCore.solve!( ) where {T, G, V} reset!(stats) _reset_power_method!(solver.v0) + LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected From 302a7b93712c4a4c8612819a5a9a268a0c5356af Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Fri, 13 Feb 2026 13:59:36 -0500 Subject: [PATCH 3/5] fix _reset_power_method to correct output --- src/utils.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 7f607fc3..15c53d9e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -2,9 +2,9 @@ export RegularizedExecutionStats import SolverCore.GenericExecutionStats -# Reset the initial vector for the power method to [-1/sqrt(n), 1/sqrt(n), -1/sqrt(n), ...]. +# Reset the initial vector for the power method to [1/sqrt(n), -1/sqrt(n), 1/sqrt(n), ...]. function _reset_power_method!(v0::AbstractVector) - v0 .= (isodd.(eachindex(v0)) .* -2 .+ 1) ./ sqrt(length(v0)) + v0 .= (isodd.(eachindex(v0)) .* 2 .- 1) ./ sqrt(length(v0)) end function power_method!(B::M, v₀::S, v₁::S, max_iter::Int = 1) where {M, S} From 73836e787f9e17874cd78f8c13d6cc1f3233cb6e Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Fri, 13 Feb 2026 14:16:36 -0500 Subject: [PATCH 4/5] implement SolverCore.reset!(solver) functions --- src/R2DH.jl | 7 ++++++- src/R2N.jl | 9 +++++++-- src/TRDH_alg.jl | 7 ++++++- src/TR_alg.jl | 10 ++++++++-- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/R2DH.jl b/src/R2DH.jl index 2a1abd63..ea8c84ba 100644 --- a/src/R2DH.jl +++ b/src/R2DH.jl @@ -81,6 +81,12 @@ function R2DHSolver( ) end +function SolverCore.reset!(solver::R2DHSolver) + LinearOperators.reset!(solver.D) +end + +SolverCore.reset!(solver::R2DHSolver, model) = SolverCore.reset!(solver) + """ R2DH(reg_nlp; kwargs…) @@ -234,7 +240,6 @@ function SolverCore.solve!( compute_grad::Bool = true, ) where {T, V} reset!(stats) - LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/R2N.jl b/src/R2N.jl index c4492d42..7c088848 100644 --- a/src/R2N.jl +++ b/src/R2N.jl @@ -96,6 +96,13 @@ function R2NSolver( ) end +function SolverCore.reset!(solver::R2NSolver) + _reset_power_method!(solver.v0) + LinearOperators.reset!(solver.subpb.model.B) +end + +SolverCore.reset!(solver::R2NSolver, model) = SolverCore.reset!(solver) + """ R2N(reg_nlp; kwargs…) @@ -225,8 +232,6 @@ function SolverCore.solve!( sub_kwargs::NamedTuple = NamedTuple(), ) where {T, V, G} reset!(stats) - _reset_power_method!(solver.v0) - LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/TRDH_alg.jl b/src/TRDH_alg.jl index d593f9cf..75127487 100644 --- a/src/TRDH_alg.jl +++ b/src/TRDH_alg.jl @@ -90,6 +90,12 @@ function TRDHSolver( ) end +function SolverCore.reset!(solver::TRDHSolver) + LinearOperators.reset!(solver.D) +end + +SolverCore.reset!(solver::TRDHSolver, model) = SolverCore.reset!(solver) + """ TRDH(reg_nlp; kwargs…) TRDH(nlp, h, χ, options; kwargs...) @@ -247,7 +253,6 @@ function SolverCore.solve!( compute_grad::Bool = true, ) where {T, G, V} reset!(stats) - LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected diff --git a/src/TR_alg.jl b/src/TR_alg.jl index 12a0d2e4..ca23a13e 100644 --- a/src/TR_alg.jl +++ b/src/TR_alg.jl @@ -95,6 +95,14 @@ function TRSolver( ) end +function SolverCore.reset!(solver::TRSolver) + _reset_power_method!(solver.v0) + LinearOperators.reset!(solver.subpb.model.B) +end + +SolverCore.reset!(solver::TRSolver, model) = SolverCore.reset!(solver) + + """ TR(reg_nlp; kwargs…) TR(nlp, h, χ, options; kwargs...) @@ -219,8 +227,6 @@ function SolverCore.solve!( compute_grad::Bool = true, ) where {T, G, V} reset!(stats) - _reset_power_method!(solver.v0) - LinearOperators.reset!(reg_nlp.model) # Retrieve workspace selected = reg_nlp.selected From 3c898ec6f756ee7319beb58220fbf41835934e0c Mon Sep 17 00:00:00 2001 From: Maxence Gollier Date: Fri, 13 Feb 2026 16:55:16 -0500 Subject: [PATCH 5/5] add condition on B before resetting --- src/R2N.jl | 3 ++- src/TR_alg.jl | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/R2N.jl b/src/R2N.jl index 7c088848..8b4eb014 100644 --- a/src/R2N.jl +++ b/src/R2N.jl @@ -98,7 +98,8 @@ end function SolverCore.reset!(solver::R2NSolver) _reset_power_method!(solver.v0) - LinearOperators.reset!(solver.subpb.model.B) + B = solver.subpb.model.B + isa(B, AbstractLinearOperator) && LinearOperators.reset!(B) end SolverCore.reset!(solver::R2NSolver, model) = SolverCore.reset!(solver) diff --git a/src/TR_alg.jl b/src/TR_alg.jl index ca23a13e..484a6a37 100644 --- a/src/TR_alg.jl +++ b/src/TR_alg.jl @@ -97,7 +97,8 @@ end function SolverCore.reset!(solver::TRSolver) _reset_power_method!(solver.v0) - LinearOperators.reset!(solver.subpb.model.B) + reset_data!(solver.subpb.model) + LinearOperators.reset!(solver.subpb.model) end SolverCore.reset!(solver::TRSolver, model) = SolverCore.reset!(solver)