# 213 - A9 - Subspace, Basis and Basis Coordinates

## 1232 days ago by Professor213

John Travis

Mississippi College

This worksheet demonstrates the idea of a 1D and 2D subspace of a 3D vector spa e.  It also exhibits the new planar coordinate system created using a given set of two basis vectors for any input third vector.

Lastly, a non-trivial example is presented where Sage computes a basic for the column space and a basis for the null space.

# This cell describes a 1D subspace of a 3D vector space. It a subspace with only one basis vector. var('x,y,z,u,v') num_show = 3 @interact def _(v1 = input_box(vector([3,6,2]),width=10,label='$v_1$')): G = Graphics() for k in range(num_show+1): G += arrow((k*v1[0],k*v1[1],k*v1[2]),((k+1)*v1[0],(k+1)*v1[1],(k+1)*v1[2]),color='red',width=3) G += arrow((-k*v1[0],-k*v1[1],-k*v1[2]),(-(k+1)*v1[0],-(k+1)*v1[1],-(k+1)*v1[2]),color='red',width=3) G.show(axes=true)

 $v_1$

## Click to the left again to hide and once more to show the dynamic interactive window

# This cell describes a 2D subspace of a 3D vector space. It a subspace with exactly two basis vectors. var('x,y,z,u,v') num_show1 = 3 num_show2 = 3 @interact def _(v1 = input_box(vector([-3,6,2]),width=10,label='$v_1$'), v2 = input_box(vector([-3,4,1]),width=10,label='$v_2$')): G = Graphics() for k in range(num_show1): G += arrow((k*v1[0],k*v1[1],k*v1[2]),((k+1)*v1[0],(k+1)*v1[1],(k+1)*v1[2]),color='red',width=3) G += arrow((-k*v1[0],-k*v1[1],-k*v1[2]),(-(k+1)*v1[0],-(k+1)*v1[1],-(k+1)*v1[2]),color='red',width=3) for k in range(num_show2): G += arrow((k*v2[0],k*v2[1],k*v2[2]),((k+1)*v2[0],(k+1)*v2[1],(k+1)*v2[2]),color='red',width=3) G += arrow((-k*v2[0],-k*v2[1],-k*v2[2]),(-(k+1)*v2[0],-(k+1)*v2[1],-(k+1)*v2[2]),color='red',width=3) G += parametric_plot3d((num_show1*v1[0]*u+num_show2*v2[0]*v, num_show1*v1[1]*u+num_show2*v2[1]*v, num_show1*v1[2]*u+num_show2*v2[2]*v), (u, -1, 1), (v, -1, 1), mesh=True,opacity=0.6) G.show()

 $v_1$ $v_2$

## Click to the left again to hide and once more to show the dynamic interactive window

# This cell illustrates basis coordinates for a vector in the span of a 2D subspace var('x,y,z,u,v') @interact def _(v1 = input_box(vector([3,6,2]),width=10,label='$v_1$'), v2 = input_box(vector([-1,5,3]),width=10,label='$v_2$'), v3 = input_box(vector([107/6,142/3,18]),width=10,label='$x$')): n = v1.cross_product(v2) # Compute the basis coordinates for v3 relative to v1 and v2 A = matrix([v1,v2,v3]).transpose().rref() c1 = A[0,2] c2 = A[1,2] G = Graphics() if (c1==0) & (c2==0): print "V3 is not in the span of V1 and V2" G += text3d('x is not in the span of V1 and V2',(1,1,5)) else: G += text3d('Basis Coordinates = ('+str(c1)+','+str(c2)+')',(c1,c2,5)) if (c1==0) & (c2==0): c1=1 c2=1 # Let's assume c1 and c2 are positive for now a = floor(c1)+1 b = floor(c2)+1 for k in range(a): # G += arrow((k*v1[0],k*v1[1],k*v1[2]),((k+1)*v1[0],(k+1)*v1[1],(k+1)*v1[2]),color='red',width=3) for j in range(b): here = (k*v1[0]+j*v2[0],k*v1[1]+j*v2[1],k*v1[2]+j*v2[2]) there =((k+1)*v1[0]+j*v2[0],(k+1)*v1[1]+j*v2[1],(k+1)*v1[2]+j*v2[2]) G += arrow(here,there,color='red',width=3) for k in range(b): for j in range(a): here = (k*v2[0]+j*v1[0],k*v2[1]+j*v1[1],k*v2[2]+j*v1[2]) there =((k+1)*v2[0]+j*v1[0],(k+1)*v2[1]+j*v1[1],(k+1)*v2[2]+j*v1[2]) G += arrow(here,there,color='red',width=3) G += arrow((0,0,0),(v1[0],v1[1],v1[2]),color='orange',zorder=3,width=4) G += text3d('v1',(v1[0]/2,v1[1]/2,v1[2]/2)) G += arrow((0,0,0),(v2[0],v2[1],v2[2]),color='orange',zorder=3,width=4) G += text3d('v2',(v2[0]/2,v2[1]/2,v2[2]/2)) G += arrow((0,0,0),(v3[0],v3[1],v3[2]),color='green',zorder=3,width=6) G += parametric_plot3d((c1*v1[0]*u+c2*v2[0]*v, c1*v1[1]*u+c2*v2[1]*v, c1*v1[2]*u+c2*v2[2]*v), (u, 0, 1.2), (v, 0, 1.2), mesh=True,opacity=0.6) G.show(spin=False)

 $v_1$ $v_2$ $x$

