Sensitivity Analysis and Robustness: How to Test Whether Model Conclusions Hold

Last Updated June 13, 2026

Sensitivity analysis and robustness testing examine how a mathematical model responds when inputs, parameters, assumptions, structures, or scenarios change. A model may appear credible under one setting while producing unstable conclusions under small changes.

Sensitivity analysis identifies which factors drive model outputs, which assumptions dominate uncertainty, and where additional evidence would matter most. Robustness asks whether conclusions, rankings, thresholds, or decisions remain stable across plausible conditions.

These practices are central to responsible mathematical modeling. They help analysts distinguish stable conclusions from fragile ones, identify influential assumptions, communicate uncertainty, prioritize data collection, and decide whether a model is fit for explanation, prediction, control, or decision support.

Editorial illustration of a scholarly modeling desk with repeated model outputs, parameter variations, contour maps, uncertainty bands, surface diagrams, and robustness comparison panels.
Sensitivity analysis and robustness testing examine how model results change when assumptions, parameters, and inputs are varied.

Responsible modeling does not stop after calibration, validation, and diagnostics. It asks what happens when the model is disturbed. If a conclusion depends on one uncertain parameter, one fragile assumption, one narrow dataset, or one favorable scenario, users need to know that before the model informs action.

Why Sensitivity Analysis Matters

Sensitivity analysis matters because models depend on choices. Inputs are uncertain. Parameters are estimated. Assumptions simplify reality. Boundaries exclude some factors. Functional relationships impose structure. Numerical methods approximate results. Scenario definitions frame possible futures.

If a model conclusion changes dramatically when one plausible value changes, the conclusion is fragile. If a model conclusion remains stable across plausible variation, the conclusion may be more robust. Sensitivity analysis helps analysts tell the difference.

Modeling concern Sensitivity question Why it matters
Parameter uncertainty Which fitted parameters most affect outputs? Shows where calibration precision matters.
Input uncertainty Which inputs drive model results? Guides data quality and measurement priorities.
Assumption dependence Which assumptions control conclusions? Reveals fragile reasoning.
Scenario variation Do conclusions persist across plausible futures? Supports robust decision-making.
Decision thresholds Can small changes reverse action? Identifies decision risk.
Model-form uncertainty Do alternative structures produce different conclusions? Shows structural dependence.

Sensitivity analysis is not only a technical appendix. It is part of the evidence for whether a model should be trusted, revised, constrained, communicated cautiously, or used only for limited purposes.

Back to top ↑

What Sensitivity Analysis Is

Sensitivity analysis studies how changes in model inputs, parameters, assumptions, or structures affect model outputs. It asks which components matter most, which outputs are stable, and which conclusions depend on uncertain choices.

A sensitivity analysis can be simple or advanced. It may vary one parameter at a time, explore a grid of parameter combinations, sample uncertain inputs, compare scenarios, calculate elasticities, or estimate global sensitivity indices.

Sensitivity approach Core idea Useful when
One-at-a-time analysis Vary one factor while holding others fixed. Initial screening and communication.
Parameter sweep Evaluate outputs over a range of parameter values. Exploring thresholds or nonlinear responses.
Elasticity analysis Measure relative output change from relative input change. Comparing sensitivities across different units.
Scenario analysis Evaluate model behavior under coherent conditions. Policy, planning, and uncertainty communication.
Global sensitivity analysis Assess influence across broad uncertainty ranges. Complex models with interactions.
Structural sensitivity Compare alternative model forms or assumptions. When model form itself is uncertain.

The right method depends on the model, purpose, uncertainty, available computation, and decision stakes. A simple model may only need transparent sweeps. A complex simulation may require global sampling, uncertainty propagation, and scenario-based robustness checks.

Back to top ↑

What Robustness Means in Modeling

Robustness means that a model’s important conclusions remain stable under plausible changes. The exact outputs may vary, but the interpretation, ranking, threshold result, or decision recommendation does not collapse under reasonable uncertainty.

Robustness is not the same as accuracy. A model can be accurate under one dataset but fragile under small assumption changes. A model can be less precise but more robust if it supports stable conclusions across many plausible conditions.

Robustness object Question Example
Output robustness Do predicted values remain within acceptable range? Forecast interval stays below risk threshold.
Ranking robustness Do scenario rankings remain stable? Policy A remains preferable to Policy B.
Threshold robustness Does the model cross an action boundary? System remains above safety minimum.
Interpretive robustness Does the explanation remain credible? Main driver remains influential.
Decision robustness Does the recommended action remain defensible? Choice performs acceptably under multiple futures.
Structural robustness Does conclusion survive alternative model forms? Different plausible models support the same warning.

