Morris Elementary Effects Method

Introduction
Say you've built a model with fifteen inputs. Which ones actually matter? Testing all fifteen properly, the rigorous way, could take thousands of runs. The Morris Elementary Effects Method gets you a trustworthy first answer in a few dozen.
It nudges one input at a time, watches how much the output jumps, and repeats that walk a handful of times from different starting points. From those jumps alone, it sorts every input into three honest buckets: doesn't matter, matters simply, or matters in a complicated way tangled up with other inputs. That's the whole method-no heavy machinery, no hidden assumptions, just a smart way to spend a small number of model runs well.
What Is the Morris Method?
Picture your model as a black box: you feed it a set of input values, it hands back one number. The Morris Method, introduced by Max Morris in 1991, changes one input at a time by a fixed step and records how much the output moves. Do that a few times per input, across a few different starting points, and two simple statistics-mu-star and sigma-tell you almost everything you need to know for a first pass.
Mu-star is the average size of the jump an input causes-how much does the output move, on average, when this input changes? Sigma is how much that jump size varies-does this input always move the output by roughly the same amount, or does it sometimes barely move it and other times swing it wildly? An input with high mu-star and low sigma is straightforwardly important. An input with high sigma is more interesting: it's either behaving nonlinearly, or ganging up with other inputs in ways a simple picture can't capture.
When to Use It
Reach for the Morris Method the moment you have more inputs than you can afford to study properly. It's the natural first move on any model-a simulation, a forecast, an engineering calculation-before deciding where a deeper, more expensive analysis is actually worth running.
| Scenario | Model | What You're Trying to Learn |
|---|---|---|
| Climate or hydrology simulation | Dozens of physical parameters, expensive to run | Which handful of parameters is worth calibrating carefully |
| Engineering design | Structural or thermal model with many tolerances | Which tolerance actually affects the design margin |
| Epidemiological model | Disease spread vs many rate parameters | Which assumptions the projections are most sensitive to |
| Before a full Sobol analysis | Any model with more inputs than you can afford to run thousands of times | Which inputs to drop before spending the bigger sampling budget |
What You Need Before You Start
- A runnable model: something you can feed a set of input values and get one output number back, reliably, as many times as you need.
- A defined range for every input: Morris works on a grid, so each input needs a plausible minimum and maximum-usually normalized to run from 0 to 1.
- A fixed step size: how big a nudge counts as "one step" for each input-typically a few grid levels' worth of its range.
- No requirement that the model be linear, smooth, or even continuous: that's the whole point-Morris is built to survive exactly the messy, nonlinear, expensive-to-run models where more elegant methods struggle.
- A willingness to accept an approximate answer: Morris ranks inputs; it does not hand you an exact variance breakdown the way Sobol Sensitivity Analysis does.
The Idea in Plain Terms
Imagine standing at one corner of your input space-every input set to some starting value. Change just the first input by one step. The output moves by some amount; that jump, divided by the step size, is called an elementary effect for that input. Now change the second input by one step from where you are now. Record its elementary effect too. Keep going until every input has taken exactly one step. That's one trajectory-a short walk through the input space that costs you \( k + 1 \) model runs for \( k \) inputs, and hands you one elementary effect per input.
One trajectory alone isn't enough-you only got a single glimpse of each input's effect, from one particular starting point. So you repeat the whole walk from several different, randomly chosen starting points. Each walk gives you one more elementary effect per input. String them together, and every input ends up with a small handful of elementary effects, sampled from different corners of the input space. That handful is all the raw material mu-star and sigma need.
The Formula, Explained
For input \( X_i \), a single elementary effect from a trajectory is simply the change in output divided by the step size \( \Delta \):
\[ EE_i = \frac{Y(X_1, \ldots, X_i + \Delta, \ldots, X_k) - Y(X_1, \ldots, X_i, \ldots, X_k)}{\Delta} \]Collect \( r \) such elementary effects for \( X_i \)-one from each of \( r \) trajectories-and compute two summary statistics:
\[ \mu^*_i = \frac{1}{r} \sum_{j=1}^{r} \left| EE_i^{(j)} \right|, \qquad \sigma_i = \sqrt{\frac{1}{r-1} \sum_{j=1}^{r} \left( EE_i^{(j)} - \bar{EE_i} \right)^2} \]\( \mu^*_i \) (mu-star) is the mean of the absolute elementary effects-using the absolute value matters, because otherwise a genuinely important input whose effect sometimes pushes the output up and sometimes down could average out to look unimportant, which defeats the purpose of screening in the first place. \( \sigma_i \) is the ordinary standard deviation of the raw (signed) effects, capturing how much they swing from one trajectory to the next.
How the Trajectories Are Built
Each input's range is divided into a small grid, typically \( p = 4 \) or \( p = 6 \) evenly spaced levels between 0 and 1. A trajectory starts at a random grid point, then changes one input at a time-in a random order-by a fixed step \( \Delta \), until every input has moved exactly once. That produces \( k + 1 \) points and \( k \) elementary effects per trajectory, one per input.
\[ \text{Total model runs} = r \times (k + 1) \]With \( k = 10 \) inputs and \( r = 20 \) trajectories, that's only 220 runs-compare that to the thousands a full Sobol Sensitivity Analysis would need on the same model. That gap in cost is the entire reason the Morris Method exists.
Worked Example: Two Trajectories by Hand
Take a small model with three inputs on a grid of four levels \( \{0, \tfrac13, \tfrac23, 1\} \), step \( \Delta = \tfrac23 \):
\[ Y = X_1 + 2X_2 + 5X_1 X_3 \]Notice the model is built so \( X_2 \) never interacts with anything-its coefficient is fixed at 2 no matter what \( X_1 \) or \( X_3 \) are doing. \( X_1 \) and \( X_3 \), on the other hand, are locked together in the \( 5X_1X_3 \) term. Watch how the elementary effects reveal exactly that structure without being told about it in advance.
Trajectory 1: start at (0, 0, 0), move \( X_1 \), then \( X_2 \), then \( X_3 \)
| Step | Point \( (X_1, X_2, X_3) \) | \( Y \) |
|---|---|---|
| Start | (0, 0, 0) | 0.000 |
| Move \( X_1 \) | (0.667, 0, 0) | 0.667 |
| Move \( X_2 \) | (0.667, 0.667, 0) | 2.000 |
| Move \( X_3 \) | (0.667, 0.667, 0.667) | 4.222 |
Dividing each output jump by \( \Delta = 0.667 \):
\[ EE_1^{(1)} = \frac{0.667 - 0.000}{0.667} = 1.000, \quad EE_2^{(1)} = \frac{2.000 - 0.667}{0.667} = 2.000, \quad EE_3^{(1)} = \frac{4.222 - 2.000}{0.667} = 3.333 \]Trajectory 2: start at (0.333, 0.333, 0), move \( X_3 \), then \( X_1 \), then \( X_2 \)
| Step | Point \( (X_1, X_2, X_3) \) | \( Y \) |
|---|---|---|
| Start | (0.333, 0.333, 0) | 1.000 |
| Move \( X_3 \) | (0.333, 0.333, 0.667) | 2.111 |
| Move \( X_1 \) | (1.000, 0.333, 0.667) | 4.556 |
| Move \( X_2 \) | (1.000, 1.000, 0.667) | 6.556 |
Putting the two trajectories together
| Input | Elementary effects | \( \mu^* \) | \( \sigma \) |
|---|---|---|---|
| \( X_1 \) | 1.000, 3.667 | 2.334 | 1.885 |
| \( X_2 \) | 2.000, 3.000 | 2.500 | 0.707 |
| \( X_3 \) | 3.333, 1.667 | 2.500 | 1.179 |
Even with just two trajectories, the story is already visible: \( X_1 \) and \( X_3 \)-the two inputs tangled together in the interaction term-show real spread in their elementary effects, while every input still looks broadly important by \( \mu^* \) alone. Run more trajectories (as the Python example below does, with 200), and the pattern sharpens considerably: \( X_2 \)'s elementary effect turns out to be exactly the same, every single time, so its \( \sigma \) converges to zero, while \( X_1 \) and \( X_3 \) keep showing real spread-precisely because they're the two inputs multiplied together in the model.
Python Example
SALib automates trajectory sampling and the mu-star/sigma calculation for the same three-input model, now with 200 trajectories instead of 2:
import numpy as np
from SALib.sample.morris import sample as morris_sample
from SALib.analyze.morris import analyze as morris_analyze
problem = {
'num_vars': 3,
'names': ['X1', 'X2', 'X3'],
'bounds': [[0, 1], [0, 1], [0, 1]]
}
# 200 trajectories, 4 grid levels -> 200 * (3 + 1) = 800 model runs
param_values = morris_sample(problem, N=200, num_levels=4)
Y = param_values[:, 0] + 2 * param_values[:, 1] + 5 * param_values[:, 0] * param_values[:, 2]
Si = morris_analyze(problem, param_values, Y, num_levels=4, print_to_console=False)
for name, mu_star, sigma in zip(Si['names'], Si['mu_star'], Si['sigma']):
print(f"{name}: mu* = {mu_star:.3f}, sigma = {sigma:.3f}")
Output:
X1: mu* = 3.550, sigma = 1.885
X2: mu* = 2.000, sigma = 0.000
X3: mu* = 2.558, sigma = 1.802
This confirms the story from the hand example, now with far more trajectories to make it unambiguous: X2's \( \sigma \) lands at exactly zero-it always moves the output by the same amount, no matter what the other inputs are doing-while X1 and X3 both carry substantial \( \sigma \), the fingerprint of the interaction term \( 5X_1X_3 \) they share.
Plotting Mu-Star Against Sigma
import matplotlib.pyplot as plt
plt.scatter(Si['mu_star'], Si['sigma'])
for name, mu_star, sigma in zip(Si['names'], Si['mu_star'], Si['sigma']):
plt.annotate(name, (mu_star, sigma))
plt.xlabel('mu* (overall importance)')
plt.ylabel('sigma (nonlinearity / interaction)')
plt.show()
How to Read the Mu-Star vs Sigma Plot
There's no p-value, no fixed cutoff-Morris gives you a picture, and the picture is meant to be read as a map of four rough regions:
- Bottom-left (low mu-star, low sigma): safe to ignore. These inputs barely move the output, consistently.
- Bottom-right (high mu-star, low sigma): the good news-important, and simply so. Their effect is roughly linear and doesn't depend much on the other inputs.
- Top region (high sigma), regardless of mu-star: the interesting cases. These inputs are either genuinely nonlinear on their own, or entangled with other inputs, as \( X_1 \) and \( X_3 \) were above-worth a closer look, ideally with Sobol Sensitivity Analysis.
- A rough rule of thumb: if \( \sigma_i \) is comparable in size to or larger than \( \mu^*_i \), treat that input as suspicious of interaction effects, not just plotted noise.
How Many Trajectories Do You Need?
- Start small, around \( r = 10 \): enough for a first-pass ranking on most models with a moderate number of inputs.
- Move to \( r = 20 \) to \( r = 50 \) if the ranking near the middle of the pack looks unstable, or if the decision riding on the screening result matters enough to double-check.
- Use the improved trajectory-selection approach from Campolongo et al. (2007), which picks a well-spread subset of many candidate trajectories rather than plain random ones-most modern software, including SALib, does this by default and gets better coverage for the same \( r \).
- Rerun at a higher \( r \) and check the ranking barely changes-if it does change a lot, you weren't at a stable \( r \) yet.
Advantages
- Cheap. Needs only \( r(k+1) \) model runs-often tens or a couple hundred, versus thousands for a full variance-based method.
- Works on almost anything. No requirement that the model be smooth, linear, or even differentiable-it only needs to be runnable.
- Two numbers tell a real story. Mu-star for importance, sigma for "is this simple or complicated"-together they flag interaction effects that a naive one-input-at-a-time check would miss entirely.
- Scales comfortably to many inputs, which is exactly where it's needed most-full variance-based methods become impractical fastest when the input count grows.
- A natural first step before a more expensive method, cutting the input list down to size before committing a larger sampling budget.
Limitations
- Approximate, not exact. Mu-star and sigma rank inputs; they don't hand you a precise share of output variance the way Sobol indices do.
- High sigma alone doesn't say what kind of complication is present-nonlinearity and interaction both raise sigma, and Morris on its own can't tell you which.
- Sensitive to the chosen grid and step size-too coarse a grid can blur real effects together; too fine a grid needs a larger step to still move the output meaningfully.
- Depends on decent trajectory coverage-too few trajectories can leave the ranking unstable, particularly for inputs in the middle of the pack.
- Assumes independent inputs, just like most standard sensitivity methods-strongly correlated inputs need a different approach.
When NOT to Use It
- Sobol Sensitivity Analysis: use instead when you need a precise, defensible variance breakdown-say, for a report or decision that needs to withstand scrutiny-not just a first-pass ranking.
- Local (derivative-based) sensitivity: use instead if the model is cheap and you only care about behavior right around one specific operating point, not across the whole input range.
- Correlated-input methods: use instead if your inputs are realistically correlated with each other-standard Morris, like standard Sobol, assumes independence.
- Very few inputs (say, two or three): at that scale, just run a fuller analysis directly-the screening step buys you little when there's nothing to screen out.
Morris vs Sobol vs One-at-a-Time
17.1 Morris Method vs Sobol Sensitivity Analysis
| Aspect | Morris Method | Sobol Sensitivity Analysis |
|---|---|---|
| Type of result | Qualitative ranking (mu-star, sigma) | Quantitative variance-based indices |
| Model runs needed | \( r(k+1) \)-typically tens to a few hundred | \( N(k+2) \)-typically thousands |
| Detects interactions | Flags their presence via high sigma, doesn't size them | Sizes them precisely, via total-order minus first-order indices |
| Best used as | A fast first pass to screen out unimportant inputs | The follow-up analysis on whatever survives screening |
17.2 Morris Method vs Plain One-at-a-Time Sensitivity Analysis
| Aspect | Morris Method | Plain One-at-a-Time |
|---|---|---|
| Starting points explored | Several, randomly placed across the input space | One, usually a single "baseline" point |
| Can flag interaction effects | Yes-inconsistent effects across trajectories show up as high sigma | No-a single baseline can't reveal effects that depend on other inputs |
| Cost | Moderate-several trajectories needed | Very low-one pass per input |
Common Misconceptions
- "Low mu-star always means the input is unimportant." Almost always true, but check sigma too-an input whose effect flips sign depending on context can occasionally have a middling mu-star while still being worth a second look.
- "Morris gives you the same information as Sobol, just cheaper." Not quite-Morris ranks and flags; it doesn't measure exact variance contributions the way Sobol indices do. Treat it as triage, not a final answer.
- "High sigma means the input doesn't matter." The opposite, usually-high sigma alongside a decent mu-star is often the most interesting result in the whole analysis, not the least.
- "More trajectories always means a better answer, so use as many as possible." More trajectories improve stability, but each one costs \( k+1 \) model runs-past a certain point the extra precision isn't worth it for what is meant to be a quick screening step.
- "The step size doesn't really matter." It does-too small a step and the elementary effects barely move the output at all; too large and you may jump past interesting local structure entirely.
Interview Questions
- Explain what an elementary effect is, in one sentence a non-technical colleague could understand.
- Why does mu-star use the absolute value of the elementary effects instead of their raw average?
- What does a high sigma value tell you about an input, and what does it not tell you?
- Walk through how one trajectory is built, and explain why it costs \( k+1 \) model runs for \( k \) inputs.
- Describe a situation where two inputs could each show a small mu-star individually but still matter a great deal together.
- Why is the Morris Method usually run before, rather than instead of, a full Sobol Sensitivity Analysis?
- How would you decide whether you've used enough trajectories?
- What assumption does the Morris Method share with Sobol Sensitivity Analysis regarding the inputs?
- If two inputs are highly correlated in reality, why is the standard Morris Method unreliable for them?
- A colleague has 30 inputs and a model that takes 10 minutes per run. Describe your recommended screening-to-analysis workflow.
Frequently Asked Questions
- It is a fast screening tool: run a model a modest number of times, and sort every input into "doesn't matter," "matters in a simple way," or "matters in a complicated, interacting way"-before spending real computational budget on a full sensitivity analysis of only the inputs that turned out to be worth studying.
- For each input, the method gathers a handful of elementary effects-small, measured jumps in the output caused by nudging that one input by a fixed step. Mu-star averages the absolute size of those jumps, telling you how important the input is overall. Sigma is how much those jumps vary from one part of the input space to another, telling you whether the input behaves consistently or is tangled up in nonlinearity and interactions.
- Morris is cheap and approximate-a good compass. Sobol is expensive and exact-a precise map. Morris tells you roughly where to look using a small number of model runs; Sobol tells you exactly how much variance each input and interaction explains, at a much higher computational cost. Most people run Morris first and Sobol second, on a shortened list of inputs.
- Roughly r times (k + 1) runs, where k is the number of inputs and r is the number of trajectories, usually somewhere between 10 and 50. Ten inputs and 20 trajectories comes to about 220 runs total-small enough to run even on a fairly slow simulator.
- The input's pushes and pulls on the output are large individually, but cancel out on average-sometimes increasing the output, sometimes decreasing it, depending on what the other inputs are doing at the time. That is the classic fingerprint of an input caught up in an interaction effect, and it is exactly what you would want to check further with Sobol Sensitivity Analysis rather than dismiss as unimportant.
Key Takeaways
- The Morris Method screens inputs by walking through the input space a handful of times, nudging one input at a step, and recording each resulting elementary effect.
- Two statistics summarize each input: mu-star (average size of its effect-overall importance) and sigma (how much that effect varies-a sign of nonlinearity or interaction).
- It needs only \( r(k+1) \) model runs, dramatically cheaper than the \( N(k+2) \) runs a full Sobol Sensitivity Analysis requires-making it the natural first move on any model with many inputs.
- In the worked example, \( X_2 \) (no interaction) showed \( \sigma = 0 \) exactly, while \( X_1 \) and \( X_3 \) (locked together in an interaction term) both showed real spread-precisely the pattern Morris is built to reveal.
- In Python,
SALib'smorrissampling and analysis modules handle trajectory generation and the mu-star/sigma calculation directly. - Treat Morris as triage, not a final verdict-use it to cut a long input list down to size, then study the survivors with a more precise method.
Most real models have more uncertain inputs than anyone has the budget to study properly, and the Morris Method exists precisely for that gap-a small number of well-chosen walks through the input space, two easy statistics per input, and a genuinely useful first read on where a model's behavior is coming from.
The worked example told the whole story in miniature: an input with no interaction settled into a perfectly steady elementary effect, while two inputs locked together in an interaction term showed real, detectable spread-all from a method cheap enough to run before committing to anything heavier. Use it to separate what's worth studying from what isn't, then bring in Sobol Sensitivity Analysis for the inputs that earn a closer look.