diff --git a/src/optimize/projected/projectednewton.jl b/src/optimize/projected/projectednewton.jl index 89a5269..949afe6 100644 --- a/src/optimize/projected/projectednewton.jl +++ b/src/optimize/projected/projectednewton.jl @@ -61,16 +61,33 @@ end isbinding(i, j) = i & j factorize(ab::ActiveBox, M) = ab.factorize(M) - function solve( - prob::OptimizationProblem, + problem::OptimizationProblem, x0, + approach::ActiveBox, + options::OptimizationOptions, +) + B0 = false * x0 * x0' + I + s0 = (x0, B0) + _solve(problem, s0, approach, options) +end +function solve( + problem::OptimizationProblem, + s0::Tuple, + approach::ActiveBox, + options::OptimizationOptions, +) + _solve(problem, s0, approach, options) +end + +function _solve( + prob::OptimizationProblem, + s0::Tuple, scheme::ActiveBox, options::OptimizationOptions, ) t0 = time() - - x0, B0 = x0, (false * x0 * x0' + I) + x0, B0 = s0 lower, upper = bounds(prob) if isnothing(scheme.ϵ) diff --git a/src/optimize/univariate/brentmin.jl b/src/optimize/univariate/brentmin.jl index c8d2488..3d2d0b2 100644 --- a/src/optimize/univariate/brentmin.jl +++ b/src/optimize/univariate/brentmin.jl @@ -14,6 +14,7 @@ function solve( end function _solve(prob, bm::BrentMin, options) + time0 = time() a, b = bounds(prob) T = typeof(a) t = 1e-8 @@ -22,10 +23,11 @@ function _solve(prob, bm::BrentMin, options) e = d = 0 * x - fv = fw = fx = value(prob, x) + f0 = fv = fw = fx = value(prob, x) p = q = r = 0 * x - - for i = 1:options.maxiter + brent_iter = 0 + while brent_iter < options.maxiter + brent_iter += 1 m = (a + b) / 2 tol = eps(T) * abs(x) + t if abs(x - m) > 2 * tol - (b - a) / 2 # stopping crit @@ -45,15 +47,11 @@ function _solve(prob, bm::BrentMin, options) end if abs(p) < abs(q * r / 2) && p < q * (a - x) && p < q * (b - x) - # the do the parapolic interpolation + # then do the parapolic interpolation d = p / q u = x + d if u - a < 2 * tol || b - u < 2 * tol - if x < m # this should just use sign - d = tol - else - d = -tol - end + d = sign(m-x)*tol end else # do golden section @@ -104,12 +102,6 @@ function _solve(prob, bm::BrentMin, options) break end end - return x, fx -end - -#= -prob = OptimizationProblem(ScalarObjective(;f=x->sign(x)), (-2.0,2.0)) -@time solve(prob, 0.0, BrentMin(), OptimizationOptions()) - -=# + return ConvergenceInfo(bm, (;x, f0, minimum=fx, time=time()-time0, iter=brent_iter), options) +end diff --git a/test/optimize/interface.jl b/test/optimize/interface.jl index c7ccd0d..9a0cf99 100644 --- a/test/optimize/interface.jl +++ b/test/optimize/interface.jl @@ -250,12 +250,21 @@ const brent_prob = OptimizationProblem(brent_scalar, (-2.0, 2.0)) @test alloc == 0 end +const f3(x) = abs(x) +const obj3 = ScalarObjective(; f=f3) +const prob3 = OptimizationProblem(obj3, (-10.1, 9.0)) @testset "brentmin" begin f(x) = (5.0 + x)^2.0 obj = ScalarObjective(; f) prob = OptimizationProblem(obj, (-10.1, 9.0)) - @test all(abs.(solve(prob, BrentMin(), OptimizationOptions()) .- (-5.0, 0.0)) .< 1e-8) + f2(x) = abs(x) + obj2 = ScalarObjective(; f=f2) + prob2 = OptimizationProblem(obj2, (-10.1, 9.0)) + + @test all(abs.(solve(prob, BrentMin(), OptimizationOptions()).info.minimum) .< 1e-8) + @test all(abs.(solve(prob2, BrentMin(), OptimizationOptions()).info.minimum) .< 1e-8) + @test all(abs.(solve(prob3, BrentMin(), OptimizationOptions()).info.minimum) .< 1e-8) end @@ -523,6 +532,11 @@ solve(static_prob_qn, rand(3), AdaMax(), OptimizationOptions(maxiter = 1000)) @test res_unc.info.solution ≈ [3.0, 2.0] res_con = solve(prob_on_bounds, copy(start), ActiveBox(), OptimizationOptions()) @test res_con.info.solution ≈ [3.5, 1.6165968467448326] + + res_con_matrix = solve(prob_on_bounds, (copy(start), [1.0 0.0;0.0 1.0]) , ActiveBox(), OptimizationOptions()) + @test res_con_matrix.info.B isa Matrix + res_con_mmatrix = solve(prob_on_bounds, (copy(start), @MMatrix([1.0 0.0;0.0 1.0])) , ActiveBox(), OptimizationOptions()) + @test res_con_mmatrix.info.B isa MMatrix end function fourth_f(x)