Skip to content

Commit

Permalink
Merge branch 'master' into 1.9-ext
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Jun 27, 2023
2 parents 74d513f + 0f123b8 commit 08013f6
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 72 deletions.
4 changes: 2 additions & 2 deletions CITATION.bib
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@article{Lubin2023,
author = {Miles Lubin and Oscar Dowson and Joaquim Dias Garcia and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
title = {JuMP 1.0: Recent improvements to a modeling language for mathematical optimization},
author = {Miles Lubin and Oscar Dowson and Joaquim {Dias Garcia} and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
title = {{JuMP} 1.0: {R}ecent improvements to a modeling language for mathematical optimization},
journal = {Mathematical Programming Computation},
year = {2023},
doi = {10.1007/s12532-023-00239-3}
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ JuMPDimensionalDataExt = "DimensionalData"

[compat]
DimensionalData = "0.24"
MathOptInterface = "1.17"
MathOptInterface = "1.18"
MutableArithmetics = "1"
OrderedCollections = "1"
SnoopPrecompile = "1"
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ following paper ([preprint](https://arxiv.org/abs/2206.03866)):

```bibtex
@article{Lubin2023,
author = {Miles Lubin and Oscar Dowson and Joaquim Dias Garcia and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
title = {JuMP 1.0: Recent improvements to a modeling language for mathematical optimization},
author = {Miles Lubin and Oscar Dowson and Joaquim {Dias Garcia} and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
title = {{JuMP} 1.0: {R}ecent improvements to a modeling language for mathematical optimization},
journal = {Mathematical Programming Computation},
year = {2023},
doi = {10.1007/s12532-023-00239-3}
Expand All @@ -68,7 +68,7 @@ For earlier works, see:
```bibtex
@article{DunningHuchetteLubin2017,
author = {Iain Dunning and Joey Huchette and Miles Lubin},
title = {JuMP: A Modeling Language for Mathematical Optimization},
title = {{JuMP}: {A} {M}odeling {L}anguage for {M}athematical {O}ptimization},
journal = {SIAM Review},
volume = {59},
number = {2},
Expand All @@ -82,7 +82,7 @@ For earlier works, see:
```bibtex
@article{LubinDunningIJOC,
author = {Miles Lubin and Iain Dunning},
title = {Computing in Operations Research Using Julia},
title = {{C}omputing in {O}perations {R}esearch {U}sing {J}ulia},
journal = {INFORMS Journal on Computing},
volume = {27},
number = {2},
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Ipopt = "=1.4.1"
JSON = "0.21"
JSONSchema = "1"
Literate = "2.8"
MathOptInterface = "=1.17.1"
MathOptInterface = "=1.18.0"
MultiObjectiveAlgorithms = "=1.0.0"
Plots = "1"
SCS = "=1.2.0"
Expand Down
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ following paper ([preprint](https://arxiv.org/abs/2206.03866)):

```bibtex
@article{Lubin2023,
author = {Miles Lubin and Oscar Dowson and Joaquim Dias Garcia and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
title = {JuMP 1.0: Recent improvements to a modeling language for mathematical optimization},
author = {Miles Lubin and Oscar Dowson and Joaquim {Dias Garcia} and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
title = {{JuMP} 1.0: {R}ecent improvements to a modeling language for mathematical optimization},
journal = {Mathematical Programming Computation},
year = {2023},
doi = {10.1007/s12532-023-00239-3}
Expand Down
18 changes: 7 additions & 11 deletions docs/src/manual/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -1222,19 +1222,15 @@ ERROR: MethodError: no method matching set_lower_bound(::AffExpr, ::Float64)
[...]
```

However, you can convert the matrix into one in which the upper triangular
elements are `VariableRef` and the lower triangular elements are `AffExpr` as
follows:
Instead, you can convert an upper-triangular elements to a variable as follows:
```jldoctest skewsymmetric
julia> y = Union{VariableRef,AffExpr}[
j > i ? first(keys(x[i, j].terms)) : x[i, j]
for i in 1:size(x, 1), j in 1:size(x, 2)
]
2×2 Matrix{Union{VariableRef, AffExpr}}:
0 x[1,2]
-x[1,2] 0
julia> to_variable(x::AffExpr) = first(keys(x.terms))
to_variable (generic function with 1 method)
julia> to_variable(x[1, 2])
x[1,2]
julia> set_lower_bound(y[1, 2], 0.0)
julia> set_lower_bound(to_variable(x[1, 2]), 0.0)
```

### Example: Hermitian positive semidefinite variables
Expand Down
7 changes: 2 additions & 5 deletions src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ end

function build_constraint(
_error::Function,
x::Matrix,
x::AbstractMatrix,
set::MOI.AbstractVectorSet,
)
return _error(
Expand All @@ -793,10 +793,7 @@ end
function build_constraint(
_error::Function,
::Matrix,
T::Union{
MOI.PositiveSemidefiniteConeSquare,
MOI.PositiveSemidefiniteConeTriangle,
},
T::MOI.PositiveSemidefiniteConeTriangle,
)
return _error("instead of `$(T)`, use `JuMP.PSDCone()`.")
end
Expand Down
2 changes: 2 additions & 0 deletions src/optimizer_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,8 @@ function set_start_values(
for (ci, dual_start) in constraint_dual
set_dual_start_value(ci, dual_start)
end
# Needed for models which bridge `min f(x)` into `min t; t >= f(x)`.
MOI.set(model, MOI.Bridges.Objective.SlackBridgePrimalDualStart(), nothing)
return
end

Expand Down
100 changes: 63 additions & 37 deletions src/sd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -137,25 +137,6 @@ triangular part of the matrix is constrained to belong to the
"""
struct PSDCone end

function build_constraint(
_error::Function,
f::AbstractMatrix{<:AbstractJuMPScalar},
::Nonnegatives,
extra::PSDCone,
)
return build_constraint(_error, f, extra)
end

function build_constraint(
_error::Function,
f::AbstractMatrix{<:AbstractJuMPScalar},
::Nonpositives,
extra::PSDCone,
)
new_f = _MA.operate!!(*, -1, f)
return build_constraint(_error, new_f, extra)
end

"""
SymmetricMatrixShape
Expand All @@ -167,6 +148,7 @@ lower-left triangular part given row by row).
struct SymmetricMatrixShape <: AbstractShape
side_dimension::Int
end

function reshape_vector(
vectorized_form::Vector{T},
shape::SymmetricMatrixShape,
Expand All @@ -181,12 +163,14 @@ function reshape_vector(
end
return LinearAlgebra.Symmetric(matrix)
end

function reshape_set(
::MOI.PositiveSemidefiniteConeTriangle,
::SymmetricMatrixShape,
)
return PSDCone()
end

function vectorize(matrix, ::SymmetricMatrixShape)
n = LinearAlgebra.checksquare(matrix)
return [matrix[i, j] for j in 1:n for i in 1:j]
Expand Down Expand Up @@ -414,12 +398,7 @@ function build_variable(
)
n = _square_side(_error, variables)
set = MOI.PositiveSemidefiniteConeTriangle(n)
shape = SymmetricMatrixShape(n)
return VariablesConstrainedOnCreation(
_vectorize_variables(_error, variables),
set,
shape,
)
return build_variable(_error, variables, set)
end

function value(
Expand Down Expand Up @@ -476,12 +455,7 @@ function build_constraint(
::PSDCone,
) where {V<:AbstractJuMPScalar,M<:AbstractMatrix{V}}
n = LinearAlgebra.checksquare(Q)
shape = SymmetricMatrixShape(n)
return VectorConstraint(
vectorize(Q, shape),
MOI.PositiveSemidefiniteConeTriangle(n),
shape,
)
return build_constraint(_error, Q, MOI.PositiveSemidefiniteConeTriangle(n))
end

"""
Expand Down Expand Up @@ -511,12 +485,7 @@ function build_constraint(
::PSDCone,
)
n = LinearAlgebra.checksquare(Q)
shape = SquareMatrixShape(n)
return VectorConstraint(
vectorize(Q, shape),
MOI.PositiveSemidefiniteConeSquare(n),
shape,
)
return build_constraint(_error, Q, MOI.PositiveSemidefiniteConeSquare(n))
end

"""
Expand Down Expand Up @@ -742,3 +711,60 @@ function build_constraint(_error::Function, ::AbstractMatrix, ::Zeros)
"`LinearAlgebra.Symmetric` or `LinearAlgebra.Hermitian`.",
)
end

function build_constraint(
_error::Function,
Q::LinearAlgebra.Symmetric{V,M},
set::MOI.AbstractSymmetricMatrixSetTriangle,
) where {V<:AbstractJuMPScalar,M<:AbstractMatrix{V}}
n = LinearAlgebra.checksquare(Q)
shape = SymmetricMatrixShape(n)
return VectorConstraint(vectorize(Q, shape), set, shape)
end

function build_constraint(
_error::Function,
Q::AbstractMatrix{<:AbstractJuMPScalar},
set::MOI.AbstractSymmetricMatrixSetSquare,
)
n = LinearAlgebra.checksquare(Q)
shape = SquareMatrixShape(n)
return VectorConstraint(vectorize(Q, shape), set, shape)
end

function build_constraint(
_error::Function,
f::AbstractMatrix{<:AbstractJuMPScalar},
::Nonnegatives,
extra::Union{
MOI.AbstractSymmetricMatrixSetTriangle,
MOI.AbstractSymmetricMatrixSetSquare,
PSDCone,
},
)
return build_constraint(_error, f, extra)
end

function build_constraint(
_error::Function,
f::AbstractMatrix{<:AbstractJuMPScalar},
::Nonpositives,
extra::Union{
MOI.AbstractSymmetricMatrixSetTriangle,
MOI.AbstractSymmetricMatrixSetSquare,
PSDCone,
},
)
new_f = _MA.operate!!(*, -1, f)
return build_constraint(_error, new_f, extra)
end

function build_variable(
_error::Function,
variables::Matrix{<:AbstractVariable},
set::MOI.AbstractSymmetricMatrixSetTriangle,
)
n = _square_side(_error, variables)
x = _vectorize_variables(_error, variables)
return VariablesConstrainedOnCreation(x, set, SymmetricMatrixShape(n))
end
9 changes: 0 additions & 9 deletions test/test_constraint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -652,15 +652,6 @@ function test_extension_PSD_constraint_errors(
)
model = ModelType()
@variable(model, X[1:2, 1:2])
err = ErrorException(
"In `@constraint(model, X in MOI.PositiveSemidefiniteConeSquare(2))`:" *
" instead of `MathOptInterface.PositiveSemidefiniteConeSquare(2)`," *
" use `JuMP.PSDCone()`.",
)
@test_throws_strip(
err,
@constraint(model, X in MOI.PositiveSemidefiniteConeSquare(2))
)
err = ErrorException(
"In `@constraint(model, X in MOI.PositiveSemidefiniteConeTriangle(2))`:" *
" instead of `MathOptInterface.PositiveSemidefiniteConeTriangle(2)`," *
Expand Down
14 changes: 14 additions & 0 deletions test/test_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,20 @@ function test_model_quad_to_soc_start_values()
return
end

function test_SlackBridgePrimalDualStart()
inner = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}())
mock = MOI.Utilities.MockOptimizer(inner)
model = direct_model(MOI.Bridges.Objective.Slack{Float64}(mock))
@variable(model, x, start = 1.0)
@objective(model, Min, x^2)
set_start_values(model; variable_primal_start = start_value)
F, S = MOI.ScalarQuadraticFunction{Float64}, MOI.LessThan{Float64}
ci = first(MOI.get(inner, MOI.ListOfConstraintIndices{F,S}()))
@test MOI.get(inner, MOI.ConstraintPrimalStart(), ci) == 0.0
@test MOI.get(inner, MOI.ConstraintDualStart(), ci) == -1.0
return
end

function test_keyword_getindex()
err = JuMP._get_index_keyword_indexing_error()
model = Model()
Expand Down

0 comments on commit 08013f6

Please sign in to comment.