diff --git a/docs/make.jl b/docs/make.jl index ccf6fa2a708..4243e04eafe 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -520,6 +520,13 @@ _validate_pages() # Build the HTML docs # ============================================================================== +Documenter.DocMeta.setdocmeta!( + JuMP, + :DocTestSetup, + :(using JuMP, JuMP.Containers); + recursive = true, +) + @time Documenter.makedocs( sitename = "JuMP", authors = "The JuMP core developers and contributors", @@ -533,21 +540,8 @@ _validate_pages() sidebar_sitename = false, ), strict = true, - # ========================================================================== - # `modules = [JuMP]`, along with `checkdocs = :exports` causes Documenter to - # throw an error if exported functions with docstrings are not contained in - # the Documentation. However, problematically, we include some MOI docs, - # which forces us to include MOI in `modules`, despite the fact that we - # don't necessarily want to document every MOI method. - # - # This is should be fine for now, because MOI doesn't export anything. - # However, also problematically, some doctests in MOI are not checked and - # are failing. Until they are fixed, we can't enable these options. - # - # TODO(odow): uncomment when possible. - # modules = [JuMP, MOI], - # checkdocs = :exports, - # ========================================================================== + modules = [JuMP], + checkdocs = :exports, # Skip doctests if --fast provided. doctest = _FIX ? :fix : !_FAST, pages = vcat(_PAGES, "release_notes.md"), diff --git a/src/Containers/DenseAxisArray.jl b/src/Containers/DenseAxisArray.jl index f2aa36a90a6..7124835bfd7 100644 --- a/src/Containers/DenseAxisArray.jl +++ b/src/Containers/DenseAxisArray.jl @@ -203,9 +203,9 @@ match `size(data)` in the corresponding dimensions. ```jldoctest julia> array = Containers.DenseAxisArray([1 2; 3 4], [:a, :b], 2:3) 2-dimensional DenseAxisArray{Int64,2,...} with index sets: - Dimension 1, Symbol[:a, :b] + Dimension 1, [:a, :b] Dimension 2, 2:3 -And data, a 2×2 Array{Int64,2}: +And data, a 2×2 Matrix{Int64}: 1 2 3 4 @@ -242,9 +242,9 @@ julia> array = Containers.DenseAxisArray{Float64}(undef, [:a, :b], 1:2); julia> fill!(array, 1.0) 2-dimensional DenseAxisArray{Float64,2,...} with index sets: - Dimension 1, Symbol[:a, :b] + Dimension 1, [:a, :b] Dimension 2, 1:2 -And data, a 2×2 Array{Float64,2}: +And data, a 2×2 Matrix{Float64}: 1.0 1.0 1.0 1.0 @@ -256,9 +256,9 @@ julia> array[:a, 2] julia> array 2-dimensional DenseAxisArray{Float64,2,...} with index sets: - Dimension 1, Symbol[:a, :b] + Dimension 1, [:a, :b] Dimension 2, 1:2 -And data, a 2×2 Array{Float64,2}: +And data, a 2×2 Matrix{Float64}: 1.0 5.0 1.0 1.0 ``` diff --git a/src/Containers/SparseAxisArray.jl b/src/Containers/SparseAxisArray.jl index ba586d2e7c1..0bfb020cc85 100644 --- a/src/Containers/SparseAxisArray.jl +++ b/src/Containers/SparseAxisArray.jl @@ -20,16 +20,16 @@ structure than `sa` even if `f(zero(T))` is not zero. ```jldoctest julia> dict = Dict((:a, 2) => 1.0, (:a, 3) => 2.0, (:b, 3) => 3.0) -Dict{Tuple{Symbol,Int64},Float64} with 3 entries: +Dict{Tuple{Symbol, Int64}, Float64} with 3 entries: + (:a, 3) => 2.0 (:b, 3) => 3.0 (:a, 2) => 1.0 - (:a, 3) => 2.0 julia> array = Containers.SparseAxisArray(dict) -JuMP.Containers.SparseAxisArray{Float64,2,Tuple{Symbol,Int64}} with 3 entries: - [b, 3] = 3.0 +SparseAxisArray{Float64, 2, Tuple{Symbol, Int64}} with 3 entries: [a, 2] = 1.0 [a, 3] = 2.0 + [b, 3] = 3.0 julia> array[:b, 3] 3.0 @@ -44,6 +44,8 @@ function SparseAxisArray(d::Dict{K,T}) where {T,N,K<:NTuple{N,Any}} return SparseAxisArray(d, ntuple(n -> Symbol("#$n"), N)) end +SparseAxisArray(d::Dict, ::Nothing) = SparseAxisArray(d) + Base.length(sa::SparseAxisArray) = length(sa.data) Base.IteratorSize(::Type{<:SparseAxisArray}) = Base.HasLength() diff --git a/src/Containers/container.jl b/src/Containers/container.jl index 5d99d69ea2e..382b9be9ec1 100644 --- a/src/Containers/container.jl +++ b/src/Containers/container.jl @@ -36,7 +36,7 @@ not supporting index names. ```jldoctest julia> Containers.container((i, j) -> i + j, Containers.vectorized_product(Base.OneTo(3), Base.OneTo(3))) -3×3 Array{Int64,2}: +3×3 Matrix{Int64}: 2 3 4 3 4 5 4 5 6 @@ -45,7 +45,7 @@ julia> Containers.container((i, j) -> i + j, Containers.vectorized_product(1:3, 2-dimensional DenseAxisArray{Int64,2,...} with index sets: Dimension 1, 1:3 Dimension 2, 1:3 -And data, a 3×3 Array{Int64,2}: +And data, a 3×3 Matrix{Int64}: 2 3 4 3 4 5 4 5 6 @@ -54,17 +54,17 @@ julia> Containers.container((i, j) -> i + j, Containers.vectorized_product(2:3, 2-dimensional DenseAxisArray{Int64,2,...} with index sets: Dimension 1, 2:3 Dimension 2, Base.OneTo(3) -And data, a 2×3 Array{Int64,2}: +And data, a 2×3 Matrix{Int64}: 3 4 5 4 5 6 julia> Containers.container((i, j) -> i + j, Containers.nested(() -> 1:3, i -> i:3, condition = (i, j) -> isodd(i) || isodd(j))) -SparseAxisArray{Int64,2,Tuple{Int64,Int64}} with 5 entries: +SparseAxisArray{Int64, 2, Tuple{Int64, Int64}} with 5 entries: + [1, 1] = 2 [1, 2] = 3 + [1, 3] = 4 [2, 3] = 5 [3, 3] = 6 - [1, 1] = 2 - [1, 3] = 4 ``` """ function container(f::Function, indices, D, names) diff --git a/src/Containers/macro.jl b/src/Containers/macro.jl index eb0236bc274..0657b2b4e06 100644 --- a/src/Containers/macro.jl +++ b/src/Containers/macro.jl @@ -337,7 +337,7 @@ The type of container can be controlled by the `container` keyword. ```jldoctest julia> Containers.@container([i = 1:3, j = 1:3], i + j) -3×3 Array{Int64,2}: +3×3 Matrix{Int64}: 2 3 4 3 4 5 4 5 6 @@ -351,7 +351,7 @@ julia> x 2-dimensional DenseAxisArray{Int64,2,...} with index sets: Dimension 1, 1:3 Dimension 2, 1:3 -And data, a 3×3 Array{Int64,2}: +And data, a 3×3 Matrix{Int64}: 2 3 4 3 4 5 4 5 6 @@ -360,18 +360,18 @@ julia> Containers.@container([i = 2:3, j = 1:3], i + j) 2-dimensional DenseAxisArray{Int64,2,...} with index sets: Dimension 1, 2:3 Dimension 2, Base.OneTo(3) -And data, a 2×3 Array{Int64,2}: +And data, a 2×3 Matrix{Int64}: 3 4 5 4 5 6 julia> Containers.@container([i = 1:3, j = 1:3; i <= j], i + j) -JuMP.Containers.SparseAxisArray{Int64,2,Tuple{Int64,Int64}} with 6 entries: +SparseAxisArray{Int64, 2, Tuple{Int64, Int64}} with 6 entries: + [1, 1] = 2 [1, 2] = 3 + [1, 3] = 4 + [2, 2] = 4 [2, 3] = 5 [3, 3] = 6 - [2, 2] = 4 - [1, 1] = 2 - [1, 3] = 4 ``` """ macro container(args...) diff --git a/src/JuMP.jl b/src/JuMP.jl index 7cf25cbc9b5..e9328ad52c1 100644 --- a/src/JuMP.jl +++ b/src/JuMP.jl @@ -255,6 +255,8 @@ Solver name: HiGHS ``` is equivalent to: ```jldoctest +julia> import HiGHS + julia> model = direct_generic_model(Float64, HiGHS.Optimizer()) A JuMP Model Feasibility problem with: @@ -358,6 +360,8 @@ Solver name: HiGHS ``` is equivalent to: ```jldoctest +julia> import HiGHS + julia> model = direct_model(HiGHS.Optimizer()) A JuMP Model Feasibility problem with: @@ -665,14 +669,14 @@ julia> remove_bridge(model, MOI.Bridges.Constraint.SOCtoNonConvexQuadBridge) julia> add_bridge( model, MOI.Bridges.Constraint.NumberConversionBridge; - coefficient_type = Complex{Float64} + coefficient_type = Complex{Float64}, ) julia> remove_bridge( - model, - MOI.Bridges.Constraint.NumberConversionBridge; - coefficient_type = Complex{Float64} - ) + model, + MOI.Bridges.Constraint.NumberConversionBridge; + coefficient_type = Complex{Float64}, + ) ``` """ function remove_bridge( @@ -869,14 +873,16 @@ julia> @variable(model, x) x julia> @variable(model, x) -ERROR: An object of name x is already attached to this model. If -this is intended, consider using the anonymous construction syntax, -e.g., `x = @variable(model, [1:N], ...)` where the name of the object -does not appear inside the macro. - -Alternatively, use `unregister(model, :x)` to first unregister the -existing name from the model. Note that this will not delete the object; -it will just remove the reference at `model[:x]`. +ERROR: An object of name x is already attached to this model. If this + is intended, consider using the anonymous construction syntax, e.g., + `x = @variable(model, [1:N], ...)` where the name of the object does + not appear inside the macro. + + Alternatively, use `unregister(model, :x)` to first unregister + the existing name from the model. Note that this will not delete the + object; it will just remove the reference at `model[:x]`. + +Stacktrace: [...] julia> num_variables(model) @@ -973,10 +979,9 @@ julia> set_optimize_hook(model, my_hook) my_hook (generic function with 1 method) julia> optimize!(model; test_arg = true) -Base.Iterators.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:test_arg,), Tuple{Bool}}}(:test_arg => 1) +Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:test_arg,), Tuple{Bool}}}(:test_arg => 1) Calling with `ignore_optimize_hook = true` ERROR: NoOptimizer() -Stacktrace: [...] ``` """ @@ -1012,9 +1017,9 @@ function _get_index_keyword_indexing_error() 1-dimensional DenseAxisArray{VariableRef,1,...} with index sets: Dimension 1, Base.OneTo(3) And data, a 3-element Vector{VariableRef}: - x[1] - x[2] - x[3] + x[1] + x[2] + x[3] julia> x[i=2] x[2] diff --git a/src/constraints.jl b/src/constraints.jl index 4732c16680b..f8175c9dcf9 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -294,17 +294,17 @@ julia> @variable(model, x) x julia> @constraint(model, con, x^2 == 1) -con : x² = 1.0 +con : x² = 1 julia> constraint_by_name(model, "kon") julia> constraint_by_name(model, "con") -con : x² = 1.0 +con : x² = 1 julia> constraint_by_name(model, "con", AffExpr, MOI.EqualTo{Float64}) julia> constraint_by_name(model, "con", QuadExpr, MOI.EqualTo{Float64}) -con : x² = 1.0 +con : x² = 1 ``` """ function constraint_by_name end @@ -381,7 +381,7 @@ julia> model = Model(); julia> @variable(model, x); julia> @constraint(model, c, 2x <= 1) -c : 2 x ≤ 1.0 +c : 2 x ≤ 1 julia> delete(model, c) @@ -739,12 +739,12 @@ julia> @variable(model, x) x julia> @constraint(model, con, 2x + 3x <= 2) -con : 5 x ≤ 2.0 +con : 5 x ≤ 2 julia> set_normalized_coefficient(con, x, 4) julia> con -con : 4 x ≤ 2.0 +con : 4 x ≤ 2 ``` """ function set_normalized_coefficient( @@ -845,12 +845,12 @@ julia> model = Model(); julia> @variable(model, x); julia> @constraint(model, con, 2x + 1 <= 2) -con : 2 x <= 1.0 +con : 2 x ≤ 1 julia> set_normalized_rhs(con, 4) julia> con -con : 2 x <= 4.0 +con : 2 x ≤ 4 ``` """ function set_normalized_rhs( @@ -937,12 +937,12 @@ julia> model = Model(); julia> @variable(model, x); julia> @constraint(model, con, 0 <= 2x - 1 <= 2) -con : 2 x ∈ [1.0, 3.0] +con : 2 x ∈ [1, 3] julia> add_to_function_constant(con, 4) julia> con -con : 2 x ∈ [-3.0, -1.0] +con : 2 x ∈ [-3, -1] ``` For vector constraints, the constant is added to the function: @@ -1255,16 +1255,16 @@ julia> @variable(model, x >= 0, Bin); julia> @constraint(model, 2x <= 1); julia> all_constraints(model, VariableRef, MOI.GreaterThan{Float64}) -1-element Array{ConstraintRef{Model,MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex,MathOptInterface.GreaterThan{Float64}},ScalarShape},1}: - x ≥ 0.0 +1-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.GreaterThan{Float64}}, ScalarShape}}: + x ≥ 0 julia> all_constraints(model, VariableRef, MOI.ZeroOne) -1-element Array{ConstraintRef{Model,MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex,MathOptInterface.ZeroOne},ScalarShape},1}: +1-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.VariableIndex, MathOptInterface.ZeroOne}, ScalarShape}}: x binary julia> all_constraints(model, AffExpr, MOI.LessThan{Float64}) -1-element Array{ConstraintRef{Model,MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.LessThan{Float64}},ScalarShape},1}: - 2 x ≤ 1.0 +1-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.LessThan{Float64}}, ScalarShape}}: + 2 x ≤ 1 ``` """ function all_constraints( @@ -1315,8 +1315,8 @@ julia> @variable(model, x >= 0, Bin); julia> @constraint(model, 2x <= 1); julia> list_of_constraint_types(model) -3-element Array{Tuple{Type,Type},1}: - (GenericAffExpr{Float64,VariableRef}, MathOptInterface.LessThan{Float64}) +3-element Vector{Tuple{Type, Type}}: + (AffExpr, MathOptInterface.LessThan{Float64}) (VariableRef, MathOptInterface.GreaterThan{Float64}) (VariableRef, MathOptInterface.ZeroOne) ``` @@ -1401,14 +1401,14 @@ julia> @NLconstraint(model, x^2 <= 1); julia> all_constraints(model; include_variable_in_set_constraints = true) 4-element Vector{ConstraintRef}: - 2 x ≤ 1.0 - x ≥ 0.0 + 2 x ≤ 1 + x ≥ 0 x integer x ^ 2.0 - 1.0 ≤ 0 julia> all_constraints(model; include_variable_in_set_constraints = false) 2-element Vector{ConstraintRef}: - 2 x ≤ 1.0 + 2 x ≤ 1 x ^ 2.0 - 1.0 ≤ 0 ``` @@ -1485,31 +1485,34 @@ new_model (generic function with 1 method) julia> model_1 = new_model(); -julia> relax_with_penalty!(model_1; default = 2.0) -Dict{ConstraintRef{Model, C, ScalarShape} where C, AffExpr} with 2 entries: - c1 : 2 x - _[3] ≤ -1.0 => _[3] - c2 : 3 x + _[2] ≥ 0.0 => _[2] +julia> penalty_map = relax_with_penalty!(model_1; default = 2.0); + +julia> penalty_map[model[:c1]] +_[3] + +julia> penalty_map[model[:c2]] +_[2] julia> print(model_1) Max 2 x - 2 _[2] - 2 _[3] + 1 Subject to - c2 : 3 x + _[2] ≥ 0.0 - c1 : 2 x - _[3] ≤ -1.0 - _[2] ≥ 0.0 - _[3] ≥ 0.0 + c2 : 3 x + _[2] ≥ 0 + c1 : 2 x - _[3] ≤ -1 + _[2] ≥ 0 + _[3] ≥ 0 julia> model_2 = new_model(); julia> relax_with_penalty!(model_2, Dict(model_2[:c2] => 3.0)) Dict{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.GreaterThan{Float64}}, ScalarShape}, AffExpr} with 1 entry: - c2 : 3 x + _[2] ≥ 0.0 => _[2] + c2 : 3 x + _[2] ≥ 0 => _[2] julia> print(model_2) Max 2 x - 3 _[2] + 1 Subject to - c2 : 3 x + _[2] ≥ 0.0 - c1 : 2 x ≤ -1.0 - _[2] ≥ 0.0 + c2 : 3 x + _[2] ≥ 0 + c1 : 2 x ≤ -1 + _[2] ≥ 0 ``` """ function relax_with_penalty!( diff --git a/src/copy.jl b/src/copy.jl index 892d156abbd..d20c8d5ae43 100644 --- a/src/copy.jl +++ b/src/copy.jl @@ -124,7 +124,7 @@ julia> @variable(model, x) x julia> @constraint(model, cref, x == 2) -cref : x = 2.0 +cref : x = 2 julia> new_model, reference_map = copy_model(model); @@ -132,7 +132,7 @@ julia> x_new = reference_map[x] x julia> cref_new = reference_map[cref] -cref : x = 2.0 +cref : x = 2 ``` """ function copy_model( @@ -228,7 +228,7 @@ julia> @variable(model, x) x julia> @constraint(model, cref, x == 2) -cref : x = 2.0 +cref : x = 2 julia> new_model = copy(model); @@ -236,7 +236,7 @@ julia> x_new = model[:x] x julia> cref_new = model[:cref] -cref : x = 2.0 +cref : x = 2 ``` """ function Base.copy(model::AbstractModel) @@ -284,10 +284,10 @@ julia> @variable(model, x >= 0) x julia> @constraint(model, c1, x >= 2) -c1 : x ≥ 2.0 +c1 : x ≥ 2 julia> @constraint(model, c2, x <= 1) -c2 : x ≤ 1.0 +c2 : x ≤ 1 julia> optimize!(model) @@ -299,8 +299,8 @@ julia> if get_attribute(model, MOI.ConflictStatus()) == MOI.CONFLICT_FOUND end Feasibility Subject to - c1 : x ≥ 2.0 - c2 : x ≤ 1.0 + c1 : x ≥ 2 + c2 : x ≤ 1 ``` """ function copy_conflict(model::GenericModel) diff --git a/src/feasibility_checker.jl b/src/feasibility_checker.jl index f7de792a202..2773a7bbdb9 100644 --- a/src/feasibility_checker.jl +++ b/src/feasibility_checker.jl @@ -45,7 +45,7 @@ julia> model = Model(); julia> @variable(model, 0.5 <= x <= 1); julia> primal_feasibility_report(model, Dict(x => 0.2)) -Dict{Any,Float64} with 1 entry: +Dict{Any, Float64} with 1 entry: x ≥ 0.5 => 0.3 ``` """ @@ -87,13 +87,13 @@ argument instead of a dictionary as the second argument. ```jldoctest julia> model = Model(); -julia> @variable(model, 0.5 <= x <= 1); +julia> @variable(model, 0.5 <= x <= 1, start = 1.3); julia> primal_feasibility_report(model) do v - return value(v) + return start_value(v) end -Dict{Any,Float64} with 1 entry: - x ≥ 0.5 => 0.3 +Dict{Any, Float64} with 1 entry: + x ≤ 1 => 0.3 ``` """ function primal_feasibility_report( diff --git a/src/lp_sensitivity2.jl b/src/lp_sensitivity2.jl index 809d1353956..700c50863cd 100644 --- a/src/lp_sensitivity2.jl +++ b/src/lp_sensitivity2.jl @@ -41,6 +41,8 @@ Note: interval constraints are NOT supported. ## Example ```jldoctest +julia> import HiGHS + julia> model = Model(HiGHS.Optimizer); julia> set_silent(model) diff --git a/src/macros.jl b/src/macros.jl index 2bb97d4df50..a9f17894ad1 100644 --- a/src/macros.jl +++ b/src/macros.jl @@ -18,12 +18,12 @@ of a macro with [`Containers._extract_kw_args`](@ref). ```jldoctest julia> call = :(f(1, a=2)) -:(f(1, a=2)) +:(f(1, a = 2)) julia> JuMP._add_kw_args(call, [:(b=3), :(c=4)]) julia> call -:(f(1, a=2, $(Expr(:escape, :(b=3))), $(Expr(:escape, :(c=4))))) +:(f(1, a = 2, \$(Expr(:escape, :(\$(Expr(:kw, :b, 3))))), \$(Expr(:escape, :(\$(Expr(:kw, :c, 4))))))) ``` """ function _add_kw_args(call, kw_args) @@ -184,6 +184,8 @@ provide a more convenient syntax: ```jldoctest operator_to_set julia> JuMP.operator_to_set(::Function, ::Val{:⊰}) = CustomSet(0.0) +julia> MOIU.supports_shift_constant(::Type{<:CustomSet}) = true + julia> MOIU.shift_constant(set::CustomSet, value) = CustomSet(set.value + value) julia> cref = @constraint(model, x ⊰ 1) @@ -265,8 +267,8 @@ julia> model = Model(); julia> @variable(model, x[1:2]) 2-element Vector{VariableRef}: - x[1] - x[2] + x[1] + x[2] julia> @constraint(model, x in Nonpositives()) [x[1], x[2]] ∈ MathOptInterface.Nonpositives(2) @@ -294,8 +296,8 @@ julia> model = Model(); julia> @variable(model, x[1:2]) 2-element Vector{VariableRef}: - x[1] - x[2] + x[1] + x[2] julia> @constraint(model, x in Zeros()) [x[1], x[2]] ∈ MathOptInterface.Zeros(2) @@ -334,10 +336,9 @@ julia> foo(x) = (println("Calling \$(x)"); x) foo (generic function with 1 method) julia> foo.(SparseArrays.sparsevec([1, 2], [1, 2])) -Calling 0 Calling 1 Calling 2 -2-element SparseVector{Int64, Int64} with 2 stored entries: +2-element SparseArrays.SparseVector{Int64, Int64} with 2 stored entries: [1] = 1 [2] = 2 ``` @@ -1320,11 +1321,11 @@ julia> @constraints(model, begin julia> print(model) Feasibility Subject to - sum_to_one[1] : y + z[1] = 1.0 - sum_to_one[2] : y + z[2] = 1.0 - sum_to_one[3] : y + z[3] = 1.0 - x ≥ 1.0 - -w + y ≤ 2.0 + sum_to_one[1] : y + z[1] = 1 + sum_to_one[2] : y + z[2] = 1 + sum_to_one[3] : y + z[3] = 1 + x ≥ 1 + -w + y ≤ 2 ``` """ :(@constraints) @@ -1616,10 +1617,10 @@ julia> @expression(model, shared, sum(i * x[i] for i in 1:5)) x[1] + 2 x[2] + 3 x[3] + 4 x[4] + 5 x[5] julia> @constraint(model, shared + y >= 5) -x[1] + 2 x[2] + 3 x[3] + 4 x[4] + 5 x[5] + y ≥ 5.0 +x[1] + 2 x[2] + 3 x[3] + 4 x[4] + 5 x[5] + y ≥ 5 julia> @constraint(model, shared + z <= 10) -x[1] + 2 x[2] + 3 x[3] + 4 x[4] + 5 x[5] + z ≤ 10.0 +x[1] + 2 x[2] + 3 x[3] + 4 x[4] + 5 x[5] + z ≤ 10 ``` The `ref` accepts index sets in the same way as `@variable`, and those indices @@ -2888,7 +2889,7 @@ end Efficiently build a nonlinear expression which can then be inserted in other nonlinear constraints and the objective. See also [`@expression`]. For example: -```jldoctest +```jldoctest api_nlexpression julia> model = Model(); julia> @variable(model, x) @@ -2907,7 +2908,7 @@ julia> @NLobjective(model, Min, my_expr) ``` Indexing over sets and anonymous expressions are also supported: -```jldoctest +```jldoctest api_nlexpression julia> @NLexpression(model, my_expr_1[i=1:3], sin(i * x)) 3-element Vector{NonlinearExpression}: subexpression[2]: sin(1.0 * x) diff --git a/src/objective.jl b/src/objective.jl index 880f32b7fa1..06a9d61b3d0 100644 --- a/src/objective.jl +++ b/src/objective.jl @@ -215,7 +215,7 @@ julia> objective_function(model, QuadExpr) 2 x + 1 julia> typeof(objective_function(model, QuadExpr)) -GenericQuadExpr{Float64,VariableRef} +QuadExpr (alias for GenericQuadExpr{Float64, GenericVariableRef{Float64}}) ``` We see with the last two commands that even if the objective function is affine, as it is convertible to a quadratic function, it can be queried as a quadratic @@ -224,7 +224,7 @@ function and the result is quadratic. However, it is not convertible to a variable. ```jldoctest objective_function; filter = r"MathOptInterface\\."s julia> objective_function(model, VariableRef) -ERROR: InexactError: convert(MathOptInterface.VariableIndex, MathOptInterface.ScalarAffineFunction{Float64}(MathOptInterface.ScalarAffineTerm{Float64}[MathOptInterface.ScalarAffineTerm{Float64}(2.0, MathOptInterface.VariableIndex(1))], 1.0)) +ERROR: InexactError: convert(MathOptInterface.VariableIndex, 1.0 + 2.0 MOI.VariableIndex(1)) [...] ``` """ diff --git a/src/optimizer_interface.jl b/src/optimizer_interface.jl index 16abe7a6fe0..2a4db592806 100644 --- a/src/optimizer_interface.jl +++ b/src/optimizer_interface.jl @@ -35,6 +35,8 @@ julia> model = Model(optimizer); is equivalent to: ```jldoctest +julia> import HiGHS + julia> model = Model(HiGHS.Optimizer); julia> set_attribute(model, "presolve", "off") @@ -289,7 +291,9 @@ Cannot be called in direct mode. """ function MOIU.reset_optimizer(model::GenericModel) error_if_direct_mode(model, :reset_optimizer) - MOIU.reset_optimizer(backend(model)) + if MOI.Utilities.state(backend(model)) == MOI.Utilities.ATTACHED_OPTIMIZER + MOIU.reset_optimizer(backend(model)) + end return end @@ -752,7 +756,7 @@ julia> @variable(model, x) x julia> @constraint(model, c, 2 * x <= 1) -c : 2 x ≤ 1.0 +c : 2 x ≤ 1 julia> get_attribute(model, MOI.Name()) "" @@ -856,7 +860,7 @@ julia> @variable(model, x) x julia> @constraint(model, c, 2 * x <= 1) -c : 2 x ≤ 1.0 +c : 2 x ≤ 1 julia> set_attribute(model, MOI.Name(), "model_new") diff --git a/src/sd.jl b/src/sd.jl index e0be834cbd3..2ff1aa23cef 100644 --- a/src/sd.jl +++ b/src/sd.jl @@ -27,7 +27,7 @@ symmetric. julia> model = Model(); julia> @variable(model, Q[1:2, 1:2] in SymmetricMatrixSpace()) -2×2 LinearAlgebra.Symmetric{VariableRef,Array{VariableRef,2}}: +2×2 LinearAlgebra.Symmetric{VariableRef, Matrix{VariableRef}}: Q[1,1] Q[1,2] Q[1,2] Q[2,2] ``` @@ -66,8 +66,8 @@ julia> model = Model(); julia> @variable(model, Q[1:2, 1:2] in HermitianMatrixSpace()) 2×2 LinearAlgebra.Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}: - real(Q[1,1]) real(Q[1,2]) + (0.0 + 1.0im) imag(Q[1,2]) - real(Q[1,2]) + (0.0 - 1.0im) imag(Q[1,2]) real(Q[2,2]) + real(Q[1,1]) real(Q[1,2]) + imag(Q[1,2]) im + real(Q[1,2]) - imag(Q[1,2]) im real(Q[2,2]) ``` """ struct HermitianMatrixSpace end @@ -100,10 +100,10 @@ julia> b = [1 2 julia> cref = @constraint(model, a >= b, PSDCone()) [x - 1 2 x - 2; - 2 x - 2 x - 4 ] ∈ PSDCone() + 2 x - 2 x - 4] ∈ PSDCone() julia> jump_function(constraint_object(cref)) -4-element Array{GenericAffExpr{Float64,VariableRef},1}: +4-element Vector{AffExpr}: x - 1 2 x - 2 2 x - 2 @@ -120,10 +120,10 @@ julia> using LinearAlgebra # For Symmetric julia> cref = @constraint(model, Symmetric(a - b) in PSDCone()) [x - 1 2 x - 2; - 2 x - 2 x - 4 ] ∈ PSDCone() + 2 x - 2 x - 4] ∈ PSDCone() julia> jump_function(constraint_object(cref)) -3-element Array{GenericAffExpr{Float64,VariableRef},1}: +3-element Vector{AffExpr}: x - 1 2 x - 2 x - 4 @@ -354,8 +354,8 @@ julia> model = Model(); julia> @variable(model, Q[1:2, 1:2] in HermitianMatrixSpace()) 2×2 LinearAlgebra.Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}: - real(Q[1,1]) real(Q[1,2]) + (0.0 + 1.0im) imag(Q[1,2]) - real(Q[1,2]) + (0.0 - 1.0im) imag(Q[1,2]) real(Q[2,2]) + real(Q[1,1]) real(Q[1,2]) + imag(Q[1,2]) im + real(Q[1,2]) - imag(Q[1,2]) im real(Q[2,2]) ``` """ function build_variable( @@ -502,26 +502,14 @@ Consider the following example: julia> model = Model(); julia> @variable(model, H[1:3, 1:3] in HermitianPSDCone()) -3×3 Matrix{GenericAffExpr{ComplexF64, VariableRef}}: - real(H[1,1]) real(H[1,2]) + (0.0 + 1.0im) imag(H[1,2]) real(H[1,3]) + (0.0 + 1.0im) imag(H[1,3]) - real(H[1,2]) + (-0.0 - 1.0im) imag(H[1,2]) real(H[2,2]) real(H[2,3]) + (0.0 + 1.0im) imag(H[2,3]) - real(H[1,3]) + (-0.0 - 1.0im) imag(H[1,3]) real(H[2,3]) + (-0.0 - 1.0im) imag(H[2,3]) real(H[3,3]) - - julia> v = all_variables(model) - 9-element Vector{VariableRef}: - real(H[1,1]) - real(H[1,2]) - real(H[2,2]) - real(H[1,3]) - real(H[2,3]) - real(H[3,3]) - imag(H[1,2]) - imag(H[1,3]) - imag(H[2,3]) +3×3 LinearAlgebra.Hermitian{GenericAffExpr{ComplexF64, VariableRef}, Matrix{GenericAffExpr{ComplexF64, VariableRef}}}: + real(H[1,1]) … real(H[1,3]) + imag(H[1,3]) im + real(H[1,2]) - imag(H[1,2]) im real(H[2,3]) + imag(H[2,3]) im + real(H[1,3]) - imag(H[1,3]) im real(H[3,3]) julia> all_constraints(model, Vector{VariableRef}, MOI.HermitianPositiveSemidefiniteConeTriangle) 1-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.HermitianPositiveSemidefiniteConeTriangle}}}: - [real(H[1,1]), real(H[1,2]), real(H[2,2]), real(H[1,3]), real(H[2,3]), real(H[3,3]), imag(H[1,2]), imag(H[1,3]), imag(H[2,3])] in MathOptInterface.HermitianPositiveSemidefiniteConeTriangle(3) + [real(H[1,1]), real(H[1,2]), real(H[2,2]), real(H[1,3]), real(H[2,3]), real(H[3,3]), imag(H[1,2]), imag(H[1,3]), imag(H[2,3])] ∈ MathOptInterface.HermitianPositiveSemidefiniteConeTriangle(3) ``` We see in the output of the last commands that 9 real variables were created. The matrix `H` contrains affine expressions in terms of these 9 variables that diff --git a/src/sets.jl b/src/sets.jl index 763528ad28e..e5651338fdf 100644 --- a/src/sets.jl +++ b/src/sets.jl @@ -293,7 +293,7 @@ x julia> print(model) Feasibility Subject to - x ∈ MathOptInterface.Semicontinuous{Float64}(1.0, 2.0) + x ∈ MathOptInterface.Semicontinuous{Int64}(1, 2) ``` """ struct Semicontinuous{T} <: AbstractScalarSet @@ -329,7 +329,7 @@ x julia> print(model) Feasibility Subject to - x ∈ MathOptInterface.Semiinteger{Float64}(3.0, 5.0) + x ∈ MathOptInterface.Semiinteger{Int64}(3, 5) ``` """ struct Semiinteger{T} <: AbstractScalarSet diff --git a/src/shapes.jl b/src/shapes.jl index 1f13fc1f0c2..62d1472db70 100644 --- a/src/shapes.jl +++ b/src/shapes.jl @@ -91,7 +91,7 @@ following code returns the matrix `Symmetric(Matrix[1 2; 2 3])`: ```jldoctest julia> reshape_vector([1, 2, 3], SymmetricMatrixShape(2)) -2×2 LinearAlgebra.Symmetric{Int64,Array{Int64,2}}: +2×2 LinearAlgebra.Symmetric{Int64, Matrix{Int64}}: 1 2 2 3 ``` diff --git a/src/variables.jl b/src/variables.jl index c6e727fd6a8..bde459de170 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -454,7 +454,7 @@ function GenericVariableRef{T}(model::GenericModel{T}) where {T} end """ - GenericVariableRef(c::ConstraintRef) + GenericVariableRef{T}(c::ConstraintRef) Get the variable associated with a `ConstraintRef`, if `c` is a constraint on a single variable. @@ -468,9 +468,9 @@ julia> @variable(model, x >= 0) x julia> c = LowerBoundRef(x) -x ≥ 0.0 +x ≥ 0 -julia> GenericVariableRef(c) == x +julia> VariableRef(c) == x true ``` """ @@ -554,7 +554,7 @@ julia> variable_by_name(model, "z") z julia> @variable(model, u[1:2]) -2-element Array{VariableRef,1}: +2-element Vector{VariableRef}: u[1] u[2] @@ -1439,7 +1439,7 @@ Consider the following example: julia> model = Model(); julia> @variable(model, x in ComplexPlane()) -real(x) + (0.0 + 1.0im) imag(x) +real(x) + imag(x) im julia> all_variables(model) 2-element Vector{VariableRef}: @@ -1705,18 +1705,18 @@ julia> undo_relax = relax_integrality(model); julia> print(model) Min x + y Subject to - x ≥ 0.0 - y ≥ 1.0 - x ≤ 1.0 - y ≤ 10.0 + x ≥ 0 + y ≥ 1 + x ≤ 1 + y ≤ 10 julia> undo_relax() julia> print(model) Min x + y Subject to - y ≥ 1.0 - y ≤ 10.0 + y ≥ 1 + y ≤ 10 y integer x binary ``` @@ -1760,16 +1760,16 @@ julia> undo_relax = fix_discrete_variables(start_value, model); julia> print(model) Min x + y Subject to - x = 1.0 - y = 2.0 + x = 1 + y = 2 julia> undo_relax() julia> print(model) Min x + y Subject to - y ≥ 1.0 - y ≤ 10.0 + y ≥ 1 + y ≤ 10 y integer x binary ```