Quadratic forms & positive definiteness
Read a quadratic form through the spectrum of its matrix, and use eigenvalue signs to test positive (semi)definiteness.
Loss surfaces, covariance matrices, and curvature in optimization all wear the same algebraic dress: a quadratic form. Reading the signs of the eigenvalues tells you whether the bowl opens up everywhere, flattens out, or has saddle directions.
Definition
A quadratic form in is a scalar function[1]
where . Without loss of generality, can always be taken symmetric: , so replace by its symmetrization. The cross-term shows that only the symmetric part matters.
For :
The level sets are ellipses (when the form is definite) or hyperbolas (when it is indefinite).
Definiteness
A symmetric matrix is called:
| Term | Condition | Eigenvalues |
|---|---|---|
| Positive definite (PD) | for all | All |
| Positive semidefinite (PSD) | for all | All |
| Negative definite (ND) | for all | All |
| Indefinite | Both signs occur | Mixed signs |
Proof that eigenvalue signs determine definiteness. By the spectral theorem . Substitute (bijective since is invertible):
If all , the sum is positive whenever , i.e. whenever . If some , choose (so ) to get . The sign pattern of the eigenvalues is exactly the definiteness.
Covariance matrices are PSD
If is a data matrix (rows are observations), the sample covariance (after centering) satisfies
so is PSD. Its eigenvalues are the squared singular values of , and they are nonnegative.
Sylvester's criterion (practical test)
For a symmetric , positive definiteness is equivalent to all leading principal minors being positive[2]. The -th leading principal minor is the determinant of the top-left block of :
This gives an test (compute determinants, each , amortized via Cholesky: if Cholesky succeeds, the matrix is PD).
Check it on arrays
import numpy as np
# PD matrix: A = Q diag(3,1) Q^T, eigenvalues 3 and 1
theta = np.pi / 6
Q = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
A = Q @ np.diag([3.0, 1.0]) @ Q.T
# Visualize q(x) on a grid and confirm q > 0 everywhere
x1, x2 = np.meshgrid(np.linspace(-1, 1, 40), np.linspace(-1, 1, 40))
X = np.stack([x1.ravel(), x2.ravel()])
q_vals = np.einsum("ij,jk,ik->i", X.T, A, X.T) # batched x^T A x
print("min quadratic form value:", q_vals.min()) # > 0 (PD)
# Indefinite matrix: eigenvalues 3 and -1
A_indef = Q @ np.diag([3.0, -1.0]) @ Q.T
q_indef = np.einsum("ij,jk,ik->i", X.T, A_indef, X.T)
print("indefinite: min =", q_indef.min(), "max =", q_indef.max()) # neg and pos
# Cholesky as PD test
try:
np.linalg.cholesky(A)
print("A is PD: Cholesky succeeded")
except np.linalg.LinAlgError:
print("not PD")
try:
np.linalg.cholesky(A_indef)
print("A_indef is PD")
except np.linalg.LinAlgError:
print("A_indef is not PD: Cholesky failed")The PD matrix's quadratic form stays positive; the indefinite one has both signs. Cholesky succeeds only for PD.
Exercises
Exercise 1. Classify by computing its eigenvalues, then confirm the classification with Sylvester's criterion.
Solution
Step 1. Solve . The characteristic polynomial is , so , giving and . Both eigenvalues are positive, so is positive definite.
Step 2. Check the leading principal minors. The first is ; the second is . Both are positive, so Sylvester's criterion confirms positive definiteness.
The two tests agree: the eigenvalue signs and the positivity of the leading minors both certify a bowl that opens upward in every direction.
Exercise 2. Prove that if is positive definite then is invertible, and that is also positive definite.
Solution
Step 1 (invertible). By the spectral theorem with all . The determinant is , so is invertible. (Equivalently, would give , forcing by definiteness, so the null space is trivial.)
Step 2 (inverse is PD). Invert the spectral form: , where has diagonal entries . Since each , each , so has all-positive eigenvalues and is positive definite.
A PD matrix and its inverse share eigenvectors and have reciprocal, still-positive, eigenvalues.
Exercise 3 (code). Generate a random symmetric matrix, shift it by until it becomes positive definite, and confirm that Cholesky succeeds exactly when the smallest eigenvalue turns positive.
Solution
import numpy as np
rng = np.random.default_rng(5)
M = rng.normal(size=(6, 6))
S = (M + M.T) / 2 # symmetric, generally indefinite
eigs = np.linalg.eigvalsh(S)
lam_min = eigs.min()
def is_pd(A):
try:
np.linalg.cholesky(A)
return True
except np.linalg.LinAlgError:
return False
# Shift just below and just above the threshold -lam_min.
I = np.eye(6)
below = S + (-lam_min - 0.01) * I # smallest eigenvalue still negative
above = S + (-lam_min + 0.01) * I # smallest eigenvalue now positive
assert not is_pd(below)
assert is_pd(above)
print("min eigenvalue of S:", round(float(lam_min), 4),
"-> PD once shifted past", round(float(-lam_min), 4))Cholesky fails while the shifted matrix still has a negative eigenvalue and succeeds the moment the shift makes every eigenvalue positive, which is the spectral characterization of positive definiteness at work.
The spectral decomposition of a rectangular matrix, where the same geometry extends to non-square transforms, is the SVD of the next lesson.
References
- [1]Horn, R. A., & Johnson, C. R. (2012). Matrix Analysis (2nd ed.). Cambridge University Press. Quadratic forms and the classification of definiteness by eigenvalue sign.↩
- [2]Golub, G. H., & Van Loan, C. F. (2013). Matrix Computations (4th ed.). Johns Hopkins University Press. Positive definiteness, Sylvester's criterion, and Cholesky as a test (doi:10.56021/9781421407944).↩