DM_LOGBETA
This function computes the log of the multivariate beta function for a Dirichlet concentration vector. The result is the normalization term used in Dirichlet and Dirichlet-Multinomial log-density and log-evidence calculations.
For concentration parameters \boldsymbol{\alpha}=(\alpha_1,\ldots,\alpha_K), the log-normalization term is:
\log B(\boldsymbol{\alpha}) = \sum_{i=1}^K \log\Gamma(\alpha_i) - \log\Gamma\!\left(\sum_{i=1}^K \alpha_i\right)
Using \log\Gamma(\cdot) directly provides stable computation for large or small positive parameters.
Excel Usage
=DM_LOGBETA(alpha)
alpha(list[list], required): Dirichlet concentration parameters as a 2D range of positive values.
Returns (float): Log of the multivariate beta function for the provided concentration parameters.
Example 1: Symmetric three-category concentration vector
Inputs:
| alpha | ||
|---|---|---|
| 2 | 2 | 2 |
Excel formula:
=DM_LOGBETA({2,2,2})
Expected output:
-4.78749
Example 2: Uneven four-category concentration vector
Inputs:
| alpha | |||
|---|---|---|---|
| 5 | 1.5 | 3 | 2.5 |
Excel formula:
=DM_LOGBETA({5,1.5,3,2.5})
Expected output:
-13.4672
Example 3: Matrix-shaped concentration input is flattened
Inputs:
| alpha | |
|---|---|
| 1.2 | 2.8 |
| 3.1 | 4.4 |
Excel formula:
=DM_LOGBETA({1.2,2.8;3.1,4.4})
Expected output:
-12.7572
Example 4: Larger concentration values remain stable in log-space
Inputs:
| alpha | ||
|---|---|---|
| 25 | 40 | 35 |
Excel formula:
=DM_LOGBETA({25,40,35})
Expected output:
-109.137
Python Code
import numpy as np
from scipy.special import gammaln as scipy_gammaln
def dm_logbeta(alpha):
"""
Compute the Dirichlet log-normalization term using log-gamma values.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.gammaln.html
This example function is provided as-is without any representation of accuracy.
Args:
alpha (list[list]): Dirichlet concentration parameters as a 2D range of positive values.
Returns:
float: Log of the multivariate beta function for the provided concentration parameters.
"""
try:
def to2d(v):
return [[v]] if not isinstance(v, list) else v
alpha = to2d(alpha)
if not isinstance(alpha, list) or not all(isinstance(row, list) for row in alpha):
return "Error: alpha must be a 2D list"
alpha_flat = []
for row in alpha:
for val in row:
try:
alpha_flat.append(float(val))
except (TypeError, ValueError):
continue
if len(alpha_flat) < 2:
return "Error: alpha must contain at least two positive values"
if any(a <= 0 for a in alpha_flat):
return "Error: alpha values must be positive"
alpha_arr = np.asarray(alpha_flat, dtype=float)
return float(np.sum(scipy_gammaln(alpha_arr)) - scipy_gammaln(np.sum(alpha_arr)))
except Exception as e:
return f"Error: {str(e)}"