Skip to content
Closed
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
4 changes: 2 additions & 2 deletions src/Bridges/Constraint/indicator_sos.jl
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ function MOI.supports(
end

function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal, bridge::IndicatorSOS1Bridge)
zvalue = MOI.get(model, MOI.VariablePrimal(attr.N), bridge.z_variable_index)
wvalue = MOI.get(model, MOI.VariablePrimal(attr.N), bridge.w_variable_index)
zvalue = MOI.get(model, MOI.VariablePrimal(attr.result_index), bridge.z_variable_index)
wvalue = MOI.get(model, MOI.VariablePrimal(attr.result_index), bridge.w_variable_index)
lin_primal_start = MOI.get(model, attr, bridge.linear_constraint_index)
return [zvalue, lin_primal_start - wvalue]
end
Expand Down
2 changes: 1 addition & 1 deletion src/Bridges/Constraint/semi_to_binary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ end

function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,
bridge::SemiToBinaryBridge)
MOI.get(model, MOI.VariablePrimal(attr.N), bridge.variable_index)
MOI.get(model, MOI.VariablePrimal(attr.result_index), bridge.variable_index)
end

function MOI.supports(
Expand Down
2 changes: 1 addition & 1 deletion src/Bridges/Constraint/soc_to_nonconvex_quad.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ end
# Attributes, Bridge acting as a constraint
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,
bridge::AbstractSOCtoNonConvexQuadBridge)
vals = MOI.get.(model, MOI.VariablePrimal(attr.N), bridge.vars)
vals = MOI.get.(model, MOI.VariablePrimal(attr.result_index), bridge.vars)
return vals
end

Expand Down
2 changes: 1 addition & 1 deletion src/Bridges/Constraint/vectorize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function MOI.get(
)
x = MOI.get(model, attr, bridge.vector_constraint)
@assert length(x) == 1
if MOIU.is_ray(MOI.get(model, MOI.PrimalStatus(attr.N)))
if MOIU.is_ray(MOI.get(model, MOI.PrimalStatus(attr.result_index)))
# If it is an infeasibility certificate, it is a ray and satisfies the
# homogenized problem, see https://github.com/jump-dev/MathOptInterface.jl/issues/433
return x[1]
Expand Down
4 changes: 2 additions & 2 deletions src/Bridges/Variable/vectorize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,
x = MOI.get(model, attr, bridge.vector_constraint)
@assert length(x) == 1
y = x[1]
if !MOIU.is_ray(MOI.get(model, MOI.PrimalStatus(attr.N)))
if !MOIU.is_ray(MOI.get(model, MOI.PrimalStatus(attr.result_index)))
# If it is an infeasibility certificate, it is a ray and satisfies the
# homogenized problem, see https://github.com/jump-dev/MathOptInterface.jl/issues/433
# Otherwise, we need to add the set constant since the ConstraintPrimal
Expand All @@ -98,7 +98,7 @@ function MOI.get(model::MOI.ModelLike,
bridge::VectorizeBridge)
value = MOI.get(model, attr, bridge.variable)
if !(attr isa MOI.VariablePrimal &&
MOIU.is_ray(MOI.get(model, MOI.PrimalStatus(attr.N))))
MOIU.is_ray(MOI.get(model, MOI.PrimalStatus(attr.result_index))))
value += bridge.set_constant
end
return value
Expand Down
2 changes: 2 additions & 0 deletions src/MathOptInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ include("modifications.jl")
include("variables.jl")
include("nlp.jl")

include("deprecate.jl")