Robustness is especially important in high-stakes modeling, complex systems, public policy, infrastructure, ecology, health, finance, sustainability, and any setting where decisions must be made under uncertainty.

Back to top ↑

Local and Global Sensitivity Analysis

Local sensitivity analysis studies how outputs change near a baseline point. It asks what happens when a parameter or input changes slightly around the selected value. Global sensitivity analysis studies influence across a broader uncertainty range, often accounting for interactions among inputs.

Approach Focus Strength Limit
Local sensitivity Small changes near a baseline. Simple, interpretable, efficient. May miss nonlinear effects or interactions.
Global sensitivity Variation across a full uncertainty space. Captures broader behavior and interactions. More computationally demanding.
Derivative-based analysis Rate of output change. Useful for smooth models. Less useful for discontinuities or thresholds.
Variance-based analysis Contribution to output variance. Useful for uncertainty attribution. Requires sampling and assumptions about ranges.
Scenario-based analysis Coherent combinations of assumptions. Useful for decision communication. Depends on scenario design.

Local analysis can be a strong first step, but it should not be confused with a full robustness test. A model may be stable near a baseline and fragile under broader uncertainty.

Back to top ↑

One-at-a-Time Variation and Parameter Sweeps

One-at-a-time variation changes a single input or parameter while holding others fixed. Parameter sweeps evaluate model outputs across a range of values. These methods are easy to explain and useful for initial screening.

They are also limited. Real systems often involve interactions: changing two assumptions together may produce a result not visible when each is changed alone. Still, one-at-a-time analysis remains valuable as a transparent first diagnostic.

Technique Best use Caution
Low-high sweep Check output under lower and upper plausible values. May miss interior thresholds.
Grid sweep Show output curve across parameter range. Can become large with many parameters.
Tornado chart Rank drivers by output impact. Usually ignores interactions.
Threshold sweep Identify values where decisions change. Requires meaningful action boundary.
Scenario sweep Evaluate named conditions. Scenario definitions can bias results.

Parameter sweeps are particularly useful when stakeholders need to see why a model is sensitive. A table or figure showing how a conclusion changes across plausible values can make uncertainty more concrete.

Back to top ↑

Elasticity, Marginal Change, and Relative Sensitivity

Some sensitivities are difficult to compare because inputs use different units. A one-unit change in rainfall, price, infection rate, failure probability, or extraction rate may not mean the same thing. Elasticity helps by measuring relative change.

Elasticity asks how a percentage change in an input affects a percentage change in an output. It is useful when analysts need to compare the influence of variables measured on different scales.

Measure Meaning Use
Marginal sensitivity Output change per unit input change. Useful when units are meaningful.
Normalized sensitivity Scaled output response. Useful for comparing across variables.
Elasticity Percent output change per percent input change. Useful across different units.
Threshold sensitivity Input change needed to cross a boundary. Useful for decision support.
Scenario sensitivity Output change under named conditions. Useful for communication and governance.

Elasticity does not replace contextual judgment. A variable may have modest average elasticity but high decision importance if it controls behavior near a threshold.

Back to top ↑

Scenario Testing and Stress Conditions

Scenario testing evaluates a model under coherent combinations of assumptions. Instead of changing one parameter at a time, scenario testing asks how the model behaves under plausible futures, stress conditions, policy alternatives, or institutional constraints.

Stress testing is a special form of scenario analysis. It intentionally examines difficult, extreme, or adverse conditions to see whether model conclusions remain credible.

Scenario type Question Use
Baseline scenario What happens under expected conditions? Reference comparison.
Optimistic scenario What happens if favorable assumptions hold? Upside exploration.
Pessimistic scenario What happens if unfavorable assumptions hold? Risk framing.
Stress scenario What happens under adverse or extreme conditions? Robustness and resilience testing.
Policy scenario What happens under a proposed intervention? Decision support.
Boundary scenario Where does the model cease to be credible? Use-limit definition.

Scenarios should be designed carefully. They are not neutral if the chosen scenarios hide inconvenient uncertainty or make one decision look artificially robust.

Back to top ↑

Sensitivity and Uncertainty Propagation

Sensitivity analysis and uncertainty propagation are closely connected. Sensitivity analysis asks which inputs matter. Uncertainty propagation asks how uncertainty in those inputs affects uncertainty in outputs.

If a highly influential input is also highly uncertain, the model’s conclusions may be fragile. If a highly uncertain input has little effect on the decision, it may be less important for immediate action.

