Library / SDK
SALib/SALib avatar
SALib/SALib

SALib: a library of global sensitivity analysis methods, all behind one problem dict

Sensitivity Analysis Library in Python. Contains Sobol, Morris, FAST, and other methods.

1,021 stars275 forksPythonMIT

At a glance

What is it?
SALib is a Python library of implementations of commonly used sensitivity analysis methods, from Sobol and Morris through FAST, PAWN, DGSM, Shapley effects, HDMR, and fractional factorial, useful in systems modelling to calculate the effects of model inputs or exogenous factors on outputs of interest. It also has a newer method chaining API built around a ProblemSpec object.
Who is it for?
SALib fits a modeller who needs to know which inputs actually drive an output, and who wants several published methods side by side rather than one homegrown estimator, especially a team already comfortable with the Saltelli sampling scheme. It is the wrong choice for a single-factor-at-a-time screening exercise, where the method list is overkill, and the wrong choice if you need a method SALib does not implement.
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 5 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

Twelve methods, one interface

SALib is a library of Python implementations of commonly used sensitivity analysis methods, useful in systems modelling to calculate the effects of model inputs or exogenous factors on outputs of interest.

The method list is long and it is the real content of the library. Sobol sensitivity analysis, following Sobol 2001, Saltelli 2002, and Saltelli et al. 2010. The Method of Morris, including groups and optimal trajectories, following Morris 1991 and Ruano et al. 2012. Radial OAT, from Campolongo and colleagues. The extended Fourier Amplitude Sensitivity Test, eFAST, from Cukier et al. 1973 and Saltelli et al. 1999, with Pujol 2006 in Iooss et al. 2021. Random Balance Designs and Fourier Amplitude Sensitivity Test, RBD-FAST, from Tarantola et al. 2006, Plischke 2010, and Tissot et al. 2012. The Delta Moment-Independent Measure from Borgonovo 2007 and Plischke et al. 2013. The Derivative-based Global Sensitivity Measure, DGSM, from Sobol and Kucherenko 2009. Shapley Effects from Goda 2021. Fractional Factorial Sensitivity Analysis from Saltelli et al. 2008. High-Dimensional Model Representation, HDMR, from Rabitz et al. 1999 and Li et al. 2010. PAWN from Pianosi and Wagener 2018 and 2015. And Regional Sensitivity Analysis, based on Hornberger and Spear 1981, with Saltelli et al. 2008 and Pianosi et al. 2016.

Each of those entries carries its own citations, which tells you something about the project. A sensitivity analysis method is not a generic algorithm, it is a specific estimator with a specific paper, a specific set of assumptions, and a specific known behaviour on your kind of model. Publishing the references next to the implementation is what turns a list of functions into something you can choose between, and it is why the library is usable by someone who does not already know which method to use.

The library also carries a JOSS paper, listed in the topics, and the citation instructions in the project summary ask you to cite the JOSS paper and a 2022 paper about accessibility and interpretability of global sensitivity analyses.

The dependencies are numpy 2.0 or newer, scipy 1.9.3 or newer, matplotlib 3.5 or newer, pandas 2.0 or newer, and multiprocess, with an optional distributed extra pulling in pathos 0.3.2 or newer.

The problem dict is the contract between you and the library

Every method in SALib takes the same two things, a problem definition and the model outputs. The problem is a dict, and the quick start shows its shape:

python
from SALib.sample import saltelli
from SALib.analyze import sobol
from SALib.test_functions import Ishigami
import numpy as np

problem = {
  'num_vars': 3,
  'names': ['x1', 'x2', 'x3'],
  'bounds': [[-np.pi, np.pi]]*3
}

# Generate samples
param_values = saltelli.sample(problem, 1024)

# Run model (example)
Y = Ishigami.evaluate(param_values)

# Perform analysis
Si = sobol.analyze(problem, Y, print_to_console=True)
# Returns a dictionary with keys 'S1', 'S1_conf', 'ST', and 'ST_conf'
# (first and total-order indices with bootstrap confidence intervals)

