October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

scipy.stats.multivariate_normal: pdf, cdf, rvs and fit (With Examples)

A practical SciPy v1.18.0 guide to multivariate_normal: input shapes, pdf and logpdf, rectangular cdf probabilities, seeded samples, fitting caveats, and singular covariance.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

scipy.stats.multivariate_normal handles four different jobs: evaluate density with pdf, compute cumulative probability with cdf, draw samples with rvs, and estimate parameters with fit. The examples below target the SciPy v1.18.0 API. The key shape rule is that the final axis of each point array contains the vector’s components.

What mean and covariance represent

A multivariate normal distribution describes a vector of related variables. Its mean is the location vector, and its cov describes variance in each component and covariance between components. For a two-component distribution, for example, the mean has shape (2,) and a full covariance matrix has shape (2, 2).

As an Amazon Associate I earn from qualifying purchases.

The SciPy v1.18.0 reference describes multivariate_normal as “A multivariate normal random variable.” Its API reference accepts covariance as a scalar (a multiple of the identity matrix), a vector of diagonal entries, a two-dimensional array, or a Covariance object. If mean is omitted, the mean is the zero vector.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import numpy as np
from scipy.stats import multivariate_normal

mean = np.array([0.0, 1.0])
cov = np.array([[1.0, 0.4],
                [0.4, 2.0]])

Choose direct calls or a frozen distribution

Use the module-level methods when parameters are supplied for an individual operation. Construct a frozen distribution when you will reuse the same mean and covariance; the object retains those parameters for subsequent calls.

# Direct call: provide parameters to the method
value = multivariate_normal.pdf([0.5, 1.2], mean=mean, cov=cov)

# Frozen distribution: provide parameters once
rv = multivariate_normal(mean=mean, cov=cov)
value_again = rv.pdf([0.5, 1.2])

For both calls, the point has shape (2,): its final axis lists the two components.

Evaluate density with pdf and logpdf

pdf(x, mean=None, cov=1, allow_singular=False) evaluates the probability density at each point. It does not return the probability that a continuous random variable equals that exact point; a density is a value used to describe probability over regions.

The density is based on the distance from the mean under the covariance geometry. For a full-rank covariance matrix Σ, the documented expression uses its determinant and inverse:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

f(x) = 1 / sqrt((2π)^k det(Σ)) × exp(-1/2 (x − μ)ᵀΣ⁻¹(x − μ))

Here μ is the mean and k is the rank of Σ. For calculations where very small densities could underflow, use logpdf to obtain log density instead.

points = np.array([
    [0.5, 1.2],
    [1.0, 0.0],
])  # shape (n, d): two points, two components each

densities = rv.pdf(points)       # shape (2,)
log_densities = rv.logpdf(points)  # shape (2,)

More generally, x may have shape (d,) for one point, (n, d) for a batch, or (..., d) for a grid or higher-dimensional batch. In every case the final dimension d identifies components; preceding dimensions identify points.

Compute cumulative probability with cdf

cdf(x, mean=None, cov=1, allow_singular=False, maxpts=1000000*dim, abseps=1e-5, releps=1e-5, lower_limit=None) computes cumulative probability up to the supplied upper point. For a multivariate distribution, this concerns a rectangular region, not a one-dimensional interval.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For example, the following requests the probability that both components are at most the corresponding upper limits. The vector’s final axis contains the two component bounds.

upper = np.array([1.0, 2.0])  # shape (d,)
p = rv.cdf(upper)

To calculate probability within a rectangular box, provide its lower and upper corners. The optional lower_limit defines the lower corner; the x argument remains the upper corner.

lower = np.array([-1.0, 0.0])
upper = np.array([1.0, 2.0])
p_box = rv.cdf(upper, lower_limit=lower)

The CDF API exposes maxpts, abseps, and releps to control the numerical integration work budget and error tolerances. Increase the point budget or tighten tolerances when the calculation’s accuracy requirements call for it, recognizing that the work and runtime may increase. The result is a numerical CDF calculation, so do not treat the tolerances as a guarantee that every problem reaches those errors.

Generate random draws with rvs

rvs(mean=None, cov=1, size=1, random_state=None) draws random vectors. When using a frozen object, its parameters are already set; specify the number of draws with size. For repeatable results, pass an explicitly seeded random generator and keep or recreate its state as intended.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
rng = np.random.default_rng(42)
samples = rv.rvs(size=5, random_state=rng)
# For a two-component distribution, samples has shape (5, 2).

The constructor also accepts a seed argument, which may be None, an integer, a RandomState, or a Generator. Reproducibility depends on using the same seed and state progression: reusing an already-advanced generator does not restart its sequence.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Fit parameters with fit

The SciPy v1.18.0 reference lists fit(x, fix_mean=None, fix_cov=None), but that signature alone does not specify the data orientation, estimator, return structure, or precise behavior of fixed parameters. Because those details determine whether a fit is correct, do not infer them from the similarly named univariate fitting API or assume a particular shape or return value without checking the targeted release’s implementation and documentation.

Before relying on fit, consult the version-specific SciPy multivariate-normal reference and confirm those details for the installed release. This article therefore does not present a fitting code example that would imply unverified orientation or output behavior.

Check covariance validity and singular cases

For an ordinary array covariance, allow_singular=False is the default and the covariance must be strictly positive definite. Set allow_singular=True only when a positive-semidefinite covariance is intentionally rank-deficient; SciPy then uses a pseudo-inverse and pseudo-determinant for the degenerate case.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

With array input, SciPy does not check covariance symmetry and uses only its lower-triangular portion. Supply a genuinely symmetric covariance matrix rather than relying on the function to validate or repair it. If cov is a Covariance object, allow_singular is ignored.

# Example of an intentionally rank-deficient covariance:
singular_cov = np.array([[1.0, 1.0],
                         [1.0, 1.0]])
rv_singular = multivariate_normal(
    mean=[0.0, 0.0],
    cov=singular_cov,
    allow_singular=True,
)

A singular covariance describes a distribution confined to a lower-dimensional subspace, rather than an ordinary full-dimensional density. SciPy documents an extension of the density definition for this case; consult its reference for the degenerate-case treatment.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.