StructuralIdentifiability.jl for more complicated systems

Hi all, I am looking at StructuralIdentifiability.jl along with ModelingToolkit.jl to see what I can do with it. Ideally, I would use it to first find out which parameters in my models are actually identifiable, and then estimate the parameters by fitting to test data. Models in questions are of things like engines and thermal fluid systems.

It seems that only ODE where the right hand side of x_dot = f(x) can be written as a rational function of the variables are supported-- p(x) / q(x) where p and q are polynomials of the variables x.

So it seems like functions like sin(), cos() and so on are out. For example this toy model for the flight of a cannonball can’t be analyzed for identifiability, unless the dynamics are linearized, which kind of defeats the purpose.

using StructuralIdentifiability
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D

vars = @variables begin
    x(t),
    y(t),
    v(t),
    γ(t),
    Drag(t)
end
pars = @parameters begin
    g = 9.80665
    ρ = 1.225
    m = 100
    Cd = 1.0
    A = 0.1
end

# Flight path equations of motion. Doesn't work
eqs = [
    Drag ~ -0.5 * ρ * v^2 * A * Cd,
    D(v) ~ Drag / m - g * sin(γ),
    D(γ) ~ -g * cos(γ) / v,
    D(y) ~ v * sin(γ),
    D(x) ~ v * cos(γ),
]

# # Works
# eqs = [
#     Drag ~ -0.5 * ρ * v^2 * A * Cd,
#     D(v) ~ Drag / m - g * γ,
#     D(γ) ~ -g * (1 - γ^2) / v,
#     D(y) ~ v * γ,
#     D(x) ~ v * (1 - γ^2),
# ]

@named _sys = System(eqs, t, vars, pars)
cannonball = mtkcompile(_sys)

u0 = [x => 0, y => 0, γ => deg2rad(45), v => 100]
prob = ODEProblem(cannonball, u0, (0, 10))

sol = solve(prob)
assess_identifiability(cannonball, known_ic=[x, y, γ, v])

The systems I would like to analyze are far more complicated than this, with plenty of thermodynamic state interpolations, square root functions, and conditional clauses, which all seem like things that wouldn’t be compatible with the rational function requirement.

I’m curious to know if there might be other approaches I am missing, or if what I am trying to do is beyond the state of the art.

Hi @mark.garnett ,

StructuralIdentifiability.jl supports only rational functions. One might be able to rewrite the model into rational form, but it’s tricky: Rationalizing input model · Issue #144 · SciML/StructuralIdentifiability.jl.

If you can, feel free to share your model, and we will have a look (in the linked issue or at demin@lix.polytechnique.fr).