Three keys, and the third is the one that matters most. `num_vars` is the number of inputs, `names` labels them, and `bounds` is a list of lower and upper pairs. A bound of `[-np.pi, np.pi]` repeated three times is the Ishigami function's domain, and the Ishigami test function is a standard benchmark with a known answer, which is why the library ships it as a test function.

The split into `sample` and `analyze` is the structural decision. Sampling and analysis are separate steps with separate namespaces, `SALib.sample` and `SALib.analyze`, and the sample step is method-specific while the analysis step is method-specific too. That is what lets you swap methods, and it is also what lets you re-analyse the same sample set with a different estimator without re-running the model, which for an expensive simulation is the difference between an hour and a day.

The `analyze` result is a dict of the indices and their confidence intervals. The Sobol keys are `S1`, `S1_conf`, `ST`, and `ST_conf`, the first-order and total-order indices with bootstrap confidence intervals. And the model itself is called with the whole array of parameter sets at once, `Ishigami.evaluate(param_values)`, so your model is expected to be vectorised.

That last point is the requirement most people miss. The sampling step generates thousands of parameter sets, and the model is evaluated on all of them in one call. A model that takes a single parameter set and cannot be batched will not work here without a wrapper.

Parameter files and a command line interface

The problem dict is not the only way to define a problem. It is also possible to specify the parameter bounds in a file with three columns:

code
# name lower_bound upper_bound
P1 0.0 1.0
P2 0.0 5.0
...etc.

And then the `problem` dictionary above can be created from the `read_param_file` function:

python
from SALib.util import read_param_file
problem = read_param_file('/path/to/file.txt')

The file format is a header line naming the three columns, then one row per parameter with a name and the two bounds. The names in the file are the same names you would have put in the `names` key, and the bounds are the same pairs, so the two routes produce an identical problem dict. That is a useful property, because a study with a dozen parameters is much easier to keep in a file than in a literal, and a file can be diffed and reviewed.

Lots of other options are included for parameter files, and there is also a command-line interface, with the advanced section in the documentation for more. The command line entry point is registered in the project metadata as `salib = SALib.scripts.salib:main`, so the tool is usable from a shell as well as from Python.

The documentation also has a FAQ and an `examples` directory for a full description of options for each method, and the examples directory in the tree is organised by method, with `examples/sobol/`, `examples/morris/`, `examples/fast/`, `examples/ff/`, `examples/rbd_fast/`, `examples/radial/`, `examples/delta/`, `examples/delta_mwe/`, `examples/dgsm/`, `examples/pawn/`, `examples/hdmr/`, `examples/enhanced_hdmr/`, `examples/shapley/`, `examples/plotting/`, `examples/Problem/`, and `examples/data/`.

The `examples/Problem/` directory is worth noting separately, because it means the newer ProblemSpec interface has its own examples, alongside a data directory for the case where you are loading model outputs rather than computing them.

Method chaining, and the ProblemSpec object

Since SALib v1.4 there is a second way to use the library, and it is the one the project is steering toward.

Chaining calls is supported from SALib v1.4, and the form is:

python
from SALib import ProblemSpec
from SALib.test_functions import Ishigami

import numpy as np


# By convention, we assign to "sp" (for "SALib Problem")
sp = ProblemSpec({
  'names': ['x1', 'x2', 'x3'],   # Name of each parameter
  'bounds': [[-np.pi, np.pi]]*3,  # bounds of each parameter
  'outputs': ['Y']               # name of outputs in expected order
})

(sp.sample_saltelli(1024, calc_second_order=True)
   .evaluate(Ishigami.evaluate)
   .analyze_sobol(print_to_console=True))

print(sp)

# Samples, model results and analyses can be extracted:
print(sp.samples)
print(sp.results)
print(sp.analysis)

# Basic plotting functionality is also provided
sp.plot()

