Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.8.2 #137

Merged
merged 6 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion .codecov.yml

This file was deleted.

17 changes: 0 additions & 17 deletions .vscode/launch.json

This file was deleted.

6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# News for EAGO Releases

## [v0.8.2](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.2) (October 27, 2024)
- Added support for `MOI.ScalarNonlinearFunction`.
- Users can now define all constraints using `@constraint` instead of needing to use `@NLconstraint`. This applies to `@objective` as well.
- Added support for variable names.
- Updated display.

## [v0.8.1](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.1) (June 15, 2023)

- Resolved an issue where integer and binary variables would sometimes throw a `MathOptInterface.UpperBoundAlreadySet` error.
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "EAGO"
uuid = "bb8be931-2a91-5aca-9f87-79e1cb69959a"
authors = ["Matthew Wilhelm <[email protected]>, Robert Gottlieb <[email protected]>, Dimitri Alston <[email protected]>, and Matthew Stuber <[email protected]>"]
version = "0.8.1"
version = "0.8.2"

[deps]
Cassette = "7057c7e9-c182-5462-911a-8362d720325c"
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ The EAGO package has numerous features: a solver accessible from JuMP/MathOptInt

## Recent News

### [v0.8.2](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.2) (October 27, 2024)
- Added support for `MOI.ScalarNonlinearFunction`.
- Users can now define all constraints using `@constraint` instead of needing to use `@NLconstraint`. This applies to `@objective` as well.
- Added support for variable names.
- Updated display.

### [v0.8.1](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.1) (June 15, 2023)

- Resolved an issue where integer and binary variables would sometimes throw a `MathOptInterface.UpperBoundAlreadySet` error.
Expand Down
12 changes: 0 additions & 12 deletions REQUIRE

This file was deleted.

