33. Adv: Hermitian and unitary matrices (complex case)

📖 Reading · 9 min
💡 Every code box below is live — edit it and hit Run.

§21.0's Spectral Theorem was stated for real symmetric matrices. This lesson extends every idea in it to complex vector spaces, where transpose alone stops being the right operation — it needs one small but essential upgrade, conjugation, and everything else follows the same pattern as before.

The conjugate transpose

For a complex matrix A, the conjugate transpose (or Hermitian adjoint) is A^*=\bar A^T — transpose, then conjugate every entry (or conjugate then transpose; the two commute). For a real matrix, conjugation does nothing, so A^*=A^T exactly — every definition below reduces to its §16–20 counterpart whenever A is real, which is the guiding check for all of this lesson.

Why plain transpose stops being enough: §20.0's dot product \vec u\cdot\vec u=\sum u_i^2 can be negative for complex \vec u (e.g. \vec u=(i,0) gives u_1^2=i^2=-1), breaking positive definiteness (§20.1) outright. The fix is the complex (Hermitian) inner product \langle\vec u,\vec v\rangle=\vec u^*\vec v=\sum\bar u_iv_i, for which \langle\vec v,\vec v\rangle=\sum|v_i|^2\ge0 always — genuinely nonnegative, restoring §20.1's axiom 3, with equality only at \vec v=\vec0.

Hermitian matrices

A is Hermitian if A^*=A — the direct complex analogue of symmetric (A^T=A). The Spectral Theorem holds for Hermitian matrices exactly as stated in §21.0: real eigenvalues, and an orthonormal (now with respect to the Hermitian inner product) eigenbasis, giving A=Q\Lambda Q^* (conjugate transpose replacing plain transpose throughout). Every proof from §21.0 carries over by replacing \cdot with \langle\cdot,\cdot\rangle and ^T with ^* verbatim.

A genuinely real matrix that's symmetric is automatically Hermitian (since A^*=A^T=A when every entry is real) — so §21.0's theorem is literally the special case of this one restricted to real entries, not a separate result needing its own proof.

Unitary matrices

Q is unitary if Q^*Q=I — the complex analogue of an orthogonal matrix (Q^TQ=I, §20.4). Unitary matrices preserve the Hermitian inner product exactly as orthogonal matrices preserve the dot product: \langle Q\vec u,Q\vec v\rangle=(Q\vec u)^*(Q\vec v)=\vec u^*Q^*Q\vec v=\vec u^*\vec v=\langle\vec u,\vec v\rangle — lengths and angles both unchanged. Q^{-1}=Q^* for unitary Q, exactly matching §20.4's P^{-1}=P^T for orthogonal P.

A real orthogonal matrix is automatically unitary (same reasoning as above), so "unitary" is the correct general term whenever complex entries might appear — §18.2's rotation matrices are real orthogonal matrices, and hence also unitary, without any extra work.

Doing it in Python

import numpy as np

A = np.array([[2, 1+1j], [1-1j, 3]])   # Hermitian: A* = A

print("A* == A:", np.allclose(A.conj().T, A), " (Hermitian)")

eigvals = np.linalg.eigvalsh(A)   # eigvalsh: for Hermitian matrices
print("eigenvalues (should be real):", [round(float(v), 4) for v in eigvals])
A* == A: True  (Hermitian)
eigenvalues (should be real): [1.0, 4.0]

A unitary matrix — a complex rotation-like transformation — checked directly:

import numpy as np

theta = np.pi / 4
Q = np.array([[np.cos(theta), -np.sin(theta)],
              [np.sin(theta),  np.cos(theta)]]).astype(complex)   # real orthogonal -> unitary

print("Q* Q == I:", bool(np.allclose(Q.conj().T @ Q, np.eye(2))))

# A genuinely complex unitary matrix
U = np.array([[1, 1j], [1j, 1]]) / np.sqrt(2)
print("U* U == I:", bool(np.allclose(U.conj().T @ U, np.eye(2))))
Q* Q == I: True
U* U == I: True

Worked example

Verify A=\begin{pmatrix}1&2-i\\2+i&3\end{pmatrix} is Hermitian, and find its eigenvalues.