The above is equivalent to the procedural approach shown previously, and the equivalence is the point. The difference is that the problem, the samples, the model results, and the analysis all live on one object, and the steps are methods on it rather than free functions with arguments threaded through.

The `ProblemSpec` constructor takes the problem dict with one addition, the `outputs` key, which names the outputs in the expected order. That is information the procedural API has no place for, because in the procedural version the output array is just an array. With the object API, the same problem can have several named outputs and the analysis knows which is which.

The `evaluate` step takes a callable, so the model is a function rather than an array you computed yourself, and the object calls it with the samples. The `calc_second_order=True` flag on the Saltelli sampler asks for the second-order indices as well as the first and total order ones, which is a sampling choice that costs extra model evaluations and buys the interaction terms.

And then there is `sp.plot()`, which is the feature the object API makes easy. Basic plotting functionality is provided, and because the object knows the problem, the samples, and the results, it can plot them together without you assembling the figure yourself.

The `print(sp)` call and the `sp.samples`, `sp.results`, and `sp.analysis` accessors are what make the object introspectable, which matters when a run takes a long time and you want to inspect the intermediate state rather than re-run it.

Packaging, distribution, and the road to 2.0

The packaging has moved to a modern stack, and the details are worth knowing if you are pinning versions.

The build backend is hatchling with hatch-vcs, so the version comes from the version control system rather than being written in the file. The Python floor is 3.10, and the classifiers list 3.10, 3.11, 3.12, and 3.14, which is a curious gap. The dependency floors are current, with numpy 2.0 or newer and pandas 2.0 or newer, so this version of SALib will not install into an environment still on numpy 1.x.

The `distributed` extra with pathos is how you run a model evaluation across processes, which matters when the model is slow enough that the sampling is not the bottleneck.

The project metadata describes SALib as tools for global sensitivity analysis containing the Sobol, Morris, FAST, DGSM, PAWN, HDMR, Moment Independent, and fractional factorial methods, and the licence is MIT with a Development Status of 5, Production/Stable.

The release history shows the recent work. v1.5.2 is from 2025-10-12, and before that v1.4.7 from 2023-01-08 and v1.4.6.1 from 2022-10-17. So there was a long period at 1.4.x, then a burst of 1.5.x releases, and the last push to the repository was on 2026-10-11, so the work is current.

The citation instructions point at two papers, the 2017 JOSS paper describing SALib as an open-source Python library for sensitivity analysis, and the 2022 paper titled Toward SALib 2.0, which is about advancing the accessibility and interpretability of global sensitivity analyses. That paper is a good description of the trajectory, since the 2.0 goal is not new methods but making the existing ones easier to reach and easier to understand, and the ProblemSpec chain and the CLI are both part of that.

The repository root is thorough about the surrounding material. There is a `CITATION.cff` for GitHub's citation feature, a `CITATIONS.rst` with the full method references, an `AUTHORS.rst`, a `FAQ.md`, a `paper/` directory, a `CHANGELOG.md`, and a `zenodo.json` for a DOI on the archive. There is a `README-advanced.md` alongside the main `README.rst`, which is where the detailed options live.

The build scripts directory in the metadata registers the `salib` console script, and the package uses a src layout with the `src/` directory at the root.

Where SALib is the wrong tool

The limits are about method choice and about what the library assumes, and they are worth stating before you adopt it for the wrong question.

First, all of these are global methods, and global methods are expensive. A Sobol analysis with second-order terms on a model with twenty inputs needs sample counts in the tens of thousands, and the model evaluation is on your budget, not the library's. The library does the sampling and the analysis, and it does not make your model cheap. For a screening question, where you want to know which of fifty inputs might matter at all, a variance-based screening method or a simple one-at-a-time sweep is the right instrument, and a global method is a way to spend a cluster's worth of compute on a question that a cheaper method answers adequately.

