The two-piece normal, also known as split normal, binormal, or double-Gaussian, results from joining at the mode the corresponding halves of two normal distributions with the same mode $\mu$ but different standard deviations $\sigma_1$ and $\sigma_2$. This idea can be seen in the following graph where we can see in blue and pink the two half densities and the resulting two-piece normal density.

The two-piece normal was proposed by German physicist and phycologist Gustav Fechner -who is also consider the founder of psychophysics– around 1887 but published posthumously ten years later. Unfortunately, Fechner work did not become popular and this lead to a series of re discoveries (as recent as 2016!). You can see a brief recap of this interesting journey in my previous post Brief History of the Two-Piece Normal.
Table of Contents
Definition
Definition. Let $f: \mathbb{R} \mapsto \mathbb{R}_{+}$ be the probability density function (pdf) of the normal distribution The pdf of the two-piece normal is given by
$$
s(x) := s\left(x; \mu,\sigma_1,\sigma_2\right) =
\begin{cases}
\dfrac{2}{\sigma_1+\sigma_2}f\left(\dfrac{x-\mu}{\sigma_1}\right), \qquad \mbox{if } x < \mu, \\
\dfrac{2}{\sigma_1+\sigma_2}f\left(\dfrac{x-\mu}{\sigma_2}\right), \qquad \mbox{if } x \geq \mu. \\
\end{cases}
$$
Observations
- $\mu$ is the unique mode of $s(x)$
- $\sigma_1$ controls the spread of $s(x)$ on the left side
- $\sigma_2$ controls the spread of $s(x)$ on the right side
- If $\sigma_1 = \sigma_2 = \sigma$, then $s$ is simply the pdf of a normal distribution with parameters $\mu$ and $\sigma$
Python Implementation
I recently released the twopiece Python library which contains the implementation of the two-piece normal distribution among others. Here, we are going to explore the features of the two-piece normal using this package. You can find details on how to install and use it in my Github Repository: twopiece.
#Import tporm from twopiece.scale
from twopiece.scale import tpnorm
# Create an instance of tpnorm
dist = tpnorm(loc=0.0, sigma1=1.0, sigma2 =1.75)
Probability Density Function
loc=0.0
sigma1=1.0
for sigma2 in np.arange(0.5, 4, 1):
dist = tpnorm(loc=loc, sigma1=sigma1, sigma2=sigma2)
x = np.arange(-12, 12, 0.1)
y = dist.pdf(x)
plt.plot(x, y, label='sigma2 = ' + str(sigma2))

Cumulative Distribution Function
loc=0.0
sigma1=1.0
for sigma2 in np.arange(0.5, 4, 1):
dist = tpnorm(loc=loc, sigma1 =sigma1, sigma2=sigma2)
x = np.arange(-12, 12, 0.1)
y = dist.cdf(x)
plt.plot(x, y, label='sigma2 = ' + str(sigma2))
plt.legend(loc='lower right')
plt.title('Two-Piece Cumulative Distribution Functions')
plt.show()

Percent Point Function
loc=0.0
sigma1=1.0
for sigma2 in np.arange(0.5, 4, 1):
dist = tpnorm(loc=loc, sigma1 =sigma1, sigma2=sigma2)
x = np.arange(0.01, 0.99, 0.01)
y = dist.ppf(x)
plt.plot(x, y, label='sigma2 = ' + str(sigma2) )
plt.legend(loc='lower right')
plt.title('Two-Piece Quantile Function')
plt.show()

Random Sample Generation
dist = tpnorm(loc=0.0, sigma1=1.0, sigma2=2.0)
sample = dist.random_sample(size = 500)

Applications
The Two-Piece normal, and more generally the family of two-piece distributions, have been extensively used in applications such as:
- Bank of England Fan Charts for Inflation Report
- Measurement Errors Models
- Forecasting and Estimation of Risk
Future posts will provide details on some of these applications!
6 thoughts on “The Two Piece Normal Distribution”