G05: Numerical linear algebra and optimization
On this page
- Prerequisites and observable goals
- The central question: which problem is hard, and which algorithm is fragile?
- Least squares is geometry with a residual
- Orthogonal transformations preserve distances
- A Householder step, derived
- What the reference does and does not promise
- Gradient descent on a quadratic
- Constraints and first-order conditions
- Independent practice
- Smallest useful hints
- Complete solutions: G05
- Readiness and continuation
Prerequisites and observable goals#
foundation A01–A06, derivatives, gradients, and matrix multiplication.
Solve a least-squares problem with an orthogonal transformation, distinguish conditioning from stability, and choose a justified step size for a quadratic objective.
The central question: which problem is hard, and which algorithm is fragile?#
A poorly conditioned problem changes its answer substantially when its data changes slightly. An unstable algorithm can introduce unnecessary error even on a well-conditioned problem. These are not synonyms. Report the norm, perturbation model, and object whose error is measured before calling a calculation “accurate.”
For an invertible matrix , the normwise condition number in the Euclidean norm is . A small singular value means some input direction produces a small output: recovering its coefficient from noisy observations is difficult. Adding more decimal digits to printed output does not solve that loss of information.
Least squares is geometry with a residual#
For and , minimize
When has full column rank, the minimizer is unique. Differentiation gives ; at the minimizer, the residual is orthogonal to every column of :
These normal equations characterize the optimum, but explicitly forming them is not always a good numerical algorithm. Their condition number satisfies under full column rank, potentially magnifying numerical difficulties.
Worked example: fit a line to . Then
The equations and give , then . Predictions are , so . Check and . The squared residual norm is , hence the half-squared objective is . These checks make the geometry visible.
Orthogonal transformations preserve distances#
An orthogonal matrix satisfies , so . A thin QR factorization of full-column-rank writes with having orthonormal columns and upper triangular. Completing to an orthogonal basis gives
Only the first term depends on . Solve the triangular system by back substitution; the leftover component is the irreducible residual. The algorithm avoids explicitly squaring the condition number by forming .
A Householder step, derived#
Given a nonzero column segment , we want a reflection that maps it to a multiple of the first coordinate vector . Choose (choose positive sign for a zero ), set , and define
Since is an orthogonal projector with , . One can check . The sign choice avoids subtracting nearly equal positive quantities when constructing the first component of .
For , choose and . Then
The reflection changes orientation but not length. Apply it to the active rows of each remaining matrix column and to the matching target segment. Repeat down the diagonal. The lab stores and applies each reflector directly rather than constructing a dense each time.
What the reference does and does not promise#
The implementation globally scales and by the largest absolute matrix entry, computes Householder steps with math.hypot, and rejects a sufficiently small remaining diagonal segment using a documented relative threshold. This is an educational full-rank solver, not a rank-revealing pivoted QR or SVD library. A tolerance-based rank decision depends on scaling and column order. Very ill-conditioned or extreme dynamic-range cases require stronger tools, condition estimates, and careful residual/backward-error analysis.
A small residual is not always a small coefficient error: with nearly dependent columns, many widely different coefficients predict almost the same vector. Conversely, a nonzero residual can be unavoidable for noisy or inconsistent observations, even when the computed minimizer is excellent. To check a result, report both residual size and sensitivity, not one scalar relabeled as universal accuracy.
Gradient descent on a quadratic#
Let with symmetric positive-definite . The optimum solves . Gradient descent uses
where . In an orthonormal eigenbasis of , each error component is multiplied by . All shrink in magnitude when
At the endpoint, the largest-eigenvalue component can oscillate without decay. A tiny step is stable but can be slow, especially when is large. The formula derives from this quadratic model; do not apply it to an arbitrary neural-network loss without establishing relevant smoothness and curvature assumptions.
For and , choosing yields factors . Starting gives and objective , down from 5. Choosing yields factors ; the second component grows while changing sign. A decreasing loss in one tested step does not prove global convergence on a different objective.
Constraints and first-order conditions#
For differentiable convex , a zero gradient is a global minimum on all of . With constraints, zero gradient need not hold at the constrained optimum. For subject to , the optimum is 1, whose derivative is . Using , the Lagrangian is . At the optimum, stationarity gives , so and complementary slackness holds. General KKT necessity needs a suitable constraint qualification; sufficiency in convex settings needs the appropriate convexity and feasible conditions. This example does not establish KKT for every nonconvex program. [G-CVX]
Independent practice#
F foundation C standard course work T transfer S optional stretch L runnable lab or project. Attempt the complete set before opening its solutions.
Derive the line-fit coefficients for the three observations above. Verify residual orthogonality and the half-squared loss.
Construct the Householder reflector for using the stable sign choice. Verify both and .
For and , solve . Change the second component of by and compare relative data and solution perturbations.
For , derive the interval of constant positive learning rates that converges for every initial error. Compute one update from with .
Solve subject to and verify the multiplier conditions. Explain why setting the objective derivative to zero alone gives an infeasible answer.
Implement least_squares in starters/numerics.py with Householder reflections and the documented finite-input, shape, and rank-threshold checks. Do not form . Test exact full-rank systems, an inconsistent fit, rank-deficient columns, unchanged inputs, and scaled versions of the same problem.
Smallest useful hints#
For .02, write and compute its outer product before division. For .03, solve each diagonal equation separately. For .06, transform the target using exactly the same row reflection as the matrix.
Complete solutions: G05#
Compare the first step where your work differs. A corrected answer is not yet an independent success.
G05.01Show solution
Solve and independently check
From and , subtract to obtain , so and . The residual vector is . Its inner products with columns and are zero. Its squared norm is , and . Full column rank ensures uniqueness. These equations verify this instance; they do not recommend normal equations as the robust default implementation.
Back to G05.01G05.02Show solution
A norm-preserving elimination step
Here and . Subtracting from identity gives the displayed . Dot products of its columns are 1, 1, and 0, proving orthogonality. Multiplication gives . The vector norm remains five. Choosing the opposite sign would still define a reflection in exact arithmetic, but the stable sign is important when the vector is already nearly aligned with the first coordinate.
Back to G05.02G05.03Show solution
Small data changes in a sensitive direction
Originally . The perturbed right side is , giving . The relative data perturbation is , while the relative solution perturbation is . The matrix condition number is . The large response is a property of solving this system, not evidence that the trivial diagonal solver introduced an unnecessary instability.
Back to G05.03G05.04Show solution
Every eigendirection must contract
The factors are and . Require both magnitudes below one, giving and ; their intersection is . At , the update is . The second sign flip is not itself divergence because its magnitude factor is .6. At , the second factor is , so convergence from every starting error fails.
Back to G05.04G05.05Show solution
The boundary changes stationarity
The unconstrained minimizer violates . The objective decreases as approaches 2 from the left, so the feasible optimum is with value 1. Set , . Feasibility, nonnegative multiplier, stationarity , and complementary slackness all hold. Convexity makes these conditions sufficient here; more general necessity claims require further assumptions.
Back to G05.05G05.06Show solution
Complete reference solver
The reflection formula is applied in place to private copies, not caller-owned data. Back substitution starts at the last triangular equation, subtracts already solved upper-diagonal contributions, and divides by the diagonal. The tests include 50 seeded exact systems and invariance under global scales and for the simple fit. These finite cases do not certify all ill-conditioned inputs.
"""G05: educational Householder least squares for bounded full-rank matrices."""
import math
def least_squares(A, b, rtol=1e-12):
m, n = len(A), len(A[0]) if A else 0
if not 1 <= n <= 64 or not n <= m <= 10000 or len(b) != m:
raise ValueError("require m >= n, 1..64 columns, <=10000 rows")
if any(len(row) != n for row in A):
raise ValueError("ragged matrix")
if not math.isfinite(rtol) or not 0 < rtol < 1:
raise ValueError("relative rank threshold must lie in (0,1)")
if any(not math.isfinite(x) for row in A for x in row) or any(not math.isfinite(x) for x in b):
raise ValueError("finite matrix and target required")
scale = max(abs(x) for row in A for x in row)
if scale == 0:
raise ValueError("rank-deficient zero matrix")
R = [[x/scale for x in row] for row in A]
target = [x/scale for x in b]
if any(not math.isfinite(x) for x in target):
raise ValueError("target exceeds supported dynamic range")
for j in range(n):
z = [R[i][j] for i in range(j,m)]
norm = math.hypot(*z)
if norm <= rtol:
raise ValueError("rank deficiency at stated relative threshold")
alpha = -math.copysign(norm,z[0])
v = list(z)
v[0] -= alpha
vnorm = math.hypot(*v)
v = [x/vnorm for x in v]
for k in range(j,n):
projection = 2*math.fsum(v[i-j]*R[i][k] for i in range(j,m))
for i in range(j,m):
R[i][k] -= projection*v[i-j]
projection = 2*math.fsum(v[i-j]*target[i] for i in range(j,m))
for i in range(j,m):
target[i] -= projection*v[i-j]
R[j][j] = alpha
for i in range(j+1,m):
R[i][j] = 0.
x = [0.]*n
for j in range(n-1,-1,-1):
remainder = math.fsum(R[j][k]*x[k] for k in range(j+1,n))
x[j] = (target[j]-remainder)/R[j][j]
if not all(math.isfinite(value) for value in x):
raise ValueError("nonfinite coefficients")
return x
if __name__ == "__main__":
print(least_squares([[1,0],[1,1],[1,2]],[1,2,2]))Readiness and continuation#
Explain why an inconsistent system has a best approximation, why is geometric, and why a small residual need not mean stable coefficients. Continue with pivoted QR, SVD-based rank determination, backward stability proofs, preconditioning, iterative Krylov solvers, and constrained convex optimization. The optional reference gives deeper convex analysis; only its public book page was used as a continuation pointer here. [G-CVX]