# submodules
include("Utilities/Utilities.jl") # MOI.Utilities
include("Test/Test.jl") # MOI.Test
Expand Down
18 changes: 9 additions & 9 deletions src/Utilities/mockoptimizer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ function MOI.set(mock::MockOptimizer, attr::MOI.DualObjectiveValue, value::Real)
mock.dual_objective_value[attr.result_index] = value
end
function MOI.set(mock::MockOptimizer, attr::MOI.PrimalStatus, value::MOI.ResultStatusCode)
mock.primal_status[attr.N] = value
mock.primal_status[attr.result_index] = value
end
function MOI.set(mock::MockOptimizer, attr::MOI.DualStatus, value::MOI.ResultStatusCode)
mock.dual_status[attr.N] = value
mock.dual_status[attr.result_index] = value
end
MOI.set(mock::MockOptimizer, ::MockModelAttribute, value::Integer) = (mock.attribute = value)
function MOI.supports(mock::MockOptimizer, attr::MOI.AbstractOptimizerAttribute)
Expand Down Expand Up @@ -315,17 +315,17 @@ function MOI.get(mock::MockOptimizer, attr::MOI.DualObjectiveValue)
end
end
function MOI.get(mock::MockOptimizer, attr::MOI.PrimalStatus)
if attr.N > mock.result_count
if attr.result_index > mock.result_count
return MOI.NO_SOLUTION
else
return get(mock.primal_status, attr.N, MOI.NO_SOLUTION)
return get(mock.primal_status, attr.result_index, MOI.NO_SOLUTION)
end
end
function MOI.get(mock::MockOptimizer, attr::MOI.DualStatus)
if attr.N > mock.result_count
if attr.result_index > mock.result_count
return MOI.NO_SOLUTION
else
return get(mock.dual_status, attr.N, MOI.NO_SOLUTION)
return get(mock.dual_status, attr.result_index, MOI.NO_SOLUTION)
end
end
MOI.get(mock::MockOptimizer, ::MockModelAttribute) = mock.attribute
Expand Down Expand Up @@ -402,7 +402,7 @@ function _safe_set_result(dict::Dict{K,V}, attr::MOI.AnyAttribute, index::K,
if !haskey(dict, xored)
dict[xored] = V()
end
dict[xored][MOI._result_index_field(attr)] = value
dict[xored][attr.result_index] = value
end
function _safe_get_result(dict::Dict, attr::MOI.AnyAttribute, index::MOI.Index,
name::String)
Expand All @@ -411,9 +411,9 @@ function _safe_get_result(dict::Dict, attr::MOI.AnyAttribute, index::MOI.Index,
if result_to_value === nothing
error("No mock $name is set for ", index_name, " `", index, "`.")
end
value = get(result_to_value, MOI._result_index_field(attr), nothing)
value = get(result_to_value, attr.result_index, nothing)
if value === nothing
error("No mock $name is set for ", index_name, " `", index, "` at result index `", MOI._result_index_field(attr), "`.")
error("No mock $name is set for ", index_name, " `", index, "` at result index `", attr.result_index, "`.")
end
return value
end
Expand Down
8 changes: 4 additions & 4 deletions src/Utilities/results.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function get_fallback(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,
idx::MOI.ConstraintIndex)
f = MOI.get(model, MOI.ConstraintFunction(), idx)
# TODO do not include constant if primal solution is a ray
return eval_variables(vi -> MOI.get(model, MOI.VariablePrimal(attr.N), vi), f)
return eval_variables(vi -> MOI.get(model, MOI.VariablePrimal(attr.result_index), vi), f)
end

################ Constraint Dual for Variable-wise constraints #################
Expand Down Expand Up @@ -267,7 +267,7 @@ function variable_dual(model::MOI.ModelLike,
ci::MOI.ConstraintIndex{<:MOI.VectorQuadraticFunction})
func = MOI.get(model, MOI.ConstraintFunction(), ci)
set = MOI.get(model, MOI.ConstraintSet(), ci)
primal_attr = MOI.VariablePrimal(attr.N)
primal_attr = MOI.VariablePrimal(attr.result_index)
coef = variable_coefficient(func, vi, vi -> MOI.get(model, primal_attr, vi))
dual = MOI.get(model, attr, ci)
return set_dot(coef, dual, set)
Expand All @@ -286,7 +286,7 @@ function variable_dual(model::MOI.ModelLike,
vi::MOI.VariableIndex,
ci::MOI.ConstraintIndex{<:MOI.ScalarQuadraticFunction})
func = MOI.get(model, MOI.ConstraintFunction(), ci)
primal_attr = MOI.VariablePrimal(attr.N)
primal_attr = MOI.VariablePrimal(attr.result_index)
coef = variable_coefficient(func, vi, vi -> MOI.get(model, primal_attr, vi))
dual = MOI.get(model, attr, ci)
return coef * dual
Expand Down Expand Up @@ -369,7 +369,7 @@ function variable_dual(model::MOI.ModelLike,
dual += sign * variable_coefficient(f, vi)
elseif F <: MOI.ScalarQuadraticFunction
f = MOI.get(model, obj_attr)
primal_attr = MOI.VariablePrimal(attr.N)
primal_attr = MOI.VariablePrimal(attr.result_index)
dual += sign * variable_coefficient(f, vi, vi -> MOI.get(model, primal_attr, vi))
else
error("Fallback getter for variable constraint dual does not",
Expand Down
56 changes: 24 additions & 32 deletions src/attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,10 @@ struct ResultIndexBoundsError{AttrType} <: Exception
attr::AttrType
result_count::Int
end
# TODO: rename the .N -> .result_index field in necessary attributes (e.g.,
# VariablePrimal, ConstraintPrimal, ConstraintDual), and remove this helper
# function.
_result_index_field(attr) = attr.result_index

function check_result_index_bounds(model::ModelLike, attr)
result_count = get(model, ResultCount())
if !(1 <= _result_index_field(attr) <= result_count)
if !(1 <= attr.result_index <= result_count)
throw(ResultIndexBoundsError(attr, result_count))
end
end
Expand Down Expand Up @@ -1004,17 +1001,16 @@ A variable attribute for the initial assignment to some primal variable's value
struct VariablePrimalStart <: AbstractVariableAttribute end

"""
VariablePrimal(N)
VariablePrimal(result_index)
VariablePrimal()

A variable attribute for the assignment to some primal variable's value in result `N`.
If `N` is omitted, it is 1 by default.
A variable attribute for the assignment to some primal variable's value in result `result_index`.
If `result_index` is omitted, it is 1 by default.
"""
struct VariablePrimal <: AbstractVariableAttribute
N::Int
result_index::Int
end
VariablePrimal() = VariablePrimal(1)
_result_index_field(attr::VariablePrimal) = attr.N

"""
CallbackVariablePrimal(callback_data)
Expand Down Expand Up @@ -1090,11 +1086,11 @@ A constraint attribute for the initial assignment to some constraint's dual valu
struct ConstraintDualStart <: AbstractConstraintAttribute end

"""
ConstraintPrimal(N)
ConstraintPrimal(result_index::Int)
ConstraintPrimal()

A constraint attribute for the assignment to some constraint's primal value(s) in result `N`.
If `N` is omitted, it is 1 by default.
A constraint attribute for the assignment to some constraint's primal value(s)
in result `result_index`. If `result_index` is omitted, it is 1 by default.

Given a constraint `function-in-set`, the `ConstraintPrimal` is the value of the
function evaluated at the primal solution of the variables. For example, given
Expand All @@ -1103,23 +1099,21 @@ a primal solution of `(x,y) = (4,5)`, the `ConstraintPrimal` solution of the
constraint is `1 * 4 + 2 * 5 + 3 = 17`.
"""
struct ConstraintPrimal <: AbstractConstraintAttribute
N::Int
result_index::Int
end
ConstraintPrimal() = ConstraintPrimal(1)
_result_index_field(attr::ConstraintPrimal) = attr.N

"""
ConstraintDual(N)
ConstraintDual(result_index)
ConstraintDual()

A constraint attribute for the assignment to some constraint's dual value(s) in result `N`.
If `N` is omitted, it is 1 by default.
A constraint attribute for the assignment to some constraint's dual value(s) in result `result_index`.
If `result_index` is omitted, it is 1 by default.
"""
struct ConstraintDual <: AbstractConstraintAttribute
N::Int
result_index::Int
end
ConstraintDual() = ConstraintDual(1)
_result_index_field(attr::ConstraintDual) = attr.N

"""
ConstraintBasisStatus(result_index)
Expand Down Expand Up @@ -1395,32 +1389,30 @@ The values indicate how to interpret the result vector.
UNKNOWN_RESULT_STATUS, OTHER_RESULT_STATUS)

"""
PrimalStatus(N)
PrimalStatus(result_index::Int)
PrimalStatus()

A model attribute for the `ResultStatusCode` of the primal result `N`.
If `N` is omitted, it defaults to 1. If `N` is larger than the value of
[`ResultCount`](@ref) then `NO_SOLUTION` is returned.
A model attribute for the `ResultStatusCode` of the primal result `result_index`.
If `result_index` is omitted, it defaults to 1. If `result_index` is larger than
the value of [`ResultCount`](@ref) then `NO_SOLUTION` is returned.
"""
struct PrimalStatus <: AbstractModelAttribute
N::Int
result_index::Int
end
PrimalStatus() = PrimalStatus(1)
_result_index_field(attr::PrimalStatus) = attr.N

"""
DualStatus(N)
DualStatus(result_index)
DualStatus()

A model attribute for the `ResultStatusCode` of the dual result `N`.
If `N` is omitted, it defaults to 1. If `N` is larger than the value of
[`ResultCount`](@ref) then `NO_SOLUTION` is returned.
A model attribute for the `ResultStatusCode` of the dual result `result_index`.
If `result_index` is omitted, it defaults to 1. If `result_index` is larger than
the value of [`ResultCount`](@ref) then `NO_SOLUTION` is returned.
"""
struct DualStatus <: AbstractModelAttribute
N::Int
result_index::Int
end
DualStatus() = DualStatus(1)
_result_index_field(attr::DualStatus) = attr.N


# Cost of bridging constrained variable in S
Expand Down
20 changes: 20 additions & 0 deletions src/deprecate.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# deprecate _result_index_field and accessing attr.N, no export
@deprecate _result_index_field(attr) attr.result_index false

function Base.getproperty(attr::Attr, f::Symbol) where Attr <:Union{
ObjectiveValue,
DualObjectiveValue,
VariablePrimal,
ConstraintPrimal,
ConstraintDual,
ConstraintBasisStatus,
PrimalStatus,
DualStatus,
NLPBlockDual,
}
if f === :N
@warn "Field attr.N is deprecated, use attr.result_index"
return getfield(attr, :result_index)
end
return getfield(attr, f)
end
9 changes: 4 additions & 5 deletions src/nlp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,16 @@ optionally a nonlinear objective.
struct NLPBlock <: AbstractModelAttribute end

"""
NLPBlockDual(N)
NLPBlockDual(result_index::Int)
NLPBlockDual()

The Lagrange multipliers on the constraints from the `NLPBlock` in result `N`.
If `N` is omitted, it is 1 by default.
The Lagrange multipliers on the constraints from the `NLPBlock` in result `result_index`.
If `result_index` is omitted, it is 1 by default.
"""
struct NLPBlockDual <: AbstractModelAttribute
N::Int
result_index::Int
end
NLPBlockDual() = NLPBlockDual(1)
_result_index_field(attr::NLPBlockDual) = attr.N

is_set_by_optimize(::NLPBlockDual) = true

Expand Down
19 changes: 19 additions & 0 deletions test/attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,23 @@
@test_throws err MOI.set(model, MOI.VariablePrimalStart(), [x],
ones(2))
end
attr = MOI.VariablePrimal()
@test_deprecated begin
@test MOI._result_index_field(attr) == 1
end

for attr_type in (
MOI.ObjectiveValue,
MOI.DualObjectiveValue,
MOI.VariablePrimal,
MOI.ConstraintPrimal,
MOI.ConstraintDual,
MOI.ConstraintBasisStatus,
MOI.PrimalStatus,
MOI.DualStatus,
MOI.NLPBlockDual,
)
attr = attr_type(1)
@test_logs (:warn, "Field attr.N is deprecated, use attr.result_index") attr.N
end
end