Input condition Sensitivity condition Implication
High uncertainty High sensitivity Priority for data collection or caution.
High uncertainty Low sensitivity Less urgent for output stability.
Low uncertainty High sensitivity Important but possibly well-controlled.
Low uncertainty Low sensitivity Lower priority for review.
Unknown uncertainty High sensitivity Potential blind spot.

This pairing helps analysts focus attention. Not every uncertain input deserves the same investment, and not every influential input is equally uncertain.

Back to top ↑

Robustness Checks and Fragility

Robustness checks test whether model conclusions survive changes in assumptions, data choices, model forms, calibration windows, parameter ranges, validation sets, or scenario definitions. Fragility appears when conclusions change under modest, plausible variation.

Robustness check Question Fragility signal
Alternative parameter ranges Do conclusions hold across plausible values? Ranking reverses under small parameter changes.
Alternative data subsets Do conclusions depend on one data window? Different calibration period changes result.
Alternative model form Do conclusions survive structural alternatives? Another plausible model supports opposite conclusion.
Alternative metric Do rankings depend on one score? Preferred option changes with metric.
Alternative scenario definition Does scenario framing control the outcome? Decision depends on favorable scenario design.
Stress condition Does the model remain credible under adverse cases? Output becomes implausible or decision flips.

Robustness checks do not require a model to be unchanged. Models are supposed to respond to changed assumptions. The question is whether the substantive conclusion or decision remains defensible.

Back to top ↑

Sensitivity Near Decision Thresholds

Sensitivity near decision thresholds is especially important. A small change in output may not matter if it stays far from an action boundary. But a small change can be decisive if it crosses a threshold that triggers action.

Threshold-sensitive modeling is common in public health, engineering safety, resource management, climate risk, finance, infrastructure planning, and policy design. In these contexts, robustness is often about whether the decision changes, not whether the exact output changes.

Threshold situation Sensitivity question Decision implication
Output far from threshold Can plausible variation cross the boundary? Decision may be stable.
Output near threshold How small a change reverses action? Decision requires caution.
Uncertain threshold Does threshold definition drive the conclusion? Review policy or safety boundary.
Multiple thresholds Which threshold is most sensitive? Prioritize decision-relevant diagnostics.
High consequence threshold What is the cost of crossing incorrectly? Use conservative robustness review.

A model can be statistically adequate but decision-fragile. Sensitivity analysis should reveal when that is the case.

Back to top ↑

Structural Sensitivity and Model-Form Dependence

Structural sensitivity asks whether conclusions depend on the mathematical form of the model. This is different from parameter sensitivity. The question is not only “What if this parameter changes?” but “What if this model structure is not the right representation?”

Structural sensitivity is important when multiple plausible models exist. A linear model, nonlinear model, differential equation model, stochastic model, network model, or agent-based model may each represent the same system differently.

Structural choice Sensitivity question Possible implication
Linear vs nonlinear form Does the conclusion depend on curvature? Linear simplification may be misleading.
Deterministic vs stochastic model Does randomness change risk interpretation? Average outcome may hide tail risk.
Aggregate vs disaggregate model Does aggregation hide heterogeneity? Subgroup dynamics may matter.
Static vs dynamic model Do feedbacks, delays, or accumulation change conclusions? Time structure may be essential.
Single model vs ensemble Do multiple model forms support the same conclusion? Ensemble reasoning may be more honest.

When structural sensitivity is high, model users should not receive a single clean answer without explanation. The model-form uncertainty itself is part of the result.

Back to top ↑

Mathematical Lens: Sensitivity, Elasticity, and Robust Decisions

A simple local sensitivity derivative measures how an output changes with respect to an input or parameter:

\[
S_i=\frac{\partial y}{\partial x_i}
\]

Interpretation: \(S_i\) measures the marginal change in output \(y\) when input \(x_i\) changes near a baseline point.

Elasticity measures relative sensitivity:

\[
E_i=\frac{\partial y}{\partial x_i}\cdot\frac{x_i}{y}
\]

Interpretation: \(E_i\) estimates the percentage change in output caused by a percentage change in input.

A robustness check can be represented as evaluating a decision across a set of plausible conditions:

\[
R(d)=\min_{\theta\in\Theta} U(d,\theta)
\]

Interpretation: Robustness \(R(d)\) may be represented as the worst-case utility of decision \(d\) across plausible parameter set \(\Theta\).

A threshold fragility measure can ask how much change is needed before an output crosses a decision boundary:

\[
F = \min_{\Delta x}\left\{|\Delta x|:\; y(x+\Delta x)\ \text{crosses threshold } T\right\}
\]

Interpretation: Smaller \(F\) indicates greater decision fragility near threshold \(T\).

These formulas show that sensitivity and robustness are not only about output movement. They are about whether movement matters for interpretation, confidence, and action.

