Open-source project
SciML/EasyModelAnalysis.jl avatar
SciML/EasyModelAnalysis.jl

EasyModelAnalysis.jl: One-Liner Queries Over SciML Differential Equation Models

High level functions for analyzing the output of simulations

87 stars14 forksJuliaMIT

At a glance

What is it?
EasyModelAnalysis.jl wraps SciML simulation output in high level query functions, so questions like first crossing times, parameter fitting and sensitivity analysis become single calls on an ODEProblem. It is a convenience layer, and the convenience has boundaries.
Who is it for?
Adopt EasyModelAnalysis.jl if you already build models with ModelingToolkit and DifferentialEquations and want common analysis questions answered without writing the surrounding loop yourself. Do not adopt it if you need a documented list of every supported query or a stable API you can pin against, because the README points to the documentation site for usage and the repository does not enumerate the query surface.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Julia, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The question EasyModelAnalysis.jl answers before you write a loop

Most simulation work ends with a solved trajectory and a question about it. When does the infected count first pass 1000? What is the probability that more than 50 individuals are infected when the parameters are distributions rather than numbers? Which variables move most when the parameters move? Which parameter values make the model match observed data? The README lists these four as the motivating examples, and each one normally costs a script: solve, scan the solution, interpolate, repeat inside a sampling loop, collect statistics.

EasyModelAnalysis.jl is aimed at people who already define models in the SciML stack. The README describes its output as "simple one-liner queries over SciML-defined differential equation models", which is a statement about the interface, not about the underlying math. The package does not replace DifferentialEquations.jl or ModelingToolkit.jl; it sits on top of a model you built with them. If your model lives in another ecosystem, or if your analysis is a one-off that you will never repeat, the wrapper adds a dependency without removing much work.

What the query layer actually sits on

The demonstration in the README builds a standard ModelingToolkit system: parameters are declared with @parameters, state variables with @variables, derivatives with Differential(t), and the equations are collected into an ODESystem. That system is passed through structural_simplify, initial conditions and parameter values are supplied as pairs, and the result is an ODEProblem with the jac = true option. The two calls at the end of the example take that problem object directly:

julia
phaseplot_extrema(prob, x, (x, y))
plot_extrema(prob, x)

The first argument is always the problem, and the remaining arguments name the variables of interest. That signature tells you what the design assumes: the analysis functions expect a fully specified problem, so the model, the initial conditions, the parameter values and the time span have already been decided before any query runs. The name extrema in both calls indicates that the functions report the extremes of a variable over the trajectory rather than the trajectory itself, and the phaseplot variant places those extrema in a two-variable plane. Because the input is a problem object rather than a raw solution array, the package can re-solve when a query needs a different sampling of the parameter space, which is what makes probability and sensitivity questions expressible as single calls.

The README does not describe the internal solver choices, the sampling algorithm behind the probability queries, or how the fitting routines optimize. Anyone who needs to defend those choices in a methods section has to read the source under src/ or the documentation, not the README.

Installing EasyModelAnalysis.jl and running the README example

The package is registered in the Julia General registry, so installation goes through the package manager. The README does not print an install line, but its quick demonstration starts by importing the package alongside the other libraries it uses, which is the practical dependency set for the example to run.

julia
using DifferentialEquations, EasyModelAnalysis, ModelingToolkit, Plots

After adding it, the quick demonstration from the README is the shortest real use. This block declares the Lorenz system and simplifies it.

julia
@parameters t σ ρ β
@variables x(t) y(t) z(t)
D = Differential(t)

eqs = [D(D(x)) ~ σ * (y - x),
    D(y) ~ x * (ρ - z) - y,
    D(z) ~ x * y - β * z]

@named sys = ODESystem(eqs)
sys = structural_simplify(sys)

The second half supplies the numbers and builds the problem. Note that the initial condition for the derivative of x is given as a pair, D(x) => 2.0, which is how the README handles a second order equation before simplification.

julia
u0 = [D(x) => 2.0,
    x => 1.0,
    y => 0.0,
    z => 0.0]

p = [σ => 28.0,
    ρ => 10.0,
    β => 8 / 3]

tspan = (0.0, 100.0)
prob = ODEProblem(sys, u0, tspan, p, jac = true)

With prob in hand, the analysis calls are one line each, exactly as the README writes them.

julia
phaseplot_extrema(prob, x, (x, y))
plot_extrema(prob, x)

Running plot_extrema(prob, x) should produce a plot of the extrema of x over the time span, and phaseplot_extrema(prob, x, (x, y)) should produce the corresponding phase plane view. If the calls error instead, the first thing to check is that the variables passed as arguments are the same symbolic variables declared with @variables, not strings or indices.

