Cannot use AD as shown in ControlSystems.jl example

I’m trying to replicate the example of using AD with ControlSystems.jl from the JuliaCon 2022 presentation (this moment), 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:

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

Here are a number of updated examples

See also Known limitations: ForwardDiff

1 Like

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

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 =#
1 Like