# What is simulation-based inference? Many scientific models are simulators. A cognitive model of decision making, an epidemiological model of an outbreak, or a biophysical model of a neuron takes parameters $\theta$ and generates synthetic data $x$. Running such a model forward is the cheap direction. The scientific question runs the other way: given observed data, which parameters are plausible? Bayesian inference answers that question with a posterior distribution $p(\theta \mid x)$. Bayes' theorem assembles it from two ingredients: a prior $p(\theta)$, what is known about the parameters before seeing the data, and the likelihood $p(x \mid \theta)$, the probability of an observation for a given set of parameters: $$ p(\theta \mid x) \propto p(x \mid \theta)\, p(\theta). $$ Probabilistic programming languages ({term}`PPL`s) such as [PyMC](https://www.pymc.io/) and [NumPyro](https://num.pyro.ai/) automate this recipe: the model is written as priors plus a likelihood, and the PPL draws posterior samples, typically with MCMC. Their own introductions cover that workflow in depth ([PyMC](https://www.pymc.io/projects/docs/en/stable/learn.html), [NumPyro](https://num.pyro.ai/en/stable/getting_started.html)). The catch is that a PPL needs the likelihood as an expression it can evaluate: for any candidate $\theta$, it must be able to ask "how probable is the observed data here?". A simulator does not answer that question. It generates $x$ from $\theta$, but the probability of any particular observation stays implicit in the simulator's internal randomness, and computing it would mean summing over every internal path that could have produced that observation. This is the intractable likelihood problem, and it keeps simulators out of PPLs. ## The idea behind SBI Simulation-based inference (SBI) turns the simulator's one strength, generating data, into the solution. Running the simulator many times at many parameter settings produces a training set of pairs $(\theta, x)$, and a neural network trained on those pairs can approximate the quantity the simulator never provided. Different SBI methods approximate different quantities. setu implements the likelihood-targeting family: - {term}`NLE` learns the conditional density $p(x \mid \theta)$ with a normalizing flow. - {term}`DiscreteNLE` targets pure-discrete observables, such as survival counts, with a categorical or count likelihood. - {term}`MixedNLE` extends NLE to genuinely mixed discrete and continuous data, such as choices paired with reaction times. - {term}`NRE` learns a likelihood-to-evidence ratio with a classifier, which serves the same role up to a constant. Targeting the likelihood, rather than the posterior directly, is a deliberate choice: a learned likelihood slots into a PPL model as one term among many, so the prior, the hierarchical structure, and the posterior-predictive checks stay in PyMC or NumPyro. The trained {term}`estimator` is also {term}`amortized`: trained once, it is reused across observations and across PPLs without retraining. ## The four-phase workflow Every setu analysis follows the same four phases: {term}`Simulate → Train → Validate → Export`. ### Simulate Draw parameters from a prior (or a broader proposal distribution) and run the simulator at each draw to build the training set of $(\theta, x)$ pairs. Per-trial covariates enter here as {term}`conditions`, so one estimator can cover an entire experimental design. Coverage matters: the estimator is only trustworthy in the region of parameter space it was trained on, so the proposal should comfortably contain every parameter value the analysis might visit. ### Train Fit the estimator to the simulated pairs by maximizing the probability the network assigns to the simulated data. Training is plain supervised learning in JAX; no PPL and no MCMC are involved yet, and the result is an immutable estimator object. ### Validate A converged loss does not make a network trustworthy. Validation is therefore a first-class phase, before any MCMC: `validate_estimator` runs a battery of diagnostics, including {term}`C2ST` (can a classifier tell estimator samples from simulator samples?) and a likelihood-level {term}`SBC` rank check. A check that lights up is a workflow signal, not a dead end: retrain with more simulations or an adjusted architecture, then re-check. ### Export One call turns the validated estimator into a likelihood term inside the PPL: ```python import pymc as pm from setu.integration.pymc import to_pymc with pm.Model(): theta = pm.Normal("theta", mu=0.0, sigma=1.0, shape=3) to_pymc(nle, theta=theta, x_observed=x_obs) ``` From here the model is ordinary PyMC or NumPyro: priors can be changed, hierarchy added, posterior-predictive checks run, all against a simulator that previously had no likelihood to offer. ## When to use setu Naming setu's niche also means naming where other tools fit better. setu is for one combination: repeated or hierarchical structure in the data (trials, subjects, groups) together with a likelihood that is intractable, so the model cannot go into a PPL directly. In practice that covers a hierarchical or trial-based simulator with no tractable likelihood; a PyMC or NumPyro model gaining a simulator component that removes its tractable likelihood; and an SBI analysis held back by hierarchical structure or slow sampling, where gradient-based sampling inside a PPL would help. Two adjacent cases are better served elsewhere. With a tractable likelihood, a PPL alone (PyMC, NumPyro, Stan) is enough, because there is no likelihood to learn. With high-dimensional observations and no repeated or hierarchical structure, a general SBI toolkit such as [sbi](https://sbi-dev.github.io/sbi/) or [BayesFlow](https://bayesflow.org/) is the natural fit: setu's advantage comes from exploiting trial structure and compiling the learned likelihood into a PPL's fast, gradient-based sampler, which those problems do not exercise. setu complements both families rather than replacing them. ## Where to go next The [tutorials](../tutorials/index) walk this workflow end to end on concrete problems. The [install guide](../how-to/install) lists the extras for each PPL backend. The [shape conventions](../reference/shapes) and the [glossary](../reference/glossary) in Reference pin down the notation used throughout.