This class requires NO CODING, i.e. this kind of lab nonsense will not show up on the exams. However, LIFE as an applied mathematician, engineer, computer scientist, etc... tends to require coding skills.
Hence, the Purpose of these "labs" are
The "Rules"
Copyright, and License
Interactive or Static Mode???
# Import basic python packages for numerical computation (numpy),
# symbolic computations (sympy), and plotting (matplotlib)
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
# cm are colormaps -- for plotting
from matplotlib import cm
# mplot3d is needed for 3D-plotting
from mpl_toolkits import mplot3d
#(not needed in this lab) from matplotlib.ticker import LinearLocator, FormatStrFormatter
#(not needed in this lab) from mpl_toolkits.mplot3d import Axes3D
Our problem of interest is [2x+8y+4z2x+5y+z4x+10y=z]=[251]
# We can use "Symbolic" matrices by invoking the Matrix command from sympy
# "Symbolic" matrices are computationally inefficient, but are useful for
# teaching and learning linear algebra on small matrices.
# First, we let A hold the coeffient matrix
A = sp.Matrix([[2, 8, 4], [2, 5, 1], [4, 10, -1]])
# ... and look at how pretty the output is, without any extra effort
A
# Next, we define the right-hand-side of the equation
#
# When you say "linear system", linear algebraists think "Ax=b",
# hence
b = sp.Matrix([[2],[5],[1]])
b
# ... and, yeah, a column vector is really just a "skinny matrix" (at least in Python)
# Note: like many computing environments, Python counts from 0
#
# This is the row of A
A[0,:]
# and this is the 2nd row
A[:,1]
# Lets create a of A, and then augment it with the right-hand-side
B = A
B = B.row_join(b)
B
# First we create a leading 1, in the first-row first-column
B[0,:] /= B[0,0]
# Since B[0,0] started out with the value 2, this exactly the operation preformed in the [Notes 1.2, slide 14]
B
# Next, we subtract appropriate multipliers of the first row from the second and third:
B[1,:] = B[1,:] - B[1,0] * B[0,:]
B
# Next, we subtract appropriate multipliers of the first row from the second and third:
B[2,:] = B[2,:] - B[2,0] * B[0,:]
B
# We now move to the second row, and make the leading coefficient 1
B[1,:] /= B[1,1]
B
# Let's eliminate "up" and "down" in the 2nd column
B[0,:] = B[0,:] - B[0,1] * B[1,:]
B[2,:] = B[2,:] - B[2,1] * B[1,:]
B
# We move to the 3rd row, and the strategy is the same: make a 1, then make 0s...
B[2,:] /= B[2,2]
B
B[0,:] = B[0,:] - B[0,2] * B[2,:]
B[1,:] = B[1,:] - B[1,2] * B[2,:]
B
We can identify the solution: [xyz]=[11−43]
The steps are so predictable we can write ourselves a little function to perform all the steps
# WARNING: This function will run into trouble if at any point we have
# WARNING: a zero in the current diagonal element M[i,i], since
# WARNING: division by zero is a Very Bad Idea!!!
#
# WARNING: Division-by-zero is NOT the only problem this can run into.
#
def my_rref( M ):
rows, cols = M.shape
for i in range(0,rows):
M[i,:] /= M[i,i]
print(M)
for j in range(0,rows):
if i != j:
M[j,:] = M[j,:] - M[j,i] * M[i,:]
print(M)
return M
# We reconstruct the non-reduced augmented matrix
B = A
B = B.row_join(b)
B
# Then we invoke our magic, uh, function:
rref_B = my_rref(B)
rref_B
Matrix([[1, 4, 2, 1], [2, 5, 1, 5], [4, 10, -1, 1]]) Matrix([[1, 4, 2, 1], [0, -3, -3, 3], [4, 10, -1, 1]]) Matrix([[1, 4, 2, 1], [0, -3, -3, 3], [0, -6, -9, -3]]) Matrix([[1, 4, 2, 1], [0, 1, 1, -1], [0, -6, -9, -3]]) Matrix([[1, 0, -2, 5], [0, 1, 1, -1], [0, -6, -9, -3]]) Matrix([[1, 0, -2, 5], [0, 1, 1, -1], [0, 0, -3, -9]]) Matrix([[1, 0, -2, 5], [0, 1, 1, -1], [0, 0, 1, 3]]) Matrix([[1, 0, 0, 11], [0, 1, 1, -1], [0, 0, 1, 3]]) Matrix([[1, 0, 0, 11], [0, 1, 0, -4], [0, 0, 1, 3]])
That is pretty nice!