Skip to content

Commit

Permalink
v0.8.2 (#137)
Browse files Browse the repository at this point in the history
* Update subsolver warning

* Update display

* Delete .vscode directory

* Delete .codecov.yml

* Delete REQUIRE

* Update news

* Update optimizer.jl
  • Loading branch information
DimitriAlston authored Oct 28, 2024
1 parent e9f8ccb commit 3b28b2e
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 82 deletions.
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

2 comments on commit 3b28b2e

@DimitriAlston
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/118181

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.8.2 -m "<description of version>" 3b28b2ec9cfb8704763d7ecb6e9c1e0a205359ad
git push origin v0.8.2

Please sign in to comment.