## Click to the left again to hide and once more to show the dynamic interactive window

# This cell takes a collection of vectors and determines a basis for the column space and a basis for the null space # These don't graph well since they are in higher dimensions # You can change these, add some, or take some out so long as they have consistent length and so that you fix the matrix A below accordingly v1 = vector(QQ,[-1,4,5,8,0]) v2 = -5*v1 v3 = 3*v1-4*v2 v4 = vector(QQ,[2,0,-7,3,-3]) v5 = v3+v4 v6 = vector(QQ,[0,0,1,-1,1]) v7 = vector(QQ,[9,-2,0,4,0]) v8 = v1+v2+v3+v4+v5+v6+v7 v9 = vector(QQ,[1,1,1,1,1]) A = matrix(QQ,[v1,v2,v3,v4,v5,v6,v7,v8,v9]).transpose() m = A.nrows() n = A.ncols() print(str(n)+' given vectors in R^'+str(m)+' collected into a matrix') show(A) # Now, do Gauss-Jordan to determine the pivot columns and therefore find the original vectors who form a basis for col(A) Arref = A.echelon_form() print('After Gauss-Jordan...') show(Arref) # ...or, just call the following Sage function to determine the column numbers (starting with 0) which have pivots in the above rref pivs = A.pivots() print('Notice that the pivot columns are the columns '+str(pivs)) Column_space_basis = A[ : , pivs] print('Extracting the original vectors corresponding to these pivot columns provides a basis for the Column Space of A.') show(Column_space_basis) # Using the rank theorem, note that ncols(A) = dim(col(A))+dim(null(A)) rankA = len(pivs) print('Therefore, the rank of the matrix A is '+str(rankA)+' which is the number of vectors in a basis for the column space of A.') dimNull = n - rankA print('Using the Rank Theorem, then the dimension of the nullspace of A must be '+str(dimNull)) print(" ") # Now, create the nullspace basis elements from the rref form. To do so, we will need to know the non-pivot # columns corresponding to free variables and let them be used to give all the other variables in the nullspace. eye = identity_matrix(dimNull) # First, we need a string of pointers to identify the non-pivot columns notpivs = str('') for k in range(n): if not k in pivs: notpivs = notpivs+str(k) # and then convert the list of non-pivot pointers to a vector for program use later nulls = vector(QQ,list(notpivs)) # Create the matrix of basis vectors for the nullspace of A by starting with a correctly-sized matrix of zeros B = matrix.zero(QQ,n,dimNull) # then set the free variables into their correct spots in the null space basis for k in range(dimNull): B[nulls[k]] = eye[k] # and then take the free variable coefficients to the other side for the pivot variables for k in range(rankA): B[pivs[k]] = -Arref[k,tuple(nulls)] print('The null space basic vectors resulting from doing Gauss-Jordan and taking non-pivots to the other side.') show(B) print('What you get if you do rref on that matrix') Brref = B.transpose().echelon_form().transpose() show(Brref) # test = -5*Brref[:,0]+Brref[:,1]-Brref[:,2]+2*Brref[:,3] # making certain something is in the kernel print('Alternatively, we can let Sage compute the kernel basis:') Ker = A.right_kernel() print(Ker) print('and you will notice that this coorelates (transpose?) to what Sage returns above. Do these vectors simply refer to an alternate basis of size '+str(dimNull)+'?') print(" ") # Let's check to see if a few vectors are in the kernel of A u1 = vector(QQ,[1,2,3,4,5,6,7,8,9]) u2 = vector(QQ,[0,0,0,0,0,0,0,0,0]) u3 = vector(QQ,[-23,0,0,-1,1,0,0,0,0]) u4 = vector(QQ,[-5,1,-1,2,75/2,79/4,79/4,-79/4,0]) u5 = vector(QQ,[4,0,0,-2,0,0,0,1,0]) print('Using the Sage built-in kernel function:') print(str(u1)+' in Kernel? '+str(u1 in Ker)) print(str(u2)+' in Kernel? '+str(u2 in Ker)) print(str(u3)+' in Kernel? '+str(u3 in Ker)) print(str(u4)+' in Kernel? '+str(u4 in Ker)) print(str(u5)+' in Kernel? '+str(u5 in Ker)) # You can also check each of these by simply muliplying A*u to see if that is the zero vector print(" ") # Finally, check to see whether this final matrix does indeed describe the nullspace using the B above. checkvec = u4 C = matrix.zero(QQ,dimNull+1,n) C[0:dimNull] = B.transpose() C[dimNull:dimNull+1] = [ checkvec ] C = C.transpose() print('You can also check if something is in the kernel (or nullspace of the column vectors) by augmenting the matrix of basis vectors with a vector of your choice and then seeing if things are consistent or not. If so, then that vector is in the nullspace. If not, then no.') print('Here, the original augmented matrix is on the left and the reduced version is on the right.') show([C,C.echelon_form()]) # and check to see whether the reduced B also works. C = matrix.zero(QQ,dimNull+1,n) C[0:dimNull] = Brref.transpose() C[dimNull:dimNull+1] = [ checkvec ] C = C.transpose() print('and checking the same thing but using the "reduced basis vectors" obtained by doing Gauss-Jordan to the original nullspace basis vectors.') show([C,C.echelon_form()])
 9 given vectors in R^5 collected into a matrix After Gauss-Jordan... Notice that the pivot columns are the columns (0, 3, 5, 6, 8) Extracting the original vectors corresponding to these pivot columns provides a basis for the Column Space of A. Therefore, the rank of the matrix A is 5 which is the number of vectors in a basis for the column space of A. Using the Rank Theorem, then the dimension of the nullspace of A must be 4 The null space basic vectors resulting from doing Gauss-Jordan and taking non-pivots to the other side. What you get if you do rref on that matrix Alternatively, we can let Sage compute the kernel basis: Vector space of degree 9 and dimension 4 over Rational Field Basis matrix: [ 1 0 0 0 -1/2 -1/4 -1/4 1/4 0] [ 0 1 0 0 5/2 5/4 5/4 -5/4 0] [ 0 0 1 0 -23/2 -23/4 -23/4 23/4 0] [ 0 0 0 1 21/2 23/4 23/4 -23/4 0] and you will notice that this coorelates (transpose?) to what Sage returns above. Do these vectors simply refer to an alternate basis of size 4? Using the Sage built-in kernel function: (1, 2, 3, 4, 5, 6, 7, 8, 9) in Kernel? False (0, 0, 0, 0, 0, 0, 0, 0, 0) in Kernel? True (-23, 0, 0, -1, 1, 0, 0, 0, 0) in Kernel? True (-5, 1, -1, 2, 75/2, 79/4, 79/4, -79/4, 0) in Kernel? True (4, 0, 0, -2, 0, 0, 0, 1, 0) in Kernel? False You can also check if something is in the kernel (or nullspace of the column vectors) by augmenting the matrix of basis vectors with a vector of your choice and then seeing if things are consistent or not. If so, then that vector is in the nullspace. If not, then no. Here, the original augmented matrix is on the left and the reduced version is on the right. and checking the same thing but using the "reduced basis vectors" obtained by doing Gauss-Jordan to the original nullspace basis vectors.  9 given vectors in R^5 collected into a matrix After Gauss-Jordan... Notice that the pivot columns are the columns (0, 3, 5, 6, 8) Extracting the original vectors corresponding to these pivot columns provides a basis for the Column Space of A. Therefore, the rank of the matrix A is 5 which is the number of vectors in a basis for the column space of A. Using the Rank Theorem, then the dimension of the nullspace of A must be 4 The null space basic vectors resulting from doing Gauss-Jordan and taking non-pivots to the other side. What you get if you do rref on that matrix Alternatively, we can let Sage compute the kernel basis: Vector space of degree 9 and dimension 4 over Rational Field Basis matrix: [ 1 0 0 0 -1/2 -1/4 -1/4 1/4 0] [ 0 1 0 0 5/2 5/4 5/4 -5/4 0] [ 0 0 1 0 -23/2 -23/4 -23/4 23/4 0] [ 0 0 0 1 21/2 23/4 23/4 -23/4 0] and you will notice that this coorelates (transpose?) to what Sage returns above. Do these vectors simply refer to an alternate basis of size 4? Using the Sage built-in kernel function: (1, 2, 3, 4, 5, 6, 7, 8, 9) in Kernel? False (0, 0, 0, 0, 0, 0, 0, 0, 0) in Kernel? True (-23, 0, 0, -1, 1, 0, 0, 0, 0) in Kernel? True (-5, 1, -1, 2, 75/2, 79/4, 79/4, -79/4, 0) in Kernel? True (4, 0, 0, -2, 0, 0, 0, 1, 0) in Kernel? False You can also check if something is in the kernel (or nullspace of the column vectors) by augmenting the matrix of basis vectors with a vector of your choice and then seeing if things are consistent or not. If so, then that vector is in the nullspace. If not, then no. Here, the original augmented matrix is on the left and the reduced version is on the right. and checking the same thing but using the "reduced basis vectors" obtained by doing Gauss-Jordan to the original nullspace basis vectors.