Skip to content

Commit 06bc2ea

Browse files
authored
Refactor SAGE (#100)
* Refactor SAGE * Rename submodule * Rename submodule * Rename submodule * Rename submodule * Rename submodule * Fixes * Fixes * Fix format * Rename
1 parent a5c4802 commit 06bc2ea

File tree

7 files changed

+103
-141
lines changed

7 files changed

+103
-141
lines changed

src/PolyJuMP.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ include("default.jl")
3434
include("model.jl")
3535
include("KKT/KKT.jl")
3636
include("QCQP/QCQP.jl")
37-
include("RelativeEntropy/RelativeEntropy.jl")
37+
include("SAGE/SAGE.jl")
3838

3939
end # module
Lines changed: 40 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,22 @@
1-
module RelativeEntropy
1+
module SAGE
22

33
import MutableArithmetics as MA
44
import MultivariatePolynomials as MP
55
import MathOptInterface as MOI
66
import JuMP
77
import PolyJuMP
88

9-
abstract type AbstractAGECone <: MOI.AbstractVectorSet end
10-
11-
"""
12-
struct SignomialSAGECone <: MOI.AbstractVectorSet
13-
α::Matrix{Int}
14-
end
15-
16-
**S**ums of **A**M/**G**M **E**xponential for signomials.
17-
"""
18-
struct SignomialSAGECone <: AbstractAGECone
19-
α::Matrix{Int}
20-
end
21-
22-
"""
23-
struct PolynomialSAGECone <: MOI.AbstractVectorSet
24-
α::Matrix{Int}
25-
end
26-
27-
**S**ums of **A**M/**G**M **E**xponential for polynomials.
28-
"""
29-
struct PolynomialSAGECone <: AbstractAGECone
9+
struct Cone{C} <: MOI.AbstractVectorSet
10+
cone::C
3011
α::Matrix{Int}
3112
end
3213

33-
struct SignomialAGECone <: AbstractAGECone
34-
α::Matrix{Int}
35-
k::Int
36-
end
37-
38-
struct PolynomialAGECone <: AbstractAGECone
39-
α::Matrix{Int}
40-
k::Int
14+
function JuMP.reshape_set(c::Cone, ::PolyJuMP.PolynomialShape)
15+
return c.cone
4116
end
4217

43-
MOI.dimension(set::AbstractAGECone) = size(set.α, 1)
44-
Base.copy(set::AbstractAGECone) = set
18+
MOI.dimension(set::Cone) = size(set.α, 1)
19+
Base.copy(set::Cone) = set
4520

4621
function _exponents_matrix(monos)
4722
α = Matrix{Int}(undef, length(monos), MP.nvariables(monos))
@@ -54,64 +29,48 @@ function _exponents_matrix(monos)
5429
return α
5530
end
5631

57-
struct SignomialSAGESet <: PolyJuMP.PolynomialSet end
58-
function JuMP.reshape_set(::SignomialSAGECone, ::PolyJuMP.PolynomialShape)
59-
return SignomialSAGESet()
60-
end
61-
function JuMP.moi_set(::SignomialSAGESet, monos)
62-
return SignomialSAGECone(_exponents_matrix(monos))
63-
end
32+
"""
33+
struct Signomials{M<:Union{Nothing,Int,MP.AbstractMonomial}} <: PolyJuMP.PolynomialSet
6434
65-
struct PolynomialSAGESet <: PolyJuMP.PolynomialSet end
66-
function JuMP.reshape_set(::PolynomialSAGECone, ::PolyJuMP.PolynomialShape)
67-
return PolynomialSAGESet()
35+
**S**ums of **A**M/**G**M **E**xponential for signomials.
36+
"""
37+
struct Signomials{M<:Union{Nothing,Int,MP.AbstractMonomial}} <:
38+
PolyJuMP.PolynomialSet
39+
monomial::M
6840
end
69-
function JuMP.moi_set(::PolynomialSAGESet, monos)
70-
return PolynomialSAGECone(_exponents_matrix(monos))
41+
Signomials() = Signomials(nothing)
42+
_index(_, ::Nothing) = nothing
43+
_index(monos, mono::MP.AbstractMonomial) = findfirst(isequal(mono), monos)::Int
44+
function JuMP.moi_set(c::Signomials, monos)
45+
return Cone(Signomials(_index(monos, c.monomial)), _exponents_matrix(monos))
7146
end
7247

73-
struct SignomialAGESet{MT<:MP.AbstractMonomial} <: PolyJuMP.PolynomialSet
74-
monomial::MT
75-
end
76-
function JuMP.reshape_set(
77-
set::SignomialAGECone,
78-
shape::PolyJuMP.PolynomialShape,
79-
)
80-
return SignomialAGESet(shape.monomials[set.k])
81-
end
82-
function JuMP.moi_set(set::SignomialAGESet, monos)
83-
k = findfirst(isequal(set.monomial), monos)
84-
return SignomialAGECone(_exponents_matrix(monos), k)
85-
end
48+
"""
49+
struct Polynomials{M<:Union{Nothing,Int,MP.AbstractMonomial}} <: PolyJuMP.PolynomialSet
8650
87-
struct PolynomialAGESet{MT<:MP.AbstractMonomial} <: PolyJuMP.PolynomialSet
88-
monomial::MT
89-
end
90-
function JuMP.reshape_set(
91-
set::PolynomialAGECone,
92-
shape::PolyJuMP.PolynomialShape,
93-
)
94-
return PolynomialAGESet(shape.monomials[set.k])
95-
end
96-
function JuMP.moi_set(set::PolynomialAGESet, monos)
97-
k = findfirst(isequal(set.monomial), monos)
98-
return PolynomialAGECone(_exponents_matrix(monos), k)
51+
**S**ums of **A**M/**G**M **E**xponential for polynomials.
52+
"""
53+
struct Polynomials{M<:Union{Nothing,Int,MP.AbstractMonomial}} <:
54+
PolyJuMP.PolynomialSet
55+
monomial::M
56+
end
57+
Polynomials() = Polynomials(nothing)
58+
function JuMP.moi_set(c::Polynomials, monos)
59+
return Cone(
60+
Polynomials(_index(monos, c.monomial)),
61+
_exponents_matrix(monos),
62+
)
9963
end
10064

10165
function setdefaults!(data::PolyJuMP.Data)
102-
PolyJuMP.setdefault!(data, PolyJuMP.NonNegPoly, PolynomialSAGESet)
66+
PolyJuMP.setdefault!(data, PolyJuMP.NonNegPoly, Polynomials)
10367
return
10468
end
10569

10670
function JuMP.build_constraint(
10771
_error::Function,
10872
p,
109-
set::Union{
110-
SignomialSAGESet,
111-
PolynomialSAGESet,
112-
SignomialAGESet,
113-
PolynomialAGESet,
114-
};
73+
set::Union{Signomials,Polynomials};
11574
kws...,
11675
)
11776
coefs = PolyJuMP.non_constant_coefficients(p)
@@ -188,7 +147,7 @@ include("bridges/sage.jl")
188147

189148
function PolyJuMP.bridges(
190149
F::Type{<:MOI.AbstractVectorFunction},
191-
::Type{<:SignomialSAGECone},
150+
::Type{Cone{Signomials{Nothing}}},
192151
)
193152
return [(SAGEBridge, PolyJuMP._coef_type(F))]
194153
end
@@ -197,7 +156,7 @@ include("bridges/age.jl")
197156

198157
function PolyJuMP.bridges(
199158
F::Type{<:MOI.AbstractVectorFunction},
200-
::Type{<:SignomialAGECone},
159+
::Type{Cone{Signomials{Int}}},
201160
)
202161
return [(AGEBridge, PolyJuMP._coef_type(F))]
203162
end
@@ -206,9 +165,9 @@ include("bridges/signomial.jl")
206165

207166
function PolyJuMP.bridges(
208167
F::Type{<:MOI.AbstractVectorFunction},
209-
::Type{<:Union{PolynomialSAGECone,PolynomialAGECone}},
210-
)
211-
return [(SignomialBridge, PolyJuMP._coef_type(F))]
168+
::Type{Cone{Polynomials{M}}},
169+
) where {M}
170+
return [(SignomialsBridge, PolyJuMP._coef_type(F))]
212171
end
213172