Back to top ↑

Example: Resource Forecasting Under Parameter Uncertainty

Consider a model of resource stock under extraction. The model depends on initial stock, growth rate, carrying capacity, extraction rate, and shock intensity. Calibration produces plausible parameter values, but analysts need to know which assumptions drive the forecast and whether the decision remains stable.

Parameter Possible uncertainty Sensitivity concern Review response
Initial stock Measurement uncertainty. Early forecast shift. Improve data audit.
Growth rate Ecological or production variability. Long-term stock trajectory. Run parameter sweep.
Carrying capacity Boundary uncertainty. Upper-limit behavior. Compare scenarios.
Extraction rate Policy and behavior uncertainty. Threshold crossing. Decision-focused robustness check.
Shock intensity Rare event uncertainty. Stress performance. Stress-test scenarios.

If extraction rate dominates threshold crossing, then policy attention should focus there. If carrying capacity changes long-term interpretation but not near-term decisions, it may matter more for scenario communication than immediate action. If shock intensity reverses the conclusion under stress, the model’s risk communication must say so plainly.

Back to top ↑

Sensitivity Analysis for Decision Support

Decision support requires sensitivity analysis to focus on what can change the action. Not every output change matters. Not every uncertainty affects the decision. Robust decision support asks which actions remain defensible across plausible conditions.

Decision-support task Sensitivity question Robustness evidence
Policy comparison Does policy ranking change under assumptions? Scenario ranking stability.
Risk threshold Can plausible variation cross action boundary? Threshold fragility analysis.
Resource allocation Do priorities change across uncertainty ranges? Rank robustness across parameter sets.
Infrastructure planning Does design remain adequate under stress? Stress and resilience scenarios.
Public communication Which assumptions should users understand? Driver ranking and uncertainty explanation.
Evidence planning Which data would most reduce decision uncertainty? High-sensitivity, high-uncertainty input review.

A decision can be robust even when forecasts vary. Conversely, a decision can be fragile even when average performance looks good. Sensitivity analysis helps separate these cases.

Back to top ↑

Ethical Stakes of Sensitivity and Robustness

Sensitivity analysis has ethical stakes because it reveals whether a model’s conclusion depends on assumptions that users may not see. If sensitivity is hidden, users may treat fragile outputs as settled evidence.

Robustness communication is also an accountability practice. It prevents a model from being presented as stronger than it is and helps decision-makers understand where uncertainty could change the conclusion.

Issue Ethical risk Responsible response
Hidden sensitive assumption Decision appears objective but depends on one fragile choice. Report influential assumptions clearly.
Selective scenario framing Chosen scenarios make one decision look artificially stable. Document scenario rationale and alternatives.
No threshold review Small uncertainty may reverse action without disclosure. Assess decision fragility near thresholds.
Overstated robustness Users trust outputs beyond evidence. State use limits and uncertainty conditions.
Ignored structural sensitivity Model-form dependence is hidden. Compare plausible model structures.
No review record Future users cannot see what was tested. Preserve sensitivity register and robustness audit.

Ethical modeling does not hide sensitivity. It uses sensitivity analysis to make uncertainty, dependency, and fragility visible.

Back to top ↑

Python Workflow: Sensitivity Register and Robustness Diagnostics

The Python workflow below evaluates a simple resource model across parameter perturbations, ranks sensitivity, flags threshold fragility, and writes a robustness assessment card.

# sensitivity_analysis_and_robustness_workflow.py
# Dependency-light workflow for sensitivity and robustness diagnostics.

from __future__ import annotations

from dataclasses import asdict, dataclass
from pathlib import Path
import csv
import json
import math
import statistics


ARTICLE_ROOT = Path(__file__).resolve().parents[1]
OUTPUTS = ARTICLE_ROOT / "outputs"
TABLES = OUTPUTS / "tables"
JSON_DIR = OUTPUTS / "json"


@dataclass(frozen=True)
class Parameter:
    name: str
    baseline: float
    low: float
    high: float
    uncertainty_label: str


@dataclass(frozen=True)
class SensitivityRecord:
    key: str
    sensitivity_layer: str
    modeling_role: str
    review_question: str
    status: str


def parameters() -> list[Parameter]:
    return [
        Parameter("initial_stock", 80.0, 72.0, 88.0, "measurement"),
        Parameter("growth_rate", 0.08, 0.04, 0.12, "parameter"),
        Parameter("carrying_capacity", 120.0, 100.0, 140.0, "structural"),
        Parameter("extraction_rate", 0.12, 0.08, 0.18, "policy"),
        Parameter("shock_intensity", 0.03, 0.00, 0.08, "scenario"),
    ]


