Skip to content

Commit b5d7233

Browse files
authored
Map finite parameters to JuMP.Parameters (#387)
* Map finite parameters to JuMP.Parameters + update tests accordingly * Simplify code in transcribe_finite_parameters!() * Update TranscriptionOpt documentation about finite parameter mapping * Add transcribe_finite_parameters! to technical API manual docs * Fix typo in transcribe_finite_parameters docstring
1 parent e4377b7 commit b5d7233

File tree

6 files changed

+49
-16
lines changed

6 files changed

+49
-16
lines changed

docs/src/guide/transcribe.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,13 @@ julia> supports(y^2 + z - 42)
469469
julia> parameter_refs(y^2 + z - 42)
470470
(t,)
471471
```
472+
For finite parameters, we can also retrieve their corresponding `JuMP` parameter with `transformation_variable`.
473+
```jldoctest transcribe
474+
julia> param = @finite_parameter(inf_model, p == 42)
475+
p
476+
477+
julia> build_transformation_backend!(inf_model)
478+
479+
julia> transformation_variable(p)
480+
p
481+
```

docs/src/manual/transcribe.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ InfiniteOpt.TranscriptionOpt.TranscriptionBackend
88
InfiniteOpt.TranscriptionOpt.TranscriptionData
99
InfiniteOpt.TranscriptionOpt.Transcription
1010
InfiniteOpt.TranscriptionOpt.set_parameter_supports
11+
InfiniteOpt.TranscriptionOpt.transcribe_finite_parameters!
1112
InfiniteOpt.TranscriptionOpt.transcribe_finite_variables!
1213
InfiniteOpt.TranscriptionOpt.transcribe_infinite_variables!
1314
InfiniteOpt.TranscriptionOpt.transcribe_derivative_variables!

src/TranscriptionOpt/model.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,13 @@ const FinVarIndex = Union{
337337
}
338338

339339
## Define the variable mapping functions
340-
# FinVarIndex
340+
# FinVarIndex & FiniteParameterIndex
341341
function transcription_variable(
342342
vref::InfiniteOpt.GeneralVariableRef,
343343
::Type{V},
344344
backend::TranscriptionBackend,
345345
label::Type{<:InfiniteOpt.AbstractSupportLabel}
346-
) where {V <: FinVarIndex}
346+
) where {V <: Union{FinVarIndex, InfiniteOpt.FiniteParameterIndex}}
347347
var = get(transcription_data(backend).finvar_mappings, vref, nothing)
348348
if isnothing(var)
349349
error("Variable reference $vref not used in transcription backend.")
@@ -551,7 +551,7 @@ function lookup_by_support(
551551
::Type{V},
552552
backend::TranscriptionBackend,
553553
support::Vector
554-
) where {V <: FinVarIndex}
554+
) where {V <: Union{FinVarIndex, InfiniteOpt.FiniteParameterIndex}}
555555
if !haskey(transcription_data(backend).finvar_mappings, vref)
556556
error("Variable reference $vref not used in transcription backend.")
557557
end

src/TranscriptionOpt/transcribe.jl

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,34 @@ end
5454
################################################################################
5555
# VARIABLE INITIALIZATION METHODS
5656
################################################################################
57+
"""
58+
transcribe_finite_parameters!(
59+
backend::TranscriptionBackend,
60+
model::InfiniteOpt.InfiniteModel
61+
)::Nothing
62+
63+
Create a transcription variable (i.e., a JuMP Parameter) for each `FiniteParameter`
64+
stored in `model` and add it to `backend`. The variable mapping is
65+
also stored in `TranscriptionData.finvar_mappings` which enables
66+
[`transcription_variable`](@ref) and [`lookup_by_support`](@ref).
67+
"""
68+
function transcribe_finite_parameters!(
69+
backend::TranscriptionBackend,
70+
model::InfiniteOpt.InfiniteModel
71+
)
72+
for (idx, object) in InfiniteOpt._data_dictionary(model, InfiniteOpt.FiniteParameter)
73+
fpref = InfiniteOpt.GeneralVariableRef(model, idx)
74+
75+
# Prepare arguments for building JuMP parameter
76+
name = object.name
77+
pValue = object.parameter.value
78+
79+
# Build the JuMP variable and add it to the backend
80+
pref = JuMP.@variable(backend.model, base_name = name, set = MOI.Parameter(pValue))
81+
transcription_data(backend).finvar_mappings[fpref] = pref
82+
end
83+
return
84+
end
5785
"""
5886
transcribe_finite_variables!(
5987
backend::TranscriptionBackend,
@@ -459,13 +487,13 @@ function transcription_expression(
459487
end
460488
end
461489

462-
# Point variables and finite variables
490+
# Point variables, finite variables and finite parameters
463491
function transcription_expression(
464492
vref::InfiniteOpt.GeneralVariableRef,
465493
index_type::Type{V},
466494
backend::TranscriptionBackend,
467495
support::Vector{Float64}
468-
) where {V <: FinVarIndex}
496+
) where {V <: Union{FinVarIndex, InfiniteOpt.FiniteParameterIndex}}
469497
return lookup_by_support(vref, index_type, backend, support)
470498
end
471499

@@ -480,15 +508,6 @@ function transcription_expression(
480508
return support[param_num]
481509
end
482510

483-
# Finite parameters
484-
function transcription_expression(
485-
vref::InfiniteOpt.GeneralVariableRef,
486-
index_type::Type{InfiniteOpt.FiniteParameterIndex},
487-
backend::TranscriptionBackend,
488-
support::Vector{Float64}
489-
)
490-
return InfiniteOpt.parameter_value(vref)
491-
end
492511

493512
# AffExpr and QuadExpr and NonlinearExpr
494513
function transcription_expression(
@@ -957,6 +976,7 @@ function build_transcription_backend!(
957976
# add nonlinear operators as needed
958977
InfiniteOpt.add_operators_to_jump(backend.model, model)
959978
# define the variables
979+
transcribe_finite_parameters!(backend, model)
960980
transcribe_finite_variables!(backend, model)
961981
transcribe_infinite_variables!(backend, model)
962982
transcribe_derivative_variables!(backend, model)

test/TranscriptionOpt/model.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,12 @@ end
404404
@variable(tb.model, b)
405405
@variable(tb.model, c)
406406
@variable(tb.model, d)
407+
@variable(tb.model, e in Parameter(42))
407408
# transcribe the variables and measures
408409
data = IOTO.transcription_data(tb)
409410
data.finvar_mappings[y] = a
410411
data.finvar_mappings[x0] = a
412+
data.finvar_mappings[finpar] = e
411413
data.infvar_mappings[x] = reshape([a, b], :, 1)
412414
data.measure_mappings[meas1] = fill(-2 * zero(AffExpr))
413415
data.measure_mappings[meas2] = [a^2 + c^2 - 2a, b^2 + d^2 - 2a]
@@ -450,7 +452,7 @@ end
450452
end
451453
# test transcription expression for finite parameters with 3 args
452454
@testset "IOTO.transcription_expression (Finite Parameter)" begin
453-
@test IOTO.transcription_expression(finpar, tb, [0.5, 1., 0.]) == 42
455+
@test IOTO.transcription_expression(finpar, tb, [0.5, 1., 0.]) == e
454456
end
455457
# test transcription expression for AffExprs with 3 args
456458
@testset "IOTO.transcription_expression (AffExpr)" begin

test/TranscriptionOpt/transcribe.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ end
535535
dt_c1 = IOTO.lookup_by_support(d1, tb, zeros(3))
536536
@test constraint_object(IOTO.transcription_constraint(c1)).func == -zt + xt[1] + dt_c1
537537
@test constraint_object(IOTO.transcription_constraint(c2)).func == zt + xt[1]
538-
expected = IOTO.transcription_variable(meas2)[2] - 2 * IOTO.transcription_variable(y0) + xt[2]
538+
expected = IOTO.transcription_variable(meas2)[2] - 2 * IOTO.transcription_variable(y0) + xt[2] + IOTO.transcription_variable(fin)
539539
@test constraint_object(IOTO.transcription_constraint(c4)).func == expected
540540
@test constraint_object(IOTO.transcription_constraint(c3)).func == xt[1] - 2wt + xt[2] + zt - d2t[1] - d2t[2]
541541
@test constraint_object(IOTO.transcription_constraint(c6)).func == [zt, wt]

0 commit comments

Comments
 (0)