Where the one-liner abstraction stops helping

The convenience comes from hiding the loop, and that is also the cost. When a query returns a number, the number is the product of a sampling or optimization procedure the caller did not specify. For a quick exploration that is fine. For a published result it is a gap: the README does not document the algorithm behind the probability query, the fitting routine, or the sensitivity measure, so reproducing a figure requires going into the documentation or the source.

There is a second boundary. Every query takes a problem, which means the model must already be expressible in ModelingToolkit and solvable by the SciML solvers. Models defined as hand-written right-hand sides outside that ecosystem, or analyses over data that was never a differential equation, have nothing for this package to attach to. The README also does not document rollback, caching behavior, or what happens when a query is repeated with modified parameters, so a workflow that depends on knowing whether a solve is reused should verify that against the source before building on it.

Finally, the release history is worth reading as a signal about API stability. The repository shows v1.0.0 in May 2024, v1.1.0 in October 2024, and v1.1.2 on 2026-06-25. The last push to the repository was on 2026-06-25. That is a small number of releases over roughly two years, which is consistent with a package that changes slowly rather than one that is churning. Slow change cuts both ways: fewer breaking upgrades, but also fewer new query types arriving quickly.

The alternative you already have installed

The honest comparison is not another analysis package but the SciML stack underneath. DifferentialEquations.jl gives you solve and the solution object with its interpolation, and you can write the scan yourself: call solve, use the solution's indexing or interpolation to find the first time a variable crosses a threshold, wrap it in a loop over sampled parameters, and collect the results. That approach costs more code but leaves every algorithmic choice visible in your own repository.

The difference in approach is where the logic lives. With EasyModelAnalysis.jl the crossing-time search, the parameter sampling and the sensitivity computation are inside the package, and you call them. With plain DifferentialEquations.jl they are in your script, and you own them. For a model you will analyze once, the script is usually shorter than learning a new interface. For a model you will interrogate repeatedly with the same four questions, the package removes the repetition, which is exactly the case the README's examples describe.

Licence, upgrades and what maintenance costs look like

The repository is MIT licensed, which permits use, modification and redistribution provided the copyright notice and permission notice are preserved. That is the most permissive common option for a Julia package and creates no copyleft obligation on code that depends on it. This is a description of the licence text, not legal advice; if the package ends up inside a distributed product, the notice requirement still applies.

Upgrade cost is low by the evidence in the release list: three releases across the period from May 2024 to June 2026, with the latest on 2026-06-25. A dependency that publishes rarely is unlikely to break your code on every Julia minor version, but it also means fixes for edge cases may sit for a while. The practical move is to pin the version in your Project.toml and treat an upgrade as a deliberate step, re-running the analysis queries whose results you depend on. Because the README does not document a deprecation policy, the release notes are the place to check what changed between v1.1.0 and v1.1.2 before bumping.

Editorial conclusion

Adopt EasyModelAnalysis.jl if you already build models with ModelingToolkit and DifferentialEquations and want common analysis questions answered without writing the surrounding loop yourself. Do not adopt it if you need a documented list of every supported query or a stable API you can pin against, because the README points to the documentation site for usage and the repository does not enumerate the query surface. Before relying on it, open the stable documentation linked from the README, confirm the query you need exists there, and check whether the answer you get is computed from a fresh solve or from a cached solution.

Frequently asked questions

What is EasyModelAnalysis.jl used for?

It provides high level query functions over SciML-defined differential equation models, so questions like the first time a variable reaches a threshold, the probability of an outcome given parameter distributions, sensitivity of variables, and parameter fitting are expressed as one-liner calls. The README frames it as making model analysis easy over models built with DifferentialEquations and ModelingToolkit.

How do I install EasyModelAnalysis.jl?

It is a registered Julia package, so it installs through the package manager with Pkg.add("EasyModelAnalysis"). The README does not print an install command, but its demonstration imports the package together with DifferentialEquations, ModelingToolkit and Plots.

What kind of object do the EasyModelAnalysis.jl query functions take?

They take a fully specified ODEProblem, as shown in the README where prob is built from a structurally simplified ODESystem with initial conditions, parameters, a time span and jac = true. The analysis calls then pass that problem plus the symbolic variables of interest.

Does EasyModelAnalysis.jl work with models not written in ModelingToolkit?

The README only demonstrates queries over a ModelingToolkit ODESystem turned into an ODEProblem, and describes the functions as queries over SciML-defined differential equation models. No support for models outside that representation appears in the README.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sciml-easymodelanalysis-jl.svg)](https://hysenlabs.com/projects/sciml-easymodelanalysis-jl)
Community notes

Community notes