def sensitivity_register() -> list[SensitivityRecord]:
    return [
        SensitivityRecord(
            key="parameter_sweep",
            sensitivity_layer="local_sensitivity",
            modeling_role="Varies individual parameters across plausible ranges.",
            review_question="Which parameters most influence model output?",
            status="active",
        ),
        SensitivityRecord(
            key="threshold_fragility",
            sensitivity_layer="decision_support",
            modeling_role="Reviews whether outputs cross a decision threshold.",
            review_question="Can plausible variation reverse the decision?",
            status="review",
        ),
        SensitivityRecord(
            key="scenario_stress",
            sensitivity_layer="robustness",
            modeling_role="Tests model behavior under adverse scenario conditions.",
            review_question="Does the conclusion survive stress assumptions?",
            status="review",
        ),
        SensitivityRecord(
            key="structural_dependence",
            sensitivity_layer="model_form",
            modeling_role="Reviews whether conclusions depend on model structure.",
            review_question="Would alternative model forms support the same conclusion?",
            status="review",
        ),
        SensitivityRecord(
            key="evidence_priority",
            sensitivity_layer="data_quality",
            modeling_role="Identifies high-sensitivity inputs that need better evidence.",
            review_question="Where would better data most reduce uncertainty?",
            status="review",
        ),
    ]


def resource_projection(
    initial_stock: float,
    growth_rate: float,
    carrying_capacity: float,
    extraction_rate: float,
    shock_intensity: float,
    years: int = 10,
) -> float:
    stock = initial_stock
    for _ in range(years):
        growth = growth_rate * stock * (1.0 - stock / carrying_capacity)
        extraction = extraction_rate * stock
        shock = shock_intensity * stock
        stock = max(0.0, stock + growth - extraction - shock)
    return round(stock, 8)


def baseline_output(params: list[Parameter]) -> float:
    values = {item.name: item.baseline for item in params}
    return resource_projection(**values)


def sweep_rows(params: list[Parameter], threshold: float = 45.0) -> list[dict[str, object]]:
    baseline_values = {item.name: item.baseline for item in params}
    base_output = resource_projection(**baseline_values)

    rows = []
    for item in params:
        for level, value in [("low", item.low), ("baseline", item.baseline), ("high", item.high)]:
            values = dict(baseline_values)
            values[item.name] = value
            output = resource_projection(**values)
            delta = output - base_output
            relative_change = delta / base_output if base_output != 0 else math.nan
            rows.append({
                "parameter": item.name,
                "uncertainty_label": item.uncertainty_label,
                "level": level,
                "value": value,
                "projected_stock": output,
                "delta_from_baseline": round(delta, 8),
                "relative_change": round(relative_change, 8),
                "below_threshold": output < threshold,
            })
    return rows


def sensitivity_summary(rows: list[dict[str, object]]) -> list[dict[str, object]]:
    grouped: dict[str, list[dict[str, object]]] = {}
    for row in rows:
        grouped.setdefault(str(row["parameter"]), []).append(row)

    output = []
    for parameter, values in grouped.items():
        stocks = [float(row["projected_stock"]) for row in values]
        rel = [abs(float(row["relative_change"])) for row in values]
        output.append({
            "parameter": parameter,
            "min_projected_stock": round(min(stocks), 8),
            "max_projected_stock": round(max(stocks), 8),
            "range_width": round(max(stocks) - min(stocks), 8),
            "max_abs_relative_change": round(max(rel), 8),
            "threshold_crossed": any(bool(row["below_threshold"]) for row in values),
        })
    return sorted(output, key=lambda row: float(row["range_width"]), reverse=True)


def sensitivity_risk_score(record: SensitivityRecord) -> float:
    score = {"active": 1.0, "review": 5.0, "revise": 8.0, "archive": 2.0}.get(
        record.status.lower(),
        4.0,
    )
    text = f"{record.sensitivity_layer} {record.modeling_role} {record.review_question}".lower()
    for term in ["threshold", "stress", "structural", "decision", "data", "uncertainty"]:
        if term in text:
            score += 1.0
    return round(score, 3)


