Skip to content
Merged
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
20 changes: 10 additions & 10 deletions src/Bridges/Constraint/geomean.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ function bridge_constraint(::Type{GeoMeanBridge{T, F, G}}, model,

xl1 = MOI.SingleVariable(xij[1])
sN = one(T) / √N
function _getx(i)
A = MOIU.promote_operation(*, T, T, MOI.SingleVariable)
function _getx(i)::A
if i > n
return sN * xl1
else
Expand All @@ -69,10 +70,9 @@ function bridge_constraint(::Type{GeoMeanBridge{T, F, G}}, model,

t = f_scalars[1]
# With sqrt(2)^l*t - xl1, we should scale both the ConstraintPrimal and ConstraintDual
tubc = MOIU.add_scalar_constraint(model,
MOIU.operate!(+, T, t, -sN * xl1),
MOI.LessThan(zero(T)),
allow_modify_function=true)
tubc = MOIU.add_scalar_constraint(
model, MOIU.operate!(+, T, t, -sN * xl1), MOI.LessThan(zero(T)),
allow_modify_function=true)

socrc = Vector{CI{G, MOI.RotatedSecondOrderCone}}(undef, N-1)
offset = offsetnext = 0
Expand All @@ -83,13 +83,13 @@ function bridge_constraint(::Type{GeoMeanBridge{T, F, G}}, model,
a = _getx(2j-1)
b = _getx(2j)
else
a = one(T) * MOI.SingleVariable(xij[offsetnext+2j-1])
b = one(T) * MOI.SingleVariable(xij[offsetnext+2j])
a = convert(A, MOI.SingleVariable(xij[offsetnext+2j-1]))
b = convert(A, MOI.SingleVariable(xij[offsetnext+2j]))
end
c = MOI.SingleVariable(xij[offset+j])
socrc[offset + j] = MOI.add_constraint(model,
MOIU.operate(vcat, T, a, b, c),
MOI.RotatedSecondOrderCone(3))
socrc[offset + j] = MOI.add_constraint(
model, MOIU.operate(vcat, T, a, b, c),
MOI.RotatedSecondOrderCone(3))
end
offset = offsetnext
end
Expand Down
24 changes: 24 additions & 0 deletions src/Utilities/functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1334,6 +1334,30 @@ function fill_vector(vector::Vector, ::Type{T}, vector_offset::Int,
funcs...)
end

function fill_variables(variables::Vector{MOI.VariableIndex}, offset::Int,
output_offset::Int, func::MOI.SingleVariable)
variables[offset + 1] = func.variable
end

function fill_variables(variables::Vector{MOI.VariableIndex}, offset::Int,
output_offset::Int, func::MOI.VectorOfVariables)
variables[offset .+ (1:length(func.variables))] .= func.variables
end

function promote_operation(::typeof(vcat), ::Type{T},
::Type{<:Union{MOI.SingleVariable,
MOI.VectorOfVariables}}...) where T
return MOI.VectorOfVariables
end
function operate(::typeof(vcat), ::Type{T},
funcs::Union{MOI.SingleVariable,
MOI.VectorOfVariables}...) where T
out_dim = sum(func -> output_dim(T, func), funcs)
variables = Vector{MOI.VariableIndex}(undef, out_dim)
fill_vector(variables, T, 0, 0, fill_variables, output_dim, funcs...)
return MOI.VectorOfVariables(variables)
end

number_of_affine_terms(::Type{T}, ::T) where T = 0
number_of_affine_terms(::Type, ::SVF) = 1
number_of_affine_terms(::Type, f::VVF) = length(f.variables)
Expand Down
13 changes: 13 additions & 0 deletions test/Bridges/Constraint/geomean.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
using Test

using MathOptInterface
const MOI = MathOptInterface
const MOIT = MathOptInterface.Test
const MOIU = MathOptInterface.Utilities
const MOIB = MathOptInterface.Bridges

include("../utilities.jl")

mock = MOIU.MockOptimizer(MOIU.Model{Float64}())
config = MOIT.TestConfig()

@testset "GeoMean" begin
mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [ones(4); 2; √2; √2])
bridged_mock = MOIB.Constraint.GeoMean{Float64}(mock)
Expand Down
12 changes: 10 additions & 2 deletions test/Utilities/functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@ z = MOI.VariableIndex(3)
v = MOI.VectorOfVariables([y, w])
wf = MOI.SingleVariable(w)
xf = MOI.SingleVariable(x)
@testset "Variable" begin
# TODO #616
@testset "Variable with $T" for T in [Int, Float64]
@test MOI.VectorOfVariables == MOIU.promote_operation(vcat, T, typeof(wf), typeof(v), typeof(xf))
vov = MOIU.operate(vcat, T, wf, v, xf)
@test vov.variables == [w, y, w, x]
@test MOI.VectorOfVariables == MOIU.promote_operation(vcat, T, typeof(v), typeof(wf), typeof(xf))
vov = MOIU.operate(vcat, T, v, wf, xf)
@test vov.variables == [y, w, w, x]
@test MOI.VectorOfVariables == MOIU.promote_operation(vcat, T, typeof(wf), typeof(xf), typeof(v))
vov = MOIU.operate(vcat, T, wf, xf, v)
@test vov.variables == [w, x, y, w]
end
f = MOI.ScalarAffineFunction(
MOI.ScalarAffineTerm.([2, 4], [x, z]), 5)
Expand Down