Second, the choice between methods is not made for you, and the methods are not interchangeable. FAST and eFAST need the inputs to be independent. Sobol indices need a specific sampling scheme. The regional sensitivity analysis method is built on a model-splitting idea that assumes a particular model structure. The Moment-Independent measure is a density-based alternative designed for cases where the model is not well approximated by a linear expansion. Picking one because it is first in the list is a common and expensive mistake, and the library's design, one entry point per method with a paper reference, is the right structure precisely because the choice matters.

Third, the library assumes your model can be evaluated on a batch. The sampling step produces a large array of parameter sets and hands them to the model in one call. A model that has side effects, that is slow to start, that writes to disk, or that is not safe to run in parallel will not slot into that, and the distributed extra exists precisely because the parallel case is common enough to need a path.

Fourth, the method list is not everything. There is no method here for a model with categorical inputs, and no method for correlated inputs except the regional one. If your problem has those features, the right implementation may be outside this library.

Fifth, the version story has been a little untidy. The 1.4.x line sat for years, the 1.5.x line came, the dependency floors moved to numpy 2.0 and pandas 2.0 in the process, and the 2.0 project the citation points at is still ahead. A team that pinned SALib years ago and wants to move forward is crossing a numpy 2.0 boundary at the same time, which is a bigger change than the SALib version bump suggests.

Sixth, and this is the one that catches people out, the confidence intervals are bootstrap estimates on a finite sample, and the accuracy of a Sobol index depends on the sample size in a way that is not obvious from the output. Two runs with different sample sizes give different intervals, and a narrow interval from an under-sampled run is still narrow. The library gives you the machinery to check this, since you can re-analyse the same samples with a different estimator, but the discipline of varying the sample size and checking the stability of the index is on you.

Editorial conclusion

SALib fits a modeller who needs to know which inputs actually drive an output, and who wants several published methods side by side rather than one homegrown estimator, especially a team already comfortable with the Saltelli sampling scheme. It is the wrong choice for a single-factor-at-a-time screening exercise, where the method list is overkill, and the wrong choice if you need a method SALib does not implement. Check three things before you rely on it: that your Python is 3.10 or newer with numpy 2.0 or newer, since the dependency floors have moved, that your model can be evaluated on a batch of parameter sets, since the whole design assumes vectorised evaluation, and that you pick a method appropriate to your sample budget, because the methods differ enormously in how many model evaluations they need.

Frequently asked questions

What is SALib and which methods does it implement?

SALib is a Python library of implementations of commonly used sensitivity analysis methods, useful in systems modelling to calculate the effects of model inputs or exogenous factors on outputs of interest. The methods include Sobol, Method of Morris, radial OAT, eFAST, RBD-FAST, the Delta Moment-Independent Measure, DGSM, Shapley Effects, fractional factorial, HDMR, PAWN, and regional sensitivity analysis.

How do I run a Sobol sensitivity analysis with SALib?

Define a problem dict with `num_vars`, `names`, and `bounds`, generate samples with `saltelli.sample(problem, 1024)`, evaluate your model on the whole sample array at once, and pass the results to `sobol.analyze(problem, Y)`, which returns a dict with the `S1`, `S1_conf`, `ST`, and `ST_conf` keys, the first-order and total-order indices with bootstrap confidence intervals.

What is ProblemSpec in SALib and how does it differ from the procedural API?

ProblemSpec is the object-based API available since SALib v1.4, and it is equivalent to the procedural approach. The problem, samples, results, and analysis all live on one object, the steps are methods that chain, the model is passed as a callable to `evaluate`, and you can inspect `sp.samples`, `sp.results`, and `sp.analysis` or call `sp.plot()` for basic plotting.

Can SALib read parameter bounds from a file?

Yes. You can specify the bounds in a file with three columns, a name, a lower bound, and an upper bound, and build the problem dict with `read_param_file` from `SALib.util`. There are many more options for parameter files, and the library also ships a command-line interface registered as the `salib` script.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. SALib/SALib on GitHub
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/salib-salib.svg)](https://hysenlabs.com/projects/salib-salib)

Was this useful?