Skip to content

New calculate_statespace function for AbstractODESystem #1103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ModelingToolkit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export DiscreteSystem, DiscreteProblem

export calculate_jacobian, generate_jacobian, generate_function
export calculate_control_jacobian, generate_control_jacobian
export calculate_statespace
export calculate_tgrad, generate_tgrad
export calculate_gradient, generate_gradient
export calculate_factorized_W, generate_factorized_W
Expand Down
24 changes: 24 additions & 0 deletions src/systems/diffeqs/abstractodesystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -727,3 +727,27 @@ end

isdifferential(expr) = istree(expr) && operation(expr) isa Differential
isdiffeq(eq) = isdifferential(eq.lhs)

"""
calculate_statespace(sys::AbstractODESystem, subs::Dict = sys.defaults; matrix_eltype::Type{T} = Float64) where T

Returns a tuple of the linearized `A` and `B` matrices for a state space model.
"""
function calculate_statespace(sys::AbstractODESystem, subs::Dict = defaults(sys); matrix_eltype::Type{T} = Float64) where T

J = calculate_jacobian(sys)
C = calculate_control_jacobian(sys)

A = Matrix{T}(undef, size(J))
B = Matrix{T}(undef, size(C))

for I in CartesianIndices(A)
A[I] = value(substitute(J[I], subs))
end

for I in CartesianIndices(B)
B[I] = value(substitute(C[I], subs))
end

return A,B
end
19 changes: 18 additions & 1 deletion test/odesystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -379,4 +379,21 @@ let
reshape(Num[0,1], 2, 1)
)

end
end

# check statespace
let
@parameters t f k d
@variables x(t) ẋ(t)
δ = Differential(t)

eqs = [δ(x) ~ ẋ, δ(ẋ) ~ f - k*x - d*ẋ]
sys = ODESystem(eqs, t, [x, ẋ], [f, d, k]; controls = [f])

A = reshape(Float64[0, -1, 1, -2], 2, 2)
B = reshape(Float64[0, 1], 2, 1)
@test isequal(
calculate_statespace(sys, Dict([k => 1, d => 2]); matrix_eltype=Float64),
(A, B)
)
end