forked from jump-dev/JuMP.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomplement.jl
75 lines (68 loc) · 2.16 KB
/
complement.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Copyright 2017, Iain Dunning, Joey Huchette, Miles Lubin, and contributors
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# This file extends JuMP to complementarity constraints. It is a good example of
# how JuMP can be extended. In particular, it allows constraints of the form:
#
# @constraint(model, complements(2x - 1, x))
# @constraint(model, 2x - 1 ⟂ x)
function _build_complements_constraint(
errorf::Function,
F::AbstractArray{<:AbstractJuMPScalar},
x::AbstractArray{<:AbstractVariableRef},
)
if size(F) != size(x)
errorf(
"size of mapping does not match size of variables: " *
"$(size(F)) != $(size(x)).",
)
end
return VectorConstraint([F; x], MOI.Complements(2 * length(F)))
end
function _build_complements_constraint(
errorf::Function,
F::Containers.SparseAxisArray{<:AbstractJuMPScalar},
x::Containers.SparseAxisArray{<:AbstractVariableRef},
)
elements = [F[i] for i in eachindex(F)]
for i in eachindex(F)
if haskey(x, i)
push!(elements, x[i])
else
errorf("keys of the SparseAxisArray's do not match.")
end
end
return VectorConstraint(elements, MOI.Complements(length(elements)))
end
function _build_complements_constraint(
errorf::Function,
::AbstractArray{<:AbstractJuMPScalar},
::AbstractArray{<:AbstractJuMPScalar},
)
return errorf("second term must be an array of variables.")
end
function _build_complements_constraint(
::Function,
F::AbstractJuMPScalar,
x::AbstractVariableRef,
)
return VectorConstraint([F, x], MOI.Complements(2))
end
function _build_complements_constraint(
errorf::Function,
::AbstractJuMPScalar,
::AbstractJuMPScalar,
)
return errorf("second term must be a variable.")
end
function parse_constraint_call(
errorf::Function,
::Bool,
::Union{Val{:complements},Val{:⟂}},
F,
x,
)
f, parse_code = _MA.rewrite(F)
return parse_code, :(_build_complements_constraint($errorf, $f, $(esc(x))))
end