Skip to content

Commit 3b336ac

Browse files
authored
Merge branch 'master' into bl/hessian_forward
2 parents db7de82 + 355a039 commit 3b336ac

30 files changed

+352
-113
lines changed

.github/workflows/format_check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
shell: julia --color=yes {0}
1919
run: |
2020
using Pkg
21-
Pkg.add(PackageSpec(name="JuliaFormatter", version="1"))
21+
Pkg.add(PackageSpec(name="JuliaFormatter", version="2"))
2222
using JuliaFormatter
2323
format(".", verbose=true)
2424
out = String(read(Cmd(`git diff`)))

src/Bridges/Constraint/Constraint.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ function add_all_bridges(model, ::Type{T}) where {T}
5656
end
5757
MOI.Bridges.add_bridge(model, GreaterToLessBridge{T})
5858
MOI.Bridges.add_bridge(model, HermitianToSymmetricPSDBridge{T})
59+
MOI.Bridges.add_bridge(model, HermitianToComplexSymmetricBridge{T})
5960
MOI.Bridges.add_bridge(model, IndicatorActiveOnFalseBridge{T})
6061
MOI.Bridges.add_bridge(model, IndicatorGreaterToLessThanBridge{T})
6162
MOI.Bridges.add_bridge(model, IndicatorLessToGreaterThanBridge{T})

