Skip to content

Commit ae23660

Browse files
authored
Remove Parameter Numbers (#397)
* remove parameter numbers * doc test fix * doc fix
1 parent a36c73a commit ae23660

32 files changed

+197
-443
lines changed

docs/src/guide/derivative.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
```@meta
22
DocTestFilters = [r"≥|>=", r" == | = ", r" ∈ | in ", r" for all | ∀ ", r"d|∂",
3-
r"integral|∫", r".*scalar_parameters.jl:813"]
3+
r"integral|∫", r".*scalar_parameters.jl:807"]
44
```
55

66
# [Derivative Operators](@id deriv_docs)
@@ -509,7 +509,7 @@ julia> derivative_constraints(d1)
509509
510510
julia> add_supports(t, 0.2)
511511
┌ Warning: Support/method changes will invalidate existing derivative evaluation constraints that have been added to the InfiniteModel. Thus, these are being deleted.
512-
└ @ InfiniteOpt ~/work/infiniteopt/InfiniteOpt.jl/src/scalar_parameters.jl:813
512+
└ @ InfiniteOpt ~/work/infiniteopt/InfiniteOpt.jl/src/scalar_parameters.jl:807
513513
514514
julia> has_derivative_constraints(d1)
515515
false

docs/src/manual/expression.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,4 @@ InfiniteOpt._constraint_dependencies
193193
InfiniteOpt._constraint_dependencies(::GeneralVariableRef)
194194
InfiniteOpt._derivative_constraint_dependencies
195195
InfiniteOpt._derivative_constraint_dependencies(::GeneralVariableRef)
196-
InfiniteOpt._parameter_number
197-
InfiniteOpt._parameter_number(::GeneralVariableRef)
198196
```

src/TranscriptionOpt/measures.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ function InfiniteOpt.add_semi_infinite_variable(
8282
InfiniteOpt.SemiInfiniteVariableIndex
8383
)
8484
push!(semi_infinite_vars, var)
85-
ivref_param_nums = InfiniteOpt._parameter_numbers(ivref)
86-
param_nums = var.parameter_nums
85+
ivref_pref_supp_idxs = data.infvar_param_idxs[ivref]
86+
pref_supp_idxs = [
87+
ivref_pref_supp_idxs[i]
88+
for i in eachindex(ivref_pref_supp_idxs)
89+
if isnan(eval_supp[i])
90+
]
8791
supp_indices = support_index_iterator(backend, var.group_int_idxs)
8892
if ivref.index_type == InfiniteOpt.ParameterFunctionIndex &&
8993
!data.update_parameter_functions
@@ -95,9 +99,9 @@ function InfiniteOpt.add_semi_infinite_variable(
9599
sizehint!(lookup_dict, length(supp_indices))
96100
for i in supp_indices
97101
raw_supp = index_to_support(backend, i)
98-
ivref_supp = [isnan(s) ? raw_supp[ivref_param_nums[j]] : s
102+
ivref_supp = [isnan(s) ? raw_supp[ivref_pref_supp_idxs[j]] : s
99103
for (j, s) in enumerate(eval_supp)]
100-
supp = raw_supp[param_nums]
104+
supp = raw_supp[pref_supp_idxs]
101105
lookup_dict[supp] = lookup_by_support(ivref, backend, ivref_supp)
102106
end
103107
if val_type == JuMP.VariableRef
@@ -106,6 +110,7 @@ function InfiniteOpt.add_semi_infinite_variable(
106110
data.pfunc_lookup[rvref] = lookup_dict
107111
end
108112
data.semi_lookup[(ivref, eval_supp)] = rvref
113+
data.infvar_param_idxs[rvref] = pref_supp_idxs
109114
return rvref
110115
end
111116
end

src/TranscriptionOpt/model.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ mutable struct TranscriptionData
2424

2525
# Metadata
2626
valid_indices::Dict{Any, Array{Bool}}
27+
infvar_param_idxs::Dict{InfiniteOpt.GeneralVariableRef, Vector{Int}}
2728

2829
# Internal variables (created via internal measure expansions)
2930
semi_infinite_vars::Vector{InfiniteOpt.SemiInfiniteVariable{InfiniteOpt.GeneralVariableRef}}
@@ -45,6 +46,7 @@ mutable struct TranscriptionData
4546
# Collected Supports
4647
supports::Tuple
4748
support_labels::Tuple
49+
param_to_support_idx::Dict{InfiniteOpt.GeneralVariableRef, Int}
4850
has_internal_supports::Bool
4951

5052
# Default constructor
@@ -61,6 +63,7 @@ mutable struct TranscriptionData
6163
Dict{InfiniteOpt.GeneralVariableRef, Float64}(),
6264
# meta data
6365
Dict{Any, Array{Bool}}(),
66+
Dict{InfiniteOpt.GeneralVariableRef, Vector{Int}}(),
6467
# internal variables
6568
Vector{InfiniteOpt.SemiInfiniteVariable{InfiniteOpt.GeneralVariableRef}}(),
6669
Dict{Tuple{InfiniteOpt.GeneralVariableRef, Vector{Float64}}, InfiniteOpt.GeneralVariableRef}(),
@@ -76,6 +79,7 @@ mutable struct TranscriptionData
7679
# support storage
7780
(),
7881
(),
82+
Dict{InfiniteOpt.GeneralVariableRef, Int}(),
7983
false,
8084
)
8185
end
@@ -90,6 +94,7 @@ function Base.empty!(data::TranscriptionData)
9094
empty!(data.pfunc_lookup)
9195
empty!(data.point_pfunc_mappings)
9296
empty!(data.valid_indices)
97+
empty!(data.infvar_param_idxs)
9398
empty!(data.semi_infinite_vars)
9499
empty!(data.semi_lookup)
95100
data.last_point_index = 0
@@ -101,6 +106,7 @@ function Base.empty!(data::TranscriptionData)
101106
empty!(data.constr_supports)
102107
data.supports = ()
103108
data.support_labels = ()
109+
empty!(data.param_to_support_idx)
104110
data.has_internal_supports = false
105111
return data
106112
end

src/TranscriptionOpt/transcribe.jl

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ function set_parameter_supports(
4848
end for (i, group) in enumerate(prefs))
4949
data.supports = supps
5050
data.support_labels = labels
51+
# Add the paramter index mapping
52+
vt_prefs = InfiniteOpt.Collections.VectorTuple(prefs)
53+
idx = 1
54+
for p in vt_prefs
55+
data.param_to_support_idx[p] = idx
56+
idx += 1
57+
end
5158
return
5259
end
5360

@@ -110,8 +117,8 @@ end
110117
const _MaxNumParamsForPrinting = 4
111118

112119
# Make variable name with infinite parameters values directly if possible
113-
function _make_var_name(base_name, param_nums, tuple_supp, var_idx)
114-
if length(param_nums) <= _MaxNumParamsForPrinting
120+
function _make_var_name(base_name, pref_supp_idxs, tuple_supp, var_idx)
121+
if length(pref_supp_idxs) <= _MaxNumParamsForPrinting
115122
return string(base_name, "(", join(tuple_supp, ", "), ")")
116123
else
117124
return string(base_name, "[", join(var_idx, ", "), "]")
@@ -141,10 +148,10 @@ function transcribe_parameter_functions!(
141148
# get the basic parameter function information
142149
pf = object.func
143150
base_name = object.name
144-
param_nums = pf.parameter_nums
145151
group_idxs = pf.group_int_idxs
146152
prefs = pf.parameter_refs
147153
data = transcription_data(backend)
154+
pref_supp_idxs = Int[data.param_to_support_idx[p] for p in prefs]
148155
# prepare for iterating over its supports
149156
supp_indices = support_index_iterator(backend, group_idxs)
150157
dims = size(supp_indices)[group_idxs]
@@ -155,12 +162,12 @@ function transcribe_parameter_functions!(
155162
lookup_dict = sizehint!(Dict{Vector{Float64}, val_type}(), length(vrefs))
156163
# Create a parameter for each support
157164
for i in supp_indices
158-
supp = index_to_support(backend, i)[param_nums]
165+
supp = index_to_support(backend, i)[pref_supp_idxs]
159166
var_idx = i.I[group_idxs]
160167
tuple_supp = Tuple(supp, prefs)
161168
p_value = pf(tuple_supp...)
162169
if data.update_parameter_functions
163-
p_name = _make_var_name(base_name, param_nums, tuple_supp, var_idx)
170+
p_name = _make_var_name(base_name, pref_supp_idxs, tuple_supp, var_idx)
164171
jump_pref = JuMP.@variable(
165172
backend.model,
166173
base_name = p_name,
@@ -182,6 +189,7 @@ function transcribe_parameter_functions!(
182189
end
183190
data.infvar_mappings[pfref] = vrefs
184191
data.infvar_supports[pfref] = supps
192+
data.infvar_param_idxs[pfref] = pref_supp_idxs
185193
end
186194
return
187195
end
@@ -217,9 +225,11 @@ end
217225

218226
# Helper function for transcribing infinite variables/derivatives
219227
function _transcribe_infinite_variable(backend, vref, base_name, info)
220-
param_nums = InfiniteOpt._parameter_numbers(vref)
228+
# basic information
221229
group_idxs = InfiniteOpt.parameter_group_int_indices(vref)
222230
prefs = InfiniteOpt.raw_parameter_refs(vref)
231+
data = transcription_data(backend)
232+
pref_supp_idxs = Int[data.param_to_support_idx[p] for p in prefs]
223233
# prepare for iterating over its supports
224234
supp_indices = support_index_iterator(backend, group_idxs)
225235
dims = size(supp_indices)[group_idxs]
@@ -229,23 +239,23 @@ function _transcribe_infinite_variable(backend, vref, base_name, info)
229239
lookup_dict = sizehint!(Dict{Vector{Float64}, JuMP.VariableRef}(), length(vrefs))
230240
# create a variable for each support
231241
for i in supp_indices
232-
supp = index_to_support(backend, i)[param_nums]
242+
supp = index_to_support(backend, i)[pref_supp_idxs]
233243
new_info = _format_infinite_info(info, supp)
234244
var_idx = i.I[group_idxs]
235245
tuple_supp = Tuple(supp, prefs)
236-
name = _make_var_name(base_name, param_nums, tuple_supp, var_idx)
246+
name = _make_var_name(base_name, pref_supp_idxs, tuple_supp, var_idx)
237247
var = JuMP.ScalarVariable(new_info)
238248
jump_vref = JuMP.add_variable(backend.model, var, name)
239249
@inbounds vrefs[var_idx...] = jump_vref
240250
lookup_dict[supp] = jump_vref
241251
@inbounds supps[var_idx...] = tuple_supp
242252
end
243253
# save the transcription information
244-
data = transcription_data(backend)
245254
gvref = InfiniteOpt.GeneralVariableRef(vref)
246255
data.infvar_lookup[gvref] = lookup_dict
247256
data.infvar_mappings[gvref] = vrefs
248257
data.infvar_supports[gvref] = supps
258+
data.infvar_param_idxs[gvref] = pref_supp_idxs
249259
return
250260
end
251261

@@ -379,11 +389,12 @@ function transcribe_semi_infinite_variables!(
379389
rvref = InfiniteOpt.GeneralVariableRef(model, idx)
380390
# setup the mappings
381391
ivref = var.infinite_variable_ref
382-
param_nums = var.parameter_nums
383-
ivref_param_nums = InfiniteOpt._parameter_numbers(ivref)
384392
eval_supp = var.eval_support
385393
group_idxs = var.group_int_idxs
386394
prefs = InfiniteOpt.raw_parameter_refs(var)
395+
data = transcription_data(backend)
396+
pref_supp_idxs = Int[data.param_to_support_idx[p] for p in prefs]
397+
ivref_pref_supp_idxs = data.infvar_param_idxs[ivref]
387398
# prepare for iterating over its supports
388399
data = transcription_data(backend)
389400
supp_indices = support_index_iterator(backend, group_idxs)
@@ -403,8 +414,8 @@ function transcribe_semi_infinite_variables!(
403414
raw_supp = index_to_support(backend, i)
404415
var_idx = i.I[group_idxs]
405416
# map to the current transcription variable
406-
supp = raw_supp[param_nums]
407-
ivref_supp = [isnan(s) ? raw_supp[ivref_param_nums[j]] : s
417+
supp = raw_supp[pref_supp_idxs]
418+
ivref_supp = [isnan(s) ? raw_supp[ivref_pref_supp_idxs[j]] : s
408419
for (j, s) in enumerate(eval_supp)]
409420
jump_vref = lookup_by_support(ivref, backend, ivref_supp)
410421
@inbounds vrefs[var_idx...] = jump_vref
@@ -421,6 +432,7 @@ function transcribe_semi_infinite_variables!(
421432
else
422433
data.pfunc_lookup[rvref] = lookup_dict
423434
end
435+
data.infvar_param_idxs[rvref] = pref_supp_idxs
424436
end
425437
return
426438
end
@@ -499,20 +511,15 @@ function transcription_expression(
499511
index_type::Type{V},
500512
backend::TranscriptionBackend,
501513
support::Vector{Float64}
502-
) where {V <: Union{InfVarIndex, InfiniteOpt.ParameterFunctionIndex, InfiniteOpt.MeasureIndex}}
503-
param_nums = InfiniteOpt._parameter_numbers(vref)
504-
return lookup_by_support(vref, index_type, backend, support[param_nums])
505-
end
506-
507-
# Semi-Infinite variables
508-
function transcription_expression(
509-
vref::InfiniteOpt.GeneralVariableRef,
510-
index_type::Type{InfiniteOpt.SemiInfiniteVariableIndex},
511-
backend::TranscriptionBackend,
512-
support::Vector{Float64}
513-
)
514-
param_nums = InfiniteOpt._parameter_numbers(vref)
515-
return lookup_by_support(vref, index_type, backend, support[param_nums])
514+
) where {V <: Union{
515+
InfVarIndex,
516+
InfiniteOpt.ParameterFunctionIndex,
517+
InfiniteOpt.MeasureIndex,
518+
InfiniteOpt.SemiInfiniteVariableIndex}
519+
}
520+
data = transcription_data(backend)
521+
pref_supp_idxs = data.infvar_param_idxs[vref]
522+
return lookup_by_support(vref, index_type, backend, support[pref_supp_idxs])
516523
end
517524

518525
# Point variables, finite variables and finite parameters
@@ -532,8 +539,8 @@ function transcription_expression(
532539
backend::TranscriptionBackend,
533540
support::Vector{Float64}
534541
) where {V <: InfiniteOpt.InfiniteParameterIndex}
535-
param_num = InfiniteOpt._parameter_number(vref)
536-
return support[param_num]
542+
data = transcription_data(backend)
543+
return support[data.param_to_support_idx[vref]]
537544
end
538545

539546
# AffExpr and QuadExpr and NonlinearExpr
@@ -544,7 +551,8 @@ function transcription_expression(
544551
)
545552
return InfiniteOpt.map_expression(
546553
v -> transcription_expression(v, backend, support),
547-
expr)
554+
expr
555+
)
548556
end
549557

550558
# Real Number
@@ -584,6 +592,8 @@ function transcribe_measures!(
584592
group_idxs = meas.group_int_idxs
585593
mref = InfiniteOpt.GeneralVariableRef(model, idx)
586594
prefs = InfiniteOpt.raw_parameter_refs(mref)
595+
data = transcription_data(backend)
596+
pref_supp_idxs = Int[data.param_to_support_idx[p] for p in prefs]
587597
# expand the measure
588598
if meas.constant_func
589599
new_expr = InfiniteOpt.analytic_expansion(meas.func, meas.data, backend)
@@ -602,15 +612,15 @@ function transcribe_measures!(
602612
raw_supp = index_to_support(backend, i)
603613
expr_idx = i.I[group_idxs]
604614
@inbounds exprs[expr_idx...] = transcription_expression(new_expr, backend, raw_supp)
605-
supp = raw_supp[meas.parameter_nums]
615+
supp = raw_supp[pref_supp_idxs]
606616
lookup_dict[supp] = lin_idx
607617
@inbounds supps[expr_idx...] = Tuple(supp, prefs)
608618
end
609619
# save the transcription information
610-
data = transcription_data(backend)
611620
data.measure_lookup[mref] = lookup_dict
612621
data.measure_mappings[mref] = exprs
613622
data.measure_supports[mref] = supps
623+
data.infvar_param_idxs[mref] = pref_supp_idxs
614624
end
615625
return
616626
end
@@ -698,13 +708,19 @@ function _get_info_constr_from_var(
698708
return JuMP.is_integer(trans_vref) ? JuMP.IntegerRef(trans_vref) : nothing
699709
end
700710

711+
# Get the parameter support indexing for a restriction
712+
function _pref_supp_idxs(constr::InfiniteOpt.DomainRestrictedConstraint, data)
713+
prefs = constr.restriction.parameter_refs
714+
return [data.param_to_support_idx[p] for p in prefs]
715+
end
716+
_pref_supp_idxs(constr, data) = Int[]
717+
701718
# Determine if a given raw support satisfies constraint domain restrictions
702719
function _support_in_restrictions(
703720
constr::InfiniteOpt.DomainRestrictedConstraint,
704721
support::Vector{Float64}
705722
)
706-
restriction = constr.restriction
707-
return restriction(support[restriction.parameter_nums])
723+
return constr.restriction(support)
708724
end
709725
function _support_in_restrictions(
710726
constr::JuMP.AbstractConstraint,
@@ -799,6 +815,7 @@ function transcribe_constraints!(
799815
set = JuMP.moi_set(constr)
800816
group_idxs = object.group_int_idxs
801817
cref = InfiniteOpt.InfOptConstraintRef(model, idx)
818+
data = transcription_data(backend)
802819
# prepare the iteration helpers
803820
supp_indices = support_index_iterator(backend, group_idxs)
804821
dims = size(supp_indices)[group_idxs]
@@ -825,11 +842,12 @@ function transcribe_constraints!(
825842
else
826843
# get basic setup information
827844
name = object.name
845+
pref_supp_idxs = _pref_supp_idxs(constr, data)
828846
for i in supp_indices
829847
raw_supp = index_to_support(backend, i)
830848
# ensure the support satisfies parameter bounds and then add it
831849
con_idx = i.I[group_idxs]
832-
if _support_in_restrictions(constr, raw_supp)
850+
if _support_in_restrictions(constr, raw_supp[pref_supp_idxs])
833851
new_name = if isempty(name)
834852
""
835853
elseif isempty(group_idxs)
@@ -849,7 +867,6 @@ function transcribe_constraints!(
849867
end
850868
# truncate the arrays in case not all the supports satisfied the bounds
851869
# and save
852-
data = transcription_data(backend)
853870
if !all(valid_idxs)
854871
data.constr_mappings[cref] = crefs[valid_idxs]
855872
data.constr_supports[cref] = supps[valid_idxs]

0 commit comments

Comments
 (0)