Advanced Examples

This page covers less common distributions, mixture models, truncated distributions, and edge cases that require special care.


Mixture Distributions

A mixture distribution combines two or more distributions with mixing weights that sum to 1.

Example — 50/50 mixture of Exponential(1) and Exponential(3):

Lower:  0
Upper:  inf
PDF:    0.5 * exp(-x) + 0.5 * 3 * exp(-3*x)  if x >= 0  else  0

Expected moments about origin:

The moments of a mixture are the weighted average of component moments:

\[\mu'_r = \sum_k w_k \cdot \mu'_{r,k}\]

For Exponential(\(\lambda\)): \(\mu'_r = r! / \lambda^r\)

μ₁ = 0.5*(1/1) + 0.5*(1/3)  = 0.6667
μ₂ = 0.5*(2/1) + 0.5*(2/9)  = 1.1111
μ₃ = 0.5*(6/1) + 0.5*(6/27) = 3.1111

Mixture of Normal Distributions

Example — Bimodal mixture: Normal(−2, 1) and Normal(3, 0.5):

Lower:  -inf
Upper:  inf
PDF:    0.6 * exp(-((x+2)**2)/2) / sqrt(2*pi)
        + 0.4 * exp(-((x-3)**2) / 0.5) / (0.5 * sqrt(2*pi))

Note

This is a multi-line expression; enter it as a single line in ToFUL. The PDF has no if/else conditional, so SymPy will attempt symbolic integration. For this mixture form, it typically succeeds.


Truncated Distributions

A truncated distribution restricts a base distribution to a subinterval and renormalises. The renormalisation constant must be computed and included explicitly.

Example — Truncated Exponential(2) on [0, 1]:

The normalising constant is: \(C = \int_0^1 2e^{-2x}\,dx = 1 - e^{-2} \approx 0.8647\)

Lower:  0
Upper:  1
PDF:    2 * exp(-2*x) / (1 - exp(-2))  if  0 <= x <= 1  else  0

Alternatively, compute the constant numerically:

PDF:    (2 * exp(-2*x)) / 0.8647  if  0 <= x <= 1  else  0

Tip

If you are unsure of the normalising constant, enter the unnormalised version first and read off the integral shown in the validation message. Then divide by that constant and recompute.


Zero-Inflated Distributions

A zero-inflated distribution places extra probability mass at zero beyond what the base distribution provides.

Example — Zero-Inflated Poisson (ZIP) with λ=3, inflation π=0.2:

\[P(X=0) = \pi + (1-\pi)e^{-\lambda}, \quad P(X=x) = (1-\pi)\frac{e^{-\lambda}\lambda^x}{x!} \text{ for } x \geq 1\]
Range:  0,1,2,3,...
PMF:    (0.2 + 0.8*exp(-3)) if x == 0 else (0.8 * exp(-3) * 3**x / factorial(x))

Known mean:

\[E[X] = (1-\pi)\lambda = 0.8 \times 3 = 2.4\]

Piecewise Linear Distribution

Example — Ascending ramp on [0,2], flat on [2,3]:

Normalising constant: area under the ramp = 1, area under flat = 0.5. Total = 1.5. Divide by 1.5 to get the PDF.

Lower:  0
Upper:  3
PDF:    (x / 1.5) if 0<=x<=2 else (2/3) if 2<x<=3 else 0

Verification: \(\int_0^2 x/1.5\,dx + \int_2^3 2/3\,dx = 4/3 \cdot 1 + 2/3 = 2/3 + 2/3 = ...\)

Use ToFUL’s validation step to confirm the PDF integrates to 1 before trusting the moments.


High-Order Moments

Computing moments of order r > 10 requires care:

  • The moment values grow rapidly with r for most distributions, easily exceeding float64 range for heavy-tailed distributions.

  • Convergence accelerators become less stable at very high orders.

  • Increase Calc precision to 12–15 when computing r > 8.

Example — Exponential(1) up to r=8:

Range:  [0, inf]
PDF:    exp(-x) if x >= 0 else 0
Max order: 8

Expected values (\(\mu'_r = r!\)):

Order

Value

μ₁

1

μ₂

2

μ₃

6

μ₄

24

μ₅

120

μ₆

720

μ₇

5040

μ₈

40320


Verifying a Custom Distribution

If you derive a novel PMF or PDF and want to verify it integrates / sums to 1 before computing moments:

  1. Enter the function with a moment order of 1.

  2. Check the validation badge — it shows the computed sum/integral.

  3. If it does not equal 1, adjust the normalising constant and retry.

  4. Once validated, increase the moment order and compute.

This workflow is more reliable than trying to compute the normalising constant analytically for complex expressions.

See also