src/Bridges/Constraint/bridges/BinPackingToMILPBridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ function MOI.Bridges.final_touch(
227227
end
228228
unit_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
229229
convex_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
230-
for xi in ret[1]::T:ret[2]::T
230+
for xi in (ret[1]::T):(ret[2]::T)
231231
new_var, _ = MOI.add_constrained_variable(model, MOI.ZeroOne())
232232
push!(bridge.variables, new_var)
233233
if !haskey(S, xi)

src/Bridges/Constraint/bridges/CircuitToMILPBridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function bridge_constraint(
5656
s::MOI.Circuit,
5757
) where {T,F<:Union{MOI.VectorOfVariables,MOI.VectorAffineFunction{T}}}
5858
n = MOI.dimension(s)
59-
z = [MOI.add_constrained_variable(model, MOI.ZeroOne())[1] for _ in 1:n^2]
59+
z = [MOI.add_constrained_variable(model, MOI.ZeroOne())[1] for _ in 1:(n^2)]
6060
Z = reshape(z, n, n)
6161
equal_to = MOI.ConstraintIndex{MOI.ScalarAffineFunction{T},MOI.EqualTo{T}}[]
6262
for (i, x) in enumerate(MOI.Utilities.eachscalar(f))

src/Bridges/Constraint/bridges/CountDistinctToMILPBridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ function _final_touch_general_case(
375375
end
376376
unit_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
377377
convex_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
378-
for xi in ret[1]::T:ret[2]::T
378+
for xi in (ret[1]::T):(ret[2]::T)
379379
new_var, _ = MOI.add_constrained_variable(model, MOI.ZeroOne())
380380
push!(bridge.variables, new_var)
381381
if !haskey(S, xi)

src/Bridges/Constraint/bridges/CountGreaterThanToMILPBridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ function _add_unit_expansion(
214214
end
215215
unit_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
216216
convex_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
217-
for xi in ret[1]::T:ret[2]::T
217+
for xi in (ret[1]::T):(ret[2]::T)
218218
new_var, _ = MOI.add_constrained_variable(model, MOI.ZeroOne())
219219
push!(bridge.variables, new_var)
220220
if !haskey(S, xi)
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Copyright (c) 2017: Miles Lubin and contributors
2+
# Copyright (c) 2017: Google Inc.
3+
#
4+
# Use of this source code is governed by an MIT-style license that can be found
5+
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
6+
7+
"""
8+
HermitianToComplexSymmetricBridge{T,F,G} <: Bridges.Constraint.AbstractBridge
9+
10+
`HermitianToSymmetricBridge` implements the following reformulation:
11+
12+
* Hermitian positive semidefinite `n x n` represented as a vector of real
13+
entries with real and imaginary parts on different entries to a vector
14+
of complex entries.
15+
16+
See also [`MOI.Bridges.Constraint.HermitianToSymmetricPSDBridge`](@ref).
17+
18+
## Source node
19+
20+
`HermitianToComplexSymmetricBridge` supports:
21+
22+
* `G` in [`MOI.HermitianPositiveSemidefiniteConeTriangle`](@ref)
23+
24+
## Target node
25+
26+
`HermitianToComplexSymmetricBridge` creates:
27+
28+
* `F` in [`MOI.PositiveSemidefiniteConeTriangle`](@ref)
29+
30+
Note that if `G` is `MOI.VectorAffineFunction{T}` then `F` will be
31+
`MOI.VectorAffineFunction{Complex{T}}`
32+
"""
33+
struct HermitianToComplexSymmetricBridge{T,F,G} <: SetMapBridge{
34+
T,
35+
MOI.PositiveSemidefiniteConeTriangle,
36+
MOI.HermitianPositiveSemidefiniteConeTriangle,
37+
F,
38+
G,
39+
}
40+
constraint::MOI.ConstraintIndex{F,MOI.PositiveSemidefiniteConeTriangle}
41+
end
42+
43+
const HermitianToComplexSymmetric{T,OT<:MOI.ModelLike} =
44+
SingleBridgeOptimizer{HermitianToComplexSymmetricBridge{T},OT}
45+
46+
# Should be favored over `HermitianToSymmetricPSDBridge`
47+
MOI.Bridges.bridging_cost(::Type{<:HermitianToComplexSymmetricBridge}) = 0.5
48+
49+
function _promote_complex_vcat(::Type{T}, ::Type{G}) where {T<:Real,G}
50+
S = MOI.Utilities.scalar_type(G)
51+
if S === T
52+
M = Complex{T}
53+
elseif S <: MOI.Utilities.TypedLike{T}
54+
M = MOI.Utilities.similar_type(S, Complex{T})
55+
else
56+
M = MOI.Utilities.promote_operation(*, Complex{T}, Complex{T}, S)
57+
end
58+
return MOI.Utilities.promote_operation(vcat, Complex{T}, M)
59+
end
60+
61+
function concrete_bridge_type(
62+
::Type{<:HermitianToComplexSymmetricBridge{T}},
63+
G::Type{<:MOI.AbstractVectorFunction},
64+
::Type{MOI.HermitianPositiveSemidefiniteConeTriangle},
65+
) where {T}
66+
F = _promote_complex_vcat(T, G)
67+
return HermitianToComplexSymmetricBridge{T,F,G}
68+
end
69+
70+
function MOI.Bridges.map_set(
71+
::Type{<:HermitianToComplexSymmetricBridge},
72+
set::MOI.HermitianPositiveSemidefiniteConeTriangle,
73+
)
74+
return MOI.PositiveSemidefiniteConeTriangle(set.side_dimension)
75+
end
76+
77+
function MOI.Bridges.inverse_map_set(
78+
::Type{<:HermitianToComplexSymmetricBridge},
79+
set::MOI.PositiveSemidefiniteConeTriangle,
80+
)
81+
return MOI.HermitianPositiveSemidefiniteConeTriangle(set.side_dimension)
82+
end
83+
84+
function MOI.Bridges.map_function(
85+
::Type{<:HermitianToComplexSymmetricBridge{T}},
86+
func,
87+
) where {T}
88+
complex_scalars = MOI.Utilities.eachscalar(func)
89+
S = MOI.Utilities.scalar_type(_promote_complex_vcat(T, typeof(func)))
90+
complex_dim = length(complex_scalars)
91+
complex_set = MOI.Utilities.set_with_dimension(
92+
MOI.HermitianPositiveSemidefiniteConeTriangle,
93+
complex_dim,
94+
)
95+
n = complex_set.side_dimension
96+
real_set = MOI.PositiveSemidefiniteConeTriangle(n)
97+
real_dim = MOI.dimension(real_set)
98+
real_scalars = Vector{S}(undef, real_dim)
99+
real_index = 0
100+
imag_index = real_dim
101+
for j in 1:n
102+
for i in 1:j
103+
real_index += 1
104+
if i == j
105+
real_scalars[real_index] = complex_scalars[real_index]
106+
else
107+
imag_index += 1
108+
real_scalars[real_index] =
109+
one(Complex{T}) * complex_scalars[real_index] +
110+
(one(T) * im) * complex_scalars[imag_index]
111+
end
112+
end
113+
end
114+
@assert length(real_scalars) == real_index
115+
@assert length(complex_scalars) == imag_index
116+
return MOI.Utilities.vectorize(real_scalars)
117+
end
118+
119+
function MOI.Bridges.inverse_adjoint_map_function(
120+
BT::Type{<:HermitianToComplexSymmetricBridge},
121+
func,
122+
)
123+
return MOI.Bridges.map_function(BT, func)
124+
end
125+
126+
function MOI.Bridges.inverse_map_function(
127+
::Type{<:HermitianToComplexSymmetricBridge},
128+
func,
129+
)
130+
real_scalars = MOI.Utilities.eachscalar(func)
131+
real_set = MOI.Utilities.set_with_dimension(
132+
MOI.PositiveSemidefiniteConeTriangle,
133+
length(real_scalars),
134+
)
135+
n = real_set.side_dimension
136+
complex_set = MOI.HermitianPositiveSemidefiniteConeTriangle(n)
137+
complex_scalars = Vector{
138+
MA.promote_operation(real, MOI.Utilities.scalar_type(typeof(func))),
139+
}(
140+
undef,
141+
MOI.dimension(complex_set),
142+
)
143+
real_index = 0
144+
imag_index = MOI.dimension(real_set)
145+
for j in 1:n
146+
for i in 1:j
147+
real_index += 1
148+
complex_scalars[real_index] = real(real_scalars[real_index])
149+
if i != j
150+
imag_index += 1
151+
complex_scalars[imag_index] = imag(real_scalars[real_index])
152+
end
153+
end
154+
end
155+
@assert length(real_scalars) == real_index
156+
@assert length(complex_scalars) == imag_index
157+
return MOI.Utilities.vectorize(complex_scalars)
158+
end
159+
160+
function MOI.Bridges.adjoint_map_function(
161+
BT::Type{<:HermitianToComplexSymmetricBridge},
162+
func,
163+
)
164+
return MOI.Bridges.inverse_map_function(BT, func)
165+
end

src/Bridges/Constraint/bridges/HermitianToSymmetricPSDBridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ function MOI.Bridges.map_function(
153153
end
154154

155155
function MOI.Bridges.inverse_map_function(
156-
BT::Type{<:HermitianToSymmetricPSDBridge},
156+
::Type{<:HermitianToSymmetricPSDBridge},
157157
func,
158158
)
159159
real_scalars = MOI.Utilities.eachscalar(func)

src/Bridges/Constraint/bridges/LogDetBridge.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ function _extract_eigenvalues(
3131
f_scalars = MOI.Utilities.eachscalar(f)
3232
tu = [f_scalars[i] for i in 1:offset]
3333
n = MOI.Utilities.trimap(d, d)
34-
X = f_scalars[offset.+(1:n)]
34+
X = f_scalars[offset .+ (1:n)]
3535
N = MOI.Utilities.trimap(2d, 2d)
3636
Δ = MOI.add_variables(model, n)
3737
Z = [zero(MOI.ScalarAffineFunction{T}) for i in 1:(N-n)]
3838
for j in 1:d
3939
for i in j:d
40-
Z[MOI.Utilities.trimap(i, d + j)-n] = Δ[MOI.Utilities.trimap(i, j)]
40+
Z[MOI.Utilities.trimap(i, d+j)-n] = Δ[MOI.Utilities.trimap(i, j)]
4141
end
42-
Z[MOI.Utilities.trimap(d + j, d + j)-n] = Δ[MOI.Utilities.trimap(j, j)]
42+
Z[MOI.Utilities.trimap(d+j, d+j)-n] = Δ[MOI.Utilities.trimap(j, j)]
4343
end
4444
Y = MOI.Utilities.operate(vcat, T, X, MOI.Utilities.vectorize(Z))
4545
set = MOI.PositiveSemidefiniteConeTriangle(2d)

src/Bridges/Constraint/bridges/ReifiedCountDistinctToMILPBridge.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ function MOI.get(
212212
)
213213
return MOI.ConstraintIndex{MOI.VariableIndex,MOI.ZeroOne}[
214214
MOI.ConstraintIndex{MOI.VariableIndex,MOI.ZeroOne}(x.value) for
215-
x in bridge.variables[1:end-2]
215+
x in bridge.variables[1:(end-2)]
216216
]
217217
end
218218

@@ -279,7 +279,7 @@ function MOI.Bridges.final_touch(
279279
end
280280
unit_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
281281
convex_f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{T}[], zero(T))
282-
for xi in ret[1]::T:ret[2]::T
282+
for xi in (ret[1]::T):(ret[2]::T)
283283
new_var, _ = MOI.add_constrained_variable(model, MOI.ZeroOne())
284284
push!(bridge.variables, new_var)
285285
if !haskey(S, xi)

0 commit comments

Comments
 (0)