Skip to content

Parameter representation for controls #1088

Closed
@ChrisRackauckas

Description

@ChrisRackauckas

The underlying problem is that we need to represent the generated f(du,u,p,t) in a way where p can hold the necessary parameters while also being a valid object for the optimal control. Without that, #1059 will not be able to generate an ODEProblem. But what kind of ODEProblem should it be generating? This issue is to specify the interface for the forward simulation and describe why that needs to be the case.

Proposed code

In a modified version of https://diffeqflux.sciml.ai/dev/examples/optimal_control/ where dx[1] also has a parameter, i.e.

function dxdt_(dx,x,p,t)
    x1, x2 = x
    dx[1] = p.p[1] * x[2]
    dx[2] = p.ctrl[1](t)^3
end

i.e. the parameters are held in some kind of struct:

ParameterController <: AbstractParameterData
  p::P
  ctrl::C
end

In this form, we need that each ctrl is a ctrl(t) which internally holds its parameterization. Then we would just build it like:

ODEProblem(sys,[x1 => ...], [p1 => ...],ctrls = [ctrl1 => DataInterpolations.ConstantInterpolation(data,data_t)])

Sounds good? Okay now the hard part.

Parameter Representation for Optimal Control

Now we want to optimize p. That can mean multiple things: optimize p.p, optimize p.ctrl, or optimize p in full. How do we make this happen? Well we can have p itself act as a vector. If trainctrl == false, then p[i] = p.p[i]. If trainp == false then p[i] == ...?. So let's talk about that part.

We need to make the parameter interface recursive. ctrl should be something that follows the interface that it acts like a parameter vector, so that ctrl[i] is something that acts like a parameter vector, so that ctrl[i][j] is something that acts like a parameter vector. If that's the case, we just map i to continue over each next parameter vector.

DataInterpolations.jl was setup in 2018 with this in mind (gotta appreciate that forward thinking 🤔 😉 ) so if you did ConstantInterpolation{true}(u,t), the u and t would be trainable, and ConstantInterpolation(u,t) = ConstantInterpolation{false}(u,t) would just make the values u trainable and the node points t of the controller would be fixed. To make this work, we would just need to have length(ConstantInterpolation(u,t)) work, and then paramlength(p) = paramlength(p.p) + paramlength(p.ctrl). Now if you have multiple controls, p.ctrl can be a tuple of controls (or vector, depending on the type stability), and then paramlength(x::Tuple) = sum(paramlength,x). Then length(p::ParameterController ) = paramlength(p).

Given this indexing, pvec = Vector(p) would "just work" via Julia's generic dispatches. However, we would still need a way to change a vector back into p, which we should implement by overloading ArrayInterface.restructure(p,pvec) (though it might just work by default?). Once this is the case, then all of GalacticOptim, adjoints, DiffEqFlux, etc. should be able to train the values of the parameters and the controllers in this form.

Pieces that are made to be constant would just be things that are kept out of the vectorization of the parameter struct.

Where to put it

Since this is a generally nice interface, it might make sense to have this be a package that we point people towards which defines a nice structure to parameters. This is also the general solution to a long-standing issue SciML/DiffEqFlux.jl#178 and SciML/SciMLSensitivity.jl#80, it might be good to call it SciMLParameters.jl or something and make it a full interface so that it's documented and people know how to make their parameters "fit" with all of the packages in the ecosystem. Having this would work make p = TupleParams(p1,p2) work in DiffEqFlux, if it's using this paramlength where on tuple it knows to just extend. ModelingToolkit.jl would then just use this new "SciML common parameter interface"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions