The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

mhn: The Modified Half-Normal Distribution

Lifecycle: experimental License: MIT R-CMD-check pkgdown

An R package providing density, distribution, quantile, and random generation functions for the Modified Half-Normal (MHN) distribution, together with closed-form / recurrence-based helpers for its moments and mode.

Overview

The MHN(\(\alpha\), \(\beta\), \(\gamma\)) distribution has support on \((0, \infty)\) and density

\[f(x \mid \alpha, \beta, \gamma) \;\propto\; x^{\alpha - 1} \exp(-\beta x^2 + \gamma x), \qquad x > 0,\]

where \(\alpha, \beta > 0\) and \(\gamma \in \mathbb{R}\). It arises as a conditional posterior in Bayesian MCMC for several common models (skew-elliptical regression, \(t\)-shrinkage priors, log-concave likelihoods with a quadratic Bayesian penalty) and generalises a number of familiar one-sided distributions:

Constraint Reduction
\(\gamma = 0\) \(\sqrt{\mathrm{Gamma}}\): \(X^2 \sim \mathrm{Gamma}(\alpha/2, \beta)\)
\(\alpha = 1\) Truncated normal on \((0, \infty)\), mean \(\gamma / (2\beta)\)
\(\alpha = 1,\; \gamma = 0\) Half-normal with scale \(1/\sqrt{2\beta}\)
\(\beta \to 0^+,\; \gamma < 0\) \(\mathrm{Gamma}(\alpha, -\gamma)\) (limit)

The package implements the efficient samplers of Sun, Kong & Pal (2023) (Algorithms 1 / 3) and the Gao & Wang (2025) Relaxed Transformed Density Rejection (RTDR) method with a uniform 1/e acceptance bound, and dispatches between them automatically.

Installation

# Development version from GitHub:
# install.packages("remotes")
remotes::install_github("t-momozaki/mhn")

Once the package is on CRAN it will also be installable with the usual

install.packages("mhn")

Quick start

library(mhn)

# Density, CDF, quantile, random generation
dmhn(c(0.5, 1, 2), alpha = 2, beta = 1, gamma = 1)
pmhn(1.5,           alpha = 2, beta = 1, gamma = 1)
qmhn(0.95,          alpha = 2, beta = 1, gamma = 1)
rmhn(10,            alpha = 2, beta = 1, gamma = 1)

# Summary statistics
mhn_mean(2, 1, 1); mhn_var(2, 1, 1); mhn_mode(2, 1, 1)

Function reference

Distribution functions

Function Description
dmhn() Density (vectorised over x and parameters; supports log = TRUE)
pmhn() Cumulative distribution function (lower.tail and log.p à la pgamma)
qmhn() Quantile function via TOMS 748 root-finder
rmhn() Random generation; method dispatch via method = c("auto", "rtdr", "sun")
dmhn(1.5, alpha = 2, beta = 1, gamma = 1, log = TRUE)
pmhn(1.5, alpha = 2, beta = 1, gamma = 1, lower.tail = FALSE)
qmhn(log(0.05), alpha = 2, beta = 1, gamma = 1, log.p = TRUE)
rmhn(5, alpha = c(1, 2, 3), beta = 1, gamma = c(0, 1, -1))  # recycled

Summary statistics

Function Description
mhn_mean() \(E(X) = \Psi[(\alpha+1)/2,\, z] \,/\, (\sqrt{\beta}\, \Psi[\alpha/2,\, z])\), with \(z = \gamma/\sqrt{\beta}\)
mhn_var() Variance from Sun et al. (2023, Lemma 2c)
mhn_skewness() Skewness \(\gamma_1\)
mhn_kurtosis() Excess kurtosis \(\gamma_2\)
mhn_mode() Mode (returns NA when no interior mode exists)
mhn_mean(2, 1, 1)       # 1.16...
mhn_skewness(2, 1, 1)   # positive (density right-skewed)
mhn_mode(0.5, 1, -1)    # NA: monotone-decreasing density

Algorithm dispatch for rmhn(method = "auto")

The default method routes each parameter triple to the cheapest sampler that is provably correct in that region. The decision rules are benchmarked in inst/benchmarks/auto_dispatch.R:

Closed-form shortcuts:
  α = 1, γ = 0    -> half-normal via |rnorm|
  γ = 0           -> sqrt(rgamma(...))
  α = 1           -> truncated normal

Region α < 1, γ > 0:
  Gao & Wang (2025) RTDR  (Sun et al. (2023) Algorithm 2 is
                           intentionally not implemented; RTDR is
                           uniformly faster here)

Region γ > 0, α > 1:
  Sun et al. (2023, Algorithm 1) (Normal or sqrt-Gamma proposal,
                                 closed-form optimal parameters)

Region γ ≤ 0:
  n-dependent (the crossover at 25 is benchmarked, not theoretical;
  see vignette("theory") §7 for the cost-decomposition derivation):
    samples per setup ≥ 25  -> RTDR (lighter per-proposal cost)
    samples per setup <  25 -> Sun Algorithm 3 (lighter setup cost)

Forcing a specific sampler:

rmhn(1000, 2, 1, 1, method = "rtdr")   # always RTDR
rmhn(1000, 2, 1, 1, method = "sun")    # always Sun (errors for α < 1, γ > 0)

Documentation

Full documentation, with a searchable function reference and rendered vignettes, is published at https://t-momozaki.github.io/mhn/.

Citation

If you use this package in academic work, please cite both the package and the methodology papers (citation("mhn") prints all three):

References

License

MIT © 2026 Tomotaka Momozaki. See LICENSE.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.