def write_csv(path: Path, rows: list[dict[str, object]]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    if not rows:
        raise ValueError(f"No rows supplied for {path}")
    with path.open("w", newline="", encoding="utf-8") as handle:
        writer = csv.DictWriter(handle, fieldnames=list(rows[0].keys()))
        writer.writeheader()
        writer.writerows(rows)


def write_json(path: Path, payload: object) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("w", encoding="utf-8") as handle:
        json.dump(payload, handle, indent=2, sort_keys=True)


def main() -> None:
    params = parameters()
    records = sensitivity_register()
    rows = sweep_rows(params)
    summary = sensitivity_summary(rows)

    register_rows = [
        {**asdict(record), "sensitivity_risk_score": sensitivity_risk_score(record)}
        for record in records
    ]

    base_output = baseline_output(params)
    threshold_crossers = [row for row in summary if bool(row["threshold_crossed"])]

    write_csv(TABLES / "sensitivity_parameter_sweep.csv", rows)
    write_csv(TABLES / "sensitivity_summary.csv", summary)
    write_csv(TABLES / "sensitivity_register.csv", register_rows)

    write_json(JSON_DIR / "robustness_assessment_card.json", {
        "article": "Sensitivity Analysis and Robustness",
        "baseline_output": base_output,
        "most_sensitive_parameter": summary[0],
        "threshold_crossing_parameters": threshold_crossers,
        "sensitivity_register": register_rows,
        "use_limit": "Sensitivity results depend on parameter ranges, scenario design, and model structure.",
        "diagnostic_checks": [
            "parameter ranges are documented",
            "baseline output is preserved",
            "sensitivity ranking is exported",
            "threshold crossings are flagged",
            "structural sensitivity remains a review obligation",
            "robustness is interpreted against decision purpose",
        ],
    })

    print("Sensitivity and robustness workflow complete.")
    print(f"Baseline output: {base_output}")
    print(f"Most sensitive parameter: {summary[0]['parameter']}")
    print(f"Wrote outputs to {OUTPUTS}")


if __name__ == "__main__":
    main()

This workflow makes sensitivity review reproducible. It records parameter ranges, output changes, sensitivity ranking, threshold crossings, review obligations, and a robustness assessment card.

Back to top ↑

R Workflow: Sensitivity Ranking and Robustness Review

The R workflow below reviews generated sensitivity outputs, ranks parameters by range width, flags threshold crossings, and creates a base R tornado-style plot.

# sensitivity_analysis_and_robustness_review.R
# Base R workflow for sensitivity ranking and robustness review.

args <- commandArgs(trailingOnly = FALSE)
file_arg <- grep("^--file=", args, value = TRUE)

if (length(file_arg) > 0) {
  script_path <- normalizePath(sub("^--file=", "", file_arg[1]), mustWork = TRUE)
  article_root <- normalizePath(file.path(dirname(script_path), ".."), mustWork = TRUE)
} else {
  article_root <- getwd()
}

tables_dir <- file.path(article_root, "outputs", "tables")
figures_dir <- file.path(article_root, "outputs", "figures")
dir.create(tables_dir, recursive = TRUE, showWarnings = FALSE)
dir.create(figures_dir, recursive = TRUE, showWarnings = FALSE)

summary_path <- file.path(tables_dir, "sensitivity_summary.csv")
register_path <- file.path(tables_dir, "sensitivity_register.csv")

if (!file.exists(summary_path) || !file.exists(register_path)) {
  stop("Missing sensitivity outputs. Run the Python workflow first.")
}

summary_data <- read.csv(summary_path, stringsAsFactors = FALSE)
register <- read.csv(register_path, stringsAsFactors = FALSE)

summary_data$range_width <- as.numeric(summary_data$range_width)
summary_data$max_abs_relative_change <- as.numeric(summary_data$max_abs_relative_change)

summary_data <- summary_data[order(-summary_data$range_width), ]

summary_data$review_priority <- ifelse(
  summary_data$threshold_crossed == "True" | summary_data$threshold_crossed == TRUE,
  "high",
  ifelse(summary_data$range_width > median(summary_data$range_width), "medium", "low")
)

register$priority <- ifelse(
  register$sensitivity_risk_score >= 8,
  "high",
  ifelse(register$sensitivity_risk_score >= 6, "medium", "low")
)

write.csv(
  summary_data,
  file.path(tables_dir, "r_sensitivity_ranking_review.csv"),
  row.names = FALSE
)

write.csv(
  register,
  file.path(tables_dir, "r_sensitivity_review_queue.csv"),
  row.names = FALSE
)

png(file.path(figures_dir, "r_sensitivity_tornado_plot.png"), width = 1100, height = 750)

barplot(
  rev(summary_data$range_width),
  names.arg = rev(summary_data$parameter),
  horiz = TRUE,
  las = 1,
  xlab = "Output range width",
  main = "Sensitivity Ranking by Output Range"
)

dev.off()

print(summary_data)
print(register)

The R layer supports review by preserving ranked sensitivity outputs, review priorities, and a visual summary of which parameters drive the model most strongly.

Back to top ↑

Haskell Workflow: Typed Sensitivity Records

Haskell is useful here because sensitivity concepts should remain distinct. Local sensitivity is not robustness. Threshold fragility is not global uncertainty. Structural sensitivity is not parameter sensitivity.

{-# OPTIONS_GHC -Wall #-}

module Main where

data SensitivityLayer
  = LocalSensitivity
  | GlobalSensitivity
  | Robustness
  | DecisionSupport
  | ModelForm
  | DataQuality
  | Governance
  deriving (Eq, Show)

data ReviewStatus
  = Active
  | RequiresReview
  | RequiresValidation
  | RequiresUncertaintyCheck
  | Revise
  deriving (Eq, Show)

data SensitivityRecord = SensitivityRecord
  { key :: String
  , layer :: SensitivityLayer
  , modelingRole :: String
  , reviewFocus :: String
  , status :: ReviewStatus
  } deriving (Eq, Show)

sensitivityRegister :: [SensitivityRecord]
sensitivityRegister =
  [ SensitivityRecord
      "parameter_sweep"
      LocalSensitivity
      "Varies individual parameters across plausible ranges."
      "Influential parameters."
      Active
  , SensitivityRecord
      "threshold_fragility"
      DecisionSupport
      "Reviews whether outputs cross a decision threshold."
      "Decision reversal."
      RequiresValidation
  , SensitivityRecord
      "scenario_stress"
      Robustness
      "Tests model behavior under adverse scenario conditions."
      "Stress robustness."
      RequiresReview
  , SensitivityRecord
      "structural_dependence"
      ModelForm
      "Reviews whether conclusions depend on model structure."
      "Model-form uncertainty."
      RequiresReview
  , SensitivityRecord
      "evidence_priority"
      DataQuality
      "Identifies high-sensitivity inputs that need better evidence."
      "Evidence priority."
      RequiresUncertaintyCheck
  ]

needsReview :: SensitivityRecord -> Bool
needsReview item =
  case status item of
    Active -> False
    _ -> True

main :: IO ()
main = do
  putStrLn "Typed sensitivity records:"
  mapM_ print sensitivityRegister

  putStrLn "\nSensitivity records requiring review:"
  mapM_ print (filter needsReview sensitivityRegister)

This typed layer supports sensitivity governance by keeping local sensitivity, robustness, decision support, model form, data quality, and governance review conceptually separate.

Back to top ↑

GitHub Repository

The companion repository for this article is designed as a reproducible mathematical-modeling workspace. It contains article-specific code, data, documentation, notebooks, schemas, and generated outputs for sensitivity registers, parameter sweeps, elasticity-style review, robustness diagnostics, threshold fragility, scenario stress checks, typed Haskell sensitivity records, uncertainty notes, and responsible decision-support workflows.

Back to top ↑

A Practical Method for Sensitivity and Robustness Assessment

Sensitivity and robustness assessment should be designed before final model interpretation. The purpose is to understand dependency, fragility, and decision stability, not to decorate an already-chosen conclusion.

Step Task Question Artifact
1 Define purpose What conclusion or decision must be tested? Sensitivity purpose statement.
2 Identify uncertain factors Which inputs, parameters, assumptions, and structures may vary? Sensitivity register.
3 Set plausible ranges What values are credible and why? Parameter range table.
4 Run baseline model What is the reference output? Baseline output record.
5 Run sweeps or samples How do outputs change? Sensitivity output table.
6 Rank drivers Which factors influence outputs most? Sensitivity ranking.
7 Check thresholds Can plausible variation reverse action? Threshold fragility note.
8 Test scenarios Do conclusions survive coherent futures or stress cases? Scenario robustness report.
9 Review structure Do alternative model forms change conclusions? Structural sensitivity note.
10 Communicate limits Where is the model stable, fragile, or uncertain? Robustness assessment card.

This method turns sensitivity analysis into a reviewable evidence trail. It helps users understand which conclusions are stable and which depend on fragile modeling choices.

Back to top ↑

Common Pitfalls

Sensitivity analysis can become superficial if it is treated as a small technical add-on rather than a central part of model assessment.

  • Testing only convenient parameters: ignoring assumptions that may be more important than fitted values.
  • Using arbitrary ranges: varying parameters without explaining why the ranges are plausible.
  • Changing one factor only: missing interactions among inputs.
  • Ignoring thresholds: reporting output changes without asking whether decisions change.
  • Hiding fragile conclusions: presenting one baseline result without showing dependency on assumptions.
  • Confusing sensitivity with uncertainty: identifying influential inputs without considering how uncertain they are.
  • Ignoring structural sensitivity: varying parameters while assuming the model form is unquestionably correct.
  • Overclaiming robustness: calling a result robust after only narrow or favorable tests.
  • No scenario rationale: choosing scenarios without documenting why they are credible.
  • No review record: leaving future users unable to see what was tested.

These pitfalls can be reduced through documented ranges, baseline records, parameter sweeps, global analysis where needed, threshold checks, scenario review, structural comparison, and explicit use-limit statements.

Back to top ↑

Conclusion: Stable Conclusions Require Disturbance

Sensitivity analysis and robustness testing are essential because model conclusions must be disturbed before they can be trusted. A conclusion that only holds under one exact assumption set is fragile. A conclusion that remains credible across plausible uncertainty is more robust.

Sensitivity analysis identifies influential inputs, parameters, assumptions, and structures. Robustness testing asks whether outputs, rankings, thresholds, interpretations, and decisions survive plausible change.

These practices do not eliminate uncertainty. They make uncertainty visible. They help analysts prioritize evidence, communicate limits, detect fragility, and avoid false confidence.

Used well, sensitivity and robustness assessment make mathematical models more accountable. They show not only what a model says, but how much that statement depends on choices that could reasonably have been different.

Back to top ↑

Back to top ↑

Further Reading

  • Saltelli, A. et al. (2008) Global Sensitivity Analysis: The Primer. Chichester: Wiley.
  • Saltelli, A. et al. (2004) Sensitivity Analysis in Practice: A Guide to Assessing Scientific Models. Chichester: Wiley.
  • Saltelli, A., Tarantola, S., Campolongo, F. and Ratto, M. (2004) Sensitivity Analysis in Practice. Chichester: Wiley.
  • Iooss, B. and Lemaître, P. (2015) ‘A review on global sensitivity analysis methods’, in Dellino, G. and Meloni, C. (eds.) Uncertainty Management in Simulation-Optimization of Complex Systems. New York: Springer.
  • Helton, J.C., Johnson, J.D., Sallaberry, C.J. and Storlie, C.B. (2006) ‘Survey of sampling-based methods for uncertainty and sensitivity analysis’, Reliability Engineering & System Safety, 91(10–11), pp. 1175–1209.
  • Herman, J.D. and Usher, W. (2017) ‘SALib: An open-source Python library for sensitivity analysis’, The Journal of Open Source Software, 2(9), p. 97.
  • Oberkampf, W.L. and Roy, C.J. (2010) Verification and Validation in Scientific Computing. Cambridge: Cambridge University Press.
  • Walker, W.E. et al. (2013) ‘Deep uncertainty’, Encyclopedia of Operations Research and Management Science. New York: Springer.
  • Lempert, R.J., Popper, S.W. and Bankes, S.C. (2003) Shaping the Next One Hundred Years: New Methods for Quantitative, Long-Term Policy Analysis. Santa Monica, CA: RAND.
  • Hastie, T., Tibshirani, R. and Friedman, J. (2009) The Elements of Statistical Learning. 2nd edn. New York: Springer.

Back to top ↑

References

  • Hastie, T., Tibshirani, R. and Friedman, J. (2009) The Elements of Statistical Learning. 2nd edn. New York: Springer.
  • Helton, J.C., Johnson, J.D., Sallaberry, C.J. and Storlie, C.B. (2006) ‘Survey of sampling-based methods for uncertainty and sensitivity analysis’, Reliability Engineering & System Safety, 91(10–11), pp. 1175–1209.
  • Herman, J.D. and Usher, W. (2017) ‘SALib: An open-source Python library for sensitivity analysis’, The Journal of Open Source Software, 2(9), p. 97.
  • Iooss, B. and Lemaître, P. (2015) ‘A review on global sensitivity analysis methods’, in Dellino, G. and Meloni, C. (eds.) Uncertainty Management in Simulation-Optimization of Complex Systems. New York: Springer.
  • Lempert, R.J., Popper, S.W. and Bankes, S.C. (2003) Shaping the Next One Hundred Years: New Methods for Quantitative, Long-Term Policy Analysis. Santa Monica, CA: RAND.
  • Oberkampf, W.L. and Roy, C.J. (2010) Verification and Validation in Scientific Computing. Cambridge: Cambridge University Press.
  • Saltelli, A. et al. (2004) Sensitivity Analysis in Practice: A Guide to Assessing Scientific Models. Chichester: Wiley.
  • Saltelli, A. et al. (2008) Global Sensitivity Analysis: The Primer. Chichester: Wiley.
  • Walker, W.E. et al. (2013) ‘Deep uncertainty’, Encyclopedia of Operations Research and Management Science. New York: Springer.

Back to top ↑

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top