214173
end

src/RelativeEntropy/bridges/age.jl renamed to src/SAGE/bridges/age.jl

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ In this bridge, we use the second formulation.
3636
"Relative entropy relaxations for signomial optimization."
3737
SIAM Journal on Optimization 26.2 (2016): 1147-1173.
3838
[MCW21] Murray, Riley, Venkat Chandrasekaran, and Adam Wierman.
39-
"Signomial and polynomial optimization via relative entropy and partial dualization."
39+
"Signomials and polynomial optimization via relative entropy and partial dualization."
4040
Mathematical Programming Computation 13 (2021): 257-295.
4141
https://arxiv.org/pdf/1907.00814.pdf
4242
"""
@@ -50,7 +50,7 @@ function MOI.Bridges.Constraint.bridge_constraint(
5050
::Type{AGEBridge{T,F,G,H}},
5151
model,
5252
func::H,
53-
set::SignomialAGECone,
53+
set::Cone{Signomials{Int}},
5454
) where {T,F,G,H}
5555
m = size(set.α, 1)
5656
ν = MOI.add_variables(model, m - 1)
@@ -59,7 +59,7 @@ function MOI.Bridges.Constraint.bridge_constraint(
5959
f = zero(typeof(sumν))
6060
j = 0
6161
for i in 1:m
62-
if i == set.k
62+
if i == set.cone.monomial
6363
MA.sub_mul!!(f, convert(T, set.α[i, var]), sumν)
6464
else
6565
j += 1
@@ -72,19 +72,23 @@ function MOI.Bridges.Constraint.bridge_constraint(
7272
f = MOI.Utilities.operate(
7373
vcat,
7474
T,
75-
scalars[set.k] + sumν,
76-
scalars[setdiff(1:m, set.k)],
75+
scalars[set.cone.monomial] + sumν,
76+
scalars[setdiff(1:m, set.cone.monomial)],
7777
MOI.VectorOfVariables(ν),
7878
)
7979
relative_entropy_constraint =
8080
MOI.add_constraint(model, f, MOI.RelativeEntropyCone(2m - 1))
81-
return AGEBridge{T,F,G,H}(set.k, ceq, relative_entropy_constraint)
81+
return AGEBridge{T,F,G,H}(
82+
set.cone.monomial,
83+
ceq,
84+
relative_entropy_constraint,
85+
)
8286
end
8387

8488
function MOI.supports_constraint(
8589
::Type{<:AGEBridge{T}},
8690
::Type{<:MOI.AbstractVectorFunction},
87-
::Type{<:SignomialAGECone},
91+
::Type{Cone{Signomials{Int}}},
8892
) where {T}
8993
return true
9094
end
@@ -102,7 +106,7 @@ end
102106
function MOI.Bridges.Constraint.concrete_bridge_type(
103107
::Type{<:AGEBridge{T}},
104108
H::Type{<:MOI.AbstractVectorFunction},
105-
::Type{<:SignomialAGECone},
109+
::Type{Cone{Signomials{Int}}},
106110
) where {T}
107111
S = MOI.Utilities.scalar_type(H)
108112
F = MOI.Utilities.promote_operation(

src/RelativeEntropy/bridges/sage.jl renamed to src/SAGE/bridges/sage.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
struct SAGEBridge{T,F,G} <: MOI.Bridges.Constraint.AbstractBridge
22
ν::Matrix{MOI.VariableIndex}
33
age_constraints::Vector{
4-
MOI.ConstraintIndex{MOI.VectorOfVariables,SignomialAGECone},
4+
MOI.ConstraintIndex{MOI.VectorOfVariables,Cone{Signomials{Int}}},
55
}
66
equality_constraints::Vector{MOI.ConstraintIndex{F,MOI.EqualTo{T}}}
77
end
@@ -10,16 +10,16 @@ function MOI.Bridges.Constraint.bridge_constraint(
1010
::Type{SAGEBridge{T,F,G}},
1111
model,
1212
func::G,
13-
set::SignomialSAGECone,
13+
set::Cone{Signomials{Nothing}},
1414
) where {T,F,G}
1515
m = size(set.α, 1)
1616
ν = Matrix{MOI.VariableIndex}(undef, m, m)
17-
A = SignomialAGECone
17+
A = Cone{Signomials{Int}}
1818
age_constraints =
1919
Vector{MOI.ConstraintIndex{MOI.VectorOfVariables,A}}(undef, m)
2020
for k in 1:m
2121
ν[k, :], age_constraints[k] =
22-
MOI.add_constrained_variables(model, A(set.α, k))
22+
MOI.add_constrained_variables(model, Cone(Signomials(k), set.α))
2323
end
2424
scalars = MOI.Utilities.eachscalar(func)
2525
equality_constraints = map(1:m) do i
@@ -39,13 +39,13 @@ end
3939
function MOI.supports_constraint(
4040
::Type{<:SAGEBridge{T}},
4141
::Type{<:MOI.AbstractVectorFunction},
42-
::Type{<:SignomialSAGECone},
42+
::Type{Cone{Signomials{Nothing}}},
4343
) where {T}
4444
return true
4545
end
4646

4747
function MOI.Bridges.added_constrained_variable_types(::Type{<:SAGEBridge})
48-
return Tuple{Type}[(SignomialAGECone,)]
48+
return Tuple{Type}[(Cone{Signomials{Int}},)]
4949
end
5050

5151
function MOI.Bridges.added_constraint_types(
@@ -57,7 +57,7 @@ end
5757
function MOI.Bridges.Constraint.concrete_bridge_type(
5858
::Type{<:SAGEBridge{T}},
5959
G::Type{<:MOI.AbstractVectorFunction},
60-
::Type{<:SignomialSAGECone},
60+
::Type{Cone{Signomials{Nothing}}},
6161
) where {T}
6262
S = MOI.Utilities.scalar_type(G)
6363
F = MOI.Utilities.promote_operation(
Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
"""
2-
SignomialBridge{T,S,P,F} <: MOI.Bridges.Constraint.AbstractBridge
2+
SignomialsBridge{T,S,P,F} <: MOI.Bridges.Constraint.AbstractBridge
33
4-
We use the Signomial Representative `SR` equation of [MCW21].
4+
We use the Signomials Representative `SR` equation of [MCW21].
55
66
[MCW20] Riley Murray, Venkat Chandrasekaran, Adam Wierman
77
"Newton Polytopes and Relative Entropy Optimization"
88
https://arxiv.org/abs/1810.01614
99
[MCW21] Murray, Riley, Venkat Chandrasekaran, and Adam Wierman.
10-
"Signomial and polynomial optimization via relative entropy and partial dualization."
10+
"Signomials and polynomial optimization via relative entropy and partial dualization."
1111
Mathematical Programming Computation 13 (2021): 257-295.
1212
https://arxiv.org/pdf/1907.00814.pdf
1313
"""
14-
struct SignomialBridge{T,S,P,F} <: MOI.Bridges.Constraint.AbstractBridge
14+
struct SignomialsBridge{T,S,P,F} <: MOI.Bridges.Constraint.AbstractBridge
1515
constraint::MOI.ConstraintIndex{F,S}
1616
end
1717

18-
_signomial(set::PolynomialSAGECone) = SignomialSAGECone(set.α)
19-
_signomial(::Type{PolynomialSAGECone}) = SignomialSAGECone
20-
_signomial(set::PolynomialAGECone) = SignomialAGECone(set.α, set.k)
21-
_signomial(::Type{PolynomialAGECone}) = SignomialAGECone
22-
2318
function MOI.Bridges.Constraint.bridge_constraint(
24-
::Type{SignomialBridge{T,S,P,F}},
19+
::Type{SignomialsBridge{T,S,P,F}},
2520
model,
2621
func::F,
2722
set,
@@ -44,42 +39,46 @@ function MOI.Bridges.Constraint.bridge_constraint(
4439
g[i] = vi
4540
end
4641
end
47-
constraint =
48-
MOI.add_constraint(model, MOI.Utilities.vectorize(g), _signomial(set))
49-
return SignomialBridge{T,S,P,F}(constraint)
42+
constraint = MOI.add_constraint(
43+
model,
44+
MOI.Utilities.vectorize(g),
45+
Cone(Signomials(set.cone.monomial), set.α),
46+
)
47+
return SignomialsBridge{T,S,P,F}(constraint)
5048
end
5149

5250
function MOI.supports_constraint(
53-
::Type{<:SignomialBridge{T}},
51+
::Type{<:SignomialsBridge{T}},
5452
::Type{<:MOI.AbstractVectorFunction},
55-
::Type{<:Union{PolynomialSAGECone,PolynomialAGECone}},
56-
) where {T}
53+
::Type{Cone{Polynomials{M}}},
54+
) where {T,M}
5755
return true
5856
end
5957

60-
function MOI.Bridges.added_constrained_variable_types(::Type{<:SignomialBridge})
58+
function MOI.Bridges.added_constrained_variable_types(
59+
::Type{<:SignomialsBridge},
60+
)
6161
return Tuple{Type}[(MOI.Reals,)]
6262
end
6363

6464
function MOI.Bridges.added_constraint_types(
65-
::Type{<:SignomialBridge{T,S,P,F}},
65+
::Type{<:SignomialsBridge{T,S,P,F}},
6666
) where {T,S,P,F}
6767
return [(F, S)]
6868
end
6969

7070
function MOI.Bridges.Constraint.concrete_bridge_type(
71-
::Type{<:SignomialBridge{T}},
71+
::Type{<:SignomialsBridge{T}},
7272
F::Type{<:MOI.AbstractVectorFunction},
73-
P::Type{<:Union{PolynomialSAGECone,PolynomialAGECone}},
74-
) where {T}
75-
S = _signomial(P)
76-
return SignomialBridge{T,S,P,F}
73+
P::Type{Cone{Polynomials{M}}},
74+
) where {T,M}
75+
return SignomialsBridge{T,Cone{Signomials{M}},P,F}
7776
end
7877

7978
function MOI.get(
8079
model::MOI.ModelLike,
8180
attr::DecompositionAttribute,
82-
bridge::SignomialBridge,
81+
bridge::SignomialsBridge,
8382
)
8483
return MOI.get(model, attr, bridge.constraint)
8584
end

0 commit comments

Comments
 (0)