# DifferentialEquations, Control Systems, and Linearization

**URL:** <https://discourse.julialang.org/t/differentialequations-control-systems-and-linearization/31178>\
**Category:** General Usage\
**Tags:** control, diffeq\
**Created:** [November 17, 2019, 1:12pm UTC](https://discourse.julialang.org/t/differentialequations-control-systems-and-linearization/31178 "2019-11-17T13:12:19Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [November 19, 2019, 10:56pm UTC](https://discourse.julialang.org/t/differentialequations-control-systems-and-linearization/31178/7 "2019-11-19T22:56:45Z")

</div>

I believe [_lens_](https://jw3126.github.io/Setfield.jl/latest/#Setfield.Lens) is the best API for this. As I [noted before](https://discourse.julialang.org/t/taking-a-derivative-of-nested-object-using-lens-from-setfield-jl/20078), lens can be used to specify arbitrary nested fields along which you are taking the derivative, for example. This can be done without defining any methods and works with vanilla Julia objects without any use of symbolic math framework (although they are very useful, of course). Because of this flexibility, I use it anywhere I need to tweak model parameters/inputs. See [this example](https://tkf.github.io/Bifurcations.jl/dev/examples/calcium/) in [Bifurcations.jl](https://github.com/tkf/Bifurcations.jl) where I specify the parameter of a plain named tuple by a simple lens (`param_axis = @lens _.i`). [SteadyStateFit.jl](https://github.com/tkf/SteadyStateFit.jl) uses lenses as “input setter” (like the argument u of f(x, u, t; p) in the OP) and the model parameter specifier. I also created a toolkit called [Kaleido.jl](https://github.com/tkf/Kaleido.jl) that can be used to, e.g., [add a constraint to a model](https://tkf.github.io/Kaleido.jl/dev/#Kaleido.constraining) and [re-parametrize a model](https://tkf.github.io/Kaleido.jl/dev/#Kaleido.setting) using [TransformVariables.jl](https://github.com/tpapp/TransformVariables.jl).

A simple implementation `ControlProblem` would be such that it generates an ODE parameter `ControlProblemWrapper` like below on the fly:

```julia
struct ControlProblemWrapper
    f! # original dynamics
    p # original parameter
    input # time-to-input mapping
    lens # input specifier
end

function f!(du, u, p::ControlProblemWrapper, t)
    q = set(p.p, p.lens, p.input(t))
    p.f!(du, q, t)
end

```

which can be used as

```julia
# Model with input function
function model!(dx,x,p,t)
   dx[1] = -p[1]*x[1] + p[2]*p[3]
end

p1 = ControlProblemWrapper(
    model!,
    (1.0, 2.0, 3.0), # 3.0 as a place holder
    u(t) = t < 5 ? 0.0 : 1.0,
    (@lens _[3]),
)

```

Now it is super easy to make other part of the model time-dependent:

```julia
p2 = ControlProblemWrapper(
    model!,
    (1.0, 2.0, 3.0),
    u(t) = t < 5 ? 0.0 : 1.0,
    (@lens _[1]), # make the first parameter time-dependent
)

```

Note that above lenses are very simple ones. You can use it to specify `(@lens _.arbitrary.nested[:complex].fields[1])`.

---

_[View the full topic](https://discourse.julialang.org/t/differentialequations-control-systems-and-linearization/31178)._
