Skip to content

Commit b26c003

Browse files
authored
Merge pull request #29 from JuliaStochOpt/jg/no_duals
add no duals option
2 parents afc3d64 + 0088128 commit b26c003

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

src/ParameterJuMP.jl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ mutable struct ParameterData
5555
solved::Bool
5656

5757
lazy::Bool
58+
59+
no_duals::Bool
5860
dual_values::Vector{Float64}
5961
function ParameterData()
6062
new(Int64[],
@@ -68,11 +70,26 @@ mutable struct ParameterData
6870
Dict{CtrRef{SAF, GE}, JuMP.GenericAffExpr{Float64,Parameter}}(),
6971
false,
7072
false,
73+
false,
7174
Float64[],
7275
)
7376
end
7477
end
7578

79+
no_duals(data::ParameterData) = data.no_duals
80+
no_duals(model::JuMP.Model) = no_duals(_getparamdata(model))
81+
82+
set_no_duals(model::JuMP.Model) = set_no_duals(_getparamdata(model))
83+
function set_no_duals(data::ParameterData)
84+
if isempty(data.current_values)
85+
data.no_duals = true
86+
elseif no_duals(data)
87+
@warn "No duals mode is already activated"
88+
else
89+
error("Parameter JuMP's no duals mode can only be activated in empty models.")
90+
end
91+
end
92+
7693
lazy_duals(data::ParameterData) = data.lazy
7794
lazy_duals(model::JuMP.Model) = lazy_duals(_getparamdata(model))
7895

@@ -215,6 +232,9 @@ function setvalue!(p::Parameter, val::Real)
215232
end
216233
function JuMP.dual(p::Parameter)
217234
params = _getparamdata(p)::ParameterData
235+
if no_duals(params)
236+
error("No dual query mode is activated for this model. If you plan to query duals you cannot call `set_no_duals`")
237+
end
218238
if lazy_duals(params)
219239
return _getdual(p)
220240
else
@@ -367,7 +387,7 @@ function _param_optimizehook(m::JuMP.Model; kwargs...)
367387
ret = JuMP.optimize!(m::JuMP.Model, ignore_optimize_hook = true, kwargs...)
368388
data.solved = true
369389

370-
if !lazy_duals(data) && JuMP.has_duals(m)
390+
if !lazy_duals(data) && JuMP.has_duals(m) && !no_duals(data)
371391
fill!(data.dual_values, 0.0)
372392
_update_duals(data, EQ)
373393
_update_duals(data, GE)

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ include("tests.jl")
2424
test10(factory)
2525
test11(factory)
2626
test12(factory)
27+
test13(factory)
2728
end
2829
;

test/tests.jl

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,12 @@ function test8(args...)
167167
end
168168

169169
function test9(args...)
170-
@testset "Test ErrorException(s)" begin
170+
@testset "Test bad model error" begin
171171
model_1 = Model(args...)
172172
@test_throws ErrorException x = Parameters(model_1, ones(5))
173173
@test_throws ErrorException y = Parameter(model_1, 1.0)
174-
174+
end
175+
@testset "Test lazy duals errors" begin
175176
model_2 = ModelWithParams(args...)
176177
ParameterJuMP.set_lazy_duals(model_2)
177178
ParameterJuMP.set_lazy_duals(model_2) # warn
@@ -322,4 +323,24 @@ function test12(args...)
322323
@test JuMP.dual(cref) == 1.0
323324
@test JuMP.dual(α) == 0.0
324325
end
326+
end
327+
328+
function test13(args...)
329+
@testset "Test no duals errors" begin
330+
model = ModelWithParams(args...)
331+
ParameterJuMP.set_no_duals(model)
332+
α = Parameter(model, 1.0)
333+
ParameterJuMP.setvalue!(α, -1.0)
334+
@variable(model, x)
335+
cref = @constraint(model, x == α)
336+
@objective(model, Max, x)
337+
JuMP.optimize!(model)
338+
@test JuMP.value(x) == -1.0
339+
@test JuMP.dual(cref) == -1.0
340+
@test_throws ErrorException JuMP.dual(α)
341+
342+
model_2 = ModelWithParams(args...)
343+
y = Parameter(model_2, 1.0)
344+
@test_throws ErrorException ParameterJuMP.set_no_duals(model_2)
345+
end
325346
end

0 commit comments

Comments
 (0)