A^*: transpose gives \begin{pmatrix}1&2+i\\2-i&3\end{pmatrix}, then conjugate every entry: \begin{pmatrix}1&2-i\\2+i&3\end{pmatrix}=A ✓ Hermitian (the diagonal entries 1,3 are real, automatically self-conjugate, and the off-diagonal entries are conjugates of each other — the general pattern for any Hermitian matrix).

\operatorname{tr}A=4. \det A=1(3)-(2-i)(2+i)=3-(4-i^2)=3-(4+1)=3-5=-2 (using (2-i)(2+i)=4-i^2=4+1=5, the standard complex-conjugate-product identity). Characteristic equation: \lambda^2-4\lambda-2=0\Rightarrow\lambda=\frac{4\pm\sqrt{16+8}}2=2\pm\sqrt6.

\boxed{\lambda=2+\sqrt6\approx4.449,\quad\lambda=2-\sqrt6\approx-0.449}

Sanity check. Both eigenvalues are real, exactly as the extended Spectral Theorem guarantees for a Hermitian matrix, despite A itself having genuinely complex (non-real) entries — the theorem's promise holds regardless of whether the entries look real. Sum: (2+\sqrt6)+(2-\sqrt6)=4=\operatorname{tr}A ✓; product: (2+\sqrt6)(2-\sqrt6)=4-6=-2=\det A ✓.

Your turn

1. Is A=\begin{pmatrix}0&i\\-i&0\end{pmatrix} Hermitian? Compute A^* directly.

2. True or false: a real orthogonal matrix is always unitary.

3. For unitary Q, what is \det Q's magnitude, |\det Q|? (Hint: use Q^*Q=I and \det(Q^*)=\overline{\det Q}.)

Solutions

1. Yes, Hermitian. Transpose: \begin{pmatrix}0&-i\\i&0\end{pmatrix}. Conjugate every entry: \begin{pmatrix}0&i\\-i&0\end{pmatrix}=A ✓. (This is one of the Pauli matrices, foundational in quantum mechanics — Hermitian matrices represent physical observables there precisely because their eigenvalues are guaranteed real, matching measurable quantities.)

2. True. Shown directly in this lesson: for real Q, conjugation does nothing, so Q^*=Q^T, and Q^TQ=I (orthogonal, §20.4) is literally the same equation as Q^*Q=I (unitary) — no additional condition to check.

3. |\det Q|=1. \det(Q^*Q)=\det I=1. \det(Q^*)\det(Q)=1, and \det(Q^*)=\overline{\det Q} (conjugating every entry conjugates the determinant, which is a polynomial in the entries), so \overline{\det Q}\cdot\det Q=|\det Q|^2=1\Rightarrow|\det Q|=1. (This matches §18.2's real case exactly: a rotation matrix has \det=\pm1, both of magnitude 1.)

Check yourself in code

Verify A=\begin{pmatrix}4&2-2i\\2+2i&1\end{pmatrix} is Hermitian and find its eigenvalues (rounded to 4 decimal places).

Print exactly this:

Hermitian: True
eigenvalues: [-0.7016, 5.7016]
import numpy as np

A = np.array([[4, 2-2j], [2+2j, 1]])
print("Hermitian:", bool(np.allclose(A.conj().T, A)))
# print the eigenvalues (via np.linalg.eigvalsh), rounded to 4 decimal places
import numpy as np

A = np.array([[4, 2-2j], [2+2j, 1]])
print("Hermitian:", bool(np.allclose(A.conj().T, A)))

eigvals = np.linalg.eigvalsh(A)
print("eigenvalues:", [round(float(v), 4) for v in eigvals])

The conjugate transpose A^*=\bar A^T is the complex-safe replacement for plain transpose: Hermitian (A^*=A) generalizes symmetric, unitary (Q^*Q=I) generalizes orthogonal, and the Spectral Theorem carries over verbatim — real eigenvalues, orthonormal eigenbasis. Every real symmetric/orthogonal matrix is automatically Hermitian/unitary, so nothing from §21.0 is lost, only extended.

Next, back to the real case with a different structural question: which symmetric matrices have positive eigenvalues, and why that turns out to matter enormously in optimization and statistics.