Skip to Content

MULTIVARIATE_NORMAL

Overview

The MULTIVARIATE_NORMAL function computes the probability density function (PDF), cumulative distribution function (CDF), log-PDF, log-CDF, entropy, or draws random samples from a multivariate normal (Gaussian) distribution. This is useful for modeling joint distributions of multiple correlated variables in statistics, finance, engineering, and data science. The multivariate normal distribution generalizes the univariate normal distribution to higher dimensions, allowing for specification of a mean vector and covariance matrix:

f(x)=1(2π)kΣexp(12(xμ)TΣ1(xμ))f(\mathbf{x}) = \frac{1}{\sqrt{(2\pi)^k |\Sigma|}} \exp\left(-\frac{1}{2} (\mathbf{x} - \boldsymbol{\mu})^T \Sigma^{-1} (\mathbf{x} - \boldsymbol{\mu})\right)

where x\mathbf{x} is a kk-dimensional vector, μ\boldsymbol{\mu} is the mean vector, and Σ\Sigma is the covariance matrix. For more details, see the scipy.stats.multivariate_normal documentation.

This wrapper exposes only the most commonly used parameters: x, mean, cov, method, and optionally size for random sampling. Advanced options and numerical integration parameters are not supported. This example function is provided as-is without any representation of accuracy.

Usage

To use the function in Excel:

=MULTIVARIATE_NORMAL(x, mean, cov, [method], [size])
  • x (2D list, required): Table of points at which to evaluate the function. Each row is a point, each column is a variable.
  • mean (2D column vector, required): Mean vector of the distribution. Must have the same number of rows as columns in x.
  • cov (2D matrix, required): Covariance matrix of the distribution. Must be square with size equal to the number of variables.
  • method (string, optional, default=pdf): Which method to compute: pdf, cdf, logpdf, logcdf, entropy, or rvs.
  • size (integer, optional): Number of samples to draw if method is rvs.

The function returns a 2D list of results for each input point, or an error message (string) if the input is invalid. For rvs, returns a 2D list of samples. For entropy, returns the same entropy value for each input row.

Examples

Example 1: Basic PDF Calculation

Inputs:

xmeancovmethod
0.00.00.00.01.00.0pdf
1.01.00.01.0

Excel formula:

=MULTIVARIATE_NORMAL({0,0;1,1}, {0;0}, {1,0;0,1})

Expected output:

Result
0.159
0.059

Example 2: CDF with Nonzero Mean

Inputs:

xmeancovmethod
0.00.01.01.01.00.0cdf
1.01.00.01.0

Excel formula:

=MULTIVARIATE_NORMAL({0,0;1,1}, {1;1}, {1,0;0,1}, "cdf")

Expected output:

Result
0.025
0.250

Example 3: Entropy Calculation

Inputs:

xmeancovmethod
0.00.00.00.01.00.0entropy
1.01.00.01.0

Excel formula:

=MULTIVARIATE_NORMAL({0,0;1,1}, {0;0}, {1,0;0,1}, "entropy")

Expected output:

Result
2.838
2.838

Example 4: Draw Random Samples

Inputs:

meancovmethodsize
0.00.01.00.0rvs2
0.01.0

Excel formula:

=MULTIVARIATE_NORMAL(, {0;0}, {1,0;0,1}, "rvs", 2)

Expected output:

Sample 1Sample 2
(values will vary)(values will vary)

For rvs, the output is a 2D list of two samples, each with two values. The actual values will vary each time the function is called.

Python Code

from scipy.stats import multivariate_normal as scipy_multivariate_normal from typing import List, Optional, Union def multivariate_normal( x: List[List[float]], mean: Optional[List[List[float]]] = None, cov: Optional[List[List[float]]] = None, method: str = 'pdf', size: Optional[int] = None ) -> Union[List[List[Optional[float]]], str]: """ Computes the PDF, CDF, log-PDF, log-CDF, entropy, or draws random samples from a multivariate normal distribution. Args: x: 2D list of float values. Points at which to evaluate the function or fit the distribution. mean: 2D list of float values (column vector). Mean of the distribution. Default is zero vector. cov: 2D list of float values. Covariance matrix of the distribution. Default is identity matrix. method: Which method to compute (str): 'pdf', 'cdf', 'logpdf', 'logcdf', 'entropy', 'rvs'. Default is 'pdf'. size: Number of samples to draw if method is 'rvs'. Optional. Returns: 2D list of results for each input point, or an error message (str) if input is invalid. This example function is provided as-is without any representation of accuracy. """ # Validate x if not isinstance(x, list) or not all(isinstance(row, list) for row in x): return "Invalid input: x must be a 2D list of floats." if len(x) == 0 or len(x[0]) == 0: return "Invalid input: x must be a non-empty 2D list." n_dim = len(x[0]) # Validate mean if mean is None: mean_vec = [0.0] * n_dim else: if not isinstance(mean, list) or not all(isinstance(row, list) for row in mean): return "Invalid input: mean must be a 2D list (column vector)." if len(mean) != n_dim or any(len(row) != 1 for row in mean): return "Invalid input: mean must be a column vector with same dimension as x." try: mean_vec = [float(row[0]) for row in mean] except Exception: return "Invalid input: mean must contain numeric values." # Validate cov if cov is None: cov_mat = [[float(i == j) for j in range(n_dim)] for i in range(n_dim)] else: if not isinstance(cov, list) or len(cov) != n_dim or any(len(row) != n_dim for row in cov): return "Invalid input: cov must be a square 2D list with shape (n_dim, n_dim)." try: cov_mat = [[float(val) for val in row] for row in cov] except Exception: return "Invalid input: cov must contain numeric values." # Validate method valid_methods = {'pdf', 'cdf', 'logpdf', 'logcdf', 'entropy', 'rvs'} if method not in valid_methods: return f"Invalid method: {method}. Must be one of {sorted(valid_methods)}." # Validate size if method == 'rvs': if size is None: return "Invalid input: size must be specified for method 'rvs'." if not isinstance(size, int) or size <= 0: return "Invalid input: size must be a positive integer." # Try to create the distribution try: dist = scipy_multivariate_normal(mean=mean_vec, cov=cov_mat) except Exception as e: return f"scipy.multivariate_normal error: {e}" # Compute result try: if method == 'pdf': result = [[float(dist.pdf(row))] for row in x] elif method == 'cdf': result = [[float(dist.cdf(row))] for row in x] elif method == 'logpdf': result = [[float(dist.logpdf(row))] for row in x] elif method == 'logcdf': result = [[float(dist.logcdf(row))] for row in x] elif method == 'entropy': ent = float(dist.entropy()) result = [[ent] for _ in x] elif method == 'rvs': samples = dist.rvs(size=size) # Ensure samples is 2D list if n_dim == 1: samples = [[float(s)] for s in samples] else: samples = [list(map(float, row)) for row in samples] result = samples if size > 1 else [samples] else: return f"Invalid method: {method}." except Exception as e: return f"scipy.multivariate_normal error: {e}" # Check for invalid values import math for row in result: for val in row: if isinstance(val, float) and (math.isnan(val) or math.isinf(val)): return "Invalid output: result contains NaN or Inf." return result

Example Workbook

Link to Workbook

Last updated on