Skip to content

Commit 9c83751

Browse files
authored
Merge branch 'main' into jg/moi
2 parents 9241ee1 + eb32401 commit 9c83751

File tree

8 files changed

+67
-19
lines changed

8 files changed

+67
-19
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ Manifest.toml
2525

2626
# other ignores
2727
.vscode/settings.json
28+
*.txt

docs/src/index.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,17 @@ data = ModelAnalyzer.analyze(
8484
model,
8585
optimizer = HiGHS.Optimizer,
8686
)
87-
# print report
87+
88+
# print report to the screen
8889
ModelAnalyzer.summarize(data)
90+
91+
# or print ehte report to a file
92+
93+
# open a file
94+
open("my_report.txt", "w") do io
95+
# print report
96+
ModelAnalyzer.summarize(io, data)
97+
end
8998
```
9099

91100
The `ModelAnalyzer.analyze(...)` function can always take the keyword arguments:
@@ -117,6 +126,6 @@ issues = ModelAnalyzer.list_of_issues(data, list[1])
117126
# the list of issues of the given type can be summarized with:
118127
ModelAnalyzer.summarize(data, issues)
119128

120-
# infdividual issues can also be summarized
129+
# individual issues can also be summarized
121130
ModelAnalyzer.summarize(data, issues[1])
122131
```

src/ModelAnalyzer.jl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ See [`summarize`](@ref), [`list_of_issues`](@ref), and
2727
function analyze end
2828