2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A development environment for robust and global optimization in Julia.
- Current Position: Alexion Pharmaceuticals
- [Robert Gottlieb](https://psor.uconn.edu/person/robert-gottlieb/), Department of Chemical and Biomolecular Engineering, University of Connecticut (UConn)
- [Dimitri Alston](https://psor.uconn.edu/person/dimitri-alston/), Department of Chemical and Biomolecular Engineering, University of Connecticut (UConn)
- [Matthew Stuber](https://chemical-biomolecular.engr.uconn.edu/people/faculty/stuber-matthew/), Associate Professor, University of Connecticut (UConn)
- [Matthew Stuber](https://chemical-biomolecular.engr.uconn.edu/people/faculty/stuber-matthew/), Pratt & Whitney Associate Professor in Advanced Systems Engineering, University of Connecticut (UConn)

If you would like to contribute, [contact us](@ref "How to Contribute to EAGO").

Expand Down
6 changes: 6 additions & 0 deletions docs/src/news.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# News for EAGO Releases

## [v0.8.2](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.2) (October 27, 2024)
- Added support for `MOI.ScalarNonlinearFunction`.
- Users can now define all constraints using `@constraint` instead of needing to use `@NLconstraint`. This applies to `@objective` as well.
- Added support for variable names.
- Updated display.

## [v0.8.1](https://github.com/PSORLab/EAGO.jl/releases/tag/v0.8.1) (June 15, 2023)

- Resolved an issue where integer and binary variables would sometimes throw a `MathOptInterface.UpperBoundAlreadySet` error.
Expand Down
19 changes: 10 additions & 9 deletions src/eago_optimizer/optimize/nonconvex/configure_subsolver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@

function set_default_config_udf!(s, m::MOI.AbstractOptimizer, verbosity::Int)
if verbosity > 0
println("EAGO lacks a specialized configuration routine for the subsolver ($(MOI.get(m, MOI.SolverName())))")
println("you selected. As a result, EAGO cannot set the subsolver tolerances based on the")
println("absolute_tolerance, relative_tolerance, and absolute_constraint_feas_tolerance")
println("parameters passed to the EAGO optimizer. Consequently, need to ensure that the tolerances")
println("set in the provided subsolver are appropriate (for instance if the absolute_tolerance = 1E-3")
println("then the absolute tolerance for a subsolver should be < 1E-4 and any feasibility tolerances")
println("should be as conservative as the absolute_constraint_feas_tolerance). If you see this message")
println("please submit an issue at https://github.com/PSORLab/EAGO.jl/issues/new/choose requesting")
println("that a configuration routine be added for this subsolver.")
@warn("""
EAGO lacks a specialized configuration routine for the subsolver ($(MOI.get(m, MOI.SolverName())))
you selected. As a result, EAGO cannot set the subsolver tolerances based on the
absolute_tolerance, relative_tolerance, and absolute_constraint_feas_tolerance
parameters passed to the EAGO optimizer. Consequently, you need to ensure that the tolerances
set in the provided subsolver are appropriate (for instance if the absolute_tolerance = 1E-3
then the absolute tolerance for a subsolver should be < 1E-4 and any feasibility tolerances
should be as conservative as the absolute_constraint_feas_tolerance). If you see this message
please submit an issue at https://github.com/PSORLab/EAGO.jl/issues/new/choose requesting
that a configuration routine be added for this subsolver.""")
end
return
end
Expand Down
57 changes: 22 additions & 35 deletions src/eago_optimizer/optimize/nonconvex/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function print_solution!(m::GlobalOptimizer)
elseif m._end_state == GS_NODE_LIMIT
println("Node Limit Exceeded")
elseif m._end_state == GS_ITERATION_LIMIT
println("Maximum Iteration Exceeded")
println("Iteration Limit Exceeded")
elseif m._end_state == GS_RELATIVE_TOL
println("Relative Tolerance Achieved")
elseif m._end_state == GS_ABSOLUTE_TOL
Expand All @@ -39,24 +39,14 @@ function print_solution!(m::GlobalOptimizer)
end
if m._end_state == GS_OPTIMAL || m._end_state == GS_RELATIVE_TOL || m._end_state == GS_ABSOLUTE_TOL
println("Optimal Solution Found at Node $(m._solution_node)")
if !_is_input_min(m)
println("Lower Bound: $(MOI.get(m, MOI.ObjectiveBound()))")
println("Upper Bound: $(MOI.get(m, MOI.ObjectiveValue()))")
else
println("Lower Bound: $(MOI.get(m, MOI.ObjectiveBound()))")
println("Upper Bound: $(MOI.get(m, MOI.ObjectiveValue()))")
end
println("Lower Bound: $(MOI.get(m, MOI.ObjectiveBound()))")
println("Upper Bound: $(MOI.get(m, MOI.ObjectiveValue()))")
elseif m._end_state == GS_INFEASIBLE
println("No Solution Found")
else
println("Best Solution Found at Node $(m._solution_node)")
if !_is_input_min(m)
println("Lower Bound: $(MOI.get(m, MOI.ObjectiveBound()))")
println("Upper Bound: $(MOI.get(m, MOI.ObjectiveValue()))")
else
println("Lower Bound: $(MOI.get(m, MOI.ObjectiveBound()))")
println("Upper Bound: $(MOI.get(m, MOI.ObjectiveValue()))")
end
println("Lower Bound: $(MOI.get(m, MOI.ObjectiveBound()))")
println("Upper Bound: $(MOI.get(m, MOI.ObjectiveValue()))")
end
if m._feasible_solution_found
println("Solution:")
Expand All @@ -68,7 +58,7 @@ function print_solution!(m::GlobalOptimizer)
addlen = maxlen .- length.(variable_names)
print_list = " ".^addlen.*variable_names
for i = 1:m._input_problem._variable_count
println(" $(print_list[i]) = $(m._continuous_solution[i])")
println(" $(print_list[i]) = $(m._continuous_solution[i])")
end
end
println(" ")
Expand Down Expand Up @@ -106,22 +96,22 @@ Print status information based on iteration count. The header print frequency is
based on the `header_iterations` setting, and the data print frequency is based on
the `output_iterations` setting.
"""
function print_iteration!(m::GlobalOptimizer)
function print_iteration!(m::GlobalOptimizer, end_flag::Bool)

if _verbosity(m) > 0

# Print header line every `header_iterations` times and print iteration summary every `output_iterations` times
if mod(m._iteration_count, m._parameters.output_iterations) === 0
if m._last_printed_iteration != m._iteration_count && (mod(m._iteration_count, m._parameters.output_iterations) === 0 || end_flag)
if m._iteration_count == m._parameters.output_iterations || mod(m._iteration_count, m._parameters.header_iterations) < m._parameters.output_iterations
println("---------------------------------------------------------------------------------------------------------------------------------")
println("| Iteration # | Nodes | Lower Bound | Upper Bound | Gap | Ratio | Timer | Time Left |")
println("---------------------------------------------------------------------------------------------------------------------------------")
end
# Print start
print_str = "| "
print_str = "| "

# Print iteration number
max_len = 12
max_len = 13
temp_str = string(m._iteration_count)
len_str = length(temp_str)
print_str *= (" "^(max_len - len_str))*temp_str*" | "
Expand All @@ -132,24 +122,15 @@ function print_iteration!(m::GlobalOptimizer)
len_str = length(temp_str)
print_str *= (" "^(max_len - len_str))*temp_str*" | "

# Determine lower and upper bound
if _is_input_min(m)
lower = m._global_lower_bound
upper = m._global_upper_bound
else
lower = m._global_lower_bound
upper = m._global_upper_bound
end

# Print lower bound
max_len = 13
temp_str = @sprintf "%.3E" lower
temp_str = @sprintf "%.3E" m._global_lower_bound
len_str = length(temp_str)
print_str *= (" "^(max_len - len_str))*temp_str*" | "

# Print upper bound
max_len = 13
temp_str = @sprintf "%.3E" upper
temp_str = @sprintf "%.3E" m._global_upper_bound
len_str = length(temp_str)
print_str *= (" "^(max_len - len_str))*temp_str*" | "

Expand All @@ -167,17 +148,23 @@ function print_iteration!(m::GlobalOptimizer)

# Print run time
max_len = 13
temp_str = @sprintf "%.3E" m._run_time
temp_str = @sprintf "%.2F" m._run_time
len_str = length(temp_str)
print_str *= (" "^(max_len - len_str))*temp_str*" | "

# Print time remaining
max_len = 13
temp_str = @sprintf "%.3E" m._time_left
temp_str = @sprintf "%.2F" m._time_left
len_str = length(temp_str)
print_str *= (" "^(max_len - len_str))*temp_str*" |"

println(print_str)

# Update printed iteration
m._last_printed_iteration = m._iteration_count
end
if end_flag
println("---------------------------------------------------------------------------------------------------------------------------------")
end
end

Expand Down Expand Up @@ -225,8 +212,8 @@ end
$(FUNCTIONNAME)

Print noteworthy information prior to running branch-and-bound. Currently prints
a note about flipping `max(f)` to `-min(-f)` internally, if a maximization problem
is inputted and `verbosity>=3`.
a note about flipping `max(f)` to `-min(-f)` internally, if the input is a
maximization problem and `verbosity>=3`.
"""
function print_preamble!(m::GlobalOptimizer)
if _verbosity(m) >= 3
Expand Down
11 changes: 6 additions & 5 deletions src/eago_optimizer/optimize/optimize_nonconvex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,7 @@ Pseudocode description of the algorithm, as implemented here:
"""
function global_solve!(m::GlobalOptimizer)

# Set counts to 1
m._iteration_count = 1
# Set initial node count
m._node_count = 1

# Prepare to run branch-and-bound
Expand All @@ -384,6 +383,8 @@ function global_solve!(m::GlobalOptimizer)
# Run branch and bound; terminate when the stack is empty or when some
# tolerance or limit is hit
while !termination_check(m)
# Update iteration counter
m._iteration_count += 1

# Fathom nodes from the stack, then pick a node and temporarily remove
# it from the stack
Expand Down Expand Up @@ -440,10 +441,9 @@ function global_solve!(m::GlobalOptimizer)
m._run_time = time() - m._start_time
m._time_left = m._parameters.time_limit - m._run_time

# Log and print information as needed and update the iteration counter
# Log and print information as needed
log_iteration!(m)
print_iteration!(m)
m._iteration_count += 1
print_iteration!(m, false)
end

# Since the algorithm has terminated, convert EAGO's end status into
Expand All @@ -452,6 +452,7 @@ function global_solve!(m::GlobalOptimizer)
set_result_status!(m)

# Print final information about the solution
print_iteration!(m, true)
print_solution!(m)
end

Expand Down
2 changes: 2 additions & 0 deletions src/eago_optimizer/types/global_optimizer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,8 @@ Base.@kwdef mutable struct GlobalOptimizer{Q,S,T<:ExtensionType} <: MOI.Abstract
_last_upper_problem_time::Float64 = 0.0
"Updated each iteration to track the time of the postprocess step"
_last_postprocessing_time::Float64 = 0.0
"Updated each time an iteration is printed"
_last_printed_iteration::Int = 0

# Reset in initial_parse! in parse.jl
"A field to track convergence progress across iterations"
Expand Down
3 changes: 2 additions & 1 deletion test/optimizer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,8 @@ end
end
@test_nowarn EAGO.print_results!(m, true)
@test_nowarn EAGO.print_results!(m, false)
@test_nowarn EAGO.print_iteration!(m)
@test_nowarn EAGO.print_iteration!(m, false)
@test_nowarn EAGO.print_iteration!(m, true)
@test_nowarn EAGO.print_node!(m)
@test_nowarn EAGO.print_problem_summary!(d, "Display Test")
end
Loading