# Cannot use AD as shown in ControlSystems.jl example

**URL:** <https://discourse.julialang.org/t/cannot-use-ad-as-shown-in-controlsystems-jl-example/136292>\
**Category:** Modelling & Simulations\
**Tags:** autodiff, controlsystems\
**Created:** [March 19, 2026, 3:27pm UTC](https://discourse.julialang.org/t/cannot-use-ad-as-shown-in-controlsystems-jl-example/136292 "2026-03-19T15:27:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![vtfanta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vtfanta/32/48144_2.png) [@vtfanta](https://discourse.julialang.org/u/vtfanta)\
**Post date:** [March 19, 2026, 3:27pm UTC](https://discourse.julialang.org/t/cannot-use-ad-as-shown-in-controlsystems-jl-example/136292/1 "2026-03-19T15:27:12Z")

</div>

I’m trying to replicate the example of using AD with ControlSystems.jl from the JuliaCon 2022 presentation ([this moment](https://youtu.be/favQKOyyx4o?t=761)), but the ForwardDiff gradient calculation errors, since there is the matrix exponential `LinearAlgebra.exp!` being called during the `step` simulation which is incompatible with the AD dual number type. However, the same code works in the referenced video. Has something changed since that time that causes this?

The code:

```julia-auto
using ControlSystems
using ForwardDiff

function cost_function(params)
    gain, pole = params
    P = tf(1, [1, 1])
    C = tf(gain, [1, pole])
    closed_loop = feedback(P * C)
    y = step(closed_loop, 0:0.1:5).y
    sum(abs2, y .- 1)
end

params0 = [1.0, 1.0]
∇cost = ForwardDiff.gradient(cost_function, params0

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 19, 2026, 4:34pm UTC](https://discourse.julialang.org/t/cannot-use-ad-as-shown-in-controlsystems-jl-example/136292/2 "2026-03-19T16:34:19Z")

</div>

Here are a number of updated examples

> **[Automatic differentiation · ControlSystems.jl](https://juliacontrol.github.io/ControlSystems.jl/stable/examples/automatic_differentiation/)**
>
> Documentation for ControlSystems.jl.

See also [Known limitations: ForwardDiff](https://juliacontrol.github.io/ControlSystems.jl/stable/examples/automatic_differentiation/#ForwardDiff)

---

<div class="post-metadata">

**Author:** ![vtfanta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vtfanta/32/48144_2.png) [@vtfanta](https://discourse.julialang.org/u/vtfanta)\
**Post date:** [March 19, 2026, 7:18pm UTC](https://discourse.julialang.org/t/cannot-use-ad-as-shown-in-controlsystems-jl-example/136292/3 "2026-03-19T19:18:51Z")

</div>

Thanks a lot! Solved using the tip from Known limitations section linked above.

```julia-auto
using ControlSystems
using ExponentialUtilities
using ForwardDiff
using ForwardDiffChainRules
using LinearAlgebra
LinearAlgebra.exp!(A::AbstractMatrix{<:ForwardDiff.Dual}) = ExponentialUtilities.exponential!(A)

function cost_function(params)
    gain, pole = params
    P = tf(1, [1, 1])
    C = tf(gain, [1, pole])
    closed_loop = feedback(P * C)
    y = step(closed_loop, 0:0.1:5).y
    sum(abs2, y .- 1)
end

params0 = [1.0, 1.0]
∇cost = ForwardDiff.gradient(cost_function, params0) 
#= 2-element Vector{Float64}:
 -13.961127368222007
  10.479573214337087 =#

```
