Briefly describe an efficient algorithm for solving an upper triangular system. Roughly how does the number of steps depend on $n$? In contrast, roughly how many steps does Gaussian elimination take?
The scipy.linalg module has a function lu which takes an array and returns the $P, L, U$ decomposition of it. In addition, the module provides a function solve_triangular(T, b, lower=True|False) which efficiently solves triangular matrices. Try combining these and what we've seen so far to solve a linear system.
Note: When playing with small examples, you don't always want to go through all decomposition stuff. The scipy.linalg module also provides a solve(A, b) method you can use instead. Try using it on a random matrix to see how it works.
By the way, why do I keep using random matrices as examples? Should I really worry that one of them is singular? For the skeptic, try generating a whole bunch of random square matrices and checking if they are singular.
Construct a $5 \times 5$ discrete Laplace matrix $A$. (You may find the helper function eye in numpy useful! You can build identity matrices using eye(n) and off-diagonal identity matrices using eye(n, k=...|-1|0|1|...).
Implement Jacobi iteration for this matrix and try solving for a vector of all ones. Run the interation for 50 steps and print out the norm of the residual as you go.