Skip to content

Commit

Permalink
Fix model parser + Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pedromxavier committed Sep 22, 2023
1 parent e4a309d commit b74c607
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 8 deletions.
4 changes: 2 additions & 2 deletions ext/QUBOTools_MOI/error.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ function qubo_parsing_error(msg::AbstractString; ads::Bool = true)
end

function Base.showerror(io::IO, e::QUBOParsingError)
show(io, e.msg)
print(io, e.msg)

if e.ads
show(
println(
io,
"""
It seems that the current model could not be converted to QUBO in a straightforward fashion 🙁
Expand Down
4 changes: 2 additions & 2 deletions ext/QUBOTools_MOI/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ function _extract_bool_model(
β += f.constant
end

return Model{VI,T,Int}(
return QUBOTools.Model{VI,T,Int}(
L, Q;
offset = β,
sense = QUBOTools.sense(MOI.get(model, MOI.ObjectiveSense())),
Expand Down Expand Up @@ -210,7 +210,7 @@ function _extract_spin_model(
β += f.constant
end

return Model{VI,T,Int}(
return QUBOTools.Model{VI,T,Int}(
L, Q;
offset = β,
sense = QUBOTools.sense(MOI.get(model, MOI.ObjectiveSense())),
Expand Down
133 changes: 131 additions & 2 deletions test/integration/ext/moi.jl
Original file line number Diff line number Diff line change
@@ -1,17 +1,146 @@
function test_moi()
@testset "□ MathOptInterface" begin
@testset "□ MathOptInterface" verbose = true begin
test_moi_variables()
test_moi_models()
end

return nothing
end

function test_moi_variables()
@testset "⊛ Variables" begin
# Check if the Spin variable set is defined
@test QUBOTools.__moi_spin_set() <: MOI.AbstractScalarSet
@test QUBOTools.__moi_spin_set() <: MOI.AbstractScalarSet

# Check if the variable ordering of variables is behaving accordingly
@test QUBOTools.varlt(VI(1), VI(1)) === false
@test QUBOTools.varlt(VI(1), VI(2)) === true
@test QUBOTools.varlt(VI(2), VI(1)) === false

# This specific ordering follows as 1, 2, 3, ..., -1, -2, -3, ...
# TODO: This is not yet implemented in the latest PBO
@test_broken QUBOTools.varlt(VI(1), VI(-1)) === true
@test_broken QUBOTools.varlt(VI(-1), VI(1)) === false
end

return nothing
end

function test_moi_models()
@testset "⊛ Model" verbose = true begin
test_moi_bool_model()
# test_moi_spin_model()
end

return nothing
end

function test_moi_bool_model()
@testset "→ Bool" begin
# TODO: Add MOIU.@model test asset that supports Spin variables
moi_model = MOIU.Model{Float64}()

v = MOI.add_variables(moi_model, 3)

MOI.set(
moi_model,
MOI.ObjectiveFunction{SQF{Float64}}(),
SQF{Float64}(
SQT{Float64}[
SQT{Float64}(12.0, v[1], v[2]),
SQT{Float64}(13.0, v[1], v[3]),
SQT{Float64}(23.0, v[2], v[3]),
SQT{Float64}(-2.0, v[1], v[1]),
SQT{Float64}(-4.0, v[2], v[2]),
SQT{Float64}(-6.0, v[3], v[3]),
],
SAT{Float64}[
SAT{Float64}(2.0, v[1]),
SAT{Float64}(4.0, v[2]),
SAT{Float64}(6.0, v[3]),
],
9.9,
),
)

MOI.set(moi_model, MOI.ObjectiveSense(), MOI.MAX_SENSE)

@test_throws Exception QUBOTools.Model{Float64}(moi_model)

MOI.add_constraint.(moi_model, v, MOI.ZeroOne())

qt_model = QUBOTools.Model{Float64}(moi_model)

n, L, Q, α, β, s, X = QUBOTools.qubo(qt_model, :dense)

@test n == 3
@test s == QUBOTools.sense(:max)
@test X == QUBOTools.domain(:bool)
@test L == [1.0, 2.0, 3.0]
@test Q == [0.0 12.0 13.0; 0.0 0.0 23.0; 0.0 0.0 0.0]
@test α == 1.0
@test β == 9.9

# MOI.add_constrained_variable(moi_model, Spin())

# @test_throws Exception QUBOTools.Model{Float64}(moi_model)
end

return nothing
end

function test_moi_spin_model()
@testset "→ Spin" begin
# TODO: Add MOIU.@model test asset that supports Spin variables
moi_model = MOIU.Model{Float64}()

v = MOI.add_variables(moi_model, 3)

MOI.set(
moi_model,
MOI.ObjectiveFunction{SQF{Float64}}(),
SQF{Float64}(
SQT{Float64}[
SQT{Float64}(12.0, v[1], v[2]),
SQT{Float64}(13.0, v[1], v[3]),
SQT{Float64}(23.0, v[2], v[3]),
SQT{Float64}(-2.0, v[1], v[1]),
SQT{Float64}(-4.0, v[2], v[2]),
SQT{Float64}(-6.0, v[3], v[3]),
],
SAT{Float64}[
SAT{Float64}(2.0, v[1]),
SAT{Float64}(4.0, v[2]),
SAT{Float64}(6.0, v[3]),
],
9.9,
),
)

MOI.set(moi_model, MOI.ObjectiveSense(), MOI.MIN_SENSE)

@test_throws Exception QUBOTools.Model{Float64}(moi_model)

MOI.add_constraint.(moi_model, v, Spin())

qt_model = QUBOTools.Model{Float64}(moi_model)

n, h, J, α, β, s, X = QUBOTools.qubo(qt_model, :dense)

@test n == 3
@test s == QUBOTools.sense(:min)
@test X == QUBOTools.domain(:spin)
@test h == [2.0, 4.0, 6.0]
@test J == [0.0 12.0 13.0; 0.0 0.0 23.0; 0.0 0.0 0.0]
@test α == 1.0
@test β == -3.9

MOI.add_constrained_variable(moi_model, MOI.ZeroOne())

@test_throws Exception QUBOTools.Model{Float64}(moi_model)
end

return nothing
end

end
15 changes: 13 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,19 @@ using RecipesBase
using QUBOTools
using MathOptInterface

const MOI = MathOptInterface
const VI = MOI.VariableIndex
# using QUBODrivers
# using ToQUBO
# using QUBO

const MOI = MathOptInterface
const MOIU = MOI.Utilities
const VI = MOI.VariableIndex
const SAF{T} = MOI.ScalarAffineFunction{T}
const SAT{T} = MOI.ScalarAffineTerm{T}
const SQF{T} = MOI.ScalarQuadraticFunction{T}
const SQT{T} = MOI.ScalarQuadraticTerm{T}

const Spin = QUBOTools.__moi_spin_set()

const __TEST_PATH__ = @__DIR__

Expand Down

0 comments on commit b74c607

Please sign in to comment.