Skip to content

Commit 7a12124

Browse files
Properly Handle Parameter Functions as JuMP.Parameters in Measures (#391)
* Create make_point_variable_ref in TranscriptionOpt/measures.jl * Add unit test for make_point_variable_ref for paramFuncs * Add unit tests for measures w/ semi-infinite + point vars * Remove transcribe semi inf + point var statements from unit test * Uncomment unit tests in TranscriptionOpt/transcribe --------- Co-authored-by: Joshua Pulsipher <[email protected]>
1 parent 0c08663 commit 7a12124

File tree

3 files changed

+60
-18
lines changed

3 files changed

+60
-18
lines changed

src/TranscriptionOpt/measures.jl

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,36 @@ function InfiniteOpt.add_semi_infinite_variable(
7474
# make the reference and map it to a transcription variable
7575
rvref = InfiniteOpt.GeneralVariableRef(inf_model, raw_index, InfiniteOpt.SemiInfiniteVariableIndex)
7676
push!(semi_infinite_vars, var)
77-
if ivref.index_type != InfiniteOpt.ParameterFunctionIndex
78-
ivref_param_nums = InfiniteOpt._parameter_numbers(ivref)
79-
param_nums = var.parameter_nums
80-
supp_indices = support_index_iterator(backend, var.group_int_idxs)
81-
lookup_dict = Dict{Vector{Float64}, JuMP.VariableRef}()
82-
sizehint!(lookup_dict, length(supp_indices))
83-
for i in supp_indices
84-
raw_supp = index_to_support(backend, i)
85-
if any(!isnan(raw_supp[ivref_param_nums[k]]) && raw_supp[ivref_param_nums[k]] != v for (k, v) in eval_supps)
86-
continue
87-
end
88-
ivref_supp = [haskey(eval_supps, j) ? eval_supps[j] : raw_supp[k]
89-
for (j, k) in enumerate(ivref_param_nums)]
90-
supp = raw_supp[param_nums]
91-
lookup_dict[supp] = lookup_by_support(ivref, backend, ivref_supp)
77+
ivref_param_nums = InfiniteOpt._parameter_numbers(ivref)
78+
param_nums = var.parameter_nums
79+
supp_indices = support_index_iterator(backend, var.group_int_idxs)
80+
lookup_dict = Dict{Vector{Float64}, JuMP.VariableRef}()
81+
sizehint!(lookup_dict, length(supp_indices))
82+
for i in supp_indices
83+
raw_supp = index_to_support(backend, i)
84+
if any(!isnan(raw_supp[ivref_param_nums[k]]) && raw_supp[ivref_param_nums[k]] != v for (k, v) in eval_supps)
85+
continue
9286
end
93-
data.infvar_lookup[rvref] = lookup_dict
87+
ivref_supp = [haskey(eval_supps, j) ? eval_supps[j] : raw_supp[k]
88+
for (j, k) in enumerate(ivref_param_nums)]
89+
supp = raw_supp[param_nums]
90+
lookup_dict[supp] = lookup_by_support(ivref, backend, ivref_supp)
9491
end
92+
data.infvar_lookup[rvref] = lookup_dict
9593
data.semi_lookup[(ivref, eval_supps)] = rvref
9694
return rvref
9795
end
9896
end
97+
98+
function InfiniteOpt.make_point_variable_ref(
99+
write_model::TranscriptionBackend,
100+
ivref,
101+
support,
102+
::Union{Type{InfiniteOpt.ParameterFunctionIndex}}
103+
)
104+
prefs = parameter_list(ivref)
105+
for i in eachindex(support)
106+
support[i] = round(support[i], sigdigits = significant_digits(prefs[i]))
107+
end
108+
return add_point_variable(write_model, ivref, support)
109+
end

test/TranscriptionOpt/measure.jl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
m = InfiniteModel()
55
@infinite_parameter(m, par in [0, 1], supports = [0, 1])
66
@infinite_parameter(m, pars[1:2] in [0, 1], supports = [0, 1])
7+
@parameter_function(m, pf == par -> sin(par))
78
@variable(m, x, Infinite(par))
89
@variable(m, y, Infinite(par, pars))
910
@variable(m, x0, Point(x, 0))
@@ -13,7 +14,12 @@
1314
@variable(tb.model, b)
1415
@variable(tb.model, c)
1516
@variable(tb.model, d)
17+
@variable(tb.model, e in Parameter(sin(0)))
18+
@variable(tb.model, f in Parameter(sin(1)))
1619
data = IOTO.transcription_data(tb)
20+
data.infvar_mappings[pf] = [e, f]
21+
data.infvar_supports[pf] = [(0.,), (1.,)]
22+
data.infvar_lookup[pf] = Dict([0] => e, [1] => f)
1723
data.infvar_mappings[x] = [a, b]
1824
data.infvar_supports[x] = [(0.,), (1.,)]
1925
data.infvar_lookup[x] = Dict([0] => a, [1] => b)
@@ -25,13 +31,25 @@
2531
data.infvar_lookup[y0] = Dict([0, 0, 0] => a, [0, 1, 1] => b)
2632
data.finvar_mappings[x0] = a
2733
IOTO.set_parameter_supports(tb, m)
34+
# test make_point_variable_ref
35+
@testset "make_point_variable_ref" begin
36+
# adding a point var from an evaluated paramFunc
37+
pfref = GeneralVariableRef(m, -1, PointVariableIndex)
38+
testRef = InfiniteOpt.make_point_variable_ref(tb, pf, Float64[1])
39+
@test isequal(pfref, testRef)
40+
@test IOTO.transcription_variable(pfref) == f
41+
# add a point var that was already added internally
42+
@test isequal(InfiniteOpt.add_point_variable(tb, pf, Float64[1]), pfref)
43+
@test IOTO.transcription_variable(pfref) == f
44+
45+
end
2846
# test add_point_variable
2947
@testset "add_point_variable" begin
3048
# add one that was already added to the infinite model
3149
@test isequal(InfiniteOpt.add_point_variable(tb, x, Float64[0]), x0)
3250
@test IOTO.transcription_variable(x0) == a
3351
# add one that hasn't been added
34-
vref = GeneralVariableRef(m, -1, PointVariableIndex)
52+
vref = GeneralVariableRef(m, -2, PointVariableIndex)
3553
@test isequal(InfiniteOpt.add_point_variable(tb, x, Float64[1]), vref)
3654
@test IOTO.transcription_variable(vref) == b
3755
# add one that has been added internally

test/TranscriptionOpt/transcribe.jl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,11 @@ end
182182
@testset "Measure/Objective Transcription" begin
183183
# Prepare the model
184184
m = InfiniteModel()
185-
@infinite_parameter(m, pars[1:2] in [0, 1], supports = [0, 1])
186185
@infinite_parameter(m, par in [0, 1], supports = [0, 1])
186+
@infinite_parameter(m, par2 in [3, 4], supports = [3, 4])
187+
@infinite_parameter(m, pars[1:2] in [0, 1], supports = [0, 1])
188+
@parameter_function(m, pf1 == par -> sin(par))
189+
@parameter_function(m, pf2 == (par, par2) -> sin(par)*cos(par2))
187190
@variable(m, x >= 0, Infinite(par))
188191
@variable(m, y == 2, Infinite(par, pars), start = (p, ps) -> p + sum(ps))
189192
@variable(m, 0 <= z <= 1, Bin)
@@ -192,10 +195,13 @@ end
192195
meas2 = integral(w, par)
193196
meas3 = integral(y^2, pars)
194197
meas4 = integral(pars[1], pars[1])
198+
meas5 = integral(pf1, par)
199+
meas6 = integral(pf2, par2)
195200
tb = m.backend
196201
IOTO.set_parameter_supports(tb, m)
197202
IOTO.transcribe_finite_variables!(tb, m)
198203
IOTO.transcribe_infinite_variables!(tb, m)
204+
IOTO.transcribe_parameter_functions!(tb, m)
199205
tx = IOTO.transcription_variable(x)
200206
ty = IOTO.transcription_variable(y)
201207
tz = IOTO.transcription_variable(z)
@@ -207,9 +213,16 @@ end
207213
@test IOTO.transcription_variable(meas2) == tw + 0
208214
@test IOTO.transcription_variable(meas3) isa Vector
209215
@test IOTO.transcription_variable(meas4) isa AffExpr
216+
meas5Eval = 0.5*sum(IOTO.transcription_variable.(pf1))
217+
@test IOTO.transcription_variable(meas5) == meas5Eval
218+
tpf2 = IOTO.transcription_variable.(pf2)
219+
meas6Eval = 0.5.*[tpf2[1] + tpf2[3], tpf2[2] + tpf2[4]]
220+
@test IOTO.transcription_variable(meas6) == meas6Eval
210221
@test supports(meas1) == ()
211222
@test supports(meas2) == ()
212223
@test supports(meas3) == [(0.,), (1., )]
224+
@test supports(meas5) == ()
225+
@test supports(meas6) == [(0.0,), (1.0,)]
213226
end
214227
# test transcribe_objective!
215228
@testset "transcribe_objective!" begin

0 commit comments

Comments
 (0)