Credible Intervals

Overview

In Bayesian inference, a credible interval is a posterior-probability statement about where a parameter is likely to lie given observed data and prior assumptions. Unlike frequentist confidence intervals, credible intervals are interpreted directly on the parameter scale: for level c, the interval contains posterior mass c. The topic is central to practical uncertainty quantification in analytics, experimentation, and engineering models where decisions depend on parameter ranges rather than point estimates. For background, see credible interval.

These tools are unified by two interval constructions: equal-tailed intervals (quantile-based) and highest posterior density (HPD) intervals (shortest high-mass regions). For posterior CDF F, an equal-tailed interval at level c is often written as [\theta_L,\theta_U] = [F^{-1}((1-c)/2),\;F^{-1}(1-(1-c)/2)]. When closed-form posteriors are available, bounds come from analytic quantiles; when only samples are available, empirical quantiles or shortest windows over sorted draws provide robust approximations.

Implementation is based primarily on SciPy, especially scipy.stats distribution objects and summary-statistics helpers, plus scipy.special for inverse incomplete-beta computations. Sample-driven intervals use NumPy quantiles for nonparametric posterior summaries. Together, these libraries provide stable, production-grade primitives for Bayesian interval construction.

For posterior uncertainty in mean/variance/scale from raw observations, BAYES_MVS_CI and MVSDIST_CI provide parallel workflows built on SciPy’s normal-theory Bayesian summaries. BAYES_MVS_CI returns interval centers and bounds directly from bayes_mvs, while MVSDIST_CI first obtains frozen posterior distributions and then evaluates means and intervals from those objects. Both are useful in measurement systems, A/B test diagnostics, and process monitoring where uncertainty around location and dispersion must be reported together.

For conjugate-model posteriors with analytic quantiles, BETA_CI_BOUNDS, GAMMA_CI_BOUNDS, and INVGAMMA_CI_BOUNDS cover common Bayesian updating patterns. BETA_CI_BOUNDS targets binomial proportions with Beta priors, making it practical for conversion rates, defect probabilities, and reliability pass/fail data. GAMMA_CI_BOUNDS is appropriate for positive rate/intensity parameters (e.g., Poisson-like rates), while INVGAMMA_CI_BOUNDS supports positive scale or variance parameters under inverse-gamma posteriors. Used together, these functions provide a compact toolkit for expressing posterior uncertainty in canonical Bayesian models.

When posterior draws are available from simulation (for example MCMC), SAMPLE_EQTAIL_CI and SAMPLE_HPD_CI estimate intervals without assuming a closed-form density. SAMPLE_EQTAIL_CI extracts quantile-based bounds and is simple, stable, and easy to compare across analyses. SAMPLE_HPD_CI approximates the narrowest interval containing the requested mass, which is often preferable for skewed posteriors. This sample-based pair is especially useful in hierarchical models, custom likelihoods, and workflows where posterior inference is available only as draws.

BAYES_MVS_CI

This function wraps SciPy’s Bayesian mean-variance-standard-deviation estimator to produce equal-tailed credible intervals for three population parameters: mean, variance, and standard deviation.

Given observed data and confidence level \alpha, it returns posterior centers and interval bounds based on Jeffreys prior assumptions used by the underlying method.

For each parameter \theta, the reported interval is an equal-tailed posterior interval:

P(\theta_{L} \leq \theta \leq \theta_{U} \mid \text{data}) = \alpha

Excel Usage

=BAYES_MVS_CI(data, alpha)
  • data (list[list], required): 2D array of sample observations (unitless).
  • alpha (float, optional, default: 0.9): Credible interval probability level (0 to 1).

Returns (list[list]): 2D table with parameter name, posterior center, and lower/upper credible bounds.

Example 1: Credible intervals for balanced sample values

Inputs:

data alpha
6 9 12 0.9
7 8 13

Excel formula:

=BAYES_MVS_CI({6,9,12;7,8,13}, 0.9)

Expected output:

Metric Center Lower Upper
Mean 9.16667 6.87407 11.4593
Variance 12.9444 3.50782 33.9015
Std Dev 3.31475 1.87292 5.8225
Example 2: Credible intervals with decimal-valued sample

Inputs:

data alpha
1.5 2 2.5 0.95
3 3.5 4

Excel formula:

=BAYES_MVS_CI({1.5,2,2.5;3,3.5,4}, 0.95)