In theory, an analogue of the Sedoglavic algorithm (https://doi.org/10.1006/jsco.2002.0532) could be helpful for such analysis, but I don’t know of there exist such implementations.

For more general models you could use sensitivity analysis to look at of the sensitivity of the model output to certain parameters, something like GlobalSensitivity.jl. That should give you an idea of which parameters affect your model the most.

In Pohjanpalo’s 1978 paper, the basic idea was that the output y(t) (as well as input u(t)) and all its derivatives are known from experimental data. So by using the chain rule on y(x,u) and inserting the model equation, relations between known y(t), u(t), and derivatives, and parameters are found. In this process, x(0) can be included in the list of unknown parameters. The “problem” with the approach is that it is difficult to know who how many terms in the Taylor series one needs to include in order to find a conclusive answer.

Was it Eduardo Sonntag who extended on this and introduced Lie derivatives for a formulation that is more usable in computer automation? Ljung and Glad used Maple (I think) with differential algebra to rewrite the model into a parameter-linear form (or: linear in identifiable parameter groups).


One of my PhD students used these ideas for a micro co-generator model with 10-11 states (or so). He finished in 2024, so relatively recent work. He started his work prior to Julia and StructuralIdentifiablity.jl, and used a combination of Matlab and Python (combination, because both had flawed tools that made it impossible to use a single tool).

An alternative idea (“practical identifiability”, work by Brun et al., ca. 2000?) is to compute sensitivity matrices, and look at when the sensitivities loose rank. The idea is that in a least squares formulation, the Hessian then becomes singular. If course, if the least squares problem has been regularized by adding the square of the parameter vector, this method fails because then the Hessian by design is non-singular.

It may be tempting to use MCMC methods to check identifiability, but then care must be shown: the prior functions as regularization (I think), so this only works if the variance of the prior is made to go to infinity.

Thank you very much for your replies @sumiya11 @jClugstor @BLI .

I am thinking that then using StructuralIdentifiability.jl will be far to big a task, or practically impossible, to make things in rational form that is faithful to the original model.

GlobalSensitivity.jl does indeed look useful-- it answers the question “what’s the uncertainty in my simulation output given the uncertainty in my parameter values” which is good to know. I suppose what I am trying to do is the inverse-- “given this test data which we know to be true, what would be the uncertainties in my parameter values?”

@BLI your suggestion to look into “practical identifiability” is good-- there seem to be a lot there, including some youtube videos from conference.

I suppose what you are saying is, I have my loss function
L(y_data, y_sim, params)=sum((y_data .- y_sim(params)).^2)/N_points

where y_data is test data, y_sim is the output of simulation, params are parameters

Find the Hessian of L wrt params, numerically, at the values of params where L is minimized. If determinant(L) is very small, then the Hessian matrix is singular or close to it then the parameters are not identifiable-- meaning there is some other value of params that will also minimize L. L should not have a regularization term otherwise it will never be singular, giving you a false answer on identifiability.

It seems like LikelihoodProfiler.jl might be something to look at as well

A group of my students tried to use the Brun et al. method on a waste water plant way back, see https://www.mic-journal.no/PDF/2006/MIC-2006-4-2.pdf . This paper contains references to a few works at the time.

A later PhD student did a more thorough study, [https://nva-resource-storage-755923822223.s3.eu-west-1.amazonaws.com/0c5e7407-3d26-413b-8e0c-974e9c946a58?response-content-type=application%2Fpdf&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEAEaCWV1LXdlc3QtMSJGMEQCIB8jIAWgE0Rr%2BfJyQh7l%2F5b79ZvIly6tsC%2BbIam10XG4AiAol508fzbmLxVWLZO9CnN7UprIQKNLHJ%2B%2FAmWmXjY2%2Fyr5BAjK%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAMaDDc1NTkyMzgyMjIyMyIMsvSoQPm8sqD9QA14Ks0EYcmP23z%2BchVnQk17egDCNpucsWEa1iKWTHC1a9R0dMpkRpOO9wD7V8xFBUE5%2BTiNvvw2QKg9LFfdk6FDwu6JbqBYJK9qrRBMP22ubVYrv39mXeLPMPMOGekajyu%2Bsj0X5rSf5G3QiOWiw64C68mNlqXD9FrF47BVuudu7PXjTligql8f0lOKMSq3%2BkCJ8zfR1guIr7fZc6PXTd1LxznKPjJSZb4dd19Cg1oEbAXeMAViykgqytDFz19pxHZEfd7PAPPprSJFeALLsK0criOpcCWnksGbye%2Bq16bEfCfbTl68qJyFk3PlWnkPuHDKY9dQ%2FEu7knONQlY%2BRUnkTv1D%2B9%2Fbxvu65XReHSTla8ipO2FQgWfGGYIxY7CJiMiAHhpjWcagwhEWohokBhURplJyVZOm%2Frn0J3CwT29uL17oYuj%2FDjwyf%2Brq45cso3ZKIz%2Bm%2F4XWOY76amDkWcuyaVPeWFQBY2lYCBpW4yXLhuRbCoTfTl59DssmZcoCONSnaLDtwFcxxny%2F5FApS67M0k4XVgNk1ilifFVJ3SZ4ylqFK3bqfNYWDB0L%2BIXu1ArJFxGynNnlqfxOWo%2FWv3oauxYdFF%2FucKjT4m1Bp%2F5r8wA%2FxR55Saj%2BQ5QGS3vLiEljZhQYn0SpwakVL0XkRjzbSkZriqaQMEZ8ENeI7WIMXShB9CFfb%2BAqdUIh8%2Bqi2FMH4ryLRF5%2BaAQsYGmmUxjFYrx5QFow7bO62W7eieigM7%2FZUubs0nFeaz25LSIwa5YTRXdIaDYoqk2kVXxh%2Bb%2BJ4zDKm5%2FRBjqkAcG0lT854%2BuM2KPDgpIE3QEE6CcPfC7llpRmt%2FxUijx6Jb55Vo5mW9mh3umBGKnQPc%2FA61%2Fz443p5rDitHieaQRDGd3WDVvgJaaYtZ%2BWc379LuSWi%2BtRlU6S9LQiwop2BTXVYFzdJ9KZX8odEkFDvAQD0rPtoIWOusdRO1MbSdBrkUaE0NY%2BHIxTOuiW%2F5POycOGNPrpNc74Y8Erpxzr514Bdi8r&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20260609T093443Z&X-Amz-SignedHeaders=host&X-Amz-Credential=ASIA3AAESE2H7K6I5ZOO%2F20260609%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Expires=600&X-Amz-Signature=6f5fd1eeb66f27887fc7f7e6ed4d7639f6a5d874267d577d19325cfcb0dcec41]