#!/usr/bin/env python # coding: utf-8 # In[1]: import matplotlib.pyplot as plt import numpy as np import sympy as sy sy.init_printing() # # Null Space # The _null space_, denoted as $\text{Nul}A$ is the solution set of a homogeneous linear system, i.e. $Ax=0$. # # A null space is a always a subspace of $\mathbb{R}^n$, why? Because one solution can always be the origin $(0, 0, ...)$. # # As an example, consider a linear system. # # $$ # 2x_1-x_2+x_3 = 0\\ # x_1+2x_2+3x_3= 0 # $$ # # The augmented matrix is # # $$ # \left[ # \begin{matrix} # 2 & -1 & 1 & 0\\ # 1 & 2 & 3 & 0 # \end{matrix} # \right] # $$ # Before solving the system, we have already known there is no unique solution since a free variable presents, due to the fact that two equation with three variables. # # Solve for the reduced echelon form. # In[2]: Aug = sy.Matrix([[2,-1,1,0],[1,2,3,0]]) Aug.rref() # $x_3$ is a free variable, the solution set can be written as # # $$ # \left[ # \begin{matrix} # x_1 \\ x_2 \\ x_3 # \end{matrix} # \right]= # \left[ # \begin{matrix} # -x_3 \\ -x_3 \\ x_3 # \end{matrix} # \right]= # x_3\left[ # \begin{matrix} # -1 \\ -1 \\ 1 # \end{matrix} # \right] # $$ # # which is a line passing both origin $(0, 0, 0)$ and $(-1, -1, 1)$, also a subspace of $\mathbb{R}^3$. # Now consider another example, suppose we have an augmented matrix # In[3]: Aug = sy.Matrix([[-3,6,-1,1,-7,0],[1,-2,2,3,-1,0],[2,-4,5,8,-4,0]]);Aug # In[4]: Aug.rref() # The solution can be written as: # $$ # \left[ # \begin{matrix} # x_1 \\ x_2 \\ x_3 \\x_4 \\ x_5 # \end{matrix} # \right]= # \left[ # \begin{matrix} # 2x_2+x_4-3x_5 \\ x_2 \\ -2x_4+2x_5 \\x_4 \\ x_5 # \end{matrix} # \right]= # x_2\left[ # \begin{matrix} # 2 \\ 1 \\ 0 \\0 \\ 0 # \end{matrix} # \right] # + # x_4\left[ # \begin{matrix} # 1 \\ 0 \\ -2 \\1 \\ 0 # \end{matrix} # \right] # +x_5\left[ # \begin{matrix} # -3 \\ 0 \\ 2 \\0 \\ 1 # \end{matrix} # \right] # $$ # The $\text{Nul}A$ is a subspace in $\mathbb{R}^5$ with $\text{dim}A=3$. # # Null Space vs Col Space # Consider matrix $A$ # In[5]: A = sy.Matrix([[2,4,-2,1],[-2,-5,7,3],[3,7,-8,6]]);A # Column space is a subspace in $\mathbb{R}^n$, what is $n$? It is the number of rows, $n=3$. # # Null space is a subspace in $\mathbb{R}^m$, what is $m$? It is the number of columns, $m=4$. # How to find any nonzero vector in $\text{Col}A$ and in $\text{Nul}A$? # # Any column in a matrix can be a nonzero vector in $\text{Col}A$, for instance first column: $(2, -2, 3)^T$. # But to find a nonzero vector in null space requires some effort, construct the augmented matrix then turn it into rref. # In[6]: Aug = sy.Matrix([[2,4,-2,1,0],[-2,-5,7,3,0],[3,7,-8,6,0]]);Aug.rref() # The solution set with a free variable $x_3$ (because column 3 has no pivot) is # # $$ # \left[ # \begin{matrix} # x_1 \\ x_2 \\ x_3\\x_4 # \end{matrix} # \right]= # \left[ # \begin{matrix} # -9x_3 \\ 5x_3 \\ x_3\\0 # \end{matrix} # \right] # $$ # # If we pick $x_3 =1$, a nonzero vector in $\text{Nul}A$ is $(-9, 5, 1, 0)^T$ # Now consider two vectors # # $$ # u = \left[ # \begin{matrix} # 3 \\ -2 \\ -1\\ 0 # \end{matrix} # \right],\qquad # v = \left[ # \begin{matrix} # 3 \\ -1\\3 # \end{matrix} # \right]\\ # $$ # Is $u$ in $\text{Nul}A$? It can be verified easily # In[7]: u = sy.Matrix([[3],[-2],[-1],[0]]) A*u # $Au\neq \mathbf{0}$, therefore $u$ is not in $\text{Nul}A$. # Is $v$ in $\text{Col}A$? Construct an augmented matrix with $v$, then solve it # In[8]: v = sy.Matrix([[3],[-1],[3]]) A.row_join(v).rref() # The augmented matrix show there are solutions, i.e. $v$ is a linear combination of its column space basis, so $v$ is in $\text{Col}A$. # # Row Space # The **Row space** denoted as $\text{Row}A$, contains all linear combination of row vectors and subspace in $\mathbb{R}^n$. # If we perform row operations on $A$ to obtain $B$, both matrices have the same row space, because $B$'s rows are linear combinations of $A$'s. However, row operation will change the row dependence. # ## An Example # Find the row, column and null space of # In[9]: A = sy.Matrix([[-2, -5, 8, 0, -17], [1, 3, -5, 1, 5], [3, 11, -19, 7, 1], [1, 7, -13, 5, -3]]);A # In[10]: B = A.rref();B # The basis of the row space of $B$ is its first 3 rows: $(1,0,1,0,1), (0, 1, -2, 0, 3), (0, 0, 0, 1, -5)$ which are also the basis of the row space of $A$. However it does not necessarily mean that first 3 rows of $A$ forms the basis for row space, because the dependence among rows changed by row operation. # In constrast, the basis of col space of $A$ is $(-2, 1, 3, 1)^T, (-5, 3, 11, 7)^T, (0, 1, 7, 5)^T$. # In[11]: Aug = A.row_join(sy.zeros(4,1));Aug.rref() # The null space is # # $$ # \left[ # \begin{matrix} # x_1 \\ x_2 \\ x_3\\x_4 \\x_5 # \end{matrix} # \right]= # \left[ # \begin{matrix} # -x_3-x_5 \\ 2x_3-3x_5 \\ x_3\\5x_5 \\x_5 # \end{matrix} # \right]= # x_3\left[ # \begin{matrix} # -1 \\ 2 \\ 1\\0 \\0 # \end{matrix} # \right]+ # x_5 # \left[ # \begin{matrix} # -1 \\ -3 \\ 0\\5 \\1 # \end{matrix} # \right] # $$ # # Rank # Definition of rank: # The _rank_ is the dimension of the column space of $A$. The _nullity_ of $A$ is the dimension of the null space. # ## The Rank Theorem # The dimensions of the column space and the row space of an $m \times n$ matrix $A$ are equal. Therefore, the rank is the same for either column space and row space. # # This common dimension, the rank of $A$, also equals the number of pivot positions in $A$ and satisfies the equation: # $$ # \operatorname{rank} A + \operatorname{dim} \mathrm{Nul} A = n # $$ # # The intuition behind this is that when a matrix $A$ is converted into its reduced row echelon form (rref) $B$, we can indirectly determine the basis of the column space by matching the columns of $B$ with those of $A$. The columns in $A$ that correspond to pivot columns in $B$ form the basis of the column space. # # In the rref, we can also directly see the basis of the row space. Each row in the basis of the row space must contain a pivot. The rows that do not contain pivots correspond to the free variables, which determine the dimension of the null space. # ## Example 1 # If $A$ is $45 \times 50$ matrix with a $10$-dimension nullity, what is the rank of $A$? # $10$-$D$ nullity means 10 free variables, so the pivots are $50-10=40$, which is also the rank of $A$. # ## Example 2 # The matrices below are row equivalent. # $$ # A=\left[\begin{array}{rrrrr} # 2 & -1 & 1 & -6 & 8 \\ # 1 & -2 & -4 & 3 & -2 \\ # -7 & 8 & 10 & 3 & -10 \\ # 4 & -5 & -7 & 0 & 4 # \end{array}\right], \quad B=\left[\begin{array}{rrrrr} # 1 & -2 & -4 & 3 & -2 \\ # 0 & 3 & 9 & -12 & 12 \\ # 0 & 0 & 0 & 0 & 0 \\ # 0 & 0 & 0 & 0 & 0 # \end{array}\right] # $$ # 1. Find rank $A$ and $\operatorname{dim}$ Nul $A$ # 2. Find bases for Col $A$ and Row $A$. # 3. What is the next step to perform to find a basis for Nul $A$ ? # 4. How many pivot columns are in a row echelon form of $A^{T} ?$ # 1. $rank(A)=2$, because $B$ has two pivots. And nullity is the number of free variables, there are 3, so $\text{dim Nul}A = 3$. # In[12]: A = sy.Matrix([[2,-1,1,-6,8,0], [1,-2,-4,3,-2,0], [-7,8,10,3,-10,0], [4,-5,-7,0,4,0]]) A.rref() # 2. Bases for $\text{Col}A$ is $(2,1,-7,4)^T, (-1,-2,8,-5)^T$, and for $\text{Row}A$ is $(1,-2,-4,3,-2),(0,3,9,-12,12)$. # The $\text{Nul}A$ and basis is # # $$ # \left[ # \begin{matrix} # x_1 \\ x_2 \\ x_3\\x_4 \\x_5 # \end{matrix} # \right]= # \left[ # \begin{matrix} # -2x_3+5x_4-6x_5 \\ -3x_3+4x_4-4x_5 \\ x_3\\x_4 \\x_5 # \end{matrix} # \right]= # x_3 # \left[ # \begin{matrix} # -2 \\ -3 \\ 1\\0 \\0 # \end{matrix} # \right]+ # x_4 # \left[ # \begin{matrix} # 5 \\ 4 \\ 0\\1 \\0 # \end{matrix} # \right]+ # x_5 # \left[ # \begin{matrix} # -6 \\ -4 \\ 0\\0 \\1 # \end{matrix} # \right] # $$ # 3. Perform rref on augmented $A$ # 4. Transpose $A$ then do rref. # In[13]: A.T.rref() # There are 2 pivot columns. # Actually, we don't need any calculation to know the rank of $A^T$, because # # $$ # rank(A)=rank(A^T) # $$ # # Orthogonality of $\text{Nul}A$ and $\text{Row}A$ # ## $\text{Nul}A \perp \text{Row}A$ # Here is the intersting connections of these subspaces we have discussed. Consider # In[14]: A = sy.Matrix([[5, 8, 2], [10, 16, 4], [3, 4, 1]]);A # In[15]: A.rref() # The basis of row space of $A$ is $(1, 0, 0)$ and $(0, 1, .25)$.And the $\text{Row}A$ is # # $$ # \text{Row}A= # s\left[ # \begin{matrix} # 1 \\ 0\\ 0 # \end{matrix} # \right]+ # t\left[ # \begin{matrix} # 0 \\ 1\\ 0.25 # \end{matrix} # \right] # $$ # The $\text{Nul}A$ is # $$ # \left[ # \begin{matrix} # x_1 \\ x_2\\ x_3 # \end{matrix} # \right]= # x_3 # \left[ # \begin{matrix} # 0 \\ -.25\\ 1 # \end{matrix} # \right] # $$ # Now we can visualize their relations geometrically. Again keep in mind that Matplotlib does not render 3D properly, so you need some imagination as well. # # Here is what we observe. # # The $\text{Row}A$ is a plane and $\text{Nul}A$ is a line which is perpendicular to the plane (maybe 3D plot not so obvious about it). It is easy to grasp the idea if you notice that in a homogeneous system $Ab = \mathbf{0}$, it breaks down into dot products # # $$ # Ab =\left[ # \begin{matrix} # A_{1\cdot}\cdot b \\ A_{2\cdot}\cdot b\\ A_{3\cdot}\cdot b # \end{matrix} # \right] # = # \left[ # \begin{matrix} # 0 \\ 0 \\ 0 # \end{matrix} # \right] # $$ # # where $A_{1\cdot}, A_{2\cdot}, A_{3\cdot}$ are the rows of $A$. In later chapters we will prove when the dot product of two vectors equals zero, they are geometrically perpendicular. # In[17]: # Generate the grid s = np.linspace(-1, 1, 10) t = np.linspace(-1, 1, 10) S, T = np.meshgrid(s, t) X = S Y = T Z = T * 0.25 # Create the figure and the 3D axis fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection='3d') # Plot the surface ax.plot_surface(X, Y, Z, alpha=0.9, cmap=plt.cm.coolwarm) # Plot the line x3 = np.linspace(-1, 1, 10) x1 = 0 * x3 x2 = -0.25 * x3 ax.plot(x1, x2, x3, lw=5) # Set axis labels ax.set_xlabel('x-axis', size=18) ax.set_ylabel('y-axis', size=18) ax.set_zlabel('z-axis', size=18) # Set axis limits ax.set_xlim([-1, 1]) ax.set_ylim([-1, 1]) ax.set_zlim([-0.25, 0.25]) # Add text annotations ax.text(1, -1, -0.25, r'$Row\ A$', size=17) ax.text(0, -0.25, 1, r'$Nul\ A$', size=17) # Set the view angle ax.view_init(elev=7, azim=20) # Show the plot plt.show() # Let me write a summary: # 1. The dimension of the row space is equal to the dimension of the column space (both are the rank of the matrix). # 2. The row space of $A$ is orthogonal to the null space of $A$. # 3. The column space of $A$ is orthogonal to the left null space of $A$. # ## $\text{Nul}A^T \perp \text{Col}A$ # The nullity of $A^T$ is # In[ ]: A = sy.Matrix([[5, 8, 2], [10, 16, 4], [3, 4, 1]]);A.T.rref() # The $\text{Nul}A^T$ is # # $$ # \left[ # \begin{matrix} # x_1 \\ x_2\\ x_3 # \end{matrix} # \right]= # x_2 # \left[ # \begin{matrix} # -2 \\ 1\\ 0 # \end{matrix} # \right] # $$ # The $\text{Col}A$ is # In[ ]: A.rref() # $$ # \text{Col}A= # s\left[ # \begin{matrix} # 5 \\ 10\\ 3 # \end{matrix} # \right]+ # t\left[ # \begin{matrix} # 8 \\ 16\\ 4 # \end{matrix} # \right] # $$ # $\text{Col}A$ is a plane and $\text{Nul}A^T$ is a line perpendicular to the plane. The intuition is similar to $\text{Nul}A \perp \text{Row}A$, here you can think of a system look like $b^TA = \mathbf{0}^T$. # In[ ]: get_ipython().run_line_magic('matplotlib', 'inline') s = np.linspace(-1, 1, 10) t = np.linspace(-1, 1, 10) S, T = np.meshgrid(s, t) X = 5*S+8*T Y = 10*S+16*T Z = 3*S+4*T fig = plt.figure(figsize = (8,8)) ax = fig.add_subplot(111,projection='3d') ax.plot_surface(X, Y, Z, cmap=plt.cm.coolwarm) x2 = np.linspace(-1, 1, 10) x3 = x2*0 x1 = -2*x2 ax.plot(x1,x2,x3, lw = 3) ax.set_xlabel('x-axis', size = 18) ax.set_ylabel('y-axis', size = 18) ax.set_zlabel('z-axis', size = 18) ax.axis([-1,1,-1,1]) ax.view_init(-67, 35) # # Rank Decomposition # Consider a matrix $A$, the purpose is to decompose it into the multiplication of $C$, $R$, which are the bases of column space and row space respectively. # $$ # A = CR # $$ # In[ ]: A = sy.Matrix([[2, 4, 1, -1], [4, 2, -4, 2], [2, -2, -5, 3], [1, 9, -3, 2]]);A # In[ ]: Arref = A.rref();Arref # Get the basis of $\text{Col}A$. # In[ ]: ColA_basis = A[:,:3];ColA_basis # Then get the $\text{Row}A$. # In[ ]: RowA_basis = Arref[0][0:3,:];RowA_basis # Multiply $CR$, we are getting back $A$. # In[ ]: ColA_basis*RowA_basis # Verify if $CR$ equals $A$. # In[ ]: ColA_basis*RowA_basis == A