WISHART
Overview
The WISHART
function computes the probability density function (PDF), log-PDF, or draws random samples from the Wishart distribution, a fundamental multivariate distribution for symmetric positive definite matrices. The Wishart distribution is widely used in statistics, especially in multivariate analysis, covariance estimation, and Bayesian statistics. The PDF for a matrix is:
where is the degrees of freedom, is the scale matrix, is the determinant, and is the multivariate gamma function. For more details, see the scipy.stats.wishart documentation .
This wrapper exposes only the most commonly used parameters: matrix input , degrees of freedom , scale matrix , method (pdf
, logpdf
, or rvs
), and sample size for random draws. Parameters for random state or advanced options are not supported. This example function is provided as-is without any representation of accuracy.
Usage
To use the function in Excel:
=WISHART(x, df, scale, [method], [size])
x
(2D array, required): Square matrix (as a 2D array) at which to evaluate the PDF/log-PDF, or ignored for random sampling.df
(integer, required): Degrees of freedom, must be greater than or equal to the dimension of the scale matrix.scale
(2D array, required): Symmetric positive definite scale matrix (2D array).method
(string, optional, default=pdf
): Which method to compute:pdf
,logpdf
, orrvs
.size
(integer, optional, only forrvs
, default=1): Number of random samples to draw.
The function returns a 2D array of results for each input, or an error message (string) if the input is invalid. For pdf
and logpdf
, the output is a single value in a 2D array. For rvs
, the output is a matrix (for one sample) or a list of matrices (for multiple samples).
Examples
Example 1: PDF Evaluation
Inputs:
x | df | scale | method | ||
---|---|---|---|---|---|
2.0 | 0.5 | 4 | 1.0 | 0.2 | |
0.5 | 1.0 | 0.2 | 0.5 |
Excel formula:
=WISHART({2,0.5;0.5,1}, 4, {1,0.2;0.2,0.5}, "pdf")
Expected output:
Result |
---|
0.035 |
Example 2: Log-PDF Evaluation
Inputs:
x | df | scale | method | ||
---|---|---|---|---|---|
2.0 | 0.5 | 4 | 1.0 | 0.2 | logpdf |
0.5 | 1.0 | 0.2 | 0.5 |
Excel formula:
=WISHART({2,0.5;0.5,1}, 4, {1,0.2;0.2,0.5}, "logpdf")
Expected output:
Result |
---|
-3.348 |
Example 3: Random Sample (Single)
Inputs:
x | df | scale | method | size | ||
---|---|---|---|---|---|---|
2.0 | 0.5 | 4 | 1.0 | 0.2 | rvs | 1 |
0.5 | 1.0 | 0.2 | 0.5 |
Excel formula:
=WISHART({2,0.5;0.5,1}, 4, {1,0.2;0.2,0.5}, "rvs", 1)
Expected output:
5.900 | 0.579 |
0.579 | 2.171 |
Example 4: Random Samples (Multiple)
Inputs:
x | df | scale | method | size | ||
---|---|---|---|---|---|---|
2.0 | 0.5 | 4 | 1.0 | 0.2 | rvs | 2 |
0.5 | 1.0 | 0.2 | 0.5 |
Excel formula:
=WISHART({2,0.5;0.5,1}, 4, {1,0.2;0.2,0.5}, "rvs", 2)
Expected output:
4.615 | -1.352 |
-1.352 | 2.453 |
7.497 | 1.428 |
1.428 | 0.872 |
For multiple samples, each pair of rows represents a sample matrix drawn from the Wishart distribution.
Python Code
from scipy.stats import wishart as scipy_wishart
from typing import List, Optional, Union
def wishart(x: List[List[float]], df: int, scale: List[List[float]], method: str = 'pdf', size: Optional[int] = None) -> Union[List[List[Optional[float]]], str]:
"""
Computes the PDF, log-PDF, or draws random samples from a Wishart distribution.
Args:
x: 2D list of float values. Points (matrices) at which to evaluate the function or draw samples.
df: Degrees of freedom (int), must be greater than or equal to the dimension of the scale matrix.
scale: 2D list of float values. Symmetric positive definite scale matrix of the distribution.
method: Which method to compute (str): 'pdf', 'logpdf', 'rvs'. Default is 'pdf'.
size: Number of samples to draw if method is 'rvs'. Optional.
Returns:
2D list of results for each input, or an error message (str) if input is invalid.
This example function is provided as-is without any representation of accuracy.
"""
# Validate scale matrix
if not isinstance(scale, list) or len(scale) < 2 or not all(isinstance(row, list) and len(row) == len(scale) for row in scale):
return "Invalid input: scale must be a 2D square list with at least two rows."
# Validate x
if not isinstance(x, list) or len(x) < 2 or not all(isinstance(row, list) and len(row) == len(x) for row in x):
return "Invalid input: x must be a 2D square list with at least two rows."
# Validate df
if not isinstance(df, int) or df < len(scale):
return "Invalid input: df must be an integer >= dimension of scale matrix."
# Validate method
if method not in ['pdf', 'logpdf', 'rvs']:
return "Invalid input: method must be one of 'pdf', 'logpdf', or 'rvs'."
# Validate size
if method == 'rvs' and size is not None and (not isinstance(size, int) or size < 1):
return "Invalid input: size must be a positive integer."
import numpy as np
try:
scale_np = np.array(scale, dtype=float)
x_np = np.array(x, dtype=float)
except Exception:
return "Invalid input: scale and x must contain numeric values."
# Check positive definiteness
try:
np.linalg.cholesky(scale_np)
except Exception:
return "Invalid input: scale matrix must be symmetric positive definite."
# PDF and logPDF require x to be a square matrix of same dimension as scale
if method in ['pdf', 'logpdf']:
if x_np.shape != scale_np.shape:
return "Invalid input: x and scale must be square matrices of the same dimension for 'pdf' and 'logpdf'."
dist = scipy_wishart(df, scale_np)
try:
if method == 'pdf':
val = dist.pdf(x_np)
else:
val = dist.logpdf(x_np)
except Exception as e:
return f"scipy.stats.wishart error: {e}"
# Return as 2D list [[value]]
if isinstance(val, (int, float)):
if np.isnan(val) or np.isinf(val):
return [["Invalid output: result is NaN or Inf."]]
return [[float(val)]]
return [[str(val)]]
elif method == 'rvs':
dist = scipy_wishart(df, scale_np)
try:
samples = dist.rvs(size=size) if size is not None else dist.rvs()
except Exception as e:
return f"scipy.stats.wishart error: {e}"
# If size is None, samples is a single matrix; else, samples is an array of matrices
def matrix_to_2dlist(mat):
return [[float(val) if not (np.isnan(val) or np.isinf(val)) else None for val in row] for row in mat]
if size is None:
return matrix_to_2dlist(samples)
else:
# samples.shape = (size, dim, dim)
return [matrix_to_2dlist(samples[i]) for i in range(samples.shape[0])]
return "Unknown error."