Skip to content

Commit

Permalink
[Utilities] use appropriate zero type for get_fallback (#2414)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Jan 29, 2024
1 parent 10d8edc commit 50d83f1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/Utilities/mockoptimizer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -667,14 +667,14 @@ function MOI.get(
end

function MOI.get(
mock::MockOptimizer,
mock::MockOptimizer{<:MOI.ModelLike,T},
attr::MOI.ConstraintDual,
idx::MOI.ConstraintIndex{F},
) where {F}
) where {T,F}
MOI.throw_if_not_valid(mock, idx)
if mock.eval_variable_constraint_dual &&
(F == MOI.VariableIndex || F == MOI.VectorOfVariables)
return get_fallback(mock, attr, idx)
return get_fallback(mock, attr, idx, T)
else
MOI.check_result_index_bounds(mock, attr)
return _safe_get_result(mock.constraint_dual, attr, idx, "dual")
Expand Down
46 changes: 28 additions & 18 deletions src/Utilities/results.jl
Original file line number Diff line number Diff line change
Expand Up @@ -318,23 +318,25 @@ function _variable_coefficient(
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
vi::MOI.VariableIndex,
ci::MOI.ConstraintIndex{<:MOI.ScalarAffineFunction},
)
) where {T}
func = MOI.get(model, MOI.ConstraintFunction(), ci)
coef = _variable_coefficient(func, vi)
dual = MOI.get(model, attr, ci)
return coef * dual
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
vi::MOI.VariableIndex,
ci::MOI.ConstraintIndex{<:MOI.ScalarQuadraticFunction},
)
) where {T}
func = MOI.get(model, MOI.ConstraintFunction(), ci)
primal = MOI.VariablePrimal(attr.result_index)
coef = _variable_coefficient(func, vi, vi -> MOI.get(model, primal, vi))
Expand All @@ -343,11 +345,12 @@ function _variable_dual(
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
vi::MOI.VariableIndex,
ci::MOI.ConstraintIndex{<:MOI.VectorAffineFunction},
)
) where {T}
func = MOI.get(model, MOI.ConstraintFunction(), ci)
set = MOI.get(model, MOI.ConstraintSet(), ci)
coef = _variable_coefficient(func, vi)
Expand All @@ -356,11 +359,12 @@ function _variable_dual(
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
vi::MOI.VariableIndex,
ci::MOI.ConstraintIndex{<:MOI.VectorQuadraticFunction},
)
) where {T}
func = MOI.get(model, MOI.ConstraintFunction(), ci)
set = MOI.get(model, MOI.ConstraintSet(), ci)
primal = MOI.VariablePrimal(attr.result_index)
Expand All @@ -370,28 +374,30 @@ function _variable_dual(
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
ci::MOI.ConstraintIndex,
vi::MOI.VariableIndex,
::Type{F},
::Type{S},
) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet}
dual = 0.0
) where {T,F<:MOI.AbstractFunction,S<:MOI.AbstractSet}
dual = zero(T)
for constraint_index in MOI.get(model, MOI.ListOfConstraintIndices{F,S}())
dual += _variable_dual(model, attr, vi, constraint_index)
dual += _variable_dual(T, model, attr, vi, constraint_index)
end
return dual
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
::MOI.ConstraintDual,
ci::MOI.ConstraintIndex,
vi::MOI.VariableIndex,
::Type{F},
::Type{S},
) where {F<:Union{MOI.VariableIndex,MOI.VectorOfVariables},S<:MOI.AbstractSet}
) where {T,F<:Union{MOI.VariableIndex,MOI.VectorOfVariables},S<:MOI.AbstractSet}
for constraint_index in MOI.get(model, MOI.ListOfConstraintIndices{F,S}())
if constraint_index == ci
continue
Expand All @@ -406,22 +412,23 @@ function _variable_dual(
)
end
end
return 0.0
return zero(T)
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
ci::MOI.ConstraintIndex,
vi::MOI.VariableIndex,
)
) where {T}
ray = is_ray(MOI.get(model, MOI.DualStatus()))
dual = 0.0
dual = zero(T)
if !ray
sense = MOI.get(model, MOI.ObjectiveSense())
# Dual definition for maximization problem corresponds to dual
# definition for minimization problem with flipped objective in MOI
sign = sense == MOI.MAX_SENSE ? -1.0 : 1.0
sign = sense == MOI.MAX_SENSE ? T(-1) : T(1)
F = MOI.get(model, MOI.ObjectiveFunctionType())
obj_attr = MOI.ObjectiveFunction{F}()
if F == MOI.VariableIndex
Expand Down Expand Up @@ -449,18 +456,19 @@ function _variable_dual(
end
end
for FS in MOI.get(model, MOI.ListOfConstraintTypesPresent())
dual -= _variable_dual(model, attr, ci, vi, FS[1], FS[2])
dual -= _variable_dual(T, model, attr, ci, vi, FS[1], FS[2])
end
return dual
end

function _variable_dual(
::Type{T},
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
ci::MOI.ConstraintIndex{MOI.VectorOfVariables},
func::MOI.VectorOfVariables,
)
dual = map(vi -> _variable_dual(model, attr, ci, vi), func.variables)
) where {T}
dual = map(vi -> _variable_dual(T, model, attr, ci, vi), func.variables)
set = MOI.get(model, MOI.ConstraintSet(), ci)
return dot_coefficients(dual, set)
end
Expand All @@ -470,7 +478,8 @@ end
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
ci::MOI.ConstraintIndex{Union{MOI.VariableIndex,MOI.VectorOfVariables}},
)
::Type{T} = Float64,
) where {T}
Compute the dual of the constraint of index `ci` using the `ConstraintDual` of
other constraints and the `ConstraintFunction` values.
Expand All @@ -483,8 +492,9 @@ function get_fallback(
model::MOI.ModelLike,
attr::MOI.ConstraintDual,
ci::MOI.ConstraintIndex{<:Union{MOI.VariableIndex,MOI.VectorOfVariables}},
)
::Type{T} = Float64,
) where {T}
MOI.check_result_index_bounds(model, attr)
f = MOI.get(model, MOI.ConstraintFunction(), ci)
return _variable_dual(model, attr, ci, f)
return _variable_dual(T, model, attr, ci, f)
end

0 comments on commit 50d83f1

Please sign in to comment.