Skip to content

Commit 08013f6

Browse files
authored
Merge branch 'master' into 1.9-ext
2 parents 74d513f + 0f123b8 commit 08013f6

File tree

11 files changed

+98
-72
lines changed

11 files changed

+98
-72
lines changed

CITATION.bib

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@article{Lubin2023,
2-
author = {Miles Lubin and Oscar Dowson and Joaquim Dias Garcia and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
3-
title = {JuMP 1.0: Recent improvements to a modeling language for mathematical optimization},
2+
author = {Miles Lubin and Oscar Dowson and Joaquim {Dias Garcia} and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
3+
title = {{JuMP} 1.0: {R}ecent improvements to a modeling language for mathematical optimization},
44
journal = {Mathematical Programming Computation},
55
year = {2023},
66
doi = {10.1007/s12532-023-00239-3}

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ JuMPDimensionalDataExt = "DimensionalData"
2020

2121
[compat]
2222
DimensionalData = "0.24"
23-
MathOptInterface = "1.17"
23+
MathOptInterface = "1.18"
2424
MutableArithmetics = "1"
2525
OrderedCollections = "1"
2626
SnoopPrecompile = "1"

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ following paper ([preprint](https://arxiv.org/abs/2206.03866)):
5454

5555
```bibtex
5656
@article{Lubin2023,
57-
author = {Miles Lubin and Oscar Dowson and Joaquim Dias Garcia and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
58-
title = {JuMP 1.0: Recent improvements to a modeling language for mathematical optimization},
57+
author = {Miles Lubin and Oscar Dowson and Joaquim {Dias Garcia} and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
58+
title = {{JuMP} 1.0: {R}ecent improvements to a modeling language for mathematical optimization},
5959
journal = {Mathematical Programming Computation},
6060
year = {2023},
6161
doi = {10.1007/s12532-023-00239-3}
@@ -68,7 +68,7 @@ For earlier works, see:
6868
```bibtex
6969
@article{DunningHuchetteLubin2017,
7070
author = {Iain Dunning and Joey Huchette and Miles Lubin},
71-
title = {JuMP: A Modeling Language for Mathematical Optimization},
71+
title = {{JuMP}: {A} {M}odeling {L}anguage for {M}athematical {O}ptimization},
7272
journal = {SIAM Review},
7373
volume = {59},
7474
number = {2},
@@ -82,7 +82,7 @@ For earlier works, see:
8282
```bibtex
8383
@article{LubinDunningIJOC,
8484
author = {Miles Lubin and Iain Dunning},
85-
title = {Computing in Operations Research Using Julia},
85+
title = {{C}omputing in {O}perations {R}esearch {U}sing {J}ulia},
8686
journal = {INFORMS Journal on Computing},
8787
volume = {27},
8888
number = {2},

docs/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Ipopt = "=1.4.1"
4444
JSON = "0.21"
4545
JSONSchema = "1"
4646
Literate = "2.8"
47-
MathOptInterface = "=1.17.1"
47+
MathOptInterface = "=1.18.0"
4848
MultiObjectiveAlgorithms = "=1.0.0"
4949
Plots = "1"
5050
SCS = "=1.2.0"

docs/src/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ following paper ([preprint](https://arxiv.org/abs/2206.03866)):
8787

8888
```bibtex
8989
@article{Lubin2023,
90-
author = {Miles Lubin and Oscar Dowson and Joaquim Dias Garcia and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
91-
title = {JuMP 1.0: Recent improvements to a modeling language for mathematical optimization},
90+
author = {Miles Lubin and Oscar Dowson and Joaquim {Dias Garcia} and Joey Huchette and Beno{\^i}t Legat and Juan Pablo Vielma},
91+
title = {{JuMP} 1.0: {R}ecent improvements to a modeling language for mathematical optimization},
9292
journal = {Mathematical Programming Computation},
9393
year = {2023},
9494
doi = {10.1007/s12532-023-00239-3}

docs/src/manual/variables.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,19 +1222,15 @@ ERROR: MethodError: no method matching set_lower_bound(::AffExpr, ::Float64)
12221222
[...]
12231223
```
12241224

1225-
However, you can convert the matrix into one in which the upper triangular
1226-
elements are `VariableRef` and the lower triangular elements are `AffExpr` as
1227-
follows:
1225+
Instead, you can convert an upper-triangular elements to a variable as follows:
12281226
```jldoctest skewsymmetric
1229-
julia> y = Union{VariableRef,AffExpr}[
1230-
j > i ? first(keys(x[i, j].terms)) : x[i, j]
1231-
for i in 1:size(x, 1), j in 1:size(x, 2)
1232-
]
1233-
2×2 Matrix{Union{VariableRef, AffExpr}}:
1234-
0 x[1,2]
1235-
-x[1,2] 0
1227+
julia> to_variable(x::AffExpr) = first(keys(x.terms))
1228+
to_variable (generic function with 1 method)
1229+
1230+
julia> to_variable(x[1, 2])
1231+
x[1,2]
12361232
1237-
julia> set_lower_bound(y[1, 2], 0.0)
1233+
julia> set_lower_bound(to_variable(x[1, 2]), 0.0)
12381234
```
12391235

12401236
### Example: Hermitian positive semidefinite variables

src/macros.jl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ end
781781

782782
function build_constraint(
783783
_error::Function,
784-
x::Matrix,
784+
x::AbstractMatrix,
785785
set::MOI.AbstractVectorSet,
786786
)
787787
return _error(
@@ -793,10 +793,7 @@ end
793793
function build_constraint(
794794
_error::Function,
795795
::Matrix,
796-
T::Union{
797-
MOI.PositiveSemidefiniteConeSquare,
798-
MOI.PositiveSemidefiniteConeTriangle,
799-
},
796+
T::MOI.PositiveSemidefiniteConeTriangle,
800797
)
801798
return _error("instead of `$(T)`, use `JuMP.PSDCone()`.")
802799
end

src/optimizer_interface.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,8 @@ function set_start_values(
11511151
for (ci, dual_start) in constraint_dual
11521152
set_dual_start_value(ci, dual_start)
11531153
end
1154+
# Needed for models which bridge `min f(x)` into `min t; t >= f(x)`.
1155+
MOI.set(model, MOI.Bridges.Objective.SlackBridgePrimalDualStart(), nothing)
11541156
return
11551157
end
11561158

src/sd.jl

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -137,25 +137,6 @@ triangular part of the matrix is constrained to belong to the
137137
"""
138138
struct PSDCone end
139139

140-
function build_constraint(
141-
_error::Function,
142-
f::AbstractMatrix{<:AbstractJuMPScalar},
143-
::Nonnegatives,
144-
extra::PSDCone,
145-
)
146-
return build_constraint(_error, f, extra)
147-
end
148-
149-
function build_constraint(
150-
_error::Function,
151-
f::AbstractMatrix{<:AbstractJuMPScalar},
152-
::Nonpositives,
153-
extra::PSDCone,
154-
)
155-
new_f = _MA.operate!!(*, -1, f)
156-
return build_constraint(_error, new_f, extra)
157-
end
158-
159140
"""
160141
SymmetricMatrixShape
161142
@@ -167,6 +148,7 @@ lower-left triangular part given row by row).
167148
struct SymmetricMatrixShape <: AbstractShape
168149
side_dimension::Int
169150
end
151+
170152
function reshape_vector(
171153
vectorized_form::Vector{T},
172154
shape::SymmetricMatrixShape,
@@ -181,12 +163,14 @@ function reshape_vector(
181163
end
182164
return LinearAlgebra.Symmetric(matrix)
183165
end
166+
184167
function reshape_set(
185168
::MOI.PositiveSemidefiniteConeTriangle,
186169
::SymmetricMatrixShape,
187170
)
188171
return PSDCone()
189172
end
173+
190174
function vectorize(matrix, ::SymmetricMatrixShape)
191175
n = LinearAlgebra.checksquare(matrix)
192176
return [matrix[i, j] for j in 1:n for i in 1:j]
@@ -414,12 +398,7 @@ function build_variable(
414398
)
415399
n = _square_side(_error, variables)
416400
set = MOI.PositiveSemidefiniteConeTriangle(n)
417-
shape = SymmetricMatrixShape(n)
418-
return VariablesConstrainedOnCreation(
419-
_vectorize_variables(_error, variables),
420-
set,
421-
shape,
422-
)
401+
return build_variable(_error, variables, set)
423402
end
424403

425404
function value(
@@ -476,12 +455,7 @@ function build_constraint(
476455
::PSDCone,
477456
) where {V<:AbstractJuMPScalar,M<:AbstractMatrix{V}}
478457
n = LinearAlgebra.checksquare(Q)
479-
shape = SymmetricMatrixShape(n)
480-
return VectorConstraint(
481-
vectorize(Q, shape),
482-
MOI.PositiveSemidefiniteConeTriangle(n),
483-
shape,
484-
)
458+
return build_constraint(_error, Q, MOI.PositiveSemidefiniteConeTriangle(n))
485459
end
486460

487461
"""
@@ -511,12 +485,7 @@ function build_constraint(
511485
::PSDCone,
512486
)
513487
n = LinearAlgebra.checksquare(Q)
514-
shape = SquareMatrixShape(n)
515-
return VectorConstraint(
516-
vectorize(Q, shape),
517-
MOI.PositiveSemidefiniteConeSquare(n),
518-
shape,
519-
)
488+
return build_constraint(_error, Q, MOI.PositiveSemidefiniteConeSquare(n))
520489
end
521490

522491
"""
@@ -742,3 +711,60 @@ function build_constraint(_error::Function, ::AbstractMatrix, ::Zeros)
742711
"`LinearAlgebra.Symmetric` or `LinearAlgebra.Hermitian`.",
743712
)
744713
end
714+
715+
function build_constraint(
716+
_error::Function,
717+
Q::LinearAlgebra.Symmetric{V,M},
718+
set::MOI.AbstractSymmetricMatrixSetTriangle,
719+
) where {V<:AbstractJuMPScalar,M<:AbstractMatrix{V}}
720+
n = LinearAlgebra.checksquare(Q)
721+
shape = SymmetricMatrixShape(n)
722+
return VectorConstraint(vectorize(Q, shape), set, shape)
723+
end
724+
725+
function build_constraint(
726+
_error::Function,
727+
Q::AbstractMatrix{<:AbstractJuMPScalar},
728+
set::MOI.AbstractSymmetricMatrixSetSquare,
729+
)
730+
n = LinearAlgebra.checksquare(Q)
731+
shape = SquareMatrixShape(n)
732+
return VectorConstraint(vectorize(Q, shape), set, shape)
733+
end
734+
735+
function build_constraint(
736+
_error::Function,
737+
f::AbstractMatrix{<:AbstractJuMPScalar},
738+
::Nonnegatives,
739+
extra::Union{
740+
MOI.AbstractSymmetricMatrixSetTriangle,
741+
MOI.AbstractSymmetricMatrixSetSquare,
742+
PSDCone,
743+
},
744+
)
745+
return build_constraint(_error, f, extra)
746+
end
747+
748+
function build_constraint(
749+
_error::Function,
750+
f::AbstractMatrix{<:AbstractJuMPScalar},
751+
::Nonpositives,
752+
extra::Union{
753+
MOI.AbstractSymmetricMatrixSetTriangle,
754+
MOI.AbstractSymmetricMatrixSetSquare,
755+
PSDCone,
756+
},
757+
)
758+
new_f = _MA.operate!!(*, -1, f)
759+
return build_constraint(_error, new_f, extra)
760+
end
761+
762+
function build_variable(
763+
_error::Function,
764+
variables::Matrix{<:AbstractVariable},
765+
set::MOI.AbstractSymmetricMatrixSetTriangle,
766+
)
767+
n = _square_side(_error, variables)
768+
x = _vectorize_variables(_error, variables)
769+
return VariablesConstrainedOnCreation(x, set, SymmetricMatrixShape(n))
770+
end

test/test_constraint.jl

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -652,15 +652,6 @@ function test_extension_PSD_constraint_errors(
652652
)
653653
model = ModelType()
654654
@variable(model, X[1:2, 1:2])
655-
err = ErrorException(
656-
"In `@constraint(model, X in MOI.PositiveSemidefiniteConeSquare(2))`:" *
657-
" instead of `MathOptInterface.PositiveSemidefiniteConeSquare(2)`," *
658-
" use `JuMP.PSDCone()`.",
659-
)
660-
@test_throws_strip(
661-
err,
662-
@constraint(model, X in MOI.PositiveSemidefiniteConeSquare(2))
663-
)
664655
err = ErrorException(
665656
"In `@constraint(model, X in MOI.PositiveSemidefiniteConeTriangle(2))`:" *
666657
" instead of `MathOptInterface.PositiveSemidefiniteConeTriangle(2)`," *

test/test_model.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,20 @@ function test_model_quad_to_soc_start_values()
11101110
return
11111111
end
11121112

1113+
function test_SlackBridgePrimalDualStart()
1114+
inner = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}())
1115+
mock = MOI.Utilities.MockOptimizer(inner)
1116+
model = direct_model(MOI.Bridges.Objective.Slack{Float64}(mock))
1117+
@variable(model, x, start = 1.0)
1118+
@objective(model, Min, x^2)
1119+
set_start_values(model; variable_primal_start = start_value)
1120+
F, S = MOI.ScalarQuadraticFunction{Float64}, MOI.LessThan{Float64}
1121+
ci = first(MOI.get(inner, MOI.ListOfConstraintIndices{F,S}()))
1122+
@test MOI.get(inner, MOI.ConstraintPrimalStart(), ci) == 0.0
1123+
@test MOI.get(inner, MOI.ConstraintDualStart(), ci) == -1.0
1124+
return
1125+
end
1126+
11131127
function test_keyword_getindex()
11141128
err = JuMP._get_index_keyword_indexing_error()
11151129
model = Model()

0 commit comments

Comments
 (0)