Expected output:

Metric Center Lower Upper
Mean 2.75 1.76834 3.73166
Variance 1.45833 0.340931 5.2634
Std Dev 1.1126 0.583893 2.29421
Example 3: Single-row sample array is accepted

Inputs:

data alpha
10 11 9 12 0.8

Excel formula:

=BAYES_MVS_CI({10,11,9,12}, 0.8)

Expected output:

Metric Center Lower Upper
Mean 10.5 9.44284 11.5572
Variance 5 0.799822 8.55616
Std Dev 1.78412 0.894328 2.92509
Example 4: Scalar sample input is normalized to 2D

Inputs:

data alpha
4 5 6 0.9

Excel formula:

=BAYES_MVS_CI({4,5,6}, 0.9)

Expected output:

Metric Center Lower Upper
Mean 5 3.31415 6.68585
Variance Infinity 0.333808 19.4957
Std Dev 1.77245 0.577761 4.4154

Python Code

Show Code
from scipy.stats import bayes_mvs as scipy_bayes_mvs

def bayes_mvs_ci(data, alpha=0.9):
    """
    Compute Bayesian credible intervals for mean, variance, and standard deviation from sample data.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.bayes_mvs.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        data (list[list]): 2D array of sample observations (unitless).
        alpha (float, optional): Credible interval probability level (0 to 1). Default is 0.9.

    Returns:
        list[list]: 2D table with parameter name, posterior center, and lower/upper credible bounds.
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        data = to2d(data)

        if not isinstance(data, list) or not all(isinstance(row, list) for row in data):
            return "Error: Invalid input - data must be a 2D list"

        if not (0 < alpha < 1):
            return "Error: alpha must be between 0 and 1"

        flat = []
        for row in data:
            for value in row:
                try:
                    flat.append(float(value))
                except (TypeError, ValueError):
                    continue

        if len(flat) < 2:
            return "Error: data must contain at least two numeric values"

        mean_res, var_res, std_res = scipy_bayes_mvs(flat, alpha=alpha)

        return [
            ["Metric", "Center", "Lower", "Upper"],
            ["Mean", float(mean_res.statistic), float(mean_res.minmax[0]), float(mean_res.minmax[1])],
            ["Variance", float(var_res.statistic), float(var_res.minmax[0]), float(var_res.minmax[1])],
            ["Std Dev", float(std_res.statistic), float(std_res.minmax[0]), float(std_res.minmax[1])]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

2D array of sample observations (unitless).
Credible interval probability level (0 to 1).

BETA_CI_BOUNDS

This function computes posterior interval endpoints for a Bernoulli/binomial proportion using Beta prior conjugacy and the inverse regularized incomplete beta function.

With prior p \sim \mathrm{Beta}(\alpha_0, \beta_0) and observed successes s in n trials, the posterior is:

p \mid s,n \sim \mathrm{Beta}(\alpha_0 + s,\; \beta_0 + n - s)

The equal-tailed credible interval with confidence level c is obtained from posterior quantiles at probabilities \frac{1-c}{2} and 1-\frac{1-c}{2}.

Excel Usage

=BETA_CI_BOUNDS(successes, trials, alpha_prior, beta_prior, confidence)
  • successes (int, required): Number of observed successes (count).
  • trials (int, required): Number of observed Bernoulli trials (count).
  • alpha_prior (float, optional, default: 1): Prior Beta alpha shape parameter (unitless).
  • beta_prior (float, optional, default: 1): Prior Beta beta shape parameter (unitless).
  • confidence (float, optional, default: 0.95): Credible interval probability level (0 to 1).

Returns (list[list]): 2D table with posterior parameters, posterior mean, and lower/upper credible bounds for the proportion.

Example 1: Uniform-prior interval for moderate success rate

Inputs:

successes trials alpha_prior beta_prior confidence
6 10 1 1 0.95

Excel formula:

=BETA_CI_BOUNDS(6, 10, 1, 1, 0.95)

Expected output:

Posterior Alpha Posterior Beta Mean Lower Upper
7 5 0.583333 0.307905 0.832512
Example 2: Informative prior shifts posterior interval

Inputs:

successes trials alpha_prior beta_prior confidence
18 30 4 3 0.9

Excel formula:

=BETA_CI_BOUNDS(18, 30, 4, 3, 0.9)

Expected output:

Posterior Alpha Posterior Beta Mean Lower Upper
22 15 0.594595 0.460489 0.722805
Example 3: Low observed success proportion interval

Inputs:

successes trials alpha_prior beta_prior confidence
2 25 1 1 0.95

Excel formula:

=BETA_CI_BOUNDS(2, 25, 1, 1, 0.95)

Expected output:

Posterior Alpha Posterior Beta Mean Lower Upper
3 24 0.111111 0.0244581 0.251303
Example 4: High-confidence posterior interval

Inputs:

successes trials alpha_prior beta_prior confidence
12 20 2 2 0.99

Excel formula:

=BETA_CI_BOUNDS(12, 20, 2, 2, 0.99)

Expected output:

Posterior Alpha Posterior Beta Mean Lower Upper
14 10 0.583333 0.326351 0.815248

Python Code

Show Code
from scipy.special import betaincinv as scipy_betaincinv

def beta_ci_bounds(successes, trials, alpha_prior=1, beta_prior=1, confidence=0.95):
    """
    Compute an equal-tailed Bayesian credible interval for a proportion using a Beta posterior.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.betaincinv.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        successes (int): Number of observed successes (count).
        trials (int): Number of observed Bernoulli trials (count).
        alpha_prior (float, optional): Prior Beta alpha shape parameter (unitless). Default is 1.
        beta_prior (float, optional): Prior Beta beta shape parameter (unitless). Default is 1.
        confidence (float, optional): Credible interval probability level (0 to 1). Default is 0.95.

    Returns:
        list[list]: 2D table with posterior parameters, posterior mean, and lower/upper credible bounds for the proportion.
    """
    try:
        if trials <= 0:
            return "Error: trials must be greater than 0"

        if successes < 0 or successes > trials:
            return "Error: successes must be between 0 and trials"

        if alpha_prior <= 0 or beta_prior <= 0:
            return "Error: alpha_prior and beta_prior must be greater than 0"

        if not (0 < confidence < 1):
            return "Error: confidence must be between 0 and 1"

        posterior_alpha = alpha_prior + successes
        posterior_beta = beta_prior + (trials - successes)

        tail_probability = (1 - confidence) / 2
        lower = float(scipy_betaincinv(posterior_alpha, posterior_beta, tail_probability))
        upper = float(scipy_betaincinv(posterior_alpha, posterior_beta, 1 - tail_probability))
        mean = float(posterior_alpha / (posterior_alpha + posterior_beta))

        return [
            ["Posterior Alpha", "Posterior Beta", "Mean", "Lower", "Upper"],
            [float(posterior_alpha), float(posterior_beta), mean, lower, upper]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Number of observed successes (count).
Number of observed Bernoulli trials (count).
Prior Beta alpha shape parameter (unitless).
Prior Beta beta shape parameter (unitless).
Credible interval probability level (0 to 1).

GAMMA_CI_BOUNDS

This function computes credible interval endpoints for a positive rate parameter whose posterior is modeled as a Gamma distribution in shape-rate form.

If \lambda \mid \text{data} \sim \mathrm{Gamma}(\alpha, \beta) with shape \alpha and rate \beta, then the equivalent SciPy parameterization uses shape a=\alpha and scale \theta=1/\beta.

The equal-tailed credible interval at confidence level c is built from posterior quantiles:

[\lambda_L, \lambda_U] = [Q((1-c)/2),\; Q(1-(1-c)/2)]

where Q is the Gamma posterior quantile function.

Excel Usage

=GAMMA_CI_BOUNDS(shape, rate, confidence)
  • shape (float, required): Posterior Gamma shape parameter alpha (unitless).
  • rate (float, required): Posterior Gamma rate parameter beta (1 per unit).
  • confidence (float, optional, default: 0.95): Credible interval probability level (0 to 1).

Returns (list[list]): 2D table with posterior mean and lower/upper credible bounds for the rate parameter.

Example 1: Typical gamma posterior interval for rate

Inputs:

shape rate confidence
8 2 0.95

Excel formula:

=GAMMA_CI_BOUNDS(8, 2, 0.95)

Expected output:

Mean Lower Upper
4 1.72692 7.21134
Example 2: Concentrated posterior with larger shape

Inputs:

shape rate confidence
25 5 0.9

Excel formula:

=GAMMA_CI_BOUNDS(25, 5, 0.9)

Expected output:

Mean Lower Upper
5 3.47643 6.75048
Example 3: Diffuse posterior with small shape

Inputs:

shape rate confidence
1.5 0.8 0.95

Excel formula:

=GAMMA_CI_BOUNDS(1.5, 0.8, 0.95)

Expected output:

Mean Lower Upper
1.875 0.134872 5.84275
Example 4: High-confidence interval for positive rate

Inputs:

shape rate confidence
12 3.5 0.99

Excel formula:

=GAMMA_CI_BOUNDS(12, 3.5, 0.99)

Expected output:

Mean Lower Upper
3.42857 1.41232 6.50836

Python Code

Show Code
from scipy.stats import gamma as scipy_gamma

def gamma_ci_bounds(shape, rate, confidence=0.95):
    """
    Compute an equal-tailed Bayesian credible interval for a positive rate parameter using Gamma quantiles.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gamma.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        shape (float): Posterior Gamma shape parameter alpha (unitless).
        rate (float): Posterior Gamma rate parameter beta (1 per unit).
        confidence (float, optional): Credible interval probability level (0 to 1). Default is 0.95.

    Returns:
        list[list]: 2D table with posterior mean and lower/upper credible bounds for the rate parameter.
    """
    try:
        if shape <= 0:
            return "Error: shape must be greater than 0"

        if rate <= 0:
            return "Error: rate must be greater than 0"

        if not (0 < confidence < 1):
            return "Error: confidence must be between 0 and 1"

        tail_probability = (1 - confidence) / 2
        scale = 1.0 / rate

        lower = float(scipy_gamma.ppf(tail_probability, a=shape, scale=scale))
        upper = float(scipy_gamma.ppf(1 - tail_probability, a=shape, scale=scale))
        mean = float(shape / rate)

        return [
            ["Mean", "Lower", "Upper"],
            [mean, lower, upper]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Posterior Gamma shape parameter alpha (unitless).
Posterior Gamma rate parameter beta (1 per unit).
Credible interval probability level (0 to 1).

INVGAMMA_CI_BOUNDS

This function computes posterior credible interval endpoints for a positive parameter modeled with an Inverse-Gamma posterior distribution.

If \theta \mid \text{data} \sim \mathrm{InvGamma}(\alpha, \beta) with shape \alpha and scale \beta, interval bounds are extracted from posterior quantiles at equal tails.

For confidence level c, the interval is:

[\theta_L, \theta_U] = [Q((1-c)/2),\; Q(1-(1-c)/2)]

where Q is the Inverse-Gamma quantile function.

Excel Usage

=INVGAMMA_CI_BOUNDS(shape, scale, confidence)
  • shape (float, required): Posterior Inverse-Gamma shape parameter alpha (unitless).
  • scale (float, required): Posterior Inverse-Gamma scale parameter beta (squared unit).
  • confidence (float, optional, default: 0.95): Credible interval probability level (0 to 1).

Returns (list[list]): 2D table with posterior mean when defined and lower/upper credible bounds.

Example 1: Typical inverse-gamma posterior interval

Inputs:

shape scale confidence
6 9 0.95

Excel formula:

=INVGAMMA_CI_BOUNDS(6, 9, 0.95)

Expected output:

Mean Lower Upper
1.8 0.771318 4.08739
Example 2: Tighter interval with higher shape

Inputs:

shape scale confidence
20 30 0.9

Excel formula:

=INVGAMMA_CI_BOUNDS(20, 30, 0.9)

Expected output:

Mean Lower Upper
1.57895 1.07607 2.26336
Example 3: Shape above one keeps finite posterior mean

Inputs:

shape scale confidence
1.2 2.5 0.95

Excel formula:

=INVGAMMA_CI_BOUNDS(1.2, 2.5, 0.95)

Expected output:

Mean Lower Upper
12.5 0.610148 48.7319
Example 4: High-confidence inverse-gamma interval

Inputs:

shape scale confidence
10 8 0.99

Excel formula:

=INVGAMMA_CI_BOUNDS(10, 8, 0.99)

Expected output:

Mean Lower Upper
0.888889 0.400032 2.15232

Python Code

Show Code
from scipy.stats import invgamma as scipy_invgamma

def invgamma_ci_bounds(shape, scale, confidence=0.95):
    """
    Compute an equal-tailed Bayesian credible interval for a positive scale or variance parameter using Inverse-Gamma quantiles.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.invgamma.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        shape (float): Posterior Inverse-Gamma shape parameter alpha (unitless).
        scale (float): Posterior Inverse-Gamma scale parameter beta (squared unit).
        confidence (float, optional): Credible interval probability level (0 to 1). Default is 0.95.

    Returns:
        list[list]: 2D table with posterior mean when defined and lower/upper credible bounds.
    """
    try:
        if shape <= 0:
            return "Error: shape must be greater than 0"

        if scale <= 0:
            return "Error: scale must be greater than 0"

        if not (0 < confidence < 1):
            return "Error: confidence must be between 0 and 1"

        tail_probability = (1 - confidence) / 2

        lower = float(scipy_invgamma.ppf(tail_probability, a=shape, scale=scale))
        upper = float(scipy_invgamma.ppf(1 - tail_probability, a=shape, scale=scale))
        mean = float(scale / (shape - 1)) if shape > 1 else ""

        return [
            ["Mean", "Lower", "Upper"],
            [mean, lower, upper]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Posterior Inverse-Gamma shape parameter alpha (unitless).
Posterior Inverse-Gamma scale parameter beta (squared unit).
Credible interval probability level (0 to 1).

MVSDIST_CI

This function wraps SciPy’s posterior distribution constructor for the mean, variance, and standard deviation inferred from sample data. It evaluates each frozen posterior distribution at its mean and extracts equal-tailed credible interval bounds.

Let \theta \in \{\mu, \sigma^2, \sigma\} denote one of the three parameters. The reported interval satisfies:

P(\theta_{L} \leq \theta \leq \theta_{U} \mid \text{data}) = \alpha

This is useful when the posterior distributions are needed directly before interval extraction.

Excel Usage

=MVSDIST_CI(data, alpha)
  • data (list[list], required): 2D array of sample observations (unitless).
  • alpha (float, optional, default: 0.9): Credible interval probability level (0 to 1).

Returns (list[list]): 2D table with posterior mean and lower/upper credible bounds for mean, variance, and standard deviation.

Example 1: Intervals from posterior distributions for typical sample

Inputs:

data alpha
5 7 8 0.9
9 10 12

Excel formula:

=MVSDIST_CI({5,7,8;9,10,12}, 0.9)

Expected output:

Metric Center Lower Upper
Mean 8.5 6.50181 10.4982
Variance 9.83333 2.66474 25.7535
Std Dev 2.88908 1.6324 5.07479
Example 2: Higher confidence interval extraction

Inputs:

data alpha
2 3 5 7 11 0.95

Excel formula:

=MVSDIST_CI({2,3,5,7,11}, 0.95)

Expected output:

Metric Center Lower Upper
Mean 5.6 1.15769 10.0423
Variance 25.6 4.59469 105.694
Std Dev 4.48399 2.14352 10.2807
Example 3: Lower confidence interval extraction

Inputs:

data alpha
1 2 2 3 4 0.75

Excel formula:

=MVSDIST_CI({1,2,2,3,4}, 0.75)

Expected output:

Metric Center Lower Upper
Mean 2.4 1.71449 3.08551
Variance 2.6 0.720816 4.26662
Std Dev 1.429 0.849009 2.06558
Example 4: Mixed-scale sample values

Inputs:

data alpha
0.5 1.2 0.85
2.8 3.6
4.4 5.1

Excel formula:

=MVSDIST_CI({0.5,1.2;2.8,3.6;4.4,5.1}, 0.85)

Expected output:

Metric Center Lower Upper
Mean 2.93333 1.68328 4.18339
Variance 5.41111 1.62198 11.6476
Std Dev 2.14315 1.27357 3.41285

Python Code

Show Code
from scipy.stats import mvsdist as scipy_mvsdist

def mvsdist_ci(data, alpha=0.9):
    """
    Compute Bayesian credible intervals from posterior distributions of mean, variance, and standard deviation.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.mvsdist.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        data (list[list]): 2D array of sample observations (unitless).
        alpha (float, optional): Credible interval probability level (0 to 1). Default is 0.9.

    Returns:
        list[list]: 2D table with posterior mean and lower/upper credible bounds for mean, variance, and standard deviation.
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        data = to2d(data)

        if not isinstance(data, list) or not all(isinstance(row, list) for row in data):
            return "Error: Invalid input - data must be a 2D list"

        if not (0 < alpha < 1):
            return "Error: alpha must be between 0 and 1"

        flat = []
        for row in data:
            for value in row:
                try:
                    flat.append(float(value))
                except (TypeError, ValueError):
                    continue

        if len(flat) < 2:
            return "Error: data must contain at least two numeric values"

        mean_dist, var_dist, std_dist = scipy_mvsdist(flat)

        mean_interval = mean_dist.interval(alpha)
        var_interval = var_dist.interval(alpha)
        std_interval = std_dist.interval(alpha)

        return [
            ["Metric", "Center", "Lower", "Upper"],
            ["Mean", float(mean_dist.mean()), float(mean_interval[0]), float(mean_interval[1])],
            ["Variance", float(var_dist.mean()), float(var_interval[0]), float(var_interval[1])],
            ["Std Dev", float(std_dist.mean()), float(std_interval[0]), float(std_interval[1])]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

2D array of sample observations (unitless).
Credible interval probability level (0 to 1).

SAMPLE_EQTAIL_CI

This function computes an equal-tailed Bayesian credible interval directly from posterior samples without assuming a closed-form distribution.

For confidence level c and posterior samples \{x_i\}_{i=1}^{n}, the interval uses empirical quantiles at probabilities \frac{1-c}{2} and 1-\frac{1-c}{2}.

[x_L, x_U] = [\hat{Q}((1-c)/2),\; \hat{Q}(1-(1-c)/2)]

where \hat{Q} is the sample quantile function computed from the posterior draws.

Excel Usage

=SAMPLE_EQTAIL_CI(samples, confidence)
  • samples (list[list], required): 2D array of posterior sample draws (unitless).
  • confidence (float, optional, default: 0.95): Credible interval probability level (0 to 1).

Returns (list[list]): 2D table with sample median and lower/upper equal-tailed credible bounds.

Example 1: Equal-tailed interval from symmetric posterior samples

Inputs:

samples confidence
-2 -1 0 1 2 0.8

Excel formula:

=SAMPLE_EQTAIL_CI({-2,-1,0,1,2}, 0.8)

Expected output:

Median Lower Upper
0 -1.6 1.6
Example 2: Equal-tailed interval from positive posterior samples

Inputs:

samples confidence
0.5 0.9 1.2 0.95
1.6 2 2.4

Excel formula:

=SAMPLE_EQTAIL_CI({0.5,0.9,1.2;1.6,2,2.4}, 0.95)

Expected output:

Median Lower Upper
1.4 0.55 2.35
Example 3: Equal-tailed interval from right-skewed posterior draws

Inputs:

samples confidence
0.2 0.3 0.4 0.8 1.5 3 0.9

Excel formula:

=SAMPLE_EQTAIL_CI({0.2,0.3,0.4,0.8,1.5,3}, 0.9)

Expected output:

Median Lower Upper
0.6 0.225 2.625
Example 4: Multi-row sample layout is flattened

Inputs:

samples confidence
1 2 0.85
3 4
5 6

Excel formula:

=SAMPLE_EQTAIL_CI({1,2;3,4;5,6}, 0.85)

Expected output:

Median Lower Upper
3.5 1.375 5.625

Python Code

Show Code
import numpy as np

def sample_eqtail_ci(samples, confidence=0.95):
    """
    Compute an equal-tailed credible interval from posterior samples using empirical quantiles.

    See: https://numpy.org/doc/stable/reference/generated/numpy.quantile.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        samples (list[list]): 2D array of posterior sample draws (unitless).
        confidence (float, optional): Credible interval probability level (0 to 1). Default is 0.95.

    Returns:
        list[list]: 2D table with sample median and lower/upper equal-tailed credible bounds.
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        samples = to2d(samples)

        if not isinstance(samples, list) or not all(isinstance(row, list) for row in samples):
            return "Error: Invalid input - samples must be a 2D list"

        if not (0 < confidence < 1):
            return "Error: confidence must be between 0 and 1"

        flat = []
        for row in samples:
            for value in row:
                try:
                    flat.append(float(value))
                except (TypeError, ValueError):
                    continue

        if len(flat) < 2:
            return "Error: samples must contain at least two numeric values"

        sorted_samples = np.sort(np.array(flat, dtype=float))
        tail_probability = (1 - confidence) / 2

        lower = float(np.quantile(sorted_samples, tail_probability))
        upper = float(np.quantile(sorted_samples, 1 - tail_probability))
        median = float(np.quantile(sorted_samples, 0.5))

        return [
            ["Median", "Lower", "Upper"],
            [median, lower, upper]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

2D array of posterior sample draws (unitless).
Credible interval probability level (0 to 1).

SAMPLE_HPD_CI

This function approximates a highest posterior density (HPD) credible interval from posterior samples by finding the shortest interval that contains the requested posterior probability mass.

Given sorted samples x_{(1)} \leq \dots \leq x_{(n)} and confidence level c, let k = \lceil c n \rceil. The HPD approximation chooses index i minimizing interval width:

w_i = x_{(i+k-1)} - x_{(i)}

and returns the corresponding bounds (x_{(i)}, x_{(i+k-1)}). This is a practical sample-based approximation often used when analytic HPD limits are unavailable.

Excel Usage

=SAMPLE_HPD_CI(samples, confidence)
  • samples (list[list], required): 2D array of posterior sample draws (unitless).
  • confidence (float, optional, default: 0.95): Credible interval probability level (0 to 1).

Returns (list[list]): 2D table with sample median and approximate HPD lower/upper bounds.

Example 1: HPD approximation for symmetric posterior samples

Inputs:

samples confidence
-3 -2 -1 0 1 2 3 0.8

Excel formula:

=SAMPLE_HPD_CI({-3,-2,-1,0,1,2,3}, 0.8)

Expected output:

Median Lower Upper
0 -3 2
Example 2: HPD approximation for right-skewed posterior samples

Inputs:

samples confidence
0.1 0.2 0.3 0.5 1 2.5 4 0.9

Excel formula:

=SAMPLE_HPD_CI({0.1,0.2,0.3,0.5,1,2.5,4}, 0.9)

Expected output:

Median Lower Upper
0.5 0.1 4
Example 3: HPD approximation on clustered sample draws

Inputs:

samples confidence
1 1.1 1.2 3.8 3.9 4 4.1 0.75

Excel formula:

=SAMPLE_HPD_CI({1,1.1,1.2,3.8,3.9,4,4.1}, 0.75)

Expected output:

Median Lower Upper
3.8 1.1 4.1
Example 4: Multi-row posterior sample layout

Inputs:

samples confidence
2 2.2 0.85
2.5 2.7
3 3.1
3.4 3.6

Excel formula:

=SAMPLE_HPD_CI({2,2.2;2.5,2.7;3,3.1;3.4,3.6}, 0.85)

Expected output:

Median Lower Upper
2.85 2 3.4

Python Code

Show Code
import numpy as np

def sample_hpd_ci(samples, confidence=0.95):
    """
    Approximate a highest posterior density interval from posterior samples using the narrowest empirical window.

    See: https://numpy.org/doc/stable/reference/generated/numpy.quantile.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        samples (list[list]): 2D array of posterior sample draws (unitless).
        confidence (float, optional): Credible interval probability level (0 to 1). Default is 0.95.

    Returns:
        list[list]: 2D table with sample median and approximate HPD lower/upper bounds.
    """
    try:
        def to2d(x):
            return [[x]] if not isinstance(x, list) else x

        samples = to2d(samples)

        if not isinstance(samples, list) or not all(isinstance(row, list) for row in samples):
            return "Error: Invalid input - samples must be a 2D list"

        if not (0 < confidence < 1):
            return "Error: confidence must be between 0 and 1"

        flat = []
        for row in samples:
            for value in row:
                try:
                    flat.append(float(value))
                except (TypeError, ValueError):
                    continue

        if len(flat) < 2:
            return "Error: samples must contain at least two numeric values"

        sorted_samples = np.sort(np.array(flat, dtype=float))
        sample_count = len(sorted_samples)
        window_size = int(np.ceil(confidence * sample_count))

        if window_size >= sample_count:
            lower = float(sorted_samples[0])
            upper = float(sorted_samples[-1])
        else:
            width_count = sample_count - window_size + 1
            widths = sorted_samples[window_size - 1:] - sorted_samples[:width_count]
            start_index = int(np.argmin(widths))
            lower = float(sorted_samples[start_index])
            upper = float(sorted_samples[start_index + window_size - 1])

        median = float(np.quantile(sorted_samples, 0.5))

        return [
            ["Median", "Lower", "Upper"],
            [median, lower, upper]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

2D array of posterior sample draws (unitless).
Credible interval probability level (0 to 1).