2929
"""
30-
summarize([io::IO,] AbstractData; model = nothing, verbose = true, max_issues = typemax(Int), kwargs...)
30+
summarize([io::IO,] AbstractData; model = nothing, verbose = true, max_issues = 10, kwargs...)
3131
3232
Print a summary of the analysis results contained in `AbstractData` to the
3333
specified IO stream. If no IO stream is provided, it defaults to `stdout`.
@@ -89,17 +89,27 @@ function summarize(
8989
end
9090
end
9191

92+
const DEFAULT_MAX_ISSUES = 10
93+
9294
function summarize(
9395
io::IO,
9496
issues::Vector{T};
9597
model = nothing,
9698
verbose = true,
97-
max_issues = typemax(Int),
99+
max_issues = DEFAULT_MAX_ISSUES,
98100
) where {T<:AbstractIssue}
99101
summarize(io, T, verbose = verbose)
100102
print(io, "\n## Number of issues\n\n")
101103
print(io, "Found ", length(issues), " issues")
102104
print(io, "\n\n## List of issues\n\n")
105+
if length(issues) > max_issues
106+
print(
107+
io,
108+
"Showing first ",
109+
max_issues,
110+
" issues ($(length(issues) - max_issues) issues ommitted)\n\n",
111+
)
112+
end
103113
for issue in first(issues, max_issues)
104114
print(io, " * ")
105115
summarize(io, issue, verbose = verbose, model = model)

src/feasibility.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ function ModelAnalyzer.summarize(
685685
io::IO,
686686
data::Data;
687687
verbose = true,
688-
max_issues = typemax(Int),
688+
max_issues = ModelAnalyzer.DEFAULT_MAX_ISSUES,
689689
configurations = true,
690690
)
691691
print(io, "## Feasibility Analysis\n\n")

src/infeasibility.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -154,20 +154,18 @@ function ModelAnalyzer.analyze(
154154
for var in JuMP.all_variables(model)
155155
lb = if JuMP.has_lower_bound(var)
156156
JuMP.lower_bound(var)
157+
elseif JuMP.is_fixed(var)
158+
JuMP.fix_value(var)
157159
else
158160
-Inf
159161
end
160162
ub = if JuMP.has_upper_bound(var)
161163
JuMP.upper_bound(var)
164+
elseif JuMP.is_fixed(var)
165+
JuMP.fix_value(var)
162166
else
163167
Inf
164168
end
165-
if lb > ub
166-
push!(out.infeasible_bounds, InfeasibleBounds(var, lb, ub))
167-
bounds_consistent = false
168-
else
169-
variables[var] = Interval(lb, ub)
170-
end
171169
if JuMP.is_integer(var)
172170
if abs(ub - lb) < 1 && ceil(ub) == ceil(lb)
173171
push!(
@@ -186,6 +184,12 @@ function ModelAnalyzer.analyze(
186184
bounds_consistent = false
187185
end
188186
end
187+
if lb > ub
188+
push!(out.infeasible_bounds, InfeasibleBounds(var, lb, ub))
189+
bounds_consistent = false
190+
else
191+
variables[var] = Interval(lb, ub)
192+
end
189193
end
190194
# check PSD diagonal >= 0 ?
191195
# other cones?
@@ -371,10 +375,6 @@ function iis_elastic_filter(original_model::JuMP.GenericModel, optimizer)
371375
end
372376
end
373377

374-
# TODO: add deletion filter
375-
# otherwise this is not an IIS (it does contain an IIS)
376-
377-
# pre_iis = Set(val[1] for val in de_elastisized)
378378
pre_iis = Set(cadidates)
379379
iis = JuMP.ConstraintRef[]
380380
for con in JuMP.all_constraints(
@@ -677,7 +677,7 @@ function ModelAnalyzer.summarize(
677677
io::IO,
678678
data::Data;
679679
verbose = true,
680-
max_issues = typemax(Int),
680+
max_issues = ModelAnalyzer.DEFAULT_MAX_ISSUES,
681681
)
682682
print(io, "## Infeasibility Analysis\n\n")
683683

src/numerical.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2427,7 +2427,7 @@ function ModelAnalyzer.summarize(
24272427
io::IO,
24282428
data::Data;
24292429
verbose = true,
2430-
max_issues = typemax(Int),
2430+
max_issues = ModelAnalyzer.DEFAULT_MAX_ISSUES,
24312431
configurations = true,
24322432
dimensions = true,
24332433
ranges = true,

test/infeasibility.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ function test_range_equalto()
219219
return
220220
end
221221

222-
function test_range_equalto()
222+
function test_range_equalto_2()
223223
model = Model()
224224
@variable(model, x == 1)
225225
@variable(model, y == 2)
@@ -261,7 +261,7 @@ function test_range_greaterthan()
261261
return
262262
end
263263

264-
function test_range_equalto()
264+
function test_range_equalto_3()
265265
model = Model()
266266
@variable(model, 10 <= x <= 11)
267267
@variable(model, 1 <= y <= 11)

test/numerical.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,34 @@ function test_qp_range()
993993
ModelAnalyzer.summarize(buf, data)
994994
ModelAnalyzer.summarize(buf, data, verbose = false)
995995

996+
open("my_report.txt", "w") do io
997+
return ModelAnalyzer.summarize(io, data)
998+
end
999+
1000+
file_data = read("my_report.txt", String)
1001+
@test occursin("## Numerical Analysis", file_data)
1002+
1003+
return
1004+
end
1005+
1006+
function test_more_than_max_issues()
1007+
model = Model()
1008+
@variable(model, xg[1:20] <= 2e9)
1009+
data = ModelAnalyzer.analyze(ModelAnalyzer.Numerical.Analyzer(), model)
1010+
list = ModelAnalyzer.list_of_issue_types(data)
1011+
@test length(list) >= 1
1012+
ret = ModelAnalyzer.list_of_issues(
1013+
data,
1014+
ModelAnalyzer.Numerical.LargeBoundCoefficient,
1015+
)
1016+
@test length(ret) == 20
1017+
1018+
buf = IOBuffer()
1019+
ModelAnalyzer.summarize(buf, data)
1020+
str = String(take!(buf))
1021+
@test occursin("Showing first ", str)
1022+
@test occursin(" issues ommitted)\n\n", str)
1023+
9961024
return
9971025
end
9981026

0 commit comments

Comments
 (0)