Skip to content

Commit e6b573a

Browse files
authored
Clean Up and Simplify Dependence on Infinite Parameters (#393)
* Updated source code * More updates and fixes * doc fix * test fixes * doctest fixes * minor fixes * minor fixes
1 parent 7614724 commit e6b573a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1573
-2438
lines changed

docs/src/develop/extensions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,12 @@ struct DiscreteVarianceData <: AbstractMeasureData
516516
label::DataType
517517
# constructor
518518
function DiscreteVarianceData(
519-
parameter_refs::Union{GeneralVariableRef, AbstractArray{<:GeneralVariableRef}},
519+
parameter_refs::Union{GeneralVariableRef, Array{<:GeneralVariableRef}},
520520
supports::Vector,
521521
label::DataType = InfiniteOpt.generate_unique_label()
522522
)
523523
# convert input as necessary to proper array format
524-
if parameter_refs isa AbstractArray
524+
if parameter_refs isa Array
525525
parameter_refs = convert(Vector, parameter_refs)
526526
supports = [convert(Vector, arr) for arr in supports]
527527
end
@@ -631,7 +631,7 @@ variance measures more convenient:
631631
```jldoctest measure_data; output = false
632632
function variance(
633633
expr::Union{JuMP.GenericAffExpr, GeneralVariableRef},
634-
params::Union{GeneralVariableRef, AbstractArray{GeneralVariableRef}};
634+
params::Union{GeneralVariableRef, Array{GeneralVariableRef}};
635635
name::String = "Var",
636636
num_supports::Int = 10,
637637
use_existing::Bool = false

docs/src/examples/Stochastic Optimization/farmer.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ model = InfiniteModel(Ipopt.Optimizer)
8080
set_optimizer_attribute(model, "print_level", 0);
8181

8282
# Now let's define the infinite parameters using [`@infinite_parameter`](@ref):
83-
@infinite_parameter(model, ξ[c in C] ~ Ξ[c], num_supports = num_scenarios)
83+
@infinite_parameter(model, ξ[c in C] ~ Ξ[c], num_supports = num_scenarios, container = Array)
8484

8585
# !!! note
8686
# Behind the scenes, an amount of random samples equal to `num_scenarios` will

docs/src/guide/derivative.md

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ julia> @infinite_parameter(model, t in [0, 10],
2727
2828
julia> @infinite_parameter(model, ξ ~ Uniform(-1, 1));
2929
30-
julia> @variable(model, y, Infinite(t, ξ));
30+
julia> @infinite_parameter(model, x in [-1, 1]);
31+
32+
julia> @variable(model, y, Infinite(t, x, ξ));
3133
3234
julia> @variable(model, q, Infinite(t));
3335
```
@@ -45,24 +47,28 @@ scenes all the appropriate calculus will be applied, creating derivative variabl
4547
as needed. For example, we can define the following:
4648
```jldoctest deriv_basic
4749
julia> d1 = deriv(y, t)
48-
∂/∂t[y(t, ξ)]
50+
∂/∂t[y(t, x, ξ)]
4951
50-
julia> d2 = ∂(y, t, ξ)
51-
∂/∂ξ[∂/∂t[y(t, ξ)]]
52+
julia> d2 = ∂(y, t, x)
53+
∂/∂x[∂/∂t[y(t, x, ξ)]]
5254
5355
julia> d3 = @∂(q, t^2) # the macro version allows the `t^2` syntax
5456
d²/dt²[q(t)]
5557
5658
julia> d_expr = deriv(y * q - 2t, t)
57-
∂/∂t[y(t, ξ)]*q(t) + d/dt[q(t)]*y(t, ξ) - 2
59+
∂/∂t[y(t, x, ξ)]*q(t) + d/dt[q(t)]*y(t, x, ξ) - 2
5860
```
5961
Thus, we can define derivatives in a variety of forms according to the problem at
60-
hand. The last example even shows how the product rule is correctly applied.
62+
hand. The last example even shows how the product rule is correctly applied.
6163

6264
!!! note
6365
For convenience in making more compact code we provide [``](@ref)
6466
as an alias for [`deriv`](@ref).
6567

68+
!!! note
69+
Derivatives taken with respect to dependent infinite parameters are not
70+
supported.
71+
6672
Also, notice that the appropriate symbolic calculus is applied to infinite
6773
parameters. For example, we could also compute:
6874
```jldoctest deriv_basic
@@ -170,7 +176,7 @@ More detailed information on `JuMP.VariableInfo` is provided in the
170176
Now that we have our variable information we can make a derivative using
171177
[`build_derivative`](@ref):
172178
```jldoctest deriv_basic
173-
julia> d = build_derivative(error, info, y, ξ, 1);
179+
julia> d = build_derivative(error, info, y, x, 1);
174180
175181
julia> d isa Derivative
176182
true
@@ -184,14 +190,14 @@ will add the [`Derivative`](@ref) object and return `GeneralVariableRef` pointin
184190
to it that we can use in `InfiniteOpt` expressions:
185191
```jldoctest deriv_basic
186192
julia> dref = add_derivative(model, d)
187-
∂/∂ξ[y(t, ξ)]
193+
∂/∂x[y(t, x, ξ)]
188194
```
189195
This will also create any appropriate information based constraints (e.g., lower
190196
bounds).
191197

192198
Finally, we note that higher order derivatives by changing the order argument:
193199
```jldoctest deriv_basic
194-
julia> d = build_derivative(error, info, y, ξ, 3); # 3rd order derivative
200+
julia> d = build_derivative(error, info, y, x, 3); # 3rd order derivative
195201
```
196202

197203
### Macro Definition
@@ -208,7 +214,7 @@ of 1 with an initial guess of 0 and assign it to an alias
208214
`GeneralVariableRef` called `dydt2`:
209215
```jldoctest deriv_basic
210216
julia> @variable(model, dydt2 >= 1, Deriv(y, t, 2), start = 0)
211-
dydt2(t, ξ)
217+
dydt2(t, x, ξ)
212218
```
213219
This will also support anonymous definition and multi-dimensional definition.
214220
Please see [Macro Variable Definition](@ref) for more information.
@@ -228,17 +234,17 @@ derivative definition, handling the nesting as appropriate. For example, we can
228234
"define" ``\frac{\partial^2 y(t, \xi)}{\partial t^2}`` again:
229235
```jldoctest deriv_basic
230236
julia> @deriv(d1, t) # recall `d1 = deriv(y, t)`
231-
dydt2(t, ξ)
237+
dydt2(t, x, ξ)
232238
233239
julia> @deriv(y, t^2)
234-
dydt2(t, ξ)
240+
dydt2(t, x, ξ)
235241
```
236242
Notice that the derivative references all point to the same derivative object we
237243
defined up above with its alias name `dydt2`. This macro can also tackle complex
238244
expressions using the appropriate calculus such as:
239245
```jldoctest deriv_basic
240246
julia> @deriv(∫(y, ξ) * q, t)
241-
d/dt[∫{ξ ∈ [-1, 1]}[y(t, ξ)]]*q(t) + d/dt[q(t)]*∫{ξ ∈ [-1, 1]}[y(t, ξ)]
247+
d/dt[∫{ξ ∈ [-1, 1]}[y(t, x, ξ)]]*q(t) + d/dt[q(t)]*∫{ξ ∈ [-1, 1]}[y(t, x, ξ)]
242248
```
243249
Thus, demonstrating the convenience of using `@deriv`.
244250

@@ -457,18 +463,18 @@ We can build these relations for a particular derivative via [`evaluate`](@ref).
457463
For example, let's build evaluation equations for `d1`:
458464
```jldoctest deriv_basic
459465
julia> d1
460-
∂/∂t[y(t, ξ)]
466+
∂/∂t[y(t, x, ξ)]
461467
462468
julia> fill_in_supports!(t, num_supports = 5) # add supports first
463469
464470
julia> evaluate(d1)
465471
466472
julia> derivative_constraints(d1)
467473
4-element Vector{InfOptConstraintRef}:
468-
2.5 ∂/∂t[y(t, ξ)](0, ξ) + y(0, ξ) - y(2.5, ξ) = 0, ∀ ξ ~ Uniform
469-
2.5 ∂/∂t[y(t, ξ)](2.5, ξ) + y(2.5, ξ) - y(5, ξ) = 0, ∀ ξ ~ Uniform
470-
2.5 ∂/∂t[y(t, ξ)](5, ξ) + y(5, ξ) - y(7.5, ξ) = 0, ∀ ξ ~ Uniform
471-
2.5 ∂/∂t[y(t, ξ)](7.5, ξ) + y(7.5, ξ) - y(10, ξ) = 0, ∀ ξ ~ Uniform
474+
2.5 ∂/∂t[y(t, x, ξ)](0, x, ξ) + y(0, x, ξ) - y(2.5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
475+
2.5 ∂/∂t[y(t, x, ξ)](2.5, x, ξ) + y(2.5, x, ξ) - y(5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
476+
2.5 ∂/∂t[y(t, x, ξ)](5, x, ξ) + y(5, x, ξ) - y(7.5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
477+
2.5 ∂/∂t[y(t, x, ξ)](7.5, x, ξ) + y(7.5, x, ξ) - y(10, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
472478
```
473479
Note that we made sure `t` had supports first over which we could carry out the
474480
evaluation, otherwise an error would have been thrown. Moreover, once the
@@ -478,15 +484,15 @@ evaluation was completed we were able to access the auxiliary equations via
478484
We can also, add the necessary auxiliary equations for all the derivatives in the
479485
model if we call [`evaluate_all_derivatives!`](@ref):
480486
```jldoctest deriv_basic
481-
julia> fill_in_supports!(ξ, num_supports = 4) # add supports first
487+
julia> fill_in_supports!(x, num_supports = 4) # add supports first
482488
483489
julia> evaluate_all_derivatives!(model)
484490
485491
julia> derivative_constraints(dydt2)
486492
3-element Vector{InfOptConstraintRef}:
487-
6.25 dydt2(0, ξ) - y(0, ξ) + 2 y(2.5, ξ) - y(5, ξ) = 0, ∀ ξ ~ Uniform
488-
6.25 dydt2(2.5, ξ) - y(2.5, ξ) + 2 y(5, ξ) - y(7.5, ξ) = 0, ∀ ξ ~ Uniform
489-
6.25 dydt2(5, ξ) - y(5, ξ) + 2 y(7.5, ξ) - y(10, ξ) = 0, ∀ ξ ~ Uniform
493+
6.25 dydt2(0, x, ξ) - y(0, x, ξ) + 2 y(2.5, x, ξ) - y(5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
494+
6.25 dydt2(2.5, x, ξ) - y(2.5, x, ξ) + 2 y(5, x, ξ) - y(7.5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
495+
6.25 dydt2(5, x, ξ) - y(5, x, ξ) + 2 y(7.5, x, ξ) - y(10, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
490496
```
491497

492498
Finally, we note that once derivative constraints have been added to the
@@ -496,10 +502,10 @@ and a warning will be thrown to indicate such:
496502
```jldoctest deriv_basic
497503
julia> derivative_constraints(d1)
498504
4-element Vector{InfOptConstraintRef}:
499-
2.5 ∂/∂t[y(t, ξ)](0, ξ) + y(0, ξ) - y(2.5, ξ) = 0, ∀ ξ ~ Uniform
500-
2.5 ∂/∂t[y(t, ξ)](2.5, ξ) + y(2.5, ξ) - y(5, ξ) = 0, ∀ ξ ~ Uniform
501-
2.5 ∂/∂t[y(t, ξ)](5, ξ) + y(5, ξ) - y(7.5, ξ) = 0, ∀ ξ ~ Uniform
502-
2.5 ∂/∂t[y(t, ξ)](7.5, ξ) + y(7.5, ξ) - y(10, ξ) = 0, ∀ ξ ~ Uniform
505+
2.5 ∂/∂t[y(t, x, ξ)](0, x, ξ) + y(0, x, ξ) - y(2.5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
506+
2.5 ∂/∂t[y(t, x, ξ)](2.5, x, ξ) + y(2.5, x, ξ) - y(5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
507+
2.5 ∂/∂t[y(t, x, ξ)](5, x, ξ) + y(5, x, ξ) - y(7.5, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
508+
2.5 ∂/∂t[y(t, x, ξ)](7.5, x, ξ) + y(7.5, x, ξ) - y(10, x, ξ) = 0, ∀ ξ ~ Uniform, x ∈ [-1, 1]
503509
504510
julia> add_supports(t, 0.2)
505511
┌ Warning: Support/method changes will invalidate existing derivative evaluation constraints that have been added to the InfiniteModel. Thus, these are being deleted.
@@ -519,7 +525,7 @@ First, let's overview the basic object inquiries: [`derivative_argument`](@ref),
519525
[`derivative_method`](@ref), and [`name`](@ref JuMP.name(::DecisionVariableRef)):
520526
```jldoctest deriv_basic
521527
julia> derivative_argument(dydt2) # get the variable the derivative operates on
522-
y(t, ξ)
528+
y(t, x, ξ)
523529
524530
julia> operator_parameter(dydt2) # get the parameter the operator is taken with respect to
525531
t
@@ -553,10 +559,10 @@ Also, since derivatives are analogous to infinite variables, they inherit many
553559
of the same queries including [`parameter_refs`](@ref):
554560
```jldoctest deriv_basic
555561
julia> parameter_refs(d1)
556-
(t, ξ)
562+
(t, x, ξ)
557563
558564
julia> parameter_refs(derivative_argument(d1))
559-
(t, ξ)
565+
(t, x, ξ)
560566
```
561567
Since derivatives simply inherit their infinite parameter dependencies from the
562568
argument variable, the above lines are equivalent.
@@ -573,7 +579,7 @@ julia> lower_bound(dydt2)
573579
1.0
574580
575581
julia> LowerBoundRef(dydt2)
576-
dydt2(t, ξ) ≥ 1, ∀ t ∈ [0, 10], ξ ~ Uniform
582+
dydt2(t, x, ξ) ≥ 1, ∀ t ∈ [0, 10], ξ ~ Uniform, x ∈ [-1, 1]
577583
578584
julia> has_upper_bound(dydt2)
579585
false
@@ -590,13 +596,13 @@ julia> num_derivatives(model)
590596
591597
julia> all_derivatives(model)
592598
7-element Vector{GeneralVariableRef}:
593-
∂/∂t[y(t, ξ)]
594-
∂/∂ξ[∂/∂t[y(t, ξ)]]
599+
∂/∂t[y(t, x, ξ)]
600+
∂/∂x[∂/∂t[y(t, x, ξ)]]
595601
d²/dt²[q(t)]
596602
d/dt[q(t)]
597-
∂/∂ξ[y(t, ξ)]
598-
dydt2(t, ξ)
599-
d/dt[∫{ξ ∈ [-1, 1]}[y(t, ξ)]]
603+
∂/∂x[y(t, x, ξ)]
604+
dydt2(t, x, ξ)
605+
∂/∂t[∫{ξ ∈ [-1, 1]}[y(t, x, ξ)]]
600606
```
601607

602608
## Modification Methods
@@ -623,7 +629,7 @@ julia> fix(dydt2, 42, force = true)
623629
julia> fix_value(dydt2)
624630
42.0
625631
626-
julia> set_start_value_function(dydt2, (t, xi) -> t + xi)
632+
julia> set_start_value_function(dydt2, (t, x, xi) -> t + x+ xi)
627633
628634
julia> unfix(dydt2)
629635

docs/src/guide/measure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ julia> md_x = DiscreteMeasureData(x, 0.25 * ones(4), [[0.25, 0.25], [0.25, 0.75]
215215
```
216216
where `md_x` cuts the domain into four 0.5-by-0.5 squares, and evaluates the
217217
integrand on the center of these squares. Note that for multivariate parameters,
218-
each support point should be an `AbstractArray` that stores the value at each dimension.
218+
each support point should be an `Array` that stores the value at each dimension.
219219

220220
In addition to the intuitive [`DiscreteMeasureData`], another type of measure data
221221
object is [`FunctionalDiscreteMeasureData`](@ref). This type captures measure data

docs/src/guide/optimize.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ We can also query the expressions via
163163
[`transformation_expression`](@ref transformation_expression(::JuMP.AbstractJuMPScalar)):
164164
```jldoctest optimize
165165
julia> transformation_expression(z - y^2 + 3) # infinite expression
166-
10-element Vector{AbstractJuMPScalar}:
166+
10-element Vector{Union{Real, AbstractJuMPScalar}}:
167167
-y(0.0)² + z + 3
168168
-y(1.11111111111)² + z + 3
169169
-y(2.22222222222)² + z + 3

docs/src/guide/parameter.md

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -295,20 +295,7 @@ julia> θ = @infinite_parameter(model, [1:2] ~ dist, num_supports = 3, base_name
295295
```
296296

297297
### Containers for Multi-Dimensional Parameters
298-
Because we build on JuMP, we can use any indices we like when making containers
299-
(e.g., arrays) for multi-dimensional parameters. For example, we can define:
300-
```jldoctest; setup = :(using InfiniteOpt; model= InfiniteModel())
301-
julia> @infinite_parameter(model, x[i = [:a, :b]] in [0, 1])
302-
1-dimensional DenseAxisArray{GeneralVariableRef,1,...} with index sets:
303-
Dimension 1, [:a, :b]
304-
And data, a 2-element Vector{GeneralVariableRef}:
305-
x[a]
306-
x[b]
307-
```
308-
309-
See
310-
[`JuMP`'s documentation on containers](https://jump.dev/JuMP.jl/v1/manual/containers/)
311-
for more information.
298+
Unlike other modelling objects, only `Array` containers are supported for infinite parameters.
312299

313300
## Supports
314301
For an infinite parameter, its supports are a finite set of points that the
@@ -452,7 +439,7 @@ In this section we introduce automatic support generation for defined
452439
parameters with no associated supports. This can be done using the
453440
[`fill_in_supports!`](@ref) functions. [`fill_in_supports!`](@ref) can take as
454441
argument a [`GeneralVariableRef`](@ref) or an
455-
`AbstractArray{<:GeneralVariableRef}`, in which case it will generate
442+
`Array{<:GeneralVariableRef}`, in which case it will generate
456443
supports for the associated infinite parameter. Alternatively,
457444
[`fill_in_supports!`](@ref) can also take an [`InfiniteModel`](@ref) as an
458445
argument, in which case it will generate supports for all infinite parameters

0 commit comments

Comments
 (0)