Skip to content

Commit fdf2559

Browse files
authored
[FileFormats.MOF] add support for Scaled set (#2263)
1 parent bff293a commit fdf2559

File tree

7 files changed

+53
-14
lines changed

7 files changed

+53
-14
lines changed

docs/src/submodules/FileFormats/overview.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ julia> print(read("file.mof.json", String))
9494
"name": "MathOptFormat Model",
9595
"version": {
9696
"major": 1,
97-
"minor": 4
97+
"minor": 5
9898
},
9999
"variables": [
100100
{
@@ -230,7 +230,7 @@ julia> good_model = JSON.parse("""
230230
{
231231
"version": {
232232
"major": 1,
233-
"minor": 4
233+
"minor": 5
234234
},
235235
"variables": [{"name": "x"}],
236236
"objective": {"sense": "feasibility"},
@@ -249,7 +249,7 @@ julia> bad_model = JSON.parse("""
249249
{
250250
"version": {
251251
"major": 1,
252-
"minor": 4
252+
"minor": 5
253253
},
254254
"variables": [{"NaMe": "x"}],
255255
"objective": {"sense": "feasibility"},

src/FileFormats/MOF/MOF.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import OrderedCollections
1111
import JSON
1212
import MathOptInterface as MOI
1313

14-
const SCHEMA_PATH = joinpath(@__DIR__, "mof.1.4.schema.json")
15-
const VERSION = v"1.4"
14+
const SCHEMA_PATH = joinpath(@__DIR__, "mof.1.5.schema.json")
15+
const VERSION = v"1.5"
1616
const SUPPORTED_VERSIONS =
17-
(v"1.4", v"1.3", v"1.2", v"1.1", v"1.0", v"0.6", v"0.5", v"0.4")
17+
(v"1.5", v"1.4", v"1.3", v"1.2", v"1.1", v"1.0", v"0.6", v"0.5", v"0.4")
1818

1919
const OrderedObject = OrderedCollections.OrderedDict{String,Any}
2020
const UnorderedObject = Dict{String,Any}
@@ -92,6 +92,7 @@ MOI.Utilities.@model(
9292

9393
# Indicator is handled by UniversalFallback.
9494
# Reified is handled by UniversalFallback.
95+
# Scaled is handled bby UniversalFallback.
9596

9697
const Model = MOI.Utilities.UniversalFallback{InnerModel{Float64}}
9798

src/FileFormats/MOF/mof.1.4.schema.json renamed to src/FileFormats/MOF/mof.1.5.schema.json

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://json-schema.org/schema#",
3-
"$id": "https://jump.dev/MathOptFormat/schemas/mof.1.4.schema.json",
3+
"$id": "https://jump.dev/MathOptFormat/schemas/mof.1.5.schema.json",
44
"title": "The schema for MathOptFormat",
55
"type": "object",
66
"required": ["version", "variables", "objective", "constraints"],
@@ -11,7 +11,7 @@
1111
"required": ["minor", "major"],
1212
"properties": {
1313
"minor": {
14-
"enum": [0, 1, 2, 3, 4]
14+
"enum": [0, 1, 2, 3, 4, 5]
1515
},
1616
"major": {
1717
"const": 1
@@ -765,8 +765,7 @@
765765
}
766766
}
767767
}, {
768-
"description": "The (vectorized) cone of symmetric positive semidefinite matrices, with `side_dimension` rows and columns, such that the off-diagonal entries are scaled by √2. The entries of the upper-right triangular part of the matrix are given column by column (or equivalently, the entries of the lower-left triangular part are given row by row).",
769-
"examples": ["{\"type\": \"ScaledPositiveSemidefiniteConeTriangle\", \"side_dimension\": 2}"],
768+
"description": "DEPRECATED: use the Scaled set combinned with PositiveSemidefiniteConeTriangle instead.",
770769
"required": ["side_dimension"],
771770
"properties": {
772771
"type": {
@@ -1151,6 +1150,18 @@
11511150
"type": "number"
11521151
}
11531152
}
1153+
}, {
1154+
"description": "The set in the `set` field, scaled such that the inner product of two elements in the set is the same as the dot product of the two vector functions. This is most useful for solvers which require PSD matrices in _scaled_ form.",
1155+
"examples": ["{\"type\": \"Scaled\", \"set\": {\"type\": \"PositiveSemidefiniteConeTriangle\", \"side_dimension\": 2}}"],
1156+
"required": ["set"],
1157+
"properties": {
1158+
"type": {
1159+
"const": "Scaled"
1160+
},
1161+
"set": {
1162+
"$ref": "#/definitions/vector_sets"
1163+
}
1164+
}
11541165
}]
11551166
}
11561167
}

src/FileFormats/MOF/read.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ end
383383
LogDetConeSquare,
384384
PositiveSemidefiniteConeTriangle,
385385
ScaledPositiveSemidefiniteConeTriangle, # Required for v1.4
386+
Scaled, # Required for v1.5
386387
PositiveSemidefiniteConeSquare,
387388
HermitianPositiveSemidefiniteConeTriangle,
388389
ExponentialCone,
@@ -543,6 +544,10 @@ function set_to_moi(
543544
return MOI.Scaled(MOI.PositiveSemidefiniteConeTriangle(d))
544545
end
545546

547+
function set_to_moi(::Val{:Scaled}, object::Object)
548+
return MOI.Scaled(set_to_moi(object["set"]))
549+
end
550+
546551
function set_to_moi(::Val{:PositiveSemidefiniteConeSquare}, object::Object)
547552
return MOI.PositiveSemidefiniteConeSquare(object["side_dimension"])
548553
end

src/FileFormats/MOF/write.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,11 @@ function moi_to_object(
358358
end
359359

360360
function moi_to_object(
361-
set::MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle},
361+
set::MOI.Scaled,
362362
name_map::Dict{MOI.VariableIndex,String},
363363
)
364364
return OrderedObject(
365-
"type" => "ScaledPositiveSemidefiniteConeTriangle",
366-
"side_dimension" => set.set.side_dimension,
365+
"type" => "Scaled",
366+
"set" => moi_to_object(set.set, name_map),
367367
)
368368
end

test/FileFormats/MOF/MOF.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,18 @@ c1: [x1, x2, x3] in ScaledPositiveSemidefiniteConeTriangle(2)
782782
)
783783
end
784784

785+
function test_Scaled_PositiveSemidefiniteConeTriangle()
786+
return _test_model_equality(
787+
"""
788+
variables: x1, x2, x3
789+
minobjective: x1
790+
c1: [x1, x2, x3] in Scaled(PositiveSemidefiniteConeTriangle(2))
791+
""",
792+
["x1", "x2", "x3"],
793+
["c1"],
794+
)
795+
end
796+
785797
function test_PositiveSemidefiniteConeSquare()
786798
return _test_model_equality(
787799
"""
@@ -1364,6 +1376,16 @@ function test_integer_coefficients()
13641376
return
13651377
end
13661378

1379+
function test_ScaledPositiveSemidefiniteConeTriangle()
1380+
object = Dict(
1381+
"type" => "ScaledPositiveSemidefiniteConeTriangle",
1382+
"side_dimension" => 2,
1383+
)
1384+
@test MOF.set_to_moi(object) ==
1385+
MOI.Scaled(MOI.PositiveSemidefiniteConeTriangle(2))
1386+
return
1387+
end
1388+
13671389
end
13681390

13691391
TestMOF.runtests()

test/FileFormats/MOF/nlp.mof.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "MathOptFormat Model",
33
"version": {
44
"major": 1,
5-
"minor": 4
5+
"minor": 5
66
},
77
"variables": [
88
{

0 commit comments

Comments
 (0)