.. _examples-advanced: Advanced Examples ================== This page covers less common distributions, mixture models, truncated distributions, and edge cases that require special care. .. contents:: On this page :local: :depth: 2 ---- 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):** .. code-block:: text 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: .. math:: \mu'_r = \sum_k w_k \cdot \mu'_{r,k} For Exponential(:math:`\lambda`): :math:`\mu'_r = r! / \lambda^r` .. code-block:: text μ₁ = 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):** .. code-block:: text 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: :math:`C = \int_0^1 2e^{-2x}\,dx = 1 - e^{-2} \approx 0.8647` .. code-block:: text Lower: 0 Upper: 1 PDF: 2 * exp(-2*x) / (1 - exp(-2)) if 0 <= x <= 1 else 0 Alternatively, compute the constant numerically: .. code-block:: text 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:** .. math:: 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 .. code-block:: text 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:** .. math:: 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. .. code-block:: text Lower: 0 Upper: 3 PDF: (x / 1.5) if 0<=x<=2 else (2/3) if 2 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:** .. code-block:: text Range: [0, inf] PDF: exp(-x) if x >= 0 else 0 Max order: 8 **Expected values** (:math:`\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 -------- * :doc:`/user-guide/discrete-rv` — handling infinite DRV support * :doc:`/user-guide/continuous-rv` — choosing integration method * :doc:`/troubleshooting/common-errors` — fixing validation failures