Linear systems and elimination
Linear systems and Gaussian elimination (lesson 3.3.1)
0 of 8 correct
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
How to type answers
- Powers with
^:x^7,2^(1/3),a^-2. - Multiply with
*or by writing side by side:3x^2,2(x+1). ln(x)is the natural log,log(x, 2)is log base 2,eis Euler's number,sqrt(x)is a square root.sin(x),cos(x)andtan(x)take radians; writepifor π andsin(x)^2for sin²x.- Your first answer to each question is saved: it counts towards your score and brings the question back for review.
- Exact answers like
ln(20)/ln(3)are best. Decimals need about 4 significant figures.
Rank and solution sets
Rank and the shape of the solution set (lesson 3.3.2)
0 of 9 correct
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
How to type answers
- Powers with
^:x^7,2^(1/3),a^-2. - Multiply with
*or by writing side by side:3x^2,2(x+1). ln(x)is the natural log,log(x, 2)is log base 2,eis Euler's number,sqrt(x)is a square root.sin(x),cos(x)andtan(x)take radians; writepifor π andsin(x)^2for sin²x.- Your first answer to each question is saved: it counts towards your score and brings the question back for review.
- Exact answers like
ln(20)/ln(3)are best. Decimals need about 4 significant figures.
Coding exercise
Gaussian elimination with partial pivoting
Write gauss_solve(A, b, tol=1e-12) that returns the solution of as a NumPy array, by the method of lesson 3.3.1. Do not call np.linalg.solve; the tests compare your answer with it.
- Turn
Aandbinto decimal arrays first (np.asarray(…, dtype=float)), and work on a new augmented matrix, so the caller's arrays are left unchanged. - For each column, swap up the row whose entry is largest in size, at or below the diagonal. If that entry is at most
toltimes the largest entry ofAin size, raiseValueError: the column has no pivot (lesson 3.3.2). - Clear the column below the pivot, then back-substitute from the bottom row.
- If
Ais not square, with one row per entry ofb, raiseValueError.
The tests use the examples of lessons 3.3.1 and 3.3.2. They include a zero pivot, a zero in the top-left corner, the tiny pivot , a singular matrix and a tall one. They also try a random 6 × 6 system.
See the tests
import numpy as np
def test_three_by_three():
"""Integer arrays work: the 3 × 3 system of lesson 3.3.1 gives (2, −1, 3)"""
A = np.array([[1, 2, 1], [2, 5, 3], [3, 4, 4]])
b = np.array([3, 8, 14])
expect_close(gauss_solve(A, b), [2, -1, 3], what="gauss_solve on the 3 × 3 example")
def test_zero_pivot():
"""A 0 in the second pivot place needs a row swap: the answer is (3, −1, 2)"""
A = [[1, 2, 1], [2, 4, 3], [1, 3, 2]]
expect_close(gauss_solve(A, [3, 8, 4]), [3, -1, 2], what="gauss_solve with a zero pivot")
def test_zero_corner():
"""A 0 in the top-left corner: x₂ = 2 and x₁ + x₂ = 3 give (1, 2)"""
expect_close(gauss_solve([[0, 1], [1, 1]], [2, 3]), [1, 2], what="gauss_solve([[0, 1], [1, 1]], [2, 3])")
def test_tiny_pivot():
"""A tiny pivot needs partial pivoting: 10⁻²⁰x₁ + x₂ = 1 and x₁ + x₂ = 2 give (1, 1)"""
x = gauss_solve([[1e-20, 1], [1, 1]], [1, 2])
expect_close(x, [1, 1], what="gauss_solve with the pivot 1e-20 (swap up the largest entry in size)", rel=1e-12)
def test_one_by_one():
"""A 1 × 1 system, 4x = 2, gives 0.5"""
expect_close(gauss_solve([[4]], [2]), [0.5], what="gauss_solve([[4]], [2])")
def test_random_system():
"""A random 6 × 6 system agrees with np.linalg.solve"""
rng = np.random.default_rng(33)
A = rng.normal(size=(6, 6))
b = rng.normal(size=6)
expect_close(gauss_solve(A, b), np.linalg.solve(A, b), what="gauss_solve on a random 6 × 6 system", rel=1e-9)
def test_inputs_unchanged():
"""The A and b passed in are left as they were"""
A = np.array([[2.0, 1.0], [6.0, 5.0]])
b = np.array([4.0, 18.0])
x = gauss_solve(A, b)
expect_close(x, [0.5, 3], what="gauss_solve on 2x₁ + x₂ = 4, 6x₁ + 5x₂ = 18")
expect_close(A, [[2, 1], [6, 5]], what="A after the call")
expect_close(b, [4, 18], what="b after the call")
def test_singular():
"""A singular matrix (rank 2, from lesson 3.3.2) raises ValueError"""
try:
gauss_solve([[1, 2, 1], [2, 4, 3], [3, 6, 4]], [4, 9, 13])
except ValueError:
return
raise AssertionError("expected ValueError: column 2 has no pivot, so there is no single solution")
def test_not_square():
"""A 3 × 2 matrix raises ValueError"""
try:
gauss_solve([[1, 1], [1, -1], [1, 2]], [3, 1, 4])
except ValueError:
return
raise AssertionError("expected ValueError for a matrix that is not square")