Module 5 · Lesson 3
Solving Linear Systems
To solve Ax = b for x, use np.linalg.solve(A, b). It is faster and
numerically more stable than computing np.linalg.inv(A) @ b — computing
a full inverse does unnecessary extra work and amplifies floating-point
error. Prefer solve over inv whenever you just need x.
np.linalg.det(A) computes the determinant. A matrix with det(A) == 0
is singular — it has no unique inverse, and np.linalg.solve will
raise a LinAlgError for it.
That said, not every LAPACK build raises reliably for a singular matrix —
some just hand back nan/inf values instead of erroring. np.isfinite(x)
is the elementwise check for exactly this: it returns False wherever a
value is nan or inf, and True everywhere else, so np.all(np.isfinite(x))
tells you in one line whether an entire array/result is “clean” (no
nan/inf anywhere).
A = np.array([[3.0, 1.0], [1.0, 2.0]])
b = np.array([9.0, 8.0])
x = np.linalg.solve(A, b)
print("solution x:", x)
print("check A @ x == b:", np.allclose(A @ x, b))
print("det(A):", np.linalg.det(A))
singular = np.array([[1.0, 2.0], [2.0, 4.0]]) # second row = 2 * first row
print("det(singular):", np.linalg.det(singular))
try:
np.linalg.solve(singular, np.array([1.0, 2.0]))
except np.linalg.LinAlgError as e:
print("LinAlgError:", e)
Output:
solution x: [2. 3.]
check A @ x == b: True
det(A): 5.000000000000001
det(singular): 0.0
LinAlgError: Singular matrix
Solve or report singular
Write solve_or_none(A, b) that returns the solution vector x to
Ax = b using np.linalg.solve, or returns None if A is singular.
Catch LinAlgError — but also treat a result containing nan/inf as
singular: depending on the exact LAPACK build, np.linalg.solve doesn't
always raise for a singular matrix, it sometimes just returns garbage
values instead, so a robust solution checks both.
💡 Hint
Wrap np.linalg.solve(A, b) in a try/except np.linalg.LinAlgError and return None in the except branch — then also check np.all(np.isfinite(x)) on whatever it returns, since a singular matrix doesn't always raise.
✅ Solution
def solve_or_none(A, b):
try:
x = np.linalg.solve(A, b)
except np.linalg.LinAlgError:
return None
return x if np.all(np.isfinite(x)) else None
Is it singular?
Write is_singular(A, tol=1e-10) that returns True if the square matrix
A is singular (its determinant is within tol of zero), False
otherwise.
💡 Hint
Compute np.linalg.det(A) and compare abs(det) against tol.
✅ Solution
def is_singular(A, tol=1e-10):
return abs(np.